summaryrefslogtreecommitdiff
path: root/mapset.c
blob: e1a8f61ea811035af50f39f9b7e6c0221e6df4fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/**
 * Navit, a modular navigation system.
 * Copyright (C) 2005-2008 Navit Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

/** @file
 * 
 * @brief Contains code used for loading more than one map
 *
 * The code in this file introduces "mapsets", which are collections of several maps.
 * This enables navit to operate on more than one map at once. See map.c / map.h to learn
 * how maps are handled.
 */

#include <string.h>
#include <glib.h>
#include <glib/gprintf.h>
#include "debug.h"
#include "item.h"
#include "mapset.h"
#include "projection.h"
#include "map.h"

/**
 * @brief A mapset
 *
 * This structure holds a complete mapset
 */
struct mapset {
	GList *maps; /**< Linked list of all the maps in the mapset */
};

/**
 * @brief Creates a new, empty mapset
 *
 * @return The new mapset 
 */
struct mapset *mapset_new(struct attr *parent, struct attr **attrs)
{
	struct mapset *ms;

	ms=g_new0(struct mapset, 1);

	return ms;
}


/**
 * @brief Adds a map to a mapset
 *
 * @param ms The mapset to add the map to
 * @param m The map to be added
 */
int
mapset_add_attr(struct mapset *ms, struct attr *attr)
{
	switch (attr->type) {
	case attr_map:
		ms->maps=g_list_append(ms->maps, attr->u.map);
		return 1;
	default:
		return 0;
	}
}

#if 0
static void mapset_maps_free(struct mapset *ms)
{
	/* todo */
}
#endif

/**
 * @brief Destroys a mapset. 
 *
 * This destroys a mapset. Please note that it does not touch the contained maps
 * in any way.
 *
 * @param ms The mapset to be destroyed
 */
void mapset_destroy(struct mapset *ms)
{
	g_free(ms);
}

/**
 * @brief Handle for a mapset in use
 *
 * This struct is used for a mapset that is in use. With this it is possible to iterate
 * all maps in a mapset.
 */
struct mapset_handle {
	GList *l;	/**< Pointer to the current (next) map */
};

/**
 * @brief Returns a new handle for a mapset
 *
 * This returns a new handle for an existing mapset. The new handle points to the first
 * map in the set.
 *
 * @param ms The mapset to get a handle of
 * @return The new mapset handle
 */
struct mapset_handle *
mapset_open(struct mapset *ms)
{
	struct mapset_handle *ret=NULL;
	if(ms)
	{
		ret=g_new(struct mapset_handle, 1);
		ret->l=ms->maps;
	}

	return ret;
}

/**
 * @brief Gets the next map from a mapset handle
 *
 * If you set active to true, this function will not return any maps that
 * have the attr_active attribute associated with them and set to false.
 *
 * @param msh The mapset handle to get the next map of
 * @param active Set to true to only get active maps (See description)
 * @return The next map
 */
struct map * mapset_next(struct mapset_handle *msh, int active)
{
	struct map *ret;
	struct attr active_attr;

	for (;;) {
		if (!msh || !msh->l)
			return NULL;
		ret=msh->l->data;
		msh->l=g_list_next(msh->l);
		if (!active)
			return ret;			
		if (!map_get_attr(ret, attr_active, &active_attr, NULL))
			return ret;
		if (active_attr.u.num)
			return ret;
	}
}

/**
 * @brief Closes a mapset handle after it is no longer used
 *
 * @param msh Mapset handle to be closed
 */
void 
mapset_close(struct mapset_handle *msh)
{
	g_free(msh);
}

/**
 * @brief Holds information about a search in a mapset
 *
 * This struct holds information about a search (e.g. for a street) in a mapset. 
 *
 * @sa For a more detailed description see the documentation of mapset_search_new().
 */
struct mapset_search {
	GList *map;					/**< The list of maps to be searched within */
	struct map_search *ms;		/**< A map search struct for the map currently active */
	struct item *item;			/**< "Superior" item. */
	struct attr *search_attr;	/**< Attribute to be searched for. */
	int partial;				/**< Indicates if one would like to have partial matches */
};

/**
 * @brief Starts a search on a mapset
 *
 * This function starts a search on a mapset. What attributes one can search for depends on the
 * map plugin. See the description of map_search_new() in map.c for details.
 *
 * If you enable partial matches bear in mind that the search matches only the begin of the
 * strings - a search for a street named "street" would match to "streetfoo", but not to
 * "somestreet". Search is case insensitive.
 *
 * The item passed to this function specifies a "superior item" to "search within" - e.g. a town 
 * in which we want to search for a street, or a country in which to search for a town.
 *
 * @param ms The mapset that should be searched
 * @param item Specifies a superior item to "search within" (see description)
 * @param search_attr Attribute specifying what to search for. See description.
 * @param partial Set this to true to also have partial matches. See description.
 * @return A new mapset search struct for this search
 */
struct mapset_search *
mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
{
	struct mapset_search *this;
	dbg(1,"enter(%p,%p,%p,%d)\n", ms, item, search_attr, partial);
	this=g_new0(struct mapset_search,1);
	if(this != NULL && ms!=NULL )
        {
		this->map=ms->maps;
		this->item=item;
		this->search_attr=search_attr;
		this->partial=partial;
		this->ms=map_search_new(this->map->data, item, search_attr, partial);
		return this;
	}
	else
	{
		return NULL;
	}
}

/**
 * @brief Returns the next found item from a mapset search
 *
 * This function returns the next item from a mapset search or NULL if there are no more items found.
 * It automatically iterates through all the maps in the mapset. Please note that maps which have the
 * attr_active attribute associated with them and set to false are not searched.
 *
 * @param this The mapset search to return an item from
 * @return The next found item or NULL if there are no more items found
 */
struct item *
mapset_search_get_item(struct mapset_search *this)
{
	struct item *ret=NULL;
	struct attr active_attr;

	while ((this) && (!this->ms || !(ret=map_search_get_item(this->ms)))) { /* The current map has no more items to be returned */
		if (this->search_attr->type >= attr_country_all && this->search_attr->type <= attr_country_name)
			break;
		for (;;) {
			this->map=g_list_next(this->map);
			if (! this->map)
				break;
			if (!map_get_attr(this->map->data, attr_active, &active_attr, NULL))
				break;
			if (active_attr.u.num)
				break;
		}
		if (! this->map)
			break;
		map_search_destroy(this->ms);
		this->ms=map_search_new(this->map->data, this->item, this->search_attr, this->partial);
	}
	return ret;
}

/**
 * @brief Destroys a mapset search
 *
 * @param this The mapset search to be destroyed
 */
void
mapset_search_destroy(struct mapset_search *this)
{
	if (this) {
		map_search_destroy(this->ms);
		g_free(this);
	}
}