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

Contents of /navit/navit/search.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (show annotations) (download)
Mon Apr 9 21:27:36 2012 UTC (10 years, 7 months ago) by zoff99
File MIME type: text/plain
File size: 58167 byte(s)
lots of new stuff, tranlsations, bug fixes ...
1 /**
2 * 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 * 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 struct search_list_level
62 {
63 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 GList *list, *curr, *last;
71 };
72
73 struct interpolation
74 {
75 int side, mode, rev;
76 char *first, *last, *curr;
77 };
78
79 struct search_list
80 {
81 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 static guint search_item_hash_hash(gconstpointer key)
93 {
94 const struct item *itm = key;
95 gconstpointer hashkey = (gconstpointer) GINT_TO_POINTER(itm->id_hi ^ itm->id_lo);
96 return g_direct_hash(hashkey);
97 }
98
99 static gboolean search_item_hash_equal(gconstpointer a, gconstpointer b)
100 {
101 const struct item *itm_a = a;
102 const struct item *itm_b = b;
103 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 ret->ms = ms;
115
116 return ret;
117 }
118
119 static void search_list_search_free(struct search_list *sl, int level);
120
121 static int search_list_level(enum attr_type attr_type)
122 {
123 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 }
148 }
149
150 static void interpolation_clear(struct interpolation *inter)
151 {
152 inter->mode = inter->side = 0;
153 g_free(inter->first);
154 g_free(inter->last);
155 g_free(inter->curr);
156 inter->first = inter->last = inter->curr = NULL;
157 }
158
159 void search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
160 {
161 struct search_list_level *le;
162 int level = search_list_level(search_attr->type);
163 this_->item = NULL;
164 interpolation_clear(&this_->inter);
165 //dbg(0,"## enter\n");
166 //dbg(0,"## level=%d\n", level);
167 if (level != -1)
168 {
169 this_->result.id = 0;
170 this_->level = level;
171 le = &this_->levels[level];
172 search_list_search_free(this_, level);
173 le->attr = attr_dup(search_attr);
174 le->partial = partial;
175 if (level > 0)
176 {
177 le = &this_->levels[level - 1];
178 le->curr = le->list;
179 }
180 //dbg(0,"## le=%p partial=%d\n", le, partial);
181 }
182 else if (search_attr->type == attr_postal)
183 {
184 g_free(this_->postal);
185 this_->postal = g_strdup(search_attr->u.str);
186 }
187 //dbg(0,"## return\n");
188 }
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 int level = search_list_level(attr_type);
194 int num = 0;
195 struct search_list_level *le;
196 struct search_list_common *slc;
197 GList *curr;
198 le = &this_->levels[level];
199 curr = le->list;
200 if (mode > 0 || !id)
201 le->selected = mode;
202 //dbg(0,"enter level=%d %d %d %p\n", level, id, mode, curr);
203 while (curr)
204 {
205 num++;
206 if (!id || num == id)
207 {
208 slc = curr->data;
209 slc->selected = mode;
210 if (id)
211 {
212 le->last = curr;
213 //dbg(0,"found\n");
214 return slc;
215 }
216 }
217 curr = g_list_next(curr);
218 }
219 //dbg(0,"not found\n");
220 return NULL;
221 }
222
223 static void search_list_common_new(struct item *item, struct search_list_common *common)
224 {
225 struct attr attr;
226 if (item_attr_get(item, attr_town_name, &attr))
227 common->town_name = map_convert_string(item->map, attr.u.str);
228 else
229 common->town_name = NULL;
230 if (item_attr_get(item, attr_county_name, &attr))
231 common->county_name = map_convert_string(item->map, attr.u.str);
232 else
233 common->county_name = NULL;
234 if (item_attr_get(item, attr_district_name, &attr))
235 common->district_name = map_convert_string(item->map, attr.u.str);
236 else
237 common->district_name = NULL;
238 if (item_attr_get(item, attr_postal, &attr))
239 common->postal = map_convert_string(item->map, attr.u.str);
240 else if (item_attr_get(item, attr_town_postal, &attr))
241 common->postal = map_convert_string(item->map, attr.u.str);
242 else
243 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 }
249
250 static void search_list_common_destroy(struct search_list_common *common)
251 {
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 ret->common.item = ret->common.unique = *item;
266 if (item_attr_get(item, attr_country_car, &attr))
267 ret->car = g_strdup(attr.u.str);
268 if (item_attr_get(item, attr_country_iso2, &attr))
269 {
270 #if HAVE_API_ANDROID
271 ret->iso2=g_malloc(strlen(attr.u.str)+1);
272 strtolower(ret->iso2, attr.u.str);
273 #else
274 ret->iso2 = g_strdup(attr.u.str);
275 #endif
276 ret->flag = g_strdup_printf("country_%s", ret->iso2);
277 }
278 if (item_attr_get(item, attr_country_iso3, &attr))
279 ret->iso3 = g_strdup(attr.u.str);
280 if (item_attr_get(item, attr_country_name, &attr))
281 ret->name = g_strdup(attr.u.str);
282 return ret;
283 }
284
285 static void search_list_country_destroy(struct search_list_country *this_)
286 {
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
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 }
310
311 search_list_common_new(item, &ret->common);
312
313 if (item_attr_get(item, attr_county_name, &attr))
314 {
315 ret->county = map_convert_string(item->map, attr.u.str);
316 }
317 else
318 {
319 ret->county = NULL;
320 }
321
322 if (item_coord_get(item, &c, 1))
323 {
324 ret->common.c=g_new(struct pcoord, 1);
325 ret->common.c->x = c.x;
326 ret->common.c->y = c.y;
327 ret->common.c->pro = map_projection(item->map);
328 }
329 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 return ret;
339 }
340
341 static void search_list_town_destroy(struct search_list_town *this_)
342 {
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
357 ret->common.item = ret->common.unique = *item;
358 if (item_attr_get(item, attr_street_name, &attr))
359 {
360 ret->name = map_convert_string(item->map, attr.u.str);
361 }
362 else
363 {
364 ret->name = NULL;
365 }
366 search_list_common_new(item, &ret->common);
367 if (item_coord_get(item, &c, 1))
368 {
369 ret->common.c=g_new(struct pcoord, 1);
370 ret->common.c->x = c.x;
371 ret->common.c->y = c.y;
372 ret->common.c->pro = map_projection(item->map);
373 }
374 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 return ret;
384 }
385
386 static void search_list_street_destroy(struct search_list_street *this_)
387 {
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 dbg(1, "interpolate %s-%s %s\n", inter->first, inter->last, inter->curr);
401 if (!inter->first || !inter->last)
402 return NULL;
403 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 g_free(inter->curr);
411 if (next == atoi(inter->last))
412 inter->curr = g_strdup(inter->last);
413 else
414 inter->curr = g_strdup_printf("%d", next);
415 }
416 else
417 {
418 g_free(inter->curr);
419 inter->curr = NULL;
420 }
421 }
422 dbg(1, "interpolate result %s\n", inter->curr);
423 return inter->curr;
424 }
425
426 static void search_interpolation_split(char *str, struct interpolation *inter)
427 {
428 char *pos = strchr(str, '-');
429 char *first, *last;
430 int len;
431 if (!pos)
432 {
433 inter->first = g_strdup(str);
434 inter->last = g_strdup(str);
435 inter->rev = 0;
436 return;
437 }
438 len = pos - str;
439 first = g_malloc(len + 1);
440 strncpy(first, str, len);
441 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 }
450 else
451 {
452 inter->first = first;
453 inter->last = last;
454 inter->rev = 0;
455 }
456 }
457
458 static int search_setup_interpolation(struct item *item, enum attr_type i0, enum attr_type i1, enum attr_type i2, struct interpolation *inter)
459 {
460 struct attr attr;
461 g_free(inter->first);
462 g_free(inter->last);
463 g_free(inter->curr);
464 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 search_interpolation_split(attr.u.str, inter);
469 inter->mode = 0;
470 }
471 else if (item_attr_get(item, i1, &attr))
472 {
473 search_interpolation_split(attr.u.str, inter);
474 inter->mode = 1;
475 }
476 else if (item_attr_get(item, i2, &attr))
477 {
478 search_interpolation_split(attr.u.str, inter);
479 inter->mode = 2;
480 }
481 else
482 return 0;
483 return 1;
484 }
485
486 static int search_match(char *str, char *search, int partial)
487 {
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 if (item_is_point(*item))
500 {
501 struct coord c;
502 if (item_coord_get(item, &c, 1))
503 {
504 ret->x = c.x;
505 ret->y = c.y;
506 }
507 else
508 {
509 g_free(ret);
510 ret = NULL;
511 }
512 }
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 item_coord_rewind(item);
519 count = item_coord_get(item, c, max);
520 hn_length = atoi(inter->last) - atoi(inter->first);
521 if (inter->rev)
522 hn_pos = atoi(inter->last) - atoi(inter->curr);
523 else
524 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 }
535 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 }
543 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 }
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 ret->common.item = ret->common.unique = *item;
567 //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 ret->house_number = map_convert_string(item->map, attr.u.str);
571 else
572 {
573 //if (item_attr_get(item, attr_street_name, &attr))
574 // dbg(0,"xx2 %s\n",attr.u.str);
575 for (;;)
576 {
577 //dbg(0,"interpolate 11");
578 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 }
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 ret->house_number = map_convert_string(item->map, hn);
605 break;
606 }
607 }
608 }
609 //dbg(0,"interpolate 33");
610 search_list_common_new(item, &ret->common);
611 ret->common.c = search_house_number_coordinate(item, ret->interpolation ? inter : NULL);
612 //dbg(0,"interpolate 44");
613 return ret;
614 }
615
616 static void search_list_house_number_destroy(struct search_list_house_number *this_)
617 {
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 static void search_list_result_destroy(int level, void *p)
626 {
627 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 }
642 }
643
644 static void search_list_search_free(struct search_list *sl, int level)
645 {
646 //dbg(0,"enter\n");
647
648 struct search_list_level *le = &sl->levels[level];
649 GList *next, *curr;
650 if (le->search)
651 {
652 mapset_search_destroy(le->search);
653 le->search = NULL;
654 }
655 #if 0 /* FIXME */
656 if (le->hash)
657 {
658 g_hash_table_destroy(le->hash);
659 le->hash=NULL;
660 }
661 #endif
662 curr = le->list;
663 while (curr)
664 {
665 search_list_result_destroy(level, curr->data);
666 next = g_list_next(curr);
667 curr = next;
668 }
669 attr_free(le->attr);
670 g_list_free(le->list);
671 le->list = NULL;
672 le->curr = NULL;
673 le->last = NULL;
674
675 //dbg(0,"return\n");
676 }
677
678 char *
679 search_postal_merge(char *mask, char *new)
680 {
681 int i;
682 char *ret = NULL;
683 dbg(1, "enter %s %s\n", mask, new);
684 if (!new)
685 return NULL;
686 if (!mask)
687 return g_strdup(new);
688 i = 0;
689 while (mask[i] && new[i])
690 {
691 if (mask[i] != '.' && mask[i] != new[i])
692 break;
693 i++;
694
695 }
696 if (mask[i])
697 {
698 ret = g_strdup(mask);
699 while (mask[i])
700 ret[i++] = '.';
701 }
702 dbg(1, "merged %s with %s as %s\n", mask, new, ret);
703 return ret;
704 }
705
706 char *
707 search_postal_merge_replace(char *mask, char *new)
708 {
709 char *ret = search_postal_merge(mask, new);
710 if (!ret)
711 return mask;
712 g_free(mask);
713 return ret;
714 }
715
716 static int postal_match(char *postal, char *mask)
717 {
718 for (;;)
719 {
720 if ((*postal != *mask) && (*mask != '.'))
721 return 0;
722 if (!*postal)
723 {
724 if (!*mask)
725 return 1;
726 else
727 return 0;
728 }
729 postal++;
730 mask++;
731 }
732 }
733
734 static int search_add_result(struct search_list_level *le, struct search_list_common *slc)
735 {
736 struct search_list_common *slo;
737 char *merged;
738
739 //dbg(0,"enter\n");
740
741 //slo=g_hash_table_lookup(le->hash, &slc->unique);
742 //if (!slo) {
743 //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 //}
755 merged = search_postal_merge(slo->postal_mask, slc->postal);
756 if (merged)
757 {
758 g_free(slo->postal_mask);
759 slo->postal_mask = merged;
760 }
761 return 0;
762 }
763
764 struct search_list_result *
765 search_list_get_result(struct search_list *this_)
766 {
767 struct search_list_level *le, *leu;
768 int level = this_->level;
769 struct attr attr2;
770 int has_street_name = 0;
771
772 //dbg(0,"******* enter *******\n");
773 le = &this_->levels[level];
774 //dbg(0,"le=%p\n", le);
775 for (;;)
776 {
777 //dbg(0,"le->search=%p\n", le->search);
778 if (!le->search)
779 {
780 //dbg(0,"partial=%d level=%d\n", le->partial, level);
781 if (!level)
782 le->parent = NULL;
783 else
784 {
785 leu = &this_->levels[level - 1];
786 //dbg(0,"leu->curr=%p\n", leu->curr);
787 for (;;)
788 {
789 //dbg(0,"*********########");
790
791 struct search_list_common *slc;
792 if (!leu->curr)
793 {
794 return NULL;
795 }
796 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 if (!slc)
801 break;
802 if (slc->selected == leu->selected)
803 break;
804 }
805 }
806 #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 le->search = mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial);
818 // ** DOC ** mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
819 le->hash = g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
820 }
821
822 //dbg(0,"le->search=%p\n", le->search);
823
824 if (!this_->item)
825 {
826 //dbg(0,"sssss 1");
827 this_->item = mapset_search_get_item(le->search);
828 //dbg(0,"sssss 1 %p\n",this_->item);
829 }
830
831 if (this_->item)
832 {
833 void *p = NULL;
834 //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 if (item_attr_get(this_->item, attr_postal_mask, &postal))
839 {
840 if (!postal_match(this_->postal, postal.u.str))
841 continue;
842 }
843 else if (item_attr_get(this_->item, attr_postal, &postal))
844 {
845 if (strcmp(this_->postal, postal.u.str))
846 continue;
847 }
848 }
849 this_->result.country = NULL;
850 this_->result.town = NULL;
851 this_->result.street = NULL;
852 this_->result.c = NULL;
853 //dbg(0,"case x LEVEL start %d\n",level);
854 switch (level)
855 {
856 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
886 // 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
893 //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
909 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
915 //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 }
935 // CASE END *********
936
937
938 if (p)
939 {
940 if (search_add_result(le, p))
941 {
942 //** this_->result.id++;
943 this_->result.id = 0;
944 //dbg(0,"++++ return result\n");
945 return &this_->result;
946 }
947 else
948 {
949 search_list_result_destroy(level, p);
950 // return &this_->result;
951 }
952 }
953 }
954 else
955 {
956 mapset_search_destroy(le->search);
957 le->search = NULL;
958 g_hash_table_destroy(le->hash);
959 if (!level)
960 {
961 break;
962 }
963 }
964 }
965 return NULL;
966 }
967
968 void search_list_destroy(struct search_list *this_)
969 {
970 g_free(this_->postal);
971 g_free(this_);
972 }
973
974 void search_init(void)
975 {
976 }
977
978 static char *
979 search_fix_spaces(char *str)
980 {
981 int i;
982 int len = strlen(str);
983 char c, *s, *d, *ret = g_strdup(str);
984
985 for (i = 0; i < len; i++)
986 {
987 if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/')
988 ret[i] = ' ';
989 }
990 s = ret;
991 d = ret;
992 len = 0;
993 do
994 {
995 c = *s++;
996 if (c != ' ' || len != 0)
997 {
998 *d++ = c;
999 len++;
1000 }
1001 while (c == ' ' && *s == ' ')
1002 s++;
1003 if (c == ' ' && *s == '\0')
1004 {
1005 d--;
1006 len--;
1007 }
1008 }
1009 while (c);
1010 return ret;
1011 }
1012
1013 static GList *
1014 search_split_phrases(char *str)
1015 {
1016 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 *d = '\0';
1029 ret = g_list_append(ret, g_strdup(tmp));
1030 }
1031 d--;
1032 }
1033 g_free(tmp);
1034 do
1035 {
1036 s++;
1037 if (*s == ' ')
1038 {
1039 s++;
1040 break;
1041 }
1042 }
1043 while (*s != '\0');
1044 }
1045 while (*s != '\0');
1046 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 while ((slr = search_list_get_result(sl)))
1059 {
1060 if (offline_search_break_searching == 1)
1061 {
1062 break;
1063 }
1064
1065 // does the streetname of the housenumber match the street we want?
1066 if (slr != NULL)
1067 {
1068 if (slr->street != NULL)
1069 if ((street_name != NULL) && (slr->street->name != NULL))
1070 {
1071
1072 if (strcmp(slr->street->name, street_name) == 0)
1073 {
1074 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
1092 //dbg(0,"res=%s\n",buffer);
1093
1094 // 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 }
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 GList *tmp = phrases;
1116 int count = 0;
1117 struct coord_geo g;
1118 struct coord c;
1119 struct attr attr2;
1120
1121 struct item *save_item;
1122 int save_level;
1123 int save_last_result_valid;
1124
1125 while ((slr = search_list_get_result(sl)))
1126 {
1127 char *buffer;
1128 char *buffer2;
1129
1130 if (offline_search_break_searching == 1)
1131 {
1132 break;
1133 }
1134
1135 if (slr->street)
1136 {
1137 // coords of result
1138 c.x = slr->street->common.c->x;
1139 c.y = slr->street->common.c->y;
1140 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 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 }
1149 else
1150 {
1151 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 }
1153 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1154
1155 //dbg(0,"res=%s\n",buffer);
1156
1157 #ifdef HAVE_API_ANDROID
1158 // return results to android as they come in ...
1159 android_return_search_result(jni,buffer);
1160 #endif
1161 count++;
1162
1163 buffer2 = g_strdup_printf("%s", slr->street->name);
1164 //dbg(0,"b2:%s\n",buffer2);
1165
1166
1167 save_item = sl->item;
1168 save_level = sl->level;
1169 save_last_result_valid = sl->last_result_valid;
1170
1171 #if 1
1172 // put words back to start!!
1173 tmp = phrases;
1174 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 attr2.type = attr_house_number;
1182 attr2.u.str = tmp->data;
1183 search_list_search(sl, &attr2, partial);
1184
1185 result_list = search_address_housenumber_real(result_list, sl, buffer2, phrases, exclude1, exclude2, exclude3, partial, jni);
1186 }
1187 tmp = g_list_next(tmp);
1188 }
1189 #endif
1190
1191 // restore again
1192 sl->item = save_item;
1193 sl->level = save_level;
1194 sl->last_result_valid = save_last_result_valid;
1195
1196 }
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 GList *tmp = phrases;
1219 int count = 0;
1220 struct coord_geo g;
1221 struct coord c;
1222 struct attr attr;
1223 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
1230 while ((slr = search_list_get_result(sl)))
1231 {
1232 char *buffer;
1233
1234 if (offline_search_break_searching == 1)
1235 {
1236 break;
1237 }
1238
1239 // coords of result
1240 c.x = slr->town->common.c->x;
1241 c.y = slr->town->common.c->y;
1242 transform_to_geo(slr->town->common.c->pro, &c, &g);
1243
1244 // TWN -> town
1245 if (slr->town->common.postal == NULL)
1246 {
1247 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 }
1249 else
1250 {
1251 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 }
1253
1254 //dbg(0,"**res=%s\n",buffer);
1255
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 if (buffer)
1264 g_free(buffer);
1265
1266 save_item = sl->item;
1267 save_level = sl->level;
1268 save_last_result_valid = sl->last_result_valid;
1269
1270 // put words back to start!!
1271 tmp = phrases;
1272
1273 while (tmp)
1274 {
1275 if (tmp != exclude1 && tmp != exclude2)
1276 {
1277 //dbg(0,"s=%s\n",tmp->data);
1278 attr.type = attr_street_name;
1279 attr.u.str = tmp->data;
1280 search_list_search(sl, &attr, partial);
1281 result_list = search_address__street(result_list, sl, phrases, exclude1, exclude2, tmp, partial, jni);
1282 }
1283 tmp = g_list_next(tmp);
1284 }
1285
1286 // restore again
1287 sl->item = save_item;
1288 sl->level = save_level;
1289 sl->last_result_valid = save_last_result_valid;
1290 }
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 GList *tmp = phrases;
1300 int count = 0;
1301 struct attr attr;
1302 struct search_list_result *slr;
1303 //dbg(0,"enter\n");
1304
1305 while ((slr = search_list_get_result(sl)))
1306 {
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 //dbg(0,"Is=%s\n",tmp->data);
1324 attr.type = attr_town_or_district_name;
1325 attr.u.str = tmp->data;
1326 search_list_search(sl, &attr, partial);
1327 result_list = search_address__town(result_list, sl, phrases, exclude, tmp, partial, jni);
1328 }
1329 //else
1330 //{
1331 //dbg(0,"Xs=%s\n",tmp->data);
1332 //}
1333 tmp = g_list_next(tmp);
1334 }
1335 //dbg(0,"return 2");
1336 return result_list;
1337 }
1338
1339 struct country2
1340 {
1341 int id;
1342 char *car;
1343 char *iso2;
1344 char *iso3;
1345 char *name;
1346 };
1347
1348 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
1633 static int ascii_cmp_local(char *name, char *match, int partial)
1634 {
1635 char *s1 = linguistics_casefold(name);
1636 char *s2 = linguistics_casefold(match);
1637 int ret = linguistics_compare(s1, s2, partial);
1638 g_free(s1);
1639 g_free(s2);
1640 return ret;
1641 }
1642
1643 struct navit *global_navit;
1644
1645 void search_full_world(char *addr, int partial, int search_order, struct jni_object *jni, struct coord_geo *search_center, int search_radius)
1646 {
1647 struct item *item;
1648 struct map_rect *mr = NULL;
1649 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 char *str = search_fix_spaces(addr);
1656 GList *phrases = search_split_phrases(str);
1657 GList *phrases_first;
1658 phrases_first = phrases;
1659
1660 ms = global_navit->mapsets->data;
1661 msh = mapset_open(ms);
1662
1663 struct pcoord center99;
1664 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 {
1668 center99.x = 0;
1669 center99.y = 0;
1670 search_radius_this = 21000000;
1671 }
1672 else
1673 {
1674 struct coord c99;
1675 transform_from_geo(projection_mg, search_center, &c99);
1676 center99.x = c99.x;
1677 center99.y = c99.y;
1678 search_radius_this = search_radius;
1679 }
1680 dbg(0, "out x=%d,y=%d,r=%d\n", center99.x, center99.y, search_radius_this);
1681
1682 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
1686 while (msh && (map = mapset_next(msh, 0)))
1687 {
1688 if (map_get_attr(map, attr_name, &map_name_attr, NULL))
1689 {
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 mr = map_rect_new(map, sel);
1698 if (mr)
1699 {
1700 char *streetname_last = NULL;
1701
1702 while ((item = map_rect_get_item(mr)))
1703 {
1704 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 {
1710 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
1719 // dbg(0,"town name=%s\n", attr.u.str);
1720
1721 phrases = phrases_first;
1722 while (phrases)
1723 {
1724 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1725 {
1726 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1727 if (calc_geo == 0)
1728 {
1729 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 #ifdef HAVE_API_ANDROID
1742 // return results to android as they come in ...
1743 android_return_search_result(jni,buffer);
1744 #endif
1745 }
1746 phrases = g_list_next(phrases);
1747
1748 }
1749 if (buffer)
1750 {
1751 g_free(buffer);
1752 }
1753 search_list_town_destroy(p);
1754 }
1755
1756 if (item_attr_get(item, attr_town_name_match, &attr))
1757 {
1758 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
1767 // dbg(0,"town name=%s\n", attr.u.str);
1768
1769 phrases = phrases_first;
1770 while (phrases)
1771 {
1772 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1773 {
1774 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1775 if (calc_geo == 0)
1776 {
1777 transform_to_geo(p->common.c->pro, &c, &g);
1778 // TWN -> town
1779 calc_geo = 1;
1780 }
1781 if (p->common.postal == NULL)
1782 {
1783 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 }
1785 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 }
1794 phrases = g_list_next(phrases);
1795
1796 }
1797 if (buffer)
1798 {
1799 g_free(buffer);
1800 }
1801 search_list_town_destroy(p);
1802 }
1803 }
1804 else if (item_is_street(*item))
1805 {
1806
1807 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 // coords of result
1820 struct coord_geo g;
1821 struct coord c;
1822 c.x = p->common.c->x;
1823 c.y = p->common.c->y;
1824 int calc_geo = 0;
1825
1826 phrases = phrases_first;
1827 while (phrases)
1828 {
1829 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1830 {
1831 if (calc_geo == 0)
1832 {
1833 transform_to_geo(p->common.c->pro, &c, &g);
1834 calc_geo = 1;
1835 }
1836 if (p->common.postal == NULL)
1837 {
1838 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 }
1840 else
1841 {
1842 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 }
1844 //dbg(0,"street3=%s\n",buffer);
1845 #ifdef HAVE_API_ANDROID
1846 // return results to android as they come in ...
1847 android_return_search_result(jni,buffer);
1848 #endif
1849 }
1850 phrases = g_list_next(phrases);
1851 }
1852 if (buffer)
1853 {
1854 g_free(buffer);
1855 }
1856 search_list_street_destroy(p);
1857 }
1858 }
1859
1860 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 }
1898 if (buffer)
1899 {
1900 g_free(buffer);
1901 }
1902 search_list_street_destroy(p);
1903
1904 }
1905
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 }
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 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 {
1975 char *str = search_fix_spaces(addr);
1976 GList *tmp, *phrases = search_split_phrases(str);
1977 GList *phrases_first;
1978 GList *ret = NULL;
1979 struct search_list *sl;
1980 struct attr attr;
1981 attr.type = attr_country_all;
1982 tmp = phrases;
1983 phrases_first = phrases;
1984 sl = search_list_new(ms);
1985
1986 dbg(0, "-- START --\n");
1987
1988 // normal search stuff -------- START ----------
1989 if (search_country_flags == 1)
1990 {
1991 dbg(0, "-- country default start --\n");
1992 //while (phrases)
1993 //{
1994 // 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 //}
2000 dbg(0, "-- country default end --\n");
2001 }
2002 else if (search_country_flags == 2)
2003 {
2004 dbg(0, "-- country sel:%s start --\n", search_country_string);
2005 // set a country
2006 struct attr country;
2007 country.type = attr_country_iso2;
2008 country.u.str = search_country_string;
2009 //while (phrases)
2010 //{
2011 // 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 //}
2017 dbg(0, "-- country sel:%s end --\n", search_country_string);
2018 }
2019 else // flags==3
2020 {
2021 dbg(0, "-- country all start --\n");
2022 // search all countries!! could take a really long time!!
2023 struct attr country;
2024 int j2 = sizeof(all_country_list) / sizeof(all_country_list[0]);
2025 int j1;
2026 for (j1 = 0; j1 < j2; j1++)
2027 {
2028 if (all_country_list[j1].iso2 != NULL)
2029 {
2030 phrases = phrases_first;
2031 //while (phrases)
2032 //{
2033 // 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 //}
2041
2042 if (offline_search_break_searching == 1)
2043 {
2044 break;
2045 }
2046 }
2047 }
2048 dbg(0, "-- country all end --\n");
2049 }
2050 // normal search stuff -------- END ----------
2051
2052 if (phrases_first)
2053 {
2054 g_list_free(phrases_first);
2055 }
2056
2057 dbg(0, "-- END --\n");
2058
2059 g_free(str);
2060 return ret;
2061 }
2062

   
Visit the ZANavi Wiki