2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
22 * @brief Contains code that makes navit able to load maps
24 * This file contains the code that makes navit able to load maps. Because
25 * navit is able to open maps in different formats, this code does not handle
26 * any map format itself. This is done by map plugins which register to this
27 * code by calling plugin_register_map_type().
29 * When opening a new map, the map plugin will return a pointer to a map_priv
30 * struct, which can be defined by the map plugin and contains whatever private
31 * data the map plugin needs to access the map. This pointer will also be used
32 * as a "handle" to access the map opened.
34 * A common task is to create a "map rect". A map rect is a rectangular part of
35 * the map, that one can for example retrieve items from. It is not possible to
36 * retrieve items directly from the complete map. Creating a map rect returns a
37 * pointer to a map_rect_priv, which contains private data for the map rect and
38 * will be used as "handle" for this map rect.
45 #include "projection.h"
49 #include "transform.h"
53 #include "xmlconfig.h"
56 * @brief Holds information about a map
58 * This structure holds information about a map.
61 struct object_func *func; /**< Object functions */
62 int refcount; /**< Reference count */
63 struct attr **attrs; /**< Attributes of this map */
64 struct map_methods meth; /**< Structure with pointers to the map plugin's functions */
65 struct map_priv *priv; /**< Private data of the map, only known to the map plugin */
66 struct callback_list *attr_cbl; /**< List of callbacks that are called when attributes change */
70 * @brief Describes a rectangular extract of a map
72 * This structure describes a rectangular extract of a map.
75 struct map *m; /**< The map this extract is from */
76 struct map_rect_priv *priv; /**< Private data of this map rect, only known to the map plugin */
80 * @brief Opens a new map
82 * This function opens a new map based on the attributes passed. This function
83 * takes the attribute "attr_type" to determine which type of map to open and passes
84 * all attributes to the map plugin's function that was specified in the
85 * plugin_register_new_map_type()-call.
87 * Note that every plugin should accept an attribute of type "attr_data" to be passed
88 * with the filename of the map to be opened as value.
90 * @param attrs Attributes specifying which map to open, see description
91 * @return The opened map or NULL on failure
94 map_new(struct attr *parent, struct attr **attrs)
97 struct map_priv *(*maptype_new)(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl);
98 struct attr *type=attr_search(attrs, NULL, attr_type);
101 dbg(0,"missing type\n");
104 maptype_new=plugin_get_map_type(type->u.str);
106 dbg(0,"invalid type '%s'\n", type->u.str);
110 m=g_new0(struct map, 1);
111 m->attrs=attr_list_dup(attrs);
114 m->attr_cbl=callback_list_new();
115 m->priv=maptype_new(&m->meth, attrs, m->attr_cbl);
124 map_ref(struct map* m)
132 * @brief Gets an attribute from a map
134 * @param this_ The map the attribute should be read from
135 * @param type The type of the attribute to be read
136 * @param attr Pointer to an attrib-structure where the attribute should be written to
137 * @param iter (NOT IMPLEMENTED) Used to iterate through all attributes of a type. Set this to NULL to get the first attribute, set this to an attr_iter to get the next attribute
138 * @return True if the attribute type was found, false if not
141 map_get_attr(struct map *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
144 if (this_->meth.map_get_attr)
145 ret=this_->meth.map_get_attr(this_->priv, type, attr);
147 ret=attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
152 * @brief Sets an attribute of a map
154 * This sets an attribute of a map, overwriting an attribute of the same type if it
155 * already exists. This function also calls all the callbacks that are registred
156 * to be called when attributes change.
158 * @param this_ The map to set the attribute of
159 * @param attr The attribute to set
160 * @return True if the attr could be set, false otherwise
163 map_set_attr(struct map *this_, struct attr *attr)
165 this_->attrs=attr_generic_set_attr(this_->attrs, attr);
166 if (this_->meth.map_set_attr)
167 this_->meth.map_set_attr(this_->priv, attr);
168 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
173 * @brief Registers a new callback for attribute-change
175 * This function registers a new callback function that should be called if the attributes
178 * @param this_ The map to associate the callback with
179 * @param cb The callback to add
182 map_add_callback(struct map *this_, struct callback *cb)
184 callback_list_add(this_->attr_cbl, cb);
188 * @brief Removes a callback from the list of attribute-change callbacks
190 * This function removes one callback from the list of callbacks functions that should be called
191 * when attributes of the map change.
193 * @param this_ The map to remove the callback from
194 * @param cb The callback to remove
197 map_remove_callback(struct map *this_, struct callback *cb)
199 callback_list_remove(this_->attr_cbl, cb);
204 * @brief Checks if strings from a map have to be converted
206 * @param this_ Map to be checked for the need to convert strings
207 * @return True if strings from the map have to be converted, false otherwise
210 map_requires_conversion(struct map *this_)
212 return (this_->meth.charset != NULL && strcmp(this_->meth.charset, "utf-8"));
216 * @brief Converts a string from a map
218 * @param this_ The map the string to be converted is from
219 * @param str The string to be converted
220 * @return The converted string. It has to be map_convert_free()d after use.
223 map_convert_string(struct map *this_, char *str)
225 return g_convert(str, -1,"utf-8",this_->meth.charset,NULL,NULL,NULL);
229 map_convert_dup(char *str)
231 return g_strdup(str);
235 * @brief Frees the memory allocated for a converted string
237 * @param str The string to be freed
240 map_convert_free(char *str)
246 * @brief Returns the projection of a map
248 * @param this_ The map to return the projection of
249 * @return The projection of the map
252 map_projection(struct map *this_)
254 return this_->meth.pro;
258 * @brief Sets the projection of a map
260 * @param this_ The map to set the projection of
261 * @param pro The projection to be set
264 map_set_projection(struct map *this_, enum projection pro)
270 * @brief Destroys an opened map
272 * @param m The map to be destroyed
276 map_destroy(struct map *m)
281 m->meth.map_destroy(m->priv);
282 attr_list_free(m->attrs);
283 callback_list_destroy(m->attr_cbl);
288 map_unref(struct map *m)
293 if (m->refcount <= 0)
298 * @brief Creates a new map rect
300 * This creates a new map rect, which can be used to retrieve items from a map. If
301 * sel is a linked-list of selections, all of them will be used. If you pass NULL as
302 * sel, this means "get me the whole map".
304 * @param m The map to build the rect on
305 * @param sel Map selection to choose the rectangle - may be NULL, see description
306 * @return A new map rect
309 map_rect_new(struct map *m, struct map_selection *sel)
314 printf("map_rect_new 0x%x,0x%x-0x%x,0x%x\n", r->lu.x, r->lu.y, r->rl.x, r->rl.y);
316 mr=g_new0(struct map_rect, 1);
318 mr->priv=m->meth.map_rect_new(m->priv, sel);
328 * @brief Gets the next item from a map rect
330 * Returns an item from a map rect and advances the "item pointer" one step further,
331 * so that at the next call the next item is returned. Returns NULL if there are no more items.
333 * @param mr The map rect to return an item from
334 * @return An item from the map rect
337 map_rect_get_item(struct map_rect *mr)
340 dbg_assert(mr != NULL);
341 dbg_assert(mr->m != NULL);
342 dbg_assert(mr->m->meth.map_rect_get_item != NULL);
343 ret=mr->m->meth.map_rect_get_item(mr->priv);
350 * @brief Returns the item specified by the ID
352 * @param mr The map rect to search for the item
353 * @param id_hi High part of the ID to be found
354 * @param id_lo Low part of the ID to be found
355 * @return The item with the specified ID or NULL if not found
358 map_rect_get_item_byid(struct map_rect *mr, int id_hi, int id_lo)
360 struct item *ret=NULL;
361 dbg_assert(mr != NULL);
362 dbg_assert(mr->m != NULL);
363 if (mr->m->meth.map_rect_get_item_byid)
364 ret=mr->m->meth.map_rect_get_item_byid(mr->priv, id_hi, id_lo);
371 * @brief Destroys a map rect
373 * @param mr The map rect to be destroyed
376 map_rect_destroy(struct map_rect *mr)
379 mr->m->meth.map_rect_destroy(mr->priv);
385 * @brief Holds information about a search on a map
387 * This structure holds information about a search performed on a map. This can be
388 * used as "handle" to retrieve items from a search.
392 struct attr search_attr;
397 * @brief Starts a search on a map
399 * This function starts a search on a map. What attributes one can search for depends on the
402 * The OSM/binfile plugin currently supports: attr_town_name, attr_street_name
403 * The MG plugin currently supports: ttr_town_postal, attr_town_name, attr_street_name
405 * If you enable partial matches bear in mind that the search matches only the begin of the
406 * strings - a search for a street named "street" would match to "streetfoo", but not to
407 * "somestreet". Search is case insensitive.
409 * The item passed to this function specifies a "superior item" to "search within" - e.g. a town
410 * in which we want to search for a street, or a country in which to search for a town.
412 * Please also note that the search for countries is not handled by map plugins but by navit internally -
413 * have a look into country.c for details. Because of that every map plugin has to accept a country item
414 * to be passed as "superior item".
416 * Note: If you change something here, please make sure to also update the documentation of mapset_search_new()
419 * @param m The map that should be searched
420 * @param item Specifies a superior item to "search within" (see description)
421 * @param search_attr Attribute specifying what to search for. See description.
422 * @param partial Set this to true to also have partial matches. See description.
423 * @return A new map search struct for this search
426 map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial)
428 struct map_search *this_;
429 dbg(1,"enter(%p,%p,%p,%d)\n", m, item, search_attr, partial);
430 dbg(1,"0x%x 0x%x 0x%x\n", attr_country_all, search_attr->type, attr_country_name);
431 this_=g_new0(struct map_search,1);
433 this_->search_attr=*search_attr;
434 if ((search_attr->type >= attr_country_all && search_attr->type <= attr_country_name) || search_attr->type == attr_country_id)
435 this_->priv=country_search_new(&this_->search_attr, partial);
437 if (m->meth.map_search_new) {
439 this_->search_attr.u.str=g_convert(this_->search_attr.u.str, -1,m->meth.charset,"utf-8",NULL,NULL,NULL);
440 this_->priv=m->meth.map_search_new(m->priv, item, &this_->search_attr, partial);
454 * @brief Returns an item from a map search
456 * This returns an item of the result of a search on a map and advances the "item pointer" one step,
457 * so that at the next call the next item will be returned. If there are no more items in the result
460 * @param this_ Map search struct of the search
461 * @return One item of the result
464 map_search_get_item(struct map_search *this_)
470 if ((this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name) || this_->search_attr.type == attr_country_id)
471 return country_search_get_item(this_->priv);
472 ret=this_->m->meth.map_search_get_item(this_->priv);
479 * @brief Destroys a map search struct
481 * @param this_ The map search struct to be destroyed
484 map_search_destroy(struct map_search *this_)
488 if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name)
489 country_search_destroy(this_->priv);
491 if (this_->m->meth.charset)
492 g_free(this_->search_attr.u.str);
493 this_->m->meth.map_search_destroy(this_->priv);
499 * @brief Creates a new rectangular map selection
501 * @param center Coordinates of the center of the new rectangle
502 * @param distance Distance of the rectangle's borders from the center
503 * @param order Desired order of the new selection
504 * @return The new map selection
506 struct map_selection *
507 map_selection_rect_new(struct pcoord *center, int distance, int order)
509 struct map_selection *ret=g_new0(struct map_selection, 1);
511 ret->range=item_range_all;
512 ret->u.c_rect.lu.x=center->x-distance;
513 ret->u.c_rect.lu.y=center->y+distance;
514 ret->u.c_rect.rl.x=center->x+distance;
515 ret->u.c_rect.rl.y=center->y-distance;
520 * @brief Duplicates a map selection, transforming coordinates
522 * This duplicates a map selection and at the same time transforms the internal
523 * coordinates of the selection from one projection to another.
525 * @param sel The map selection to be duplicated
526 * @param from The projection used for the selection at the moment
527 * @param to The projection that should be used for the duplicated selection
528 * @return A duplicated, transformed map selection
530 struct map_selection *
531 map_selection_dup_pro(struct map_selection *sel, enum projection from, enum projection to)
533 struct map_selection *next,**last;
534 struct map_selection *ret=NULL;
537 next = g_new(struct map_selection, 1);
539 if (from != projection_none || to != projection_none) {
540 transform_from_to(&sel->u.c_rect.lu, from, &next->u.c_rect.lu, to);
541 transform_from_to(&sel->u.c_rect.rl, from, &next->u.c_rect.rl, to);
551 * @brief Duplicates a map selection
553 * @param sel The map selection to duplicate
554 * @return The duplicated map selection
556 struct map_selection *
557 map_selection_dup(struct map_selection *sel)
559 return map_selection_dup_pro(sel, projection_none, projection_none);
563 * @brief Destroys a map selection
565 * @param sel The map selection to be destroyed
568 map_selection_destroy(struct map_selection *sel)
570 struct map_selection *next;
579 * @brief Checks if a selection contains a rectangle containing an item
581 * This function checks if a selection contains a rectangle which exactly contains
582 * an item. The rectangle is automatically built around the given item.
584 * @param sel The selection to be checked
585 * @param item The item that the rectangle should be built around
586 * @return True if the rectangle is within the selection, false otherwise
589 map_selection_contains_item_rect(struct map_selection *sel, struct item *item)
594 while (item_coord_get(item, &c, 1)) {
599 coord_rect_extend(&r, &c);
604 return map_selection_contains_rect(sel, &r);
610 * @brief Checks if a selection contains a item range
612 * This function checks if a selection contains at least one of the items in range
614 * @param sel The selection to be checked
615 * @param follow Whether the next pointer of the selection should be followed
616 * @param ranges The item ranges to be checked
617 * @count the number of elements in ranges
618 * @return True if there is a match, false otherwise
622 map_selection_contains_item_range(struct map_selection *sel, int follow, struct item_range *range, int count)
628 for (i = 0 ; i < count ; i++) {
629 if (item_range_intersects_range(&sel->range, &range[i]))
639 * @brief Checks if a selection contains a item
641 * This function checks if a selection contains a item type
643 * @param sel The selection to be checked
644 * @param follow Whether the next pointer of the selection should be followed
645 * @param item The item type to be checked
646 * @return True if there is a match, false otherwise
650 map_selection_contains_item(struct map_selection *sel, int follow, enum item_type type)
655 if (item_range_contains_item(&sel->range, type))
667 * @brief Checks if a pointer points to the private data of a map
669 * @param map The map whose private data should be checked.
670 * @param priv The private data that should be checked.
671 * @return True if priv is the private data of map
674 map_priv_is(struct map *map, struct map_priv *priv)
676 return (map->priv == priv);
680 map_dump_filedesc(struct map *map, FILE *out)
682 struct map_rect *mr=map_rect_new(map, NULL);
685 while ((item = map_rect_get_item(mr)))
686 item_dump_filedesc(item, map, out);
687 map_rect_destroy(mr);
691 map_dump_file(struct map *map, const char *file)
696 map_dump_filedesc(map, f);
699 dbg(0,"failed to open file '%s'\n",file);
703 map_dump(struct map *map)
705 map_dump_filedesc(map, stdout);
709 map_rect_create_item(struct map_rect *mr, enum item_type type_)
711 if(mr && mr->priv && mr->m) {
712 return mr->m->meth.map_rect_create_item(mr->priv, type_) ;
719 struct object_func map_func = {
721 (object_func_new)map_new,
722 (object_func_get_attr)map_get_attr,
723 (object_func_iter_new)NULL,
724 (object_func_iter_destroy)NULL,
725 (object_func_set_attr)map_set_attr,
726 (object_func_add_attr)NULL,
727 (object_func_remove_attr)NULL,
728 (object_func_init)NULL,
729 (object_func_destroy)map_destroy,
730 (object_func_dup)NULL,
731 (object_func_ref)map_ref,
732 (object_func_unref)map_unref,