Adding comments to mapset.c
[navit-package] / navit / mapset.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 /** @file
21  * 
22  * @brief Contains code used for loading more than one map
23  *
24  * The code in this file introduces "mapsets", which are collections of several maps.
25  * This enables navit to operate on more than one map at once. See map.c / map.h to learn
26  * how maps are handled.
27  */
28
29 #include <string.h>
30 #include <glib.h>
31 #include <glib/gprintf.h>
32 #include "debug.h"
33 #include "item.h"
34 #include "mapset.h"
35 #include "projection.h"
36 #include "map.h"
37
38 /**
39  * @brief A mapset
40  *
41  * This structure holds a complete mapset
42  */
43 struct mapset {
44         GList *maps; /**< Linked list of all the maps in the mapset */
45 };
46
47 /**
48  * @brief Creates a new, empty mapset
49  *
50  * @return The new mapset 
51  */
52 struct mapset *mapset_new(void)
53 {
54         struct mapset *ms;
55
56         ms=g_new0(struct mapset, 1);
57
58         return ms;
59 }
60
61 /**
62  * @brief Adds a map to a mapset
63  *
64  * @param ms The mapset to add the map to
65  * @param m The map to be added
66  */
67 void mapset_add(struct mapset *ms, struct map *m)
68 {
69         ms->maps=g_list_append(ms->maps, m);
70 }
71
72 #if 0
73 static void mapset_maps_free(struct mapset *ms)
74 {
75         /* todo */
76 }
77 #endif
78
79 /**
80  * @brief Destroys a mapset. 
81  *
82  * This destroys a mapset. Please note that it does not touch the contained maps
83  * in any way.
84  *
85  * @param ms The mapset to be destroyed
86  */
87 void mapset_destroy(struct mapset *ms)
88 {
89         g_free(ms);
90 }
91
92 /**
93  * @brief Handle for a mapset in use
94  *
95  * This struct is used for a mapset that is in use. With this it is possible to iterate
96  * all maps in a mapset.
97  */
98 struct mapset_handle {
99         GList *l;       /**< Pointer to the current (next) map */
100 };
101
102 /**
103  * @brief Returns a new handle for a mapset
104  *
105  * This returns a new handle for an existing mapset. The new handle points to the first
106  * map in the set.
107  *
108  * @param ms The mapset to get a handle of
109  * @return The new mapset handle
110  */
111 struct mapset_handle *
112 mapset_open(struct mapset *ms)
113 {
114         struct mapset_handle *ret;
115
116         ret=g_new(struct mapset_handle, 1);
117         ret->l=ms->maps;
118
119         return ret;
120 }
121
122 /**
123  * @brief Gets the next map from a mapset handle
124  *
125  * If you set active to true, this function will not return any maps that
126  * have the attr_active attribute associated with them and set to false.
127  *
128  * @param msh The mapset handle to get the next map of
129  * @param active Set to true to only get active maps (See description)
130  * @return The next map
131  */
132 struct map * mapset_next(struct mapset_handle *msh, int active)
133 {
134         struct map *ret;
135         struct attr active_attr;
136
137         for (;;) {
138                 if (!msh->l)
139                         return NULL;
140                 ret=msh->l->data;
141                 msh->l=g_list_next(msh->l);
142                 if (!active)
143                         return ret;                     
144                 if (!map_get_attr(ret, attr_active, &active_attr, NULL))
145                         return ret;
146                 if (active_attr.u.num)
147                         return ret;
148         }
149 }
150
151 /**
152  * @brief Closes a mapset handle after it is no longer used
153  *
154  * @param msh Mapset handle to be closed
155  */
156 void 
157 mapset_close(struct mapset_handle *msh)
158 {
159         g_free(msh);
160 }
161
162 /**
163  * @brief Holds information about a search in a mapset
164  *
165  * This struct holds information about a search (e.g. for a street) in a mapset. 
166  *
167  * @sa For a more detailed description see the documentation of mapset_search_new().
168  */
169 struct mapset_search {
170         GList *map;                                     /**< The list of maps to be searched within */
171         struct map_search *ms;          /**< A map search struct for the map currently active */
172         struct item *item;                      /**< "Superior" item. */
173         struct attr *search_attr;       /**< Attribute to be searched for. */
174         int partial;                            /**< Indicates if one would like to have partial matches */
175 };
176
177 /**
178  * @brief Starts a search on a mapset
179  *
180  * This function starts a search on a mapset. What attributes one can search for depends on the
181  * map plugin. See the description of map_search_new() in map.c for details.
182  *
183  * If you enable partial matches bear in mind that the search matches only the begin of the
184  * strings - a search for a street named "street" would match to "streetfoo", but not to
185  * "somestreet". Search is case insensitive.
186  *
187  * The item passed to this function specifies a "superior item" to "search within" - e.g. a town 
188  * in which we want to search for a street, or a country in which to search for a town.
189  *
190  * @param ms The mapset that should be searched
191  * @param item Specifies a superior item to "search within" (see description)
192  * @param search_attr Attribute specifying what to search for. See description.
193  * @param partial Set this to true to also have partial matches. See description.
194  * @return A new mapset search struct for this search
195  */
196 struct mapset_search *
197 mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
198 {
199         struct mapset_search *this;
200         dbg(1,"enter(%p,%p,%p,%d)\n", ms, item, search_attr, partial);
201         this=g_new0(struct mapset_search,1);
202         this->map=ms->maps;
203         this->item=item;
204         this->search_attr=search_attr;
205         this->partial=partial;
206         this->ms=map_search_new(this->map->data, item, search_attr, partial);
207         return this;
208 }
209
210 /**
211  * @brief Returns the next found item from a mapset search
212  *
213  * This function returns the next item from a mapset search or NULL if there are no more items found.
214  * It automatically iterates through all the maps in the mapset. Please note that maps which have the
215  * attr_active attribute associated with them and set to false are not searched.
216  *
217  * @param this The mapset search to return an item from
218  * @return The next found item or NULL if there are no more items found
219  */
220 struct item *
221 mapset_search_get_item(struct mapset_search *this)
222 {
223         struct item *ret=NULL;
224         struct attr active_attr;
225
226         while (!this->ms || !(ret=map_search_get_item(this->ms))) { /* The current map has no more items to be returned */
227                 if (this->search_attr->type >= attr_country_all && this->search_attr->type <= attr_country_name)
228                         break;
229                 for (;;) {
230                         this->map=g_list_next(this->map);
231                         if (! this->map)
232                                 break;
233                         if (!map_get_attr(this->map->data, attr_active, &active_attr, NULL))
234                                 break;
235                         if (active_attr.u.num)
236                                 break;
237                 }
238                 if (! this->map)
239                         break;
240                 map_search_destroy(this->ms);
241                 this->ms=map_search_new(this->map->data, this->item, this->search_attr, this->partial);
242         }
243         return ret;
244 }
245
246 /**
247  * @brief Destroys a mapset search
248  *
249  * @param this The mapset search to be destroyed
250  */
251 void
252 mapset_search_destroy(struct mapset_search *this)
253 {
254         if (this) {
255                 map_search_destroy(this->ms);
256                 g_free(this);
257         }
258 }