/[zanavi_public1]/navit/navit/search.c
ZANavi

Contents of /navit/navit/search.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (hide annotations) (download)
Mon Apr 9 21:27:36 2012 UTC (12 years ago) by zoff99
File MIME type: text/plain
File size: 58167 byte(s)
lots of new stuff, tranlsations, bug fixes ...
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3     * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
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     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     #include <stdlib.h>
40     #include <glib.h>
41     #include <string.h>
42     #include <math.h>
43     #include "debug.h"
44     #include "projection.h"
45     #include "item.h"
46     #include "map.h"
47     #include "mapset.h"
48     #include "coord.h"
49     #include "transform.h"
50     #include "search.h"
51     #include "country.h"
52     #include "navit.h"
53    
54     #if HAVE_API_ANDROID
55     #include "android.h"
56     #endif
57     #include "layout.h"
58     #include "map.h"
59     #include "linguistics.h"
60    
61 zoff99 27 struct search_list_level
62     {
63 zoff99 2 struct mapset *ms;
64     struct search_list_common *parent;
65     struct attr *attr;
66     int partial;
67     int selected;
68     struct mapset_search *search;
69     GHashTable *hash;
70 zoff99 27 GList *list, *curr, *last;
71 zoff99 2 };
72    
73 zoff99 27 struct interpolation
74     {
75 zoff99 2 int side, mode, rev;
76     char *first, *last, *curr;
77     };
78    
79 zoff99 27 struct search_list
80     {
81 zoff99 2 struct mapset *ms;
82     struct item *item;
83     int level;
84     struct search_list_level levels[4];
85     struct search_list_result result;
86     struct search_list_result last_result;
87     int last_result_valid;
88     char *postal;
89     struct interpolation inter;
90     };
91    
92 zoff99 27 static guint search_item_hash_hash(gconstpointer key)
93 zoff99 2 {
94 zoff99 27 const struct item *itm = key;
95     gconstpointer hashkey = (gconstpointer) GINT_TO_POINTER(itm->id_hi ^ itm->id_lo);
96 zoff99 2 return g_direct_hash(hashkey);
97     }
98    
99 zoff99 27 static gboolean search_item_hash_equal(gconstpointer a, gconstpointer b)
100 zoff99 2 {
101 zoff99 27 const struct item *itm_a = a;
102     const struct item *itm_b = b;
103 zoff99 2 if (item_is_equal_id(*itm_a, *itm_b))
104     return TRUE;
105     return FALSE;
106     }
107    
108     struct search_list *
109     search_list_new(struct mapset *ms)
110     {
111     struct search_list *ret;
112    
113     ret=g_new0(struct search_list, 1);
114 zoff99 27 ret->ms = ms;
115    
116 zoff99 2 return ret;
117     }
118    
119     static void search_list_search_free(struct search_list *sl, int level);
120    
121 zoff99 27 static int search_list_level(enum attr_type attr_type)
122 zoff99 2 {
123 zoff99 27 switch (attr_type)
124     {
125     case attr_country_all:
126     case attr_country_id:
127     case attr_country_iso2:
128     case attr_country_iso3:
129     case attr_country_car:
130     case attr_country_name:
131     return 0;
132     case attr_town_postal:
133     return 1;
134     case attr_town_name:
135     case attr_district_name:
136     case attr_town_or_district_name:
137     return 1;
138     case attr_street_name:
139     return 2;
140     case attr_house_number:
141     return 3;
142     case attr_postal:
143     return -1;
144     default:
145     dbg(0, "unknown search '%s'\n", attr_to_name(attr_type));
146     return -1;
147 zoff99 2 }
148     }
149    
150 zoff99 27 static void interpolation_clear(struct interpolation *inter)
151 zoff99 2 {
152 zoff99 27 inter->mode = inter->side = 0;
153 zoff99 2 g_free(inter->first);
154     g_free(inter->last);
155     g_free(inter->curr);
156 zoff99 27 inter->first = inter->last = inter->curr = NULL;
157 zoff99 2 }
158    
159 zoff99 27 void search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
160 zoff99 2 {
161     struct search_list_level *le;
162 zoff99 27 int level = search_list_level(search_attr->type);
163     this_->item = NULL;
164 zoff99 2 interpolation_clear(&this_->inter);
165 zoff99 15 //dbg(0,"## enter\n");
166     //dbg(0,"## level=%d\n", level);
167     if (level != -1)
168     {
169 zoff99 27 this_->result.id = 0;
170     this_->level = level;
171     le = &this_->levels[level];
172 zoff99 2 search_list_search_free(this_, level);
173 zoff99 27 le->attr = attr_dup(search_attr);
174     le->partial = partial;
175 zoff99 15 if (level > 0)
176     {
177 zoff99 27 le = &this_->levels[level - 1];
178     le->curr = le->list;
179 zoff99 2 }
180 zoff99 15 //dbg(0,"## le=%p partial=%d\n", le, partial);
181     }
182     else if (search_attr->type == attr_postal)
183     {
184 zoff99 2 g_free(this_->postal);
185 zoff99 27 this_->postal = g_strdup(search_attr->u.str);
186 zoff99 2 }
187 zoff99 15 //dbg(0,"## return\n");
188 zoff99 2 }
189    
190     struct search_list_common *
191     search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode)
192     {
193 zoff99 27 int level = search_list_level(attr_type);
194     int num = 0;
195 zoff99 2 struct search_list_level *le;
196     struct search_list_common *slc;
197     GList *curr;
198 zoff99 27 le = &this_->levels[level];
199     curr = le->list;
200 zoff99 2 if (mode > 0 || !id)
201 zoff99 27 le->selected = mode;
202 zoff99 2 //dbg(0,"enter level=%d %d %d %p\n", level, id, mode, curr);
203 zoff99 27 while (curr)
204     {
205 zoff99 2 num++;
206 zoff99 27 if (!id || num == id)
207     {
208     slc = curr->data;
209     slc->selected = mode;
210     if (id)
211     {
212     le->last = curr;
213 zoff99 2 //dbg(0,"found\n");
214     return slc;
215     }
216     }
217 zoff99 27 curr = g_list_next(curr);
218 zoff99 2 }
219     //dbg(0,"not found\n");
220     return NULL;
221     }
222    
223 zoff99 27 static void search_list_common_new(struct item *item, struct search_list_common *common)
224 zoff99 2 {
225     struct attr attr;
226     if (item_attr_get(item, attr_town_name, &attr))
227 zoff99 27 common->town_name = map_convert_string(item->map, attr.u.str);
228 zoff99 2 else
229 zoff99 27 common->town_name = NULL;
230 zoff99 2 if (item_attr_get(item, attr_county_name, &attr))
231 zoff99 27 common->county_name = map_convert_string(item->map, attr.u.str);
232 zoff99 2 else
233 zoff99 27 common->county_name = NULL;
234 zoff99 2 if (item_attr_get(item, attr_district_name, &attr))
235 zoff99 27 common->district_name = map_convert_string(item->map, attr.u.str);
236 zoff99 2 else
237 zoff99 27 common->district_name = NULL;
238 zoff99 2 if (item_attr_get(item, attr_postal, &attr))
239 zoff99 27 common->postal = map_convert_string(item->map, attr.u.str);
240 zoff99 2 else if (item_attr_get(item, attr_town_postal, &attr))
241 zoff99 27 common->postal = map_convert_string(item->map, attr.u.str);
242 zoff99 2 else
243 zoff99 27 common->postal = NULL;
244     if (item_attr_get(item, attr_postal_mask, &attr))
245     common->postal_mask = map_convert_string(item->map, attr.u.str);
246     else
247     common->postal_mask = NULL;
248 zoff99 2 }
249    
250 zoff99 27 static void search_list_common_destroy(struct search_list_common *common)
251 zoff99 2 {
252     map_convert_free(common->town_name);
253     map_convert_free(common->district_name);
254     map_convert_free(common->county_name);
255     map_convert_free(common->postal);
256     map_convert_free(common->postal_mask);
257     }
258    
259     static struct search_list_country *
260     search_list_country_new(struct item *item)
261     {
262     struct search_list_country *ret=g_new0(struct search_list_country, 1);
263     struct attr attr;
264    
265 zoff99 27 ret->common.item = ret->common.unique = *item;
266 zoff99 2 if (item_attr_get(item, attr_country_car, &attr))
267 zoff99 27 ret->car = g_strdup(attr.u.str);
268     if (item_attr_get(item, attr_country_iso2, &attr))
269     {
270 zoff99 2 #if HAVE_API_ANDROID
271     ret->iso2=g_malloc(strlen(attr.u.str)+1);
272     strtolower(ret->iso2, attr.u.str);
273     #else
274 zoff99 27 ret->iso2 = g_strdup(attr.u.str);
275 zoff99 2 #endif
276 zoff99 27 ret->flag = g_strdup_printf("country_%s", ret->iso2);
277 zoff99 2 }
278     if (item_attr_get(item, attr_country_iso3, &attr))
279 zoff99 27 ret->iso3 = g_strdup(attr.u.str);
280 zoff99 2 if (item_attr_get(item, attr_country_name, &attr))
281 zoff99 27 ret->name = g_strdup(attr.u.str);
282 zoff99 2 return ret;
283     }
284    
285 zoff99 27 static void search_list_country_destroy(struct search_list_country *this_)
286 zoff99 2 {
287     g_free(this_->car);
288     g_free(this_->iso2);
289     g_free(this_->iso3);
290     g_free(this_->flag);
291     g_free(this_->name);
292     g_free(this_);
293     }
294    
295     static struct search_list_town *
296     search_list_town_new(struct item *item)
297     {
298     struct search_list_town *ret=g_new0(struct search_list_town, 1);
299     struct attr attr;
300     struct coord c;
301 zoff99 27
302     ret->itemt = *item;
303     ret->common.item = ret->common.unique = *item;
304    
305     if (item_attr_get(item, attr_town_streets_item, &attr))
306     {
307     //dbg(1, "town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
308     ret->common.unique = *attr.u.item;
309 zoff99 2 }
310 zoff99 27
311 zoff99 2 search_list_common_new(item, &ret->common);
312 zoff99 27
313 zoff99 2 if (item_attr_get(item, attr_county_name, &attr))
314 zoff99 27 {
315     ret->county = map_convert_string(item->map, attr.u.str);
316     }
317 zoff99 2 else
318 zoff99 27 {
319     ret->county = NULL;
320     }
321    
322     if (item_coord_get(item, &c, 1))
323     {
324 zoff99 2 ret->common.c=g_new(struct pcoord, 1);
325 zoff99 27 ret->common.c->x = c.x;
326     ret->common.c->y = c.y;
327 zoff99 2 ret->common.c->pro = map_projection(item->map);
328     }
329 zoff99 27 else
330     {
331     // some error with lat/lng !!
332     // but still return something, or app will crash
333     ret->common.c=g_new(struct pcoord, 1);
334     ret->common.c->x = 0;
335     ret->common.c->y = 0;
336     ret->common.c->pro = map_projection(item->map);
337     }
338 zoff99 2 return ret;
339     }
340    
341 zoff99 27 static void search_list_town_destroy(struct search_list_town *this_)
342 zoff99 2 {
343     map_convert_free(this_->county);
344     search_list_common_destroy(&this_->common);
345     if (this_->common.c)
346     g_free(this_->common.c);
347     g_free(this_);
348     }
349    
350     static struct search_list_street *
351     search_list_street_new(struct item *item)
352     {
353     struct search_list_street *ret=g_new0(struct search_list_street, 1);
354     struct attr attr;
355     struct coord c;
356 zoff99 27
357     ret->common.item = ret->common.unique = *item;
358 zoff99 2 if (item_attr_get(item, attr_street_name, &attr))
359 zoff99 27 {
360     ret->name = map_convert_string(item->map, attr.u.str);
361     }
362 zoff99 2 else
363 zoff99 27 {
364     ret->name = NULL;
365     }
366 zoff99 2 search_list_common_new(item, &ret->common);
367 zoff99 27 if (item_coord_get(item, &c, 1))
368     {
369 zoff99 2 ret->common.c=g_new(struct pcoord, 1);
370 zoff99 27 ret->common.c->x = c.x;
371     ret->common.c->y = c.y;
372 zoff99 2 ret->common.c->pro = map_projection(item->map);
373     }
374 zoff99 27 else
375     {
376     // some error with lat/lng !!
377     // but still return something, or app will crash
378     ret->common.c=g_new(struct pcoord, 1);
379     ret->common.c->x = 0;
380     ret->common.c->y = 0;
381     ret->common.c->pro = map_projection(item->map);
382     }
383 zoff99 2 return ret;
384     }
385    
386 zoff99 27 static void search_list_street_destroy(struct search_list_street *this_)
387 zoff99 2 {
388     map_convert_free(this_->name);
389     search_list_common_destroy(&this_->common);
390     if (this_->common.c)
391     {
392     g_free(this_->common.c);
393     }
394     g_free(this_);
395     }
396    
397     static char *
398     search_interpolate(struct interpolation *inter)
399     {
400 zoff99 27 dbg(1, "interpolate %s-%s %s\n", inter->first, inter->last, inter->curr);
401 zoff99 2 if (!inter->first || !inter->last)
402     return NULL;
403 zoff99 27 if (!inter->curr)
404     inter->curr = g_strdup(inter->first);
405     else
406     {
407     if (strcmp(inter->curr, inter->last))
408     {
409     int next = atoi(inter->curr) + (inter->mode ? 2 : 1);
410 zoff99 2 g_free(inter->curr);
411     if (next == atoi(inter->last))
412 zoff99 27 inter->curr = g_strdup(inter->last);
413 zoff99 2 else
414 zoff99 27 inter->curr = g_strdup_printf("%d", next);
415     }
416     else
417     {
418 zoff99 2 g_free(inter->curr);
419 zoff99 27 inter->curr = NULL;
420 zoff99 2 }
421     }
422 zoff99 27 dbg(1, "interpolate result %s\n", inter->curr);
423 zoff99 2 return inter->curr;
424     }
425    
426 zoff99 27 static void search_interpolation_split(char *str, struct interpolation *inter)
427 zoff99 2 {
428 zoff99 27 char *pos = strchr(str, '-');
429     char *first, *last;
430 zoff99 2 int len;
431 zoff99 27 if (!pos)
432     {
433     inter->first = g_strdup(str);
434     inter->last = g_strdup(str);
435     inter->rev = 0;
436 zoff99 2 return;
437     }
438 zoff99 27 len = pos - str;
439     first = g_malloc(len + 1);
440 zoff99 2 strncpy(first, str, len);
441 zoff99 27 first[len] = '\0';
442     last = g_strdup(pos + 1);
443     dbg(1, "%s = %s - %s\n", str, first, last);
444     if (atoi(first) > atoi(last))
445     {
446     inter->first = last;
447     inter->last = first;
448     inter->rev = 1;
449 zoff99 2 }
450 zoff99 27 else
451     {
452     inter->first = first;
453     inter->last = last;
454     inter->rev = 0;
455     }
456 zoff99 2 }
457    
458 zoff99 27 static int search_setup_interpolation(struct item *item, enum attr_type i0, enum attr_type i1, enum attr_type i2, struct interpolation *inter)
459 zoff99 2 {
460     struct attr attr;
461     g_free(inter->first);
462     g_free(inter->last);
463     g_free(inter->curr);
464 zoff99 27 inter->first = inter->last = inter->curr = NULL;
465     dbg(1, "setup %s\n", attr_to_name(i0));
466     if (item_attr_get(item, i0, &attr))
467     {
468 zoff99 2 search_interpolation_split(attr.u.str, inter);
469 zoff99 27 inter->mode = 0;
470     }
471     else if (item_attr_get(item, i1, &attr))
472     {
473 zoff99 2 search_interpolation_split(attr.u.str, inter);
474 zoff99 27 inter->mode = 1;
475     }
476     else if (item_attr_get(item, i2, &attr))
477     {
478 zoff99 2 search_interpolation_split(attr.u.str, inter);
479 zoff99 27 inter->mode = 2;
480     }
481     else
482 zoff99 2 return 0;
483     return 1;
484     }
485    
486 zoff99 27 static int search_match(char *str, char *search, int partial)
487 zoff99 2 {
488     if (!partial)
489     return (!g_strcasecmp(str, search));
490     else
491     return (!g_strncasecmp(str, search, strlen(search)));
492     }
493    
494     static struct pcoord *
495     search_house_number_coordinate(struct item *item, struct interpolation *inter)
496     {
497     struct pcoord *ret=g_new(struct pcoord, 1);
498     ret->pro = map_projection(item->map);
499 zoff99 27 if (item_is_point(*item))
500     {
501 zoff99 2 struct coord c;
502 zoff99 27 if (item_coord_get(item, &c, 1))
503     {
504     ret->x = c.x;
505     ret->y = c.y;
506     }
507     else
508     {
509 zoff99 2 g_free(ret);
510 zoff99 27 ret = NULL;
511 zoff99 2 }
512 zoff99 27 }
513     else
514     {
515     int count, max = 1024;
516     int hn_pos, hn_length;
517     struct coord *c = g_alloca(sizeof(struct coord) * max);
518 zoff99 2 item_coord_rewind(item);
519 zoff99 27 count = item_coord_get(item, c, max);
520     hn_length = atoi(inter->last) - atoi(inter->first);
521 zoff99 2 if (inter->rev)
522 zoff99 27 hn_pos = atoi(inter->last) - atoi(inter->curr);
523 zoff99 2 else
524 zoff99 27 hn_pos = atoi(inter->curr) - atoi(inter->first);
525     if (count)
526     {
527     int i, distance_sum = 0, hn_distance;
528     int *distances = g_alloca(sizeof(int) * (count - 1));
529     dbg(1, "count=%d hn_length=%d hn_pos=%d (%s of %s-%s)\n", count, hn_length, hn_pos, inter->curr, inter->first, inter->last);
530     if (!hn_length)
531     {
532     hn_length = 2;
533     hn_pos = 1;
534 zoff99 2 }
535 zoff99 27 if (count == max)
536     dbg(0, "coordinate overflow\n");
537     for (i = 0; i < count - 1; i++)
538     {
539     distances[i] = navit_sqrt(transform_distance_sq(&c[i], &c[i + 1]));
540     distance_sum += distances[i];
541     dbg(1, "distance[%d]=%d\n", i, distances[i]);
542 zoff99 2 }
543 zoff99 27 dbg(1, "sum=%d\n", distance_sum);
544     hn_distance = distance_sum * hn_pos / hn_length;
545     dbg(1, "hn_distance=%d\n", hn_distance);
546     i = 0;
547     while (i < count - 1 && hn_distance > distances[i])
548     hn_distance -= distances[i++];
549     dbg(1, "remaining distance=%d from %d\n", hn_distance, distances[i]);
550     ret->x = (c[i + 1].x - c[i].x) * hn_distance / distances[i] + c[i].x;
551     ret->y = (c[i + 1].y - c[i].y) * hn_distance / distances[i] + c[i].y;
552 zoff99 2 }
553     }
554     return ret;
555     }
556    
557     static struct search_list_house_number *
558     search_list_house_number_new(struct item *item, struct interpolation *inter, char *inter_match, int inter_partial)
559     {
560     struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1);
561     struct attr attr;
562     char *hn;
563    
564     // dbg(0,"@@@@ enter @@@@\n");
565    
566 zoff99 27 ret->common.item = ret->common.unique = *item;
567 zoff99 2 //if (item_attr_get(item, attr_street_name, &attr))
568     // dbg(0,"xx1 %s\n",attr.u.str);
569     if (item_attr_get(item, attr_house_number, &attr))
570 zoff99 27 ret->house_number = map_convert_string(item->map, attr.u.str);
571     else
572     {
573 zoff99 2 //if (item_attr_get(item, attr_street_name, &attr))
574     // dbg(0,"xx2 %s\n",attr.u.str);
575 zoff99 27 for (;;)
576     {
577 zoff99 2 //dbg(0,"interpolate 11");
578 zoff99 27 ret->interpolation = 1;
579     switch (inter->side)
580     {
581     case 0:
582     //dbg(0,"interpolate 11 0");
583     inter->side = -1;
584     search_setup_interpolation(item, attr_house_number_left, attr_house_number_left_odd, attr_house_number_left_even, inter);
585     case -1:
586     //dbg(0,"interpolate 11 -1");
587     if ((hn = search_interpolate(inter)))
588     break;
589     inter->side = 1;
590     search_setup_interpolation(item, attr_house_number_right, attr_house_number_right_odd, attr_house_number_right_even, inter);
591     case 1:
592     //dbg(0,"interpolate 11 1");
593     if ((hn = search_interpolate(inter)))
594     break;
595     default:
596     //dbg(0,"interpolate 11 default");
597     g_free(ret);
598     return NULL;
599 zoff99 2 }
600     if (search_match(hn, inter_match, inter_partial))
601     {
602     //dbg(0,"interpolate 22");
603     //dbg(0,"match %s %s-%s\n",hn, inter->first, inter->last);
604 zoff99 27 ret->house_number = map_convert_string(item->map, hn);
605 zoff99 2 break;
606     }
607     }
608     }
609     //dbg(0,"interpolate 33");
610     search_list_common_new(item, &ret->common);
611 zoff99 27 ret->common.c = search_house_number_coordinate(item, ret->interpolation ? inter : NULL);
612 zoff99 2 //dbg(0,"interpolate 44");
613     return ret;
614     }
615    
616 zoff99 27 static void search_list_house_number_destroy(struct search_list_house_number *this_)
617 zoff99 2 {
618     map_convert_free(this_->house_number);
619     search_list_common_destroy(&this_->common);
620     if (this_->common.c)
621     g_free(this_->common.c);
622     g_free(this_);
623     }
624    
625 zoff99 27 static void search_list_result_destroy(int level, void *p)
626 zoff99 2 {
627 zoff99 27 switch (level)
628     {
629     case 0:
630     search_list_country_destroy(p);
631     break;
632     case 1:
633     search_list_town_destroy(p);
634     break;
635     case 2:
636     search_list_street_destroy(p);
637     break;
638     case 3:
639     search_list_house_number_destroy(p);
640     break;
641 zoff99 2 }
642     }
643    
644 zoff99 27 static void search_list_search_free(struct search_list *sl, int level)
645 zoff99 2 {
646     //dbg(0,"enter\n");
647    
648 zoff99 27 struct search_list_level *le = &sl->levels[level];
649     GList *next, *curr;
650 zoff99 2 if (le->search)
651     {
652     mapset_search_destroy(le->search);
653 zoff99 27 le->search = NULL;
654 zoff99 2 }
655     #if 0 /* FIXME */
656 zoff99 27 if (le->hash)
657     {
658 zoff99 2 g_hash_table_destroy(le->hash);
659     le->hash=NULL;
660     }
661     #endif
662 zoff99 27 curr = le->list;
663 zoff99 2 while (curr)
664     {
665     search_list_result_destroy(level, curr->data);
666 zoff99 27 next = g_list_next(curr);
667     curr = next;
668 zoff99 2 }
669     attr_free(le->attr);
670     g_list_free(le->list);
671 zoff99 27 le->list = NULL;
672     le->curr = NULL;
673     le->last = NULL;
674 zoff99 2
675     //dbg(0,"return\n");
676     }
677    
678     char *
679     search_postal_merge(char *mask, char *new)
680     {
681     int i;
682 zoff99 27 char *ret = NULL;
683     dbg(1, "enter %s %s\n", mask, new);
684 zoff99 2 if (!new)
685     return NULL;
686     if (!mask)
687     return g_strdup(new);
688 zoff99 27 i = 0;
689     while (mask[i] && new[i])
690     {
691 zoff99 2 if (mask[i] != '.' && mask[i] != new[i])
692     break;
693     i++;
694 zoff99 27
695 zoff99 2 }
696 zoff99 27 if (mask[i])
697     {
698     ret = g_strdup(mask);
699     while (mask[i])
700     ret[i++] = '.';
701 zoff99 2 }
702 zoff99 27 dbg(1, "merged %s with %s as %s\n", mask, new, ret);
703 zoff99 2 return ret;
704     }
705    
706     char *
707     search_postal_merge_replace(char *mask, char *new)
708     {
709 zoff99 27 char *ret = search_postal_merge(mask, new);
710 zoff99 2 if (!ret)
711     return mask;
712     g_free(mask);
713     return ret;
714     }
715    
716 zoff99 27 static int postal_match(char *postal, char *mask)
717 zoff99 2 {
718 zoff99 27 for (;;)
719     {
720 zoff99 2 if ((*postal != *mask) && (*mask != '.'))
721     return 0;
722 zoff99 27 if (!*postal)
723     {
724 zoff99 2 if (!*mask)
725     return 1;
726     else
727     return 0;
728     }
729     postal++;
730     mask++;
731     }
732     }
733    
734 zoff99 27 static int search_add_result(struct search_list_level *le, struct search_list_common *slc)
735 zoff99 2 {
736     struct search_list_common *slo;
737     char *merged;
738 zoff99 15
739     //dbg(0,"enter\n");
740    
741     //slo=g_hash_table_lookup(le->hash, &slc->unique);
742     //if (!slo) {
743 zoff99 27 //g_hash_table_insert(le->hash, &slc->unique, slc);
744     if (slc->postal && !slc->postal_mask)
745     {
746     slc->postal_mask = g_strdup(slc->postal);
747     }
748     // ******
749     g_list_free(le->list);
750     le->list = NULL;
751     // ******
752     le->list = g_list_append(le->list, slc);
753     return 1;
754 zoff99 15 //}
755 zoff99 27 merged = search_postal_merge(slo->postal_mask, slc->postal);
756 zoff99 15 if (merged)
757     {
758 zoff99 2 g_free(slo->postal_mask);
759 zoff99 27 slo->postal_mask = merged;
760 zoff99 2 }
761     return 0;
762     }
763    
764     struct search_list_result *
765     search_list_get_result(struct search_list *this_)
766     {
767 zoff99 27 struct search_list_level *le, *leu;
768     int level = this_->level;
769 zoff99 2 struct attr attr2;
770 zoff99 27 int has_street_name = 0;
771 zoff99 2
772 zoff99 11 //dbg(0,"******* enter *******\n");
773 zoff99 27 le = &this_->levels[level];
774 zoff99 2 //dbg(0,"le=%p\n", le);
775     for (;;)
776     {
777     //dbg(0,"le->search=%p\n", le->search);
778 zoff99 27 if (!le->search)
779 zoff99 2 {
780     //dbg(0,"partial=%d level=%d\n", le->partial, level);
781 zoff99 27 if (!level)
782     le->parent = NULL;
783 zoff99 2 else
784     {
785 zoff99 27 leu = &this_->levels[level - 1];
786 zoff99 2 //dbg(0,"leu->curr=%p\n", leu->curr);
787     for (;;)
788     {
789     //dbg(0,"*********########");
790    
791     struct search_list_common *slc;
792 zoff99 27 if (!leu->curr)
793 zoff99 2 {
794     return NULL;
795     }
796 zoff99 27 le->parent = leu->curr->data;
797     leu->last = leu->curr;
798     leu->curr = g_list_next(leu->curr);
799     slc = (struct search_list_common *) (le->parent);
800 zoff99 2 if (!slc)
801     break;
802     if (slc->selected == leu->selected)
803     break;
804     }
805     }
806 zoff99 15 #if 0
807     if (le->parent)
808     {
809     dbg(0,"mapset_search_new with item(%d,%d)\n", le->parent->item.id_hi, le->parent->item.id_lo);
810     }
811     else
812     {
813     dbg(0,"NO parent!!\n");
814     }
815     dbg(0,"############## attr=%s\n", attr_to_name(le->attr->type));
816     #endif
817 zoff99 27 le->search = mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial);
818 zoff99 11 // ** DOC ** mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
819 zoff99 27 le->hash = g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
820 zoff99 2 }
821 zoff99 15
822 zoff99 2 //dbg(0,"le->search=%p\n", le->search);
823 zoff99 15
824 zoff99 2 if (!this_->item)
825     {
826     //dbg(0,"sssss 1");
827 zoff99 27 this_->item = mapset_search_get_item(le->search);
828 zoff99 2 //dbg(0,"sssss 1 %p\n",this_->item);
829     }
830 zoff99 15
831 zoff99 2 if (this_->item)
832     {
833 zoff99 27 void *p = NULL;
834 zoff99 2 //dbg(0,"id_hi=%d id_lo=%d\n", this_->item->id_hi, this_->item->id_lo);
835     if (this_->postal)
836     {
837     struct attr postal;
838 zoff99 27 if (item_attr_get(this_->item, attr_postal_mask, &postal))
839     {
840 zoff99 2 if (!postal_match(this_->postal, postal.u.str))
841     continue;
842 zoff99 27 }
843     else if (item_attr_get(this_->item, attr_postal, &postal))
844     {
845 zoff99 2 if (strcmp(this_->postal, postal.u.str))
846     continue;
847     }
848     }
849 zoff99 27 this_->result.country = NULL;
850     this_->result.town = NULL;
851     this_->result.street = NULL;
852     this_->result.c = NULL;
853 zoff99 2 //dbg(0,"case x LEVEL start %d\n",level);
854     switch (level)
855     {
856 zoff99 27 case 0:
857     //dbg(0,"case 0 COUNTRY");
858     p = search_list_country_new(this_->item);
859     this_->result.country = p;
860     this_->result.country->common.parent = NULL;
861     this_->item = NULL;
862     break;
863     case 1:
864     //dbg(0,"case 1 TOWN");
865     p = search_list_town_new(this_->item);
866     this_->result.town = p;
867     this_->result.town->common.parent = this_->levels[0].last->data;
868     this_->result.country = this_->result.town->common.parent;
869     this_->result.c = this_->result.town->common.c;
870     this_->item = NULL;
871     break;
872     case 2:
873     //dbg(0,"case 2 STREET");
874     p = search_list_street_new(this_->item);
875     this_->result.street = p;
876     this_->result.street->common.parent = this_->levels[1].last->data;
877     this_->result.town = this_->result.street->common.parent;
878     this_->result.country = this_->result.town->common.parent;
879     this_->result.c = this_->result.street->common.c;
880     this_->item = NULL;
881     break;
882     case 3:
883     //dbg(0,"case 3 HOUSENUMBER");
884     has_street_name = 0;
885 zoff99 2
886 zoff99 27 // if this housenumber has a streetname tag, set the name now
887     if (item_attr_get(this_->item, attr_street_name, &attr2))
888     {
889     // dbg(0,"streetname: %s\n",attr2.u.str);
890     has_street_name = 1;
891     }
892 zoff99 2
893 zoff99 27 //dbg(0,"case 3 XXXX 1\n");
894     p = search_list_house_number_new(this_->item, &this_->inter, le->attr->u.str, le->partial);
895     //dbg(0,"case 3 XXXX 2\n");
896     if (!p)
897     {
898     interpolation_clear(&this_->inter);
899     this_->item = NULL;
900     continue;
901     }
902     //dbg(0,"case 3 XXXX 3\n");
903     this_->result.house_number = p;
904     if (!this_->result.house_number->interpolation)
905     {
906     this_->item = NULL;
907     }
908 zoff99 2
909 zoff99 27 this_->result.house_number->common.parent = this_->levels[2].last->data;
910     this_->result.street = this_->result.house_number->common.parent;
911     this_->result.town = this_->result.street->common.parent;
912     this_->result.country = this_->result.town->common.parent;
913     this_->result.c = this_->result.house_number->common.c;
914 zoff99 2
915 zoff99 27 //dbg(0,"case 3 XXXX 4\n");
916     if (has_street_name == 1)
917     {
918     gchar *tmp_name = g_strdup(attr2.u.str);
919     this_->result.street->name = tmp_name;
920     //dbg(0,"res streetname=%s\n",this_->result.street->name);
921     }
922     else
923     {
924     //
925     // this crashes all the time -> so dont use!
926     //static struct search_list_street null_street;
927     //this_->result.street=&null_street;
928     // this crashes all the time -> so dont use!
929     //
930     this_->result.street->name = NULL;
931     }
932     //dbg(0,"case 3 XXXX 5\n");
933     break;
934 zoff99 2 }
935 zoff99 15 // CASE END *********
936    
937    
938 zoff99 2 if (p)
939     {
940     if (search_add_result(le, p))
941     {
942 zoff99 15 //** this_->result.id++;
943 zoff99 27 this_->result.id = 0;
944 zoff99 15 //dbg(0,"++++ return result\n");
945 zoff99 2 return &this_->result;
946     }
947     else
948     {
949     search_list_result_destroy(level, p);
950 zoff99 15 // return &this_->result;
951 zoff99 2 }
952     }
953 zoff99 15 }
954     else
955     {
956 zoff99 2 mapset_search_destroy(le->search);
957 zoff99 27 le->search = NULL;
958 zoff99 2 g_hash_table_destroy(le->hash);
959 zoff99 27 if (!level)
960 zoff99 15 {
961 zoff99 2 break;
962 zoff99 15 }
963 zoff99 2 }
964     }
965     return NULL;
966     }
967    
968 zoff99 27 void search_list_destroy(struct search_list *this_)
969 zoff99 2 {
970     g_free(this_->postal);
971     g_free(this_);
972     }
973    
974 zoff99 27 void search_init(void)
975 zoff99 2 {
976     }
977    
978     static char *
979     search_fix_spaces(char *str)
980     {
981     int i;
982 zoff99 27 int len = strlen(str);
983     char c, *s, *d, *ret = g_strdup(str);
984 zoff99 2
985 zoff99 27 for (i = 0; i < len; i++)
986     {
987 zoff99 2 if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/')
988 zoff99 27 ret[i] = ' ';
989 zoff99 2 }
990 zoff99 27 s = ret;
991     d = ret;
992     len = 0;
993     do
994     {
995     c = *s++;
996     if (c != ' ' || len != 0)
997     {
998     *d++ = c;
999 zoff99 2 len++;
1000     }
1001     while (c == ' ' && *s == ' ')
1002     s++;
1003 zoff99 27 if (c == ' ' && *s == '\0')
1004     {
1005 zoff99 2 d--;
1006     len--;
1007     }
1008 zoff99 27 }
1009     while (c);
1010 zoff99 2 return ret;
1011     }
1012    
1013     static GList *
1014     search_split_phrases(char *str)
1015     {
1016 zoff99 27 char *tmp, *s, *d;
1017     GList *ret = NULL;
1018     s = str;
1019     do
1020     {
1021     tmp = g_strdup(s);
1022     d = tmp + strlen(s) - 1;
1023     ret = g_list_append(ret, g_strdup(s));
1024     while (d >= tmp)
1025     {
1026     if (*d == ' ')
1027     {
1028 zoff99 2 *d = '\0';
1029 zoff99 27 ret = g_list_append(ret, g_strdup(tmp));
1030 zoff99 2 }
1031     d--;
1032     }
1033     g_free(tmp);
1034 zoff99 27 do
1035     {
1036 zoff99 2 s++;
1037 zoff99 27 if (*s == ' ')
1038     {
1039 zoff99 2 s++;
1040     break;
1041     }
1042 zoff99 27 }
1043     while (*s != '\0');
1044     }
1045     while (*s != '\0');
1046 zoff99 2 return ret;
1047     }
1048    
1049     static GList *
1050     search_address_housenumber_real(GList *result_list, struct search_list *sl, char *street_name, GList *phrases, GList *exclude1, GList *exclude2, GList *exclude3, int partial, struct jni_object *jni)
1051     {
1052     struct search_list_result *slr;
1053     struct coord_geo g;
1054     struct coord c;
1055    
1056     //dbg(0,"enter\n");
1057    
1058 zoff99 27 while ((slr = search_list_get_result(sl)))
1059 zoff99 2 {
1060 zoff99 27 if (offline_search_break_searching == 1)
1061 zoff99 15 {
1062     break;
1063     }
1064    
1065 zoff99 2 // does the streetname of the housenumber match the street we want?
1066     if (slr != NULL)
1067     {
1068     if (slr->street != NULL)
1069 zoff99 27 if ((street_name != NULL) && (slr->street->name != NULL))
1070     {
1071 zoff99 12
1072 zoff99 27 if (strcmp(slr->street->name, street_name) == 0)
1073 zoff99 2 {
1074 zoff99 27 char *buffer;
1075     // coords of result
1076     c.x = slr->house_number->common.c->x;
1077     c.y = slr->house_number->common.c->y;
1078     transform_to_geo(slr->house_number->common.c->pro, &c, &g);
1079     // SHN -> street with house number
1080     // return a string like: "SHN:H111L5555:16.766:48.76:full address name is at the end"
1081     // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 max. 15 chars -> this sould be max. about 335 chars long
1082     if (slr->town->common.postal == NULL)
1083     {
1084     buffer = g_strdup_printf("SHN:H%dL%d:%f:%f:%.101s,%.101s, %.101s %.15s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.town_name, slr->street->name, slr->house_number->house_number);
1085     }
1086     else
1087     {
1088     buffer = g_strdup_printf("SHN:H%dL%d:%f:%f:%.101s,%.7s %.101s, %.101s %.15s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.postal, slr->town->common.town_name, slr->street->name,
1089     slr->house_number->house_number);
1090     }
1091 zoff99 2
1092 zoff99 27 //dbg(0,"res=%s\n",buffer);
1093 zoff99 2
1094 zoff99 27 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1095     #ifdef HAVE_API_ANDROID
1096     // return results to android as they come in ...
1097     android_return_search_result(jni,buffer);
1098     #endif
1099     g_free(buffer);
1100     }
1101 zoff99 2 }
1102     }
1103     }
1104    
1105     //dbg(0,"return 2\n");
1106     return result_list;
1107     }
1108    
1109     static GList *
1110     search_address__street(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, GList *exclude3, int partial, struct jni_object *jni)
1111     {
1112     //dbg(0,"enter\n");
1113    
1114     struct search_list_result *slr = NULL;
1115 zoff99 27 GList *tmp = phrases;
1116     int count = 0;
1117 zoff99 2 struct coord_geo g;
1118     struct coord c;
1119     struct attr attr2;
1120    
1121 zoff99 15 struct item *save_item;
1122     int save_level;
1123     int save_last_result_valid;
1124 zoff99 2
1125 zoff99 27 while ((slr = search_list_get_result(sl)))
1126 zoff99 2 {
1127     char *buffer;
1128     char *buffer2;
1129    
1130 zoff99 27 if (offline_search_break_searching == 1)
1131 zoff99 15 {
1132     break;
1133     }
1134    
1135 zoff99 2 if (slr->street)
1136     {
1137     // coords of result
1138 zoff99 27 c.x = slr->street->common.c->x;
1139     c.y = slr->street->common.c->y;
1140 zoff99 2 transform_to_geo(slr->street->common.c->pro, &c, &g);
1141    
1142     // STR -> street
1143     // return a string like: "STR:H1111L5555:16.766:-48.76:full address name is at the end"
1144     // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 chars -> this sould be max. about 320 chars long
1145     if (slr->town->common.postal == NULL)
1146     {
1147 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s,%.101s, %.101s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.town_name, slr->street->name);
1148 zoff99 2 }
1149     else
1150     {
1151 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s,%.7s %.101s, %.101s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.postal, slr->town->common.town_name, slr->street->name);
1152 zoff99 2 }
1153     // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1154    
1155     //dbg(0,"res=%s\n",buffer);
1156    
1157 zoff99 27 #ifdef HAVE_API_ANDROID
1158 zoff99 2 // return results to android as they come in ...
1159     android_return_search_result(jni,buffer);
1160 zoff99 27 #endif
1161 zoff99 2 count++;
1162    
1163 zoff99 27 buffer2 = g_strdup_printf("%s", slr->street->name);
1164 zoff99 15 //dbg(0,"b2:%s\n",buffer2);
1165 zoff99 2
1166 zoff99 15
1167 zoff99 27 save_item = sl->item;
1168     save_level = sl->level;
1169     save_last_result_valid = sl->last_result_valid;
1170 zoff99 15
1171     #if 1
1172     // put words back to start!!
1173 zoff99 27 tmp = phrases;
1174 zoff99 2 while (tmp)
1175     {
1176     //dbg(0,"s0=%s\n",tmp->data);
1177     if (tmp != exclude1 && tmp != exclude2 && tmp != exclude3)
1178     {
1179     //dbg(0,"s=%s\n",tmp->data);
1180    
1181 zoff99 27 attr2.type = attr_house_number;
1182     attr2.u.str = tmp->data;
1183 zoff99 2 search_list_search(sl, &attr2, partial);
1184    
1185 zoff99 27 result_list = search_address_housenumber_real(result_list, sl, buffer2, phrases, exclude1, exclude2, exclude3, partial, jni);
1186 zoff99 2 }
1187 zoff99 27 tmp = g_list_next(tmp);
1188 zoff99 2 }
1189 zoff99 15 #endif
1190    
1191     // restore again
1192 zoff99 27 sl->item = save_item;
1193     sl->level = save_level;
1194     sl->last_result_valid = save_last_result_valid;
1195 zoff99 15
1196 zoff99 2 }
1197    
1198     if (buffer2)
1199     {
1200     g_free(buffer2);
1201     }
1202    
1203     if (buffer)
1204     {
1205     g_free(buffer);
1206     }
1207     }
1208    
1209     //dbg(0,"return 2\n");
1210     return result_list;
1211     }
1212    
1213     static GList *
1214     search_address__town(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, int partial, struct jni_object *jni)
1215     {
1216     //dbg(0,"enter\n");
1217     struct search_list_result *slr;
1218 zoff99 27 GList *tmp = phrases;
1219     int count = 0;
1220 zoff99 2 struct coord_geo g;
1221     struct coord c;
1222     struct attr attr;
1223 zoff99 15 struct attr attrx;
1224     // struct search_list *sl2=search_list_new(sl->ms);
1225     struct item *save_item;
1226     int save_level;
1227     int save_last_result_valid;
1228     // int first=1;
1229 zoff99 2
1230 zoff99 27 while ((slr = search_list_get_result(sl)))
1231 zoff99 2 {
1232     char *buffer;
1233 zoff99 15
1234 zoff99 27 if (offline_search_break_searching == 1)
1235 zoff99 15 {
1236     break;
1237     }
1238    
1239 zoff99 2 // coords of result
1240 zoff99 27 c.x = slr->town->common.c->x;
1241     c.y = slr->town->common.c->y;
1242 zoff99 2 transform_to_geo(slr->town->common.c->pro, &c, &g);
1243    
1244     // TWN -> town
1245     if (slr->town->common.postal == NULL)
1246     {
1247 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s,%.101s", slr->town->common.item.id_hi, slr->town->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.town_name);
1248 zoff99 2 }
1249     else
1250     {
1251 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s,%.7s %.101s", slr->town->common.item.id_hi, slr->town->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.postal, slr->town->common.town_name);
1252 zoff99 2 }
1253    
1254 zoff99 15 //dbg(0,"**res=%s\n",buffer);
1255 zoff99 2
1256     // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1257     #ifdef HAVE_API_ANDROID
1258     // return results to android as they come in ...
1259     android_return_search_result(jni,buffer);
1260     #endif
1261    
1262     count++;
1263 zoff99 15 if (buffer)
1264     g_free(buffer);
1265 zoff99 2
1266 zoff99 27 save_item = sl->item;
1267     save_level = sl->level;
1268     save_last_result_valid = sl->last_result_valid;
1269 zoff99 15
1270     // put words back to start!!
1271 zoff99 27 tmp = phrases;
1272 zoff99 15
1273 zoff99 2 while (tmp)
1274     {
1275     if (tmp != exclude1 && tmp != exclude2)
1276     {
1277     //dbg(0,"s=%s\n",tmp->data);
1278 zoff99 27 attr.type = attr_street_name;
1279     attr.u.str = tmp->data;
1280 zoff99 2 search_list_search(sl, &attr, partial);
1281 zoff99 27 result_list = search_address__street(result_list, sl, phrases, exclude1, exclude2, tmp, partial, jni);
1282 zoff99 2 }
1283 zoff99 27 tmp = g_list_next(tmp);
1284 zoff99 2 }
1285    
1286 zoff99 15 // restore again
1287 zoff99 27 sl->item = save_item;
1288     sl->level = save_level;
1289     sl->last_result_valid = save_last_result_valid;
1290 zoff99 2 }
1291    
1292     //dbg(0,"return 2\n");
1293     return result_list;
1294     }
1295    
1296     static GList *
1297     search_address__country(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude, int partial, struct jni_object *jni)
1298     {
1299 zoff99 27 GList *tmp = phrases;
1300     int count = 0;
1301 zoff99 2 struct attr attr;
1302     struct search_list_result *slr;
1303     //dbg(0,"enter\n");
1304    
1305 zoff99 27 while ((slr = search_list_get_result(sl)))
1306 zoff99 2 {
1307     //dbg(0,"1 slr=%p\n",slr->country);
1308     //dbg(0,"2 slr=%s\n",slr->country->name);
1309     //dbg(0,"3 slr=%s\n",slr->country->iso2);
1310     count++;
1311     }
1312     //dbg(0,"count %d\n",count);
1313     if (!count)
1314     {
1315     //dbg(0,"return 1");
1316     return result_list;
1317     }
1318    
1319     while (tmp)
1320     {
1321     if (tmp != exclude)
1322     {
1323 zoff99 15 //dbg(0,"Is=%s\n",tmp->data);
1324 zoff99 27 attr.type = attr_town_or_district_name;
1325     attr.u.str = tmp->data;
1326 zoff99 2 search_list_search(sl, &attr, partial);
1327 zoff99 27 result_list = search_address__town(result_list, sl, phrases, exclude, tmp, partial, jni);
1328 zoff99 2 }
1329 zoff99 15 //else
1330     //{
1331 zoff99 27 //dbg(0,"Xs=%s\n",tmp->data);
1332 zoff99 15 //}
1333 zoff99 27 tmp = g_list_next(tmp);
1334 zoff99 2 }
1335     //dbg(0,"return 2");
1336     return result_list;
1337     }
1338    
1339 zoff99 27 struct country2
1340     {
1341 zoff99 2 int id;
1342     char *car;
1343     char *iso2;
1344     char *iso3;
1345     char *name;
1346     };
1347    
1348 zoff99 27 static struct country2 all_country_list[] =
1349     {
1350     { 20, "AND", "AD", "AND", /* 020 */"Andorra" },
1351     { 784, "UAE", "AE", "ARE", /* 784 */
1352     "United Arab Emirates" },
1353     { 4, "AFG", "AF", "AFG", /* 004 */"Afghanistan" },
1354     { 28, "AG", "AG", "ATG", /* 028 */"Antigua and Barbuda" },
1355     { 660, NULL, "AI", "AIA", /* 660 */"Anguilla" },
1356     { 8, "AL", "AL", "ALB", /* 008 */"Albania" },
1357     { 51, "ARM", "AM", "ARM", /* 051 */"Armenia" },
1358     { 530, "NA", "AN", "ANT", /* 530 */
1359     "Netherlands Antilles" },
1360     { 24, "ANG", "AO", "AGO", /* 024 */"Angola" },
1361     { 10, NULL, "AQ", "ATA", /* 010 */"Antarctica" },
1362     { 32, "RA", "AR", "ARG", /* 032 */"Argentina" },
1363     { 16, NULL, "AS", "ASM", /* 016 */"American Samoa" },
1364     { 40, "A", "AT", "AUT", /* 040 */"Austria" },
1365     { 36, "AUS", "AU", "AUS", /* 036 */"Australia" },
1366     { 533, "ARU", "AW", "ABW", /* 533 */"Aruba" },
1367     { 248, "AX", "AX", "ALA", /* 248 */"Aland Islands" },
1368     { 31, "AZ", "AZ", "AZE", /* 031 */"Azerbaijan" },
1369     { 70, "BiH", "BA", "BIH", /* 070 */
1370     "Bosnia and Herzegovina" },
1371     { 52, "BDS", "BB", "BRB", /* 052 */"Barbados" },
1372     { 50, "BD", "BD", "BGD", /* 050 */"Bangladesh" },
1373     { 56, "B", "BE", "BEL", /* 056 */"Belgium" },
1374     { 854, "BF", "BF", "BFA", /* 854 */"Burkina Faso" },
1375     { 100, "BG", "BG", "BGR", /* 100 */"Bulgaria" },
1376     { 48, "BRN", "BH", "BHR", /* 048 */"Bahrain" },
1377     { 108, "RU", "BI", "BDI", /* 108 */"Burundi" },
1378     { 204, "BJ", "BJ", "BEN", /* 204 */"Benin" },
1379     { 652, NULL, "BL", "BLM", /* 652 */"Saint Barthelemy" },
1380     { 60, NULL, "BM", "BMU", /* 060 */"Bermuda" },
1381     { 96, "BRU", "BN", "BRN", /* 096 */"Brunei Darussalam" },
1382     { 68, "BOL", "BO", "BOL", /* 068 */"Bolivia" },
1383     { 76, "BR", "BR", "BRA", /* 076 */"Brazil" },
1384     { 44, "BS", "BS", "BHS", /* 044 */"Bahamas" },
1385     { 64, "BHT", "BT", "BTN", /* 064 */"Bhutan" },
1386     { 74, NULL, "BV", "BVT", /* 074 */"Bouvet Island" },
1387     { 72, "RB", "BW", "BWA", /* 072 */"Botswana" },
1388     { 112, "BY", "BY", "BLR", /* 112 */"Belarus" },
1389     { 84, "BZ", "BZ", "BLZ", /* 084 */"Belize" },
1390     { 124, "CDN", "CA", "CAN", /* 124 */"Canada" },
1391     { 166, NULL, "CC", "CCK", /* 166 */
1392     "Cocos (Keeling) Islands" },
1393     { 180, "CGO", "CD", "COD", /* 180 */
1394     "Congo, Democratic Republic of the" },
1395     { 140, "RCA", "CF", "CAF", /* 140 */
1396     "Central African Republic" },
1397     { 178, NULL, "CG", "COG", /* 178 */"Congo" },
1398     { 756, "CH", "CH", "CHE", /* 756 */"Switzerland" },
1399     { 384, "CI", "CI", "CIV", /* 384 */"Cote d'Ivoire" },
1400     { 184, NULL, "CK", "COK", /* 184 */"Cook Islands" },
1401     { 152, "RCH", "CL", "CHL", /* 152 */"Chile" },
1402     { 120, "CAM", "CM", "CMR", /* 120 */"Cameroon" },
1403     { 156, "RC", "CN", "CHN", /* 156 */"China" },
1404     { 170, "CO", "CO", "COL", /* 170 */"Colombia" },
1405     { 188, "CR", "CR", "CRI", /* 188 */"Costa Rica" },
1406     { 192, "C", "CU", "CUB", /* 192 */"Cuba" },
1407     { 132, "CV", "CV", "CPV", /* 132 */"Cape Verde" },
1408     { 162, NULL, "CX", "CXR", /* 162 */"Christmas Island" },
1409     { 196, "CY", "CY", "CYP", /* 196 */"Cyprus" },
1410     { 203, "CZ", "CZ", "CZE", /* 203 */"Czech Republic" },
1411     { 276, "D", "DE", "DEU", /* 276 */"Germany" },
1412     { 262, "DJI", "DJ", "DJI", /* 262 */"Djibouti" },
1413     { 208, "DK", "DK", "DNK", /* 208 */"Denmark" },
1414     { 212, "WD", "DM", "DMA", /* 212 */"Dominica" },
1415     { 214, "DOM", "DO", "DOM", /* 214 */
1416     "Dominican Republic" },
1417     { 12, "DZ", "DZ", "DZA", /* 012 */"Algeria" },
1418     { 218, "EC", "EC", "ECU", /* 218 */"Ecuador" },
1419     { 233, "EST", "EE", "EST", /* 233 */"Estonia" },
1420     { 818, "ET", "EG", "EGY", /* 818 */"Egypt" },
1421     { 732, "WSA", "EH", "ESH", /* 732 */"Western Sahara" },
1422     { 232, "ER", "ER", "ERI", /* 232 */"Eritrea" },
1423     { 724, "E", "ES", "ESP", /* 724 */"Spain" },
1424     { 231, "ETH", "ET", "ETH", /* 231 */"Ethiopia" },
1425     { 246, "FIN", "FI", "FIN", /* 246 */"Finland" },
1426     { 242, "FJI", "FJ", "FJI", /* 242 */"Fiji" },
1427     { 238, NULL, "FK", "FLK", /* 238 */
1428     "Falkland Islands (Malvinas)" },
1429     { 583, "FSM", "FM", "FSM", /* 583 */
1430     "Micronesia, Federated States of" },
1431     { 234, "FO", "FO", "FRO", /* 234 */"Faroe Islands" },
1432     { 250, "F", "FR", "FRA", /* 250 */"France" },
1433     { 266, "G", "GA", "GAB", /* 266 */"Gabon" },
1434     { 826, "GB", "GB", "GBR", /* 826 */"United Kingdom" },
1435     { 308, "WG", "GD", "GRD", /* 308 */"Grenada" },
1436     { 268, "GE", "GE", "GEO", /* 268 */"Georgia" },
1437     { 254, NULL, "GF", "GUF", /* 254 */"French Guiana" },
1438     { 831, NULL, "GG", "GGY", /* 831 */"Guernsey" },
1439     { 288, "GH", "GH", "GHA", /* 288 */"Ghana" },
1440     { 292, "GBZ", "GI", "GIB", /* 292 */"Gibraltar" },
1441     { 304, "KN", "GL", "GRL", /* 304 */"Greenland" },
1442     { 270, "WAG", "GM", "GMB", /* 270 */"Gambia" },
1443     { 324, "RG", "GN", "GIN", /* 324 */"Guinea" },
1444     { 312, NULL, "GP", "GLP", /* 312 */"Guadeloupe" },
1445     { 226, "GQ", "GQ", "GNQ", /* 226 */"Equatorial Guinea" },
1446     { 300, "GR", "GR", "GRC", /* 300 */"Greece" },
1447     { 239, NULL, "GS", "SGS", /* 239 */
1448     "South Georgia and the South Sandwich Islands" },
1449     { 320, "GCA", "GT", "GTM", /* 320 */"Guatemala" },
1450     { 316, NULL, "GU", "GUM", /* 316 */"Guam" },
1451     { 624, "GUB", "GW", "GNB", /* 624 */"Guinea-Bissau" },
1452     { 328, "GUY", "GY", "GUY", /* 328 */"Guyana" },
1453     { 344, "HK", "HK", "HKG", /* 344 */"Hong Kong" },
1454     { 334, NULL, "HM", "HMD", /* 334 */
1455     "Heard Island and McDonald Islands" },
1456     { 340, "HN", "HN", "HND", /* 340 */"Honduras" },
1457     { 191, "HR", "HR", "HRV", /* 191 */"Croatia" },
1458     { 332, "RH", "HT", "HTI", /* 332 */"Haiti" },
1459     { 348, "H", "HU", "HUN", /* 348 */"Hungary" },
1460     { 360, "RI", "ID", "IDN", /* 360 */"Indonesia" },
1461     { 372, "IRL", "IE", "IRL", /* 372 */"Ireland" },
1462     { 376, "IL", "IL", "ISR", /* 376 */"Israel" },
1463     { 833, NULL, "IM", "IMN", /* 833 */"Isle of Man" },
1464     { 356, "IND", "IN", "IND", /* 356 */"India" },
1465     { 86, NULL, "IO", "IOT", /* 086 */
1466     "British Indian Ocean Territory" },
1467     { 368, "IRQ", "IQ", "IRQ", /* 368 */"Iraq" },
1468     { 364, "IR", "IR", "IRN", /* 364 */
1469     "Iran, Islamic Republic of" },
1470     { 352, "IS", "IS", "ISL", /* 352 */"Iceland" },
1471     { 380, "I", "IT", "ITA", /* 380 */"Italy" },
1472     { 832, NULL, "JE", "JEY", /* 832 */"Jersey" },
1473     { 388, "JA", "JM", "JAM", /* 388 */"Jamaica" },
1474     { 400, "JOR", "JO", "JOR", /* 400 */"Jordan" },
1475     { 392, "J", "JP", "JPN", /* 392 */"Japan" },
1476     { 404, "EAK", "KE", "KEN", /* 404 */"Kenya" },
1477     { 417, "KS", "KG", "KGZ", /* 417 */"Kyrgyzstan" },
1478     { 116, "K", "KH", "KHM", /* 116 */"Cambodia" },
1479     { 296, "KIR", "KI", "KIR", /* 296 */"Kiribati" },
1480     { 174, "COM", "KM", "COM", /* 174 */"Comoros" },
1481     { 659, "KAN", "KN", "KNA", /* 659 */
1482     "Saint Kitts and Nevis" },
1483     { 408, "KP", "KP", "PRK", /* 408 */
1484     "Korea, Democratic People's Republic of" },
1485     { 410, "ROK", "KR", "KOR", /* 410 */
1486     "Korea, Republic of" },
1487     { 414, "KWT", "KW", "KWT", /* 414 */"Kuwait" },
1488     { 136, NULL, "KY", "CYM", /* 136 */"Cayman Islands" },
1489     { 398, "KZ", "KZ", "KAZ", /* 398 */"Kazakhstan" },
1490     { 418, "LAO", "LA", "LAO", /* 418 */
1491     "Lao People's Democratic Republic" },
1492     { 422, "RL", "LB", "LBN", /* 422 */"Lebanon" },
1493     { 662, "WL", "LC", "LCA", /* 662 */"Saint Lucia" },
1494     { 438, "FL", "LI", "LIE", /* 438 */"Liechtenstein" },
1495     { 144, "CL", "LK", "LKA", /* 144 */"Sri Lanka" },
1496     { 430, "LB", "LR", "LBR", /* 430 */"Liberia" },
1497     { 426, "LS", "LS", "LSO", /* 426 */"Lesotho" },
1498     { 440, "LT", "LT", "LTU", /* 440 */"Lithuania" },
1499     { 442, "L", "LU", "LUX", /* 442 */"Luxembourg" },
1500     { 428, "LV", "LV", "LVA", /* 428 */"Latvia" },
1501     { 434, "LAR", "LY", "LBY", /* 434 */
1502     "Libyan Arab Jamahiriya" },
1503     { 504, "MA", "MA", "MAR", /* 504 */"Morocco" },
1504     { 492, "MC", "MC", "MCO", /* 492 */"Monaco" },
1505     { 498, "MD", "MD", "MDA", /* 498 */
1506     "Moldova, Republic of" },
1507     { 499, "MNE", "ME", "MNE", /* 499 */"Montenegro" },
1508     { 663, NULL, "MF", "MAF", /* 663 */
1509     "Saint Martin (French part)" },
1510     { 450, "RM", "MG", "MDG", /* 450 */"Madagascar" },
1511     { 584, "MH", "MH", "MHL", /* 584 */"Marshall Islands" },
1512     { 807, "MK", "MK", "MKD", /* 807 */
1513     "Macedonia, the former Yugoslav Republic of" },
1514     { 466, "RMM", "ML", "MLI", /* 466 */"Mali" },
1515     { 104, "MYA", "MM", "MMR", /* 104 */"Myanmar" },
1516     { 496, "MGL", "MN", "MNG", /* 496 */"Mongolia" },
1517     { 446, NULL, "MO", "MAC", /* 446 */"Macao" },
1518     { 580, NULL, "MP", "MNP", /* 580 */
1519     "Northern Mariana Islands" },
1520     { 474, NULL, "MQ", "MTQ", /* 474 */"Martinique" },
1521     { 478, "RIM", "MR", "MRT", /* 478 */"Mauritania" },
1522     { 500, NULL, "MS", "MSR", /* 500 */"Montserrat" },
1523     { 470, "M", "MT", "MLT", /* 470 */"Malta" },
1524     { 480, "MS", "MU", "MUS", /* 480 */"Mauritius" },
1525     { 462, "MV", "MV", "MDV", /* 462 */"Maldives" },
1526     { 454, "MW", "MW", "MWI", /* 454 */"Malawi" },
1527     { 484, "MEX", "MX", "MEX", /* 484 */"Mexico" },
1528     { 458, "MAL", "MY", "MYS", /* 458 */"Malaysia" },
1529     { 508, "MOC", "MZ", "MOZ", /* 508 */"Mozambique" },
1530     { 516, "NAM", "NA", "NAM", /* 516 */"Namibia" },
1531     { 540, "NCL", "NC", "NCL", /* 540 */"New Caledonia" },
1532     { 562, "RN", "NE", "NER", /* 562 */"Niger" },
1533     { 574, NULL, "NF", "NFK", /* 574 */"Norfolk Island" },
1534     { 566, "NGR", "NG", "NGA", /* 566 */"Nigeria" },
1535     { 558, "NIC", "NI", "NIC", /* 558 */"Nicaragua" },
1536     { 528, "NL", "NL", "NLD", /* 528 */"Netherlands" },
1537     { 578, "N", "NO", "NOR", /* 578 */"Norway" },
1538     { 524, "NEP", "NP", "NPL", /* 524 */"Nepal" },
1539     { 520, "NAU", "NR", "NRU", /* 520 */"Nauru" },
1540     { 570, NULL, "NU", "NIU", /* 570 */"Niue" },
1541     { 554, "NZ", "NZ", "NZL", /* 554 */"New Zealand" },
1542     { 512, "OM", "OM", "OMN", /* 512 */"Oman" },
1543     { 591, "PA", "PA", "PAN", /* 591 */"Panama" },
1544     { 604, "PE", "PE", "PER", /* 604 */"Peru" },
1545     { 258, NULL, "PF", "PYF", /* 258 */"French Polynesia" },
1546     { 598, "PNG", "PG", "PNG", /* 598 */"Papua New Guinea" },
1547     { 608, "RP", "PH", "PHL", /* 608 */"Philippines" },
1548     { 586, "PK", "PK", "PAK", /* 586 */"Pakistan" },
1549     { 616, "PL", "PL", "POL", /* 616 */"Poland" },
1550     { 666, NULL, "PM", "SPM", /* 666 */
1551     "Saint Pierre and Miquelon" },
1552     { 612, NULL, "PN", "PCN", /* 612 */"Pitcairn" },
1553     { 630, "PRI", "PR", "PRI", /* 630 */"Puerto Rico" },
1554     { 275, "AUT", "PS", "PSE", /* 275 */
1555     "Palestinian Territory, Occupied" },
1556     { 620, "P", "PT", "PRT", /* 620 */"Portugal" },
1557     { 585, "PAL", "PW", "PLW", /* 585 */"Palau" },
1558     { 600, "PY", "PY", "PRY", /* 600 */"Paraguay" },
1559     { 634, "Q", "QA", "QAT", /* 634 */"Qatar" },
1560     { 638, NULL, "RE", "REU", /* 638 */"Reunion" },
1561     { 642, "RO", "RO", "ROU", /* 642 */"Romania" },
1562     { 688, "SRB", "RS", "SRB", /* 688 */"Serbia" },
1563     { 643, "RUS", "RU", "RUS", /* 643 */
1564     "Russian Federation" },
1565     { 646, "RWA", "RW", "RWA", /* 646 */"Rwanda" },
1566     { 682, "KSA", "SA", "SAU", /* 682 */"Saudi Arabia" },
1567     { 90, "SOL", "SB", "SLB", /* 090 */"Solomon Islands" },
1568     { 690, "SY", "SC", "SYC", /* 690 */"Seychelles" },
1569     { 736, "SUD", "SD", "SDN", /* 736 */"Sudan" },
1570     { 752, "S", "SE", "SWE", /* 752 */"Sweden" },
1571     { 702, "SGP", "SG", "SGP", /* 702 */"Singapore" },
1572     { 654, NULL, "SH", "SHN", /* 654 */"Saint Helena" },
1573     { 705, "SLO", "SI", "SVN", /* 705 */"Slovenia" },
1574     { 744, NULL, "SJ", "SJM", /* 744 */
1575     "Svalbard and Jan Mayen" },
1576     { 703, "SK", "SK", "SVK", /* 703 */"Slovakia" },
1577     { 694, "WAL", "SL", "SLE", /* 694 */"Sierra Leone" },
1578     { 674, "RSM", "SM", "SMR", /* 674 */"San Marino" },
1579     { 686, "SN", "SN", "SEN", /* 686 */"Senegal" },
1580     { 706, "SO", "SO", "SOM", /* 706 */"Somalia" },
1581     { 740, "SME", "SR", "SUR", /* 740 */"Suriname" },
1582     { 678, "STP", "ST", "STP", /* 678 */
1583     "Sao Tome and Principe" },
1584     { 222, "ES", "SV", "SLV", /* 222 */"El Salvador" },
1585     { 760, "SYR", "SY", "SYR", /* 760 */
1586     "Syrian Arab Republic" },
1587     { 748, "SD", "SZ", "SWZ", /* 748 */"Swaziland" },
1588     { 796, NULL, "TC", "TCA", /* 796 */
1589     "Turks and Caicos Islands" },
1590     { 148, "TD", "TD", "TCD", /* 148 */"Chad" },
1591     { 260, "ARK", "TF", "ATF", /* 260 */
1592     "French Southern Territories" },
1593     { 768, "RT", "TG", "TGO", /* 768 */"Togo" },
1594     { 764, "T", "TH", "THA", /* 764 */"Thailand" },
1595     { 762, "TJ", "TJ", "TJK", /* 762 */"Tajikistan" },
1596     { 772, NULL, "TK", "TKL", /* 772 */"Tokelau" },
1597     { 626, "TL", "TL", "TLS", /* 626 */"Timor-Leste" },
1598     { 795, "TM", "TM", "TKM", /* 795 */"Turkmenistan" },
1599     { 788, "TN", "TN", "TUN", /* 788 */"Tunisia" },
1600     { 776, "TON", "TO", "TON", /* 776 */"Tonga" },
1601     { 792, "TR", "TR", "TUR", /* 792 */"Turkey" },
1602     { 780, "TT", "TT", "TTO", /* 780 */
1603     "Trinidad and Tobago" },
1604     { 798, "TUV", "TV", "TUV", /* 798 */"Tuvalu" },
1605     { 158, NULL, "TW", "TWN", /* 158 */
1606     "Taiwan, Province of China" },
1607     { 834, "EAT", "TZ", "TZA", /* 834 */
1608     "Tanzania, United Republic of" },
1609     { 804, "UA", "UA", "UKR", /* 804 */"Ukraine" },
1610     { 800, "EAU", "UG", "UGA", /* 800 */"Uganda" },
1611     { 581, NULL, "UM", "UMI", /* 581 */
1612     "United States Minor Outlying Islands" },
1613     { 840, "USA", "US", "USA", /* 840 */"United States" },
1614     { 858, "ROU", "UY", "URY", /* 858 */"Uruguay" },
1615     { 860, "UZ", "UZ", "UZB", /* 860 */"Uzbekistan" },
1616     { 336, "SCV", "VA", "VAT", /* 336 */
1617     "Holy See (Vatican City State)" },
1618     { 670, "WV", "VC", "VCT", /* 670 */"Saint Vincent and the Grenadines" },
1619     { 862, "YV", "VE", "VEN", /* 862 */"Venezuela" },
1620     { 92, NULL, "VG", "VGB", /* 092 */ "Virgin Islands, British" },
1621     { 850, NULL, "VI", "VIR", /* 850 */ "Virgin Islands, U.S." },
1622     { 704, "VN", "VN", "VNM", /* 704 */"Viet Nam" },
1623     { 548, "VAN", "VU", "VUT", /* 548 */"Vanuatu" },
1624     { 876, NULL, "WF", "WLF", /* 876 */"Wallis and Futuna" },
1625     { 882, "WS", "WS", "WSM", /* 882 */"Samoa" },
1626     { 887, "YAR", "YE", "YEM", /* 887 */"Yemen" },
1627     { 175, NULL, "YT", "MYT", /* 175 */"Mayotte" },
1628     { 710, "ZA", "ZA", "ZAF", /* 710 */"South Africa" },
1629     { 894, "Z", "ZM", "ZMB", /* 894 */"Zambia" },
1630     { 716, "ZW", "ZW", "ZWE", /* 716 */"Zimbabwe" },
1631     { 999, "*", "*", "*", /* 999 */"Unknown" }, };
1632 zoff99 2
1633 zoff99 27 static int ascii_cmp_local(char *name, char *match, int partial)
1634 zoff99 2 {
1635 zoff99 27 char *s1 = linguistics_casefold(name);
1636     char *s2 = linguistics_casefold(match);
1637     int ret = linguistics_compare(s1, s2, partial);
1638 zoff99 15 g_free(s1);
1639     g_free(s2);
1640 zoff99 2 return ret;
1641     }
1642    
1643     struct navit *global_navit;
1644    
1645 zoff99 27 void search_full_world(char *addr, int partial, int search_order, struct jni_object *jni, struct coord_geo *search_center, int search_radius)
1646 zoff99 2 {
1647     struct item *item;
1648 zoff99 27 struct map_rect *mr = NULL;
1649 zoff99 2 struct mapset *ms;
1650     struct mapset_handle *msh;
1651     struct map* map = NULL;
1652     struct attr map_name_attr;
1653     struct attr attr;
1654    
1655 zoff99 27 char *str = search_fix_spaces(addr);
1656     GList *phrases = search_split_phrases(str);
1657 zoff99 2 GList *phrases_first;
1658 zoff99 27 phrases_first = phrases;
1659 zoff99 2
1660 zoff99 27 ms = global_navit->mapsets->data;
1661     msh = mapset_open(ms);
1662 zoff99 2
1663     struct pcoord center99;
1664 zoff99 27 int search_radius_this = 0;
1665     dbg(0, "in lat=%f,lng=%f\n", search_center->lat, search_center->lng);
1666     if ((search_center->lat == 0) && (search_center->lng == 0))
1667 zoff99 2 {
1668 zoff99 27 center99.x = 0;
1669     center99.y = 0;
1670     search_radius_this = 21000000;
1671 zoff99 2 }
1672     else
1673     {
1674     struct coord c99;
1675     transform_from_geo(projection_mg, search_center, &c99);
1676 zoff99 27 center99.x = c99.x;
1677     center99.y = c99.y;
1678     search_radius_this = search_radius;
1679 zoff99 2 }
1680 zoff99 27 dbg(0, "out x=%d,y=%d,r=%d\n", center99.x, center99.y, search_radius_this);
1681 zoff99 2
1682 zoff99 27 struct map_selection *sel = map_selection_rect_new(&center99, search_radius_this, search_order);
1683     sel->range.min = type_town_label;
1684     sel->range.max = type_area;
1685 zoff99 2
1686 zoff99 27 while (msh && (map = mapset_next(msh, 0)))
1687 zoff99 2 {
1688 zoff99 27 if (map_get_attr(map, attr_name, &map_name_attr, NULL))
1689 zoff99 2 {
1690     if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
1691     {
1692     if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/navitmap", map_name_attr.u.str, 38) == 0)
1693     {
1694     // its an sdcard map
1695     //dbg(0,"map name=%s",map_name_attr.u.str);
1696     // mr=map_rect_new(map, NULL);
1697 zoff99 27 mr = map_rect_new(map, sel);
1698 zoff99 2 if (mr)
1699     {
1700 zoff99 27 char *streetname_last = NULL;
1701 zoff99 2
1702 zoff99 27 while ((item = map_rect_get_item(mr)))
1703 zoff99 2 {
1704 zoff99 27 if ((item_is_town(*item)) || (item_is_district(*item)))
1705     {
1706     struct search_list_town *p = NULL;
1707    
1708     if (item_attr_get(item, attr_town_name, &attr))
1709 zoff99 2 {
1710 zoff99 27 p = search_list_town_new(item);
1711     char *buffer = NULL;
1712     // coords of result
1713     struct coord_geo g;
1714     struct coord c;
1715     c.x = p->common.c->x;
1716     c.y = p->common.c->y;
1717     int calc_geo = 0;
1718 zoff99 2
1719 zoff99 27 // dbg(0,"town name=%s\n", attr.u.str);
1720    
1721     phrases = phrases_first;
1722     while (phrases)
1723 zoff99 2 {
1724 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1725 zoff99 2 {
1726 zoff99 27 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1727     if (calc_geo == 0)
1728 zoff99 2 {
1729 zoff99 27 transform_to_geo(p->common.c->pro, &c, &g);
1730     // TWN -> town
1731     calc_geo = 1;
1732     }
1733     if (p->common.postal == NULL)
1734     {
1735     buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.town_name);
1736     }
1737     else
1738     {
1739     buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, p->common.town_name);
1740     }
1741 zoff99 12 #ifdef HAVE_API_ANDROID
1742 zoff99 27 // return results to android as they come in ...
1743     android_return_search_result(jni,buffer);
1744 zoff99 12 #endif
1745 zoff99 27 }
1746     phrases = g_list_next(phrases);
1747 zoff99 2
1748     }
1749 zoff99 27 if (buffer)
1750     {
1751     g_free(buffer);
1752     }
1753     search_list_town_destroy(p);
1754 zoff99 2 }
1755 zoff99 27
1756     if (item_attr_get(item, attr_town_name_match, &attr))
1757 zoff99 2 {
1758 zoff99 27 p = search_list_town_new(item);
1759     char *buffer = NULL;
1760     // coords of result
1761     struct coord_geo g;
1762     struct coord c;
1763     c.x = p->common.c->x;
1764     c.y = p->common.c->y;
1765     int calc_geo = 0;
1766 zoff99 2
1767 zoff99 27 // dbg(0,"town name=%s\n", attr.u.str);
1768 zoff99 2
1769 zoff99 27 phrases = phrases_first;
1770     while (phrases)
1771 zoff99 2 {
1772 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1773 zoff99 2 {
1774 zoff99 27 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1775     if (calc_geo == 0)
1776 zoff99 2 {
1777 zoff99 27 transform_to_geo(p->common.c->pro, &c, &g);
1778     // TWN -> town
1779     calc_geo = 1;
1780 zoff99 2 }
1781 zoff99 27 if (p->common.postal == NULL)
1782 zoff99 2 {
1783 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.town_name);
1784 zoff99 2 }
1785 zoff99 27 else
1786     {
1787     buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, p->common.town_name);
1788     }
1789     #ifdef HAVE_API_ANDROID
1790     // return results to android as they come in ...
1791     android_return_search_result(jni,buffer);
1792     #endif
1793 zoff99 2 }
1794 zoff99 27 phrases = g_list_next(phrases);
1795    
1796 zoff99 2 }
1797 zoff99 27 if (buffer)
1798 zoff99 2 {
1799 zoff99 27 g_free(buffer);
1800     }
1801     search_list_town_destroy(p);
1802     }
1803     }
1804     else if (item_is_street(*item))
1805     {
1806 zoff99 2
1807 zoff99 27 struct search_list_street *p = NULL;
1808    
1809     if (item_attr_get(item, attr_label, &attr))
1810     {
1811     // dbg(0,"street1=%s\n",map_convert_string(item->map, attr.u.str));
1812     if ((streetname_last == NULL) || (strcmp(streetname_last, attr.u.str) != 0))
1813     {
1814     // dbg(0,"street2=%s\n",map_convert_string(item->map, attr.u.str));
1815     streetname_last = g_strdup_printf("%s", attr.u.str);
1816    
1817     p = search_list_street_new(item);
1818     char *buffer = NULL;
1819 zoff99 2 // coords of result
1820     struct coord_geo g;
1821     struct coord c;
1822 zoff99 27 c.x = p->common.c->x;
1823     c.y = p->common.c->y;
1824     int calc_geo = 0;
1825 zoff99 2
1826 zoff99 27 phrases = phrases_first;
1827 zoff99 2 while (phrases)
1828     {
1829     if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1830     {
1831 zoff99 27 if (calc_geo == 0)
1832 zoff99 2 {
1833     transform_to_geo(p->common.c->pro, &c, &g);
1834 zoff99 27 calc_geo = 1;
1835 zoff99 2 }
1836     if (p->common.postal == NULL)
1837     {
1838 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, attr.u.str);
1839 zoff99 2 }
1840     else
1841     {
1842 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, attr.u.str);
1843 zoff99 2 }
1844 zoff99 27 //dbg(0,"street3=%s\n",buffer);
1845 zoff99 12 #ifdef HAVE_API_ANDROID
1846 zoff99 2 // return results to android as they come in ...
1847     android_return_search_result(jni,buffer);
1848 zoff99 12 #endif
1849 zoff99 2 }
1850 zoff99 27 phrases = g_list_next(phrases);
1851 zoff99 2 }
1852     if (buffer)
1853     {
1854     g_free(buffer);
1855     }
1856     search_list_street_destroy(p);
1857 zoff99 27 }
1858     }
1859 zoff99 2
1860 zoff99 27 if (item_attr_get(item, attr_street_name_match, &attr))
1861     {
1862     //dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
1863    
1864     p = search_list_street_new(item);
1865     char *buffer = NULL;
1866     // coords of result
1867     struct coord_geo g;
1868     struct coord c;
1869     c.x = p->common.c->x;
1870     c.y = p->common.c->y;
1871     int calc_geo = 0;
1872    
1873     phrases = phrases_first;
1874     while (phrases)
1875     {
1876     if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1877     {
1878     if (calc_geo == 0)
1879     {
1880     transform_to_geo(p->common.c->pro, &c, &g);
1881     calc_geo = 1;
1882     }
1883     if (p->common.postal == NULL)
1884     {
1885     buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, attr.u.str);
1886     }
1887     else
1888     {
1889     buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, attr.u.str);
1890     }
1891     #ifdef HAVE_API_ANDROID
1892     // return results to android as they come in ...
1893     android_return_search_result(jni,buffer);
1894     #endif
1895     }
1896     phrases = g_list_next(phrases);
1897 zoff99 2 }
1898 zoff99 27 if (buffer)
1899     {
1900     g_free(buffer);
1901     }
1902     search_list_street_destroy(p);
1903    
1904 zoff99 2 }
1905 zoff99 27
1906     if (item_attr_get(item, attr_street_name_systematic, &attr))
1907     {
1908     //dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
1909    
1910     p = search_list_street_new(item);
1911     char *buffer = NULL;
1912     // coords of result
1913     struct coord_geo g;
1914     struct coord c;
1915     c.x = p->common.c->x;
1916     c.y = p->common.c->y;
1917     int calc_geo = 0;
1918    
1919     phrases = phrases_first;
1920     while (phrases)
1921     {
1922     if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1923     {
1924     if (calc_geo == 0)
1925     {
1926     transform_to_geo(p->common.c->pro, &c, &g);
1927     calc_geo = 1;
1928     }
1929     if (p->common.postal == NULL)
1930     {
1931     buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, attr.u.str);
1932     }
1933     else
1934     {
1935     buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, attr.u.str);
1936     }
1937     #ifdef HAVE_API_ANDROID
1938     // return results to android as they come in ...
1939     android_return_search_result(jni,buffer);
1940     #endif
1941     }
1942     phrases = g_list_next(phrases);
1943     }
1944     if (buffer)
1945     {
1946     g_free(buffer);
1947     }
1948     search_list_street_destroy(p);
1949    
1950     }
1951     }
1952 zoff99 2 }
1953     g_free(streetname_last);
1954     map_rect_destroy(mr);
1955     }
1956     }
1957     }
1958     }
1959     }
1960    
1961     map_selection_destroy(sel);
1962    
1963     if (phrases)
1964     {
1965     g_list_free(phrases);
1966     }
1967     g_free(str);
1968    
1969     mapset_close(msh);
1970     }
1971    
1972     GList *
1973 zoff99 27 search_by_address(GList *result_list, struct mapset *ms, char *addr, int partial, struct jni_object *jni, int search_country_flags, char *search_country_string)
1974 zoff99 2 {
1975 zoff99 27 char *str = search_fix_spaces(addr);
1976     GList *tmp, *phrases = search_split_phrases(str);
1977 zoff99 2 GList *phrases_first;
1978     GList *ret = NULL;
1979     struct search_list *sl;
1980     struct attr attr;
1981 zoff99 27 attr.type = attr_country_all;
1982     tmp = phrases;
1983     phrases_first = phrases;
1984     sl = search_list_new(ms);
1985 zoff99 2
1986 zoff99 27 dbg(0, "-- START --\n");
1987 zoff99 2
1988     // normal search stuff -------- START ----------
1989     if (search_country_flags == 1)
1990     {
1991 zoff99 27 dbg(0, "-- country default start --\n");
1992 zoff99 15 //while (phrases)
1993     //{
1994 zoff99 27 // dbg(0,"s=%s\n",phrases->data);
1995     // set default country
1996     search_list_search(sl, country_default(), 0);
1997     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
1998     // phrases=g_list_next(phrases);
1999 zoff99 15 //}
2000 zoff99 27 dbg(0, "-- country default end --\n");
2001 zoff99 2 }
2002     else if (search_country_flags == 2)
2003     {
2004 zoff99 27 dbg(0, "-- country sel:%s start --\n", search_country_string);
2005 zoff99 2 // set a country
2006     struct attr country;
2007 zoff99 27 country.type = attr_country_iso2;
2008     country.u.str = search_country_string;
2009 zoff99 15 //while (phrases)
2010     //{
2011 zoff99 27 // dbg(0,"s=%s\n",phrases->data);
2012     search_list_search(sl, &country, 0);
2013     // set a country
2014     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2015     //phrases=g_list_next(phrases);
2016 zoff99 15 //}
2017 zoff99 27 dbg(0, "-- country sel:%s end --\n", search_country_string);
2018 zoff99 2 }
2019     else // flags==3
2020     {
2021 zoff99 27 dbg(0, "-- country all start --\n");
2022 zoff99 2 // search all countries!! could take a really long time!!
2023     struct attr country;
2024 zoff99 27 int j2 = sizeof(all_country_list) / sizeof(all_country_list[0]);
2025 zoff99 2 int j1;
2026 zoff99 27 for (j1 = 0; j1 < j2; j1++)
2027 zoff99 2 {
2028     if (all_country_list[j1].iso2 != NULL)
2029     {
2030 zoff99 27 phrases = phrases_first;
2031 zoff99 15 //while (phrases)
2032     //{
2033 zoff99 27 // dbg(0,"s country=%s\n",all_country_list[j1].iso2);
2034     // dbg(0,"s=%s\n",phrases->data);
2035     country.type = attr_country_iso2;
2036     country.u.str = all_country_list[j1].iso2;
2037     search_list_search(sl, &country, 0);
2038     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2039     //phrases=g_list_next(phrases);
2040 zoff99 15 //}
2041    
2042 zoff99 27 if (offline_search_break_searching == 1)
2043 zoff99 15 {
2044     break;
2045 zoff99 2 }
2046     }
2047     }
2048 zoff99 27 dbg(0, "-- country all end --\n");
2049 zoff99 2 }
2050     // normal search stuff -------- END ----------
2051    
2052     if (phrases_first)
2053     {
2054     g_list_free(phrases_first);
2055     }
2056    
2057 zoff99 27 dbg(0, "-- END --\n");
2058 zoff99 2
2059     g_free(str);
2060     return ret;
2061     }
2062    

   
Visit the ZANavi Wiki