Add:Core:Added address search again and made it available in a way similar to other...
[profile/ivi/navit.git] / navit / navit / map.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 that makes navit able to load maps
23  *
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().
28  *
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.
33  *
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.
39  */
40
41 #include <glib.h>
42 #include <string.h>
43 #include "debug.h"
44 #include "coord.h"
45 #include "projection.h"
46 #include "item.h"
47 #include "map.h"
48 #include "maptype.h"
49 #include "transform.h"
50 #include "plugin.h"
51 #include "callback.h"
52 #include "country.h"
53 #include "xmlconfig.h"
54
55 /**
56  * @brief Holds information about a map
57  *
58  * This structure holds information about a map.
59  */
60 struct 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 */
67 };
68
69 /**
70  * @brief Describes a rectangular extract of a map
71  *
72  * This structure describes a rectangular extract of a map.
73  */
74 struct map_rect {
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 */
77 };
78
79 /**
80  * @brief Opens a new map
81  *
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.
86  *
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.
89  *
90  * @param attrs Attributes specifying which map to open, see description
91  * @return The opened map or NULL on failure
92  */
93 struct map *
94 map_new(struct attr *parent, struct attr **attrs)
95 {
96         struct map *m;
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);
99
100         if (! type) {
101                 dbg(0,"missing type\n");
102                 return NULL;
103         }
104         maptype_new=plugin_get_map_type(type->u.str);
105         if (! maptype_new) {
106                 dbg(0,"invalid type '%s'\n", type->u.str);
107                 return NULL;
108         }
109
110         m=g_new0(struct map, 1);
111         m->attrs=attr_list_dup(attrs);
112         m->func=&map_func;
113         m->refcount = 1;
114         m->attr_cbl=callback_list_new();
115         m->priv=maptype_new(&m->meth, attrs, m->attr_cbl);
116         if (! m->priv) {
117                 map_destroy(m);
118                 m=NULL;
119         }
120         return m;
121 }
122
123 struct map *
124 map_ref(struct map* m)
125 {
126         m->refcount++;
127         return m;
128 }
129
130
131 /**
132  * @brief Gets an attribute from a map
133  *
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
139  */
140 int
141 map_get_attr(struct map *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
142 {
143         int ret=0;
144         if (this_->meth.map_get_attr)
145                 ret=this_->meth.map_get_attr(this_->priv, type, attr);
146         if (!ret)
147                 ret=attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
148         return ret;
149 }
150
151 /**
152  * @brief Sets an attribute of a map
153  *
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.
157  *
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
161  */
162 int
163 map_set_attr(struct map *this_, struct attr *attr)
164 {
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);
169         return 1;
170 }
171
172 /**
173  * @brief Registers a new callback for attribute-change
174  *
175  * This function registers a new callback function that should be called if the attributes
176  * of the map change.
177  *
178  * @param this_ The map to associate the callback with
179  * @param cb The callback to add
180  */
181 void
182 map_add_callback(struct map *this_, struct callback *cb)
183 {
184         callback_list_add(this_->attr_cbl, cb);
185 }
186
187 /**
188  * @brief Removes a callback from the list of attribute-change callbacks
189  *
190  * This function removes one callback from the list of callbacks functions that should be called
191  * when attributes of the map change.
192  *
193  * @param this_ The map to remove the callback from
194  * @param cb The callback to remove
195  */
196 void
197 map_remove_callback(struct map *this_, struct callback *cb)
198 {
199         callback_list_remove(this_->attr_cbl, cb);
200 }
201
202
203 /**
204  * @brief Checks if strings from a map have to be converted
205  *
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
208  */
209 int
210 map_requires_conversion(struct map *this_)
211 {
212         return (this_->meth.charset != NULL && strcmp(this_->meth.charset, "utf-8"));
213 }
214
215 /**
216  * @brief Converts a string from a map
217  *
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.
221  */
222 char *
223 map_convert_string(struct map *this_, char *str)
224 {
225         return g_convert(str, -1,"utf-8",this_->meth.charset,NULL,NULL,NULL);
226 }
227
228 char *
229 map_convert_dup(char *str)
230 {
231         return g_strdup(str);
232 }
233
234 /**
235  * @brief Frees the memory allocated for a converted string
236  *
237  * @param str The string to be freed
238  */
239 void
240 map_convert_free(char *str)
241 {
242         g_free(str);
243 }
244
245 /**
246  * @brief Returns the projection of a map
247  *
248  * @param this_ The map to return the projection of
249  * @return The projection of the map
250  */
251 enum projection
252 map_projection(struct map *this_)
253 {
254         return this_->meth.pro;
255 }
256
257 /**
258  * @brief Sets the projection of a map
259  *
260  * @param this_ The map to set the projection of
261  * @param pro The projection to be set
262  */
263 void
264 map_set_projection(struct map *this_, enum projection pro)
265 {
266         this_->meth.pro=pro;
267 }
268
269 /**
270  * @brief Destroys an opened map
271  *
272  * @param m The map to be destroyed
273  */
274
275 void
276 map_destroy(struct map *m)
277 {
278         if (!m)
279                 return;
280         if (m->priv)
281                 m->meth.map_destroy(m->priv);
282         attr_list_free(m->attrs);
283         callback_list_destroy(m->attr_cbl);
284         g_free(m);
285 }
286
287 void
288 map_unref(struct map *m)
289 {
290         if(!m)
291                 return;
292         m->refcount--;
293         if (m->refcount <= 0)
294                 map_destroy(m);
295 }
296
297 /**
298  * @brief Creates a new map rect
299  *
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".
303  *
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
307  */
308 struct map_rect *
309 map_rect_new(struct map *m, struct map_selection *sel)
310 {
311         struct map_rect *mr;
312
313 #if 0
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);
315 #endif
316         mr=g_new0(struct map_rect, 1);
317         mr->m=m;
318         mr->priv=m->meth.map_rect_new(m->priv, sel);
319         if (! mr->priv) {
320                 g_free(mr);
321                 mr=NULL;
322         }
323
324         return mr;
325 }
326
327 /**
328  * @brief Gets the next item from a map rect
329  *
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.
332  *
333  * @param mr The map rect to return an item from
334  * @return An item from the map rect
335  */
336 struct item *
337 map_rect_get_item(struct map_rect *mr)
338 {
339         struct item *ret;
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);
344         if (ret)
345                 ret->map=mr->m;
346         return ret;
347 }
348
349 /**
350  * @brief Returns the item specified by the ID
351  *
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
356  */
357 struct item *
358 map_rect_get_item_byid(struct map_rect *mr, int id_hi, int id_lo)
359 {
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);
365         if (ret)
366                 ret->map=mr->m;
367         return ret;
368 }
369
370 /**
371  * @brief Destroys a map rect
372  *
373  * @param mr The map rect to be destroyed
374  */
375 void
376 map_rect_destroy(struct map_rect *mr)
377 {
378         if (mr) {
379                 mr->m->meth.map_rect_destroy(mr->priv);
380                 g_free(mr);
381         }
382 }
383
384 /**
385  * @brief Holds information about a search on a map
386  *
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.
389  */
390 struct map_search {
391         struct map *m;
392         struct attr search_attr;
393         void *priv;
394 };
395
396 /**
397  * @brief Starts a search on a map
398  *
399  * This function starts a search on a map. What attributes one can search for depends on the
400  * map plugin.
401  *
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
404  *
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.
408  *
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.
411  *
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".
415  * 
416  * Note: If you change something here, please make sure to also update the documentation of mapset_search_new()
417  * in mapset.c!
418  *
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
424  */
425 struct map_search *
426 map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial)
427 {
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);
432         this_->m=m;
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);
436         else {
437                 if (m->meth.map_search_new) {
438                         if (m->meth.charset)
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);
441                         if (! this_->priv) {
442                                 g_free(this_);
443                                 this_=NULL;
444                         }
445                 } else {
446                         g_free(this_);
447                         this_=NULL;
448                 }
449         }
450         return this_;
451 }
452
453 /**
454  * @brief Returns an item from a map search
455  *
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
458  * NULL is returned.
459  *
460  * @param this_ Map search struct of the search
461  * @return One item of the result
462  */
463 struct item *
464 map_search_get_item(struct map_search *this_)
465 {
466         struct item *ret;
467
468         if (! this_)
469                 return NULL;
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);
473         if (ret)
474                 ret->map=this_->m;
475         return ret;
476 }
477
478 /**
479  * @brief Destroys a map search struct
480  *
481  * @param this_ The map search struct to be destroyed
482  */
483 void
484 map_search_destroy(struct map_search *this_)
485 {
486         if (! this_)
487                 return;
488         if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name)
489                 country_search_destroy(this_->priv);
490         else {
491                 if (this_->m->meth.charset)
492                                 g_free(this_->search_attr.u.str);
493                 this_->m->meth.map_search_destroy(this_->priv);
494         }
495         g_free(this_);
496 }
497
498 /**
499  * @brief Creates a new rectangular map selection
500  *
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
505  */
506 struct map_selection *
507 map_selection_rect_new(struct pcoord *center, int distance, int order)
508 {
509         struct map_selection *ret=g_new0(struct map_selection, 1);
510         ret->order=order;
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;
516         return ret;
517 }
518
519 /**
520  * @brief Duplicates a map selection, transforming coordinates
521  *
522  * This duplicates a map selection and at the same time transforms the internal
523  * coordinates of the selection from one projection to another.
524  *
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
529  */
530 struct map_selection *
531 map_selection_dup_pro(struct map_selection *sel, enum projection from, enum projection to)
532 {
533         struct map_selection *next,**last;
534         struct map_selection *ret=NULL;
535         last=&ret;
536         while (sel) {
537                 next = g_new(struct map_selection, 1);
538                 *next=*sel;
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);
542                 }
543                 *last=next;
544                 last=&next->next;
545                 sel = sel->next;
546         }
547         return ret;
548 }
549
550 /**
551  * @brief Duplicates a map selection
552  *
553  * @param sel The map selection to duplicate
554  * @return The duplicated map selection
555  */
556 struct map_selection *
557 map_selection_dup(struct map_selection *sel)
558 {
559         return map_selection_dup_pro(sel, projection_none, projection_none);
560 }
561
562 /**
563  * @brief Destroys a map selection
564  *
565  * @param sel The map selection to be destroyed
566  */
567 void
568 map_selection_destroy(struct map_selection *sel)
569 {
570         struct map_selection *next;
571         while (sel) {
572                 next = sel->next;
573                 g_free(sel);
574                 sel = next;
575         }
576 }
577
578 /**
579  * @brief Checks if a selection contains a rectangle containing an item
580  *
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.
583  *
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
587  */
588 int
589 map_selection_contains_item_rect(struct map_selection *sel, struct item *item)
590 {
591         struct coord c;
592         struct coord_rect r;
593         int count=0;
594         while (item_coord_get(item, &c, 1)) {
595                 if (! count) {
596                         r.lu=c;
597                         r.rl=c;
598                 } else
599                         coord_rect_extend(&r, &c);
600                 count++;
601         }
602         if (! count)
603                 return 0;
604         return map_selection_contains_rect(sel, &r);
605
606 }
607
608
609 /**
610  * @brief Checks if a selection contains a item range
611  *
612  * This function checks if a selection contains at least one of the items in range
613  *
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
619  */
620
621 int
622 map_selection_contains_item_range(struct map_selection *sel, int follow, struct item_range *range, int count)
623 {
624         int i;
625         if (! sel)
626                 return 1;
627         while (sel) {
628                 for (i = 0 ; i < count ; i++) {
629                         if (item_range_intersects_range(&sel->range, &range[i]))
630                                 return 1;
631                 }
632                 if (! follow)
633                         break;
634                 sel=sel->next;
635         }
636         return 0;
637 }
638 /**
639  * @brief Checks if a selection contains a item 
640  *
641  * This function checks if a selection contains a item type
642  *
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
647  */
648
649 int
650 map_selection_contains_item(struct map_selection *sel, int follow, enum item_type type)
651 {
652         if (! sel)
653                 return 1;
654         while (sel) {
655                 if (item_range_contains_item(&sel->range, type))
656                         return 1;
657                 if (! follow)
658                         break;
659                 sel=sel->next;
660         }
661         return 0;
662 }
663
664
665
666 /**
667  * @brief Checks if a pointer points to the private data of a map
668  *
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
672  */
673 int
674 map_priv_is(struct map *map, struct map_priv *priv)
675 {
676         return (map->priv == priv);
677 }
678
679 void
680 map_dump_filedesc(struct map *map, FILE *out)
681 {
682         struct map_rect *mr=map_rect_new(map, NULL);
683         struct item *item;
684
685         while ((item = map_rect_get_item(mr))) 
686                 item_dump_filedesc(item, map, out);
687         map_rect_destroy(mr);
688 }
689
690 void
691 map_dump_file(struct map *map, const char *file)
692 {
693         FILE *f;
694         f=fopen(file,"w");
695         if (f) {
696                 map_dump_filedesc(map, f);
697                 fclose(f);
698         } else 
699                 dbg(0,"failed to open file '%s'\n",file);
700 }
701
702 void
703 map_dump(struct map *map)
704 {
705         map_dump_filedesc(map, stdout);
706 }
707
708 struct item * 
709 map_rect_create_item(struct map_rect *mr, enum item_type type_)
710 {
711         if(mr && mr->priv && mr->m) {
712                 return mr->m->meth.map_rect_create_item(mr->priv, type_) ;
713         }
714         else {
715                 return NULL;
716         }
717 }
718
719 struct object_func map_func = {
720         attr_map,
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,
733 };
734
735
736