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

Contents of /navit/navit/search.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations) (download)
Sun Jun 17 08:12:47 2012 UTC (11 years, 10 months ago) by zoff99
File MIME type: text/plain
File size: 58861 byte(s)
lots of new stuff and 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 if (offline_search_break_searching == 1)
1177 {
1178 break;
1179 }
1180
1181 //dbg(0,"s0=%s\n",tmp->data);
1182 if (tmp != exclude1 && tmp != exclude2 && tmp != exclude3)
1183 {
1184 //dbg(0,"s=%s\n",tmp->data);
1185
1186 attr2.type = attr_house_number;
1187 attr2.u.str = tmp->data;
1188 search_list_search(sl, &attr2, partial);
1189
1190 result_list = search_address_housenumber_real(result_list, sl, buffer2, phrases, exclude1, exclude2, exclude3, partial, jni);
1191 }
1192 tmp = g_list_next(tmp);
1193 }
1194 #endif
1195
1196 // restore again
1197 sl->item = save_item;
1198 sl->level = save_level;
1199 sl->last_result_valid = save_last_result_valid;
1200
1201 }
1202
1203 if (buffer2)
1204 {
1205 g_free(buffer2);
1206 }
1207
1208 if (buffer)
1209 {
1210 g_free(buffer);
1211 }
1212 }
1213
1214 //dbg(0,"return 2\n");
1215 return result_list;
1216 }
1217
1218 static GList *
1219 search_address__town(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, int partial, struct jni_object *jni)
1220 {
1221 //dbg(0,"enter\n");
1222 struct search_list_result *slr;
1223 GList *tmp = phrases;
1224 int count = 0;
1225 struct coord_geo g;
1226 struct coord c;
1227 struct attr attr;
1228 struct attr attrx;
1229 // struct search_list *sl2=search_list_new(sl->ms);
1230 struct item *save_item;
1231 int save_level;
1232 int save_last_result_valid;
1233 // int first=1;
1234
1235 while ((slr = search_list_get_result(sl)))
1236 {
1237 char *buffer;
1238
1239 if (offline_search_break_searching == 1)
1240 {
1241 break;
1242 }
1243
1244 // coords of result
1245 c.x = slr->town->common.c->x;
1246 c.y = slr->town->common.c->y;
1247 transform_to_geo(slr->town->common.c->pro, &c, &g);
1248
1249 // TWN -> town
1250 if (slr->town->common.postal == NULL)
1251 {
1252 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);
1253 }
1254 else
1255 {
1256 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);
1257 }
1258
1259 //dbg(0,"**res=%s\n",buffer);
1260
1261 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1262 #ifdef HAVE_API_ANDROID
1263 // return results to android as they come in ...
1264 android_return_search_result(jni,buffer);
1265 #endif
1266
1267 count++;
1268 if (buffer)
1269 g_free(buffer);
1270
1271 save_item = sl->item;
1272 save_level = sl->level;
1273 save_last_result_valid = sl->last_result_valid;
1274
1275 // put words back to start!!
1276 tmp = phrases;
1277
1278 while (tmp)
1279 {
1280 if (offline_search_break_searching == 1)
1281 {
1282 break;
1283 }
1284
1285 if (tmp != exclude1 && tmp != exclude2)
1286 {
1287 //dbg(0,"s=%s\n",tmp->data);
1288 attr.type = attr_street_name;
1289 attr.u.str = tmp->data;
1290 search_list_search(sl, &attr, partial);
1291 result_list = search_address__street(result_list, sl, phrases, exclude1, exclude2, tmp, partial, jni);
1292 }
1293 tmp = g_list_next(tmp);
1294 }
1295
1296 // restore again
1297 sl->item = save_item;
1298 sl->level = save_level;
1299 sl->last_result_valid = save_last_result_valid;
1300 }
1301
1302 //dbg(0,"return 2\n");
1303 return result_list;
1304 }
1305
1306 static GList *
1307 search_address__country(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude, int partial, struct jni_object *jni)
1308 {
1309 GList *tmp = phrases;
1310 int count = 0;
1311 struct attr attr;
1312 struct search_list_result *slr;
1313 //dbg(0,"enter\n");
1314
1315 while ((slr = search_list_get_result(sl)))
1316 {
1317 //dbg(0,"1 slr=%p\n",slr->country);
1318 //dbg(0,"2 slr=%s\n",slr->country->name);
1319 //dbg(0,"3 slr=%s\n",slr->country->iso2);
1320 count++;
1321 }
1322 //dbg(0,"count %d\n",count);
1323 if (!count)
1324 {
1325 //dbg(0,"return 1");
1326 return result_list;
1327 }
1328
1329 while (tmp)
1330 {
1331 if (tmp != exclude)
1332 {
1333 //dbg(0,"Is=%s\n",tmp->data);
1334 attr.type = attr_town_or_district_name;
1335 attr.u.str = tmp->data;
1336 search_list_search(sl, &attr, partial);
1337 result_list = search_address__town(result_list, sl, phrases, exclude, tmp, partial, jni);
1338 }
1339 //else
1340 //{
1341 //dbg(0,"Xs=%s\n",tmp->data);
1342 //}
1343 tmp = g_list_next(tmp);
1344 }
1345 //dbg(0,"return 2");
1346 return result_list;
1347 }
1348
1349 struct country2
1350 {
1351 int id;
1352 char *car;
1353 char *iso2;
1354 char *iso3;
1355 char *name;
1356 };
1357
1358 static struct country2 all_country_list[] =
1359 {
1360 { 20, "AND", "AD", "AND", /* 020 */"Andorra" },
1361 { 784, "UAE", "AE", "ARE", /* 784 */
1362 "United Arab Emirates" },
1363 { 4, "AFG", "AF", "AFG", /* 004 */"Afghanistan" },
1364 { 28, "AG", "AG", "ATG", /* 028 */"Antigua and Barbuda" },
1365 { 660, NULL, "AI", "AIA", /* 660 */"Anguilla" },
1366 { 8, "AL", "AL", "ALB", /* 008 */"Albania" },
1367 { 51, "ARM", "AM", "ARM", /* 051 */"Armenia" },
1368 { 530, "NA", "AN", "ANT", /* 530 */
1369 "Netherlands Antilles" },
1370 { 24, "ANG", "AO", "AGO", /* 024 */"Angola" },
1371 { 10, NULL, "AQ", "ATA", /* 010 */"Antarctica" },
1372 { 32, "RA", "AR", "ARG", /* 032 */"Argentina" },
1373 { 16, NULL, "AS", "ASM", /* 016 */"American Samoa" },
1374 { 40, "A", "AT", "AUT", /* 040 */"Austria" },
1375 { 36, "AUS", "AU", "AUS", /* 036 */"Australia" },
1376 { 533, "ARU", "AW", "ABW", /* 533 */"Aruba" },
1377 { 248, "AX", "AX", "ALA", /* 248 */"Aland Islands" },
1378 { 31, "AZ", "AZ", "AZE", /* 031 */"Azerbaijan" },
1379 { 70, "BiH", "BA", "BIH", /* 070 */
1380 "Bosnia and Herzegovina" },
1381 { 52, "BDS", "BB", "BRB", /* 052 */"Barbados" },
1382 { 50, "BD", "BD", "BGD", /* 050 */"Bangladesh" },
1383 { 56, "B", "BE", "BEL", /* 056 */"Belgium" },
1384 { 854, "BF", "BF", "BFA", /* 854 */"Burkina Faso" },
1385 { 100, "BG", "BG", "BGR", /* 100 */"Bulgaria" },
1386 { 48, "BRN", "BH", "BHR", /* 048 */"Bahrain" },
1387 { 108, "RU", "BI", "BDI", /* 108 */"Burundi" },
1388 { 204, "BJ", "BJ", "BEN", /* 204 */"Benin" },
1389 { 652, NULL, "BL", "BLM", /* 652 */"Saint Barthelemy" },
1390 { 60, NULL, "BM", "BMU", /* 060 */"Bermuda" },
1391 { 96, "BRU", "BN", "BRN", /* 096 */"Brunei Darussalam" },
1392 { 68, "BOL", "BO", "BOL", /* 068 */"Bolivia" },
1393 { 76, "BR", "BR", "BRA", /* 076 */"Brazil" },
1394 { 44, "BS", "BS", "BHS", /* 044 */"Bahamas" },
1395 { 64, "BHT", "BT", "BTN", /* 064 */"Bhutan" },
1396 { 74, NULL, "BV", "BVT", /* 074 */"Bouvet Island" },
1397 { 72, "RB", "BW", "BWA", /* 072 */"Botswana" },
1398 { 112, "BY", "BY", "BLR", /* 112 */"Belarus" },
1399 { 84, "BZ", "BZ", "BLZ", /* 084 */"Belize" },
1400 { 124, "CDN", "CA", "CAN", /* 124 */"Canada" },
1401 { 166, NULL, "CC", "CCK", /* 166 */
1402 "Cocos (Keeling) Islands" },
1403 { 180, "CGO", "CD", "COD", /* 180 */
1404 "Congo, Democratic Republic of the" },
1405 { 140, "RCA", "CF", "CAF", /* 140 */
1406 "Central African Republic" },
1407 { 178, NULL, "CG", "COG", /* 178 */"Congo" },
1408 { 756, "CH", "CH", "CHE", /* 756 */"Switzerland" },
1409 { 384, "CI", "CI", "CIV", /* 384 */"Cote d'Ivoire" },
1410 { 184, NULL, "CK", "COK", /* 184 */"Cook Islands" },
1411 { 152, "RCH", "CL", "CHL", /* 152 */"Chile" },
1412 { 120, "CAM", "CM", "CMR", /* 120 */"Cameroon" },
1413 { 156, "RC", "CN", "CHN", /* 156 */"China" },
1414 { 170, "CO", "CO", "COL", /* 170 */"Colombia" },
1415 { 188, "CR", "CR", "CRI", /* 188 */"Costa Rica" },
1416 { 192, "C", "CU", "CUB", /* 192 */"Cuba" },
1417 { 132, "CV", "CV", "CPV", /* 132 */"Cape Verde" },
1418 { 162, NULL, "CX", "CXR", /* 162 */"Christmas Island" },
1419 { 196, "CY", "CY", "CYP", /* 196 */"Cyprus" },
1420 { 203, "CZ", "CZ", "CZE", /* 203 */"Czech Republic" },
1421 { 276, "D", "DE", "DEU", /* 276 */"Germany" },
1422 { 262, "DJI", "DJ", "DJI", /* 262 */"Djibouti" },
1423 { 208, "DK", "DK", "DNK", /* 208 */"Denmark" },
1424 { 212, "WD", "DM", "DMA", /* 212 */"Dominica" },
1425 { 214, "DOM", "DO", "DOM", /* 214 */
1426 "Dominican Republic" },
1427 { 12, "DZ", "DZ", "DZA", /* 012 */"Algeria" },
1428 { 218, "EC", "EC", "ECU", /* 218 */"Ecuador" },
1429 { 233, "EST", "EE", "EST", /* 233 */"Estonia" },
1430 { 818, "ET", "EG", "EGY", /* 818 */"Egypt" },
1431 { 732, "WSA", "EH", "ESH", /* 732 */"Western Sahara" },
1432 { 232, "ER", "ER", "ERI", /* 232 */"Eritrea" },
1433 { 724, "E", "ES", "ESP", /* 724 */"Spain" },
1434 { 231, "ETH", "ET", "ETH", /* 231 */"Ethiopia" },
1435 { 246, "FIN", "FI", "FIN", /* 246 */"Finland" },
1436 { 242, "FJI", "FJ", "FJI", /* 242 */"Fiji" },
1437 { 238, NULL, "FK", "FLK", /* 238 */
1438 "Falkland Islands (Malvinas)" },
1439 { 583, "FSM", "FM", "FSM", /* 583 */
1440 "Micronesia, Federated States of" },
1441 { 234, "FO", "FO", "FRO", /* 234 */"Faroe Islands" },
1442 { 250, "F", "FR", "FRA", /* 250 */"France" },
1443 { 266, "G", "GA", "GAB", /* 266 */"Gabon" },
1444 { 826, "GB", "GB", "GBR", /* 826 */"United Kingdom" },
1445 { 308, "WG", "GD", "GRD", /* 308 */"Grenada" },
1446 { 268, "GE", "GE", "GEO", /* 268 */"Georgia" },
1447 { 254, NULL, "GF", "GUF", /* 254 */"French Guiana" },
1448 { 831, NULL, "GG", "GGY", /* 831 */"Guernsey" },
1449 { 288, "GH", "GH", "GHA", /* 288 */"Ghana" },
1450 { 292, "GBZ", "GI", "GIB", /* 292 */"Gibraltar" },
1451 { 304, "KN", "GL", "GRL", /* 304 */"Greenland" },
1452 { 270, "WAG", "GM", "GMB", /* 270 */"Gambia" },
1453 { 324, "RG", "GN", "GIN", /* 324 */"Guinea" },
1454 { 312, NULL, "GP", "GLP", /* 312 */"Guadeloupe" },
1455 { 226, "GQ", "GQ", "GNQ", /* 226 */"Equatorial Guinea" },
1456 { 300, "GR", "GR", "GRC", /* 300 */"Greece" },
1457 { 239, NULL, "GS", "SGS", /* 239 */
1458 "South Georgia and the South Sandwich Islands" },
1459 { 320, "GCA", "GT", "GTM", /* 320 */"Guatemala" },
1460 { 316, NULL, "GU", "GUM", /* 316 */"Guam" },
1461 { 624, "GUB", "GW", "GNB", /* 624 */"Guinea-Bissau" },
1462 { 328, "GUY", "GY", "GUY", /* 328 */"Guyana" },
1463 { 344, "HK", "HK", "HKG", /* 344 */"Hong Kong" },
1464 { 334, NULL, "HM", "HMD", /* 334 */
1465 "Heard Island and McDonald Islands" },
1466 { 340, "HN", "HN", "HND", /* 340 */"Honduras" },
1467 { 191, "HR", "HR", "HRV", /* 191 */"Croatia" },
1468 { 332, "RH", "HT", "HTI", /* 332 */"Haiti" },
1469 { 348, "H", "HU", "HUN", /* 348 */"Hungary" },
1470 { 360, "RI", "ID", "IDN", /* 360 */"Indonesia" },
1471 { 372, "IRL", "IE", "IRL", /* 372 */"Ireland" },
1472 { 376, "IL", "IL", "ISR", /* 376 */"Israel" },
1473 { 833, NULL, "IM", "IMN", /* 833 */"Isle of Man" },
1474 { 356, "IND", "IN", "IND", /* 356 */"India" },
1475 { 86, NULL, "IO", "IOT", /* 086 */
1476 "British Indian Ocean Territory" },
1477 { 368, "IRQ", "IQ", "IRQ", /* 368 */"Iraq" },
1478 { 364, "IR", "IR", "IRN", /* 364 */
1479 "Iran, Islamic Republic of" },
1480 { 352, "IS", "IS", "ISL", /* 352 */"Iceland" },
1481 { 380, "I", "IT", "ITA", /* 380 */"Italy" },
1482 { 832, NULL, "JE", "JEY", /* 832 */"Jersey" },
1483 { 388, "JA", "JM", "JAM", /* 388 */"Jamaica" },
1484 { 400, "JOR", "JO", "JOR", /* 400 */"Jordan" },
1485 { 392, "J", "JP", "JPN", /* 392 */"Japan" },
1486 { 404, "EAK", "KE", "KEN", /* 404 */"Kenya" },
1487 { 417, "KS", "KG", "KGZ", /* 417 */"Kyrgyzstan" },
1488 { 116, "K", "KH", "KHM", /* 116 */"Cambodia" },
1489 { 296, "KIR", "KI", "KIR", /* 296 */"Kiribati" },
1490 { 174, "COM", "KM", "COM", /* 174 */"Comoros" },
1491 { 659, "KAN", "KN", "KNA", /* 659 */
1492 "Saint Kitts and Nevis" },
1493 { 408, "KP", "KP", "PRK", /* 408 */
1494 "Korea, Democratic People's Republic of" },
1495 { 410, "ROK", "KR", "KOR", /* 410 */
1496 "Korea, Republic of" },
1497 { 414, "KWT", "KW", "KWT", /* 414 */"Kuwait" },
1498 { 136, NULL, "KY", "CYM", /* 136 */"Cayman Islands" },
1499 { 398, "KZ", "KZ", "KAZ", /* 398 */"Kazakhstan" },
1500 { 418, "LAO", "LA", "LAO", /* 418 */
1501 "Lao People's Democratic Republic" },
1502 { 422, "RL", "LB", "LBN", /* 422 */"Lebanon" },
1503 { 662, "WL", "LC", "LCA", /* 662 */"Saint Lucia" },
1504 { 438, "FL", "LI", "LIE", /* 438 */"Liechtenstein" },
1505 { 144, "CL", "LK", "LKA", /* 144 */"Sri Lanka" },
1506 { 430, "LB", "LR", "LBR", /* 430 */"Liberia" },
1507 { 426, "LS", "LS", "LSO", /* 426 */"Lesotho" },
1508 { 440, "LT", "LT", "LTU", /* 440 */"Lithuania" },
1509 { 442, "L", "LU", "LUX", /* 442 */"Luxembourg" },
1510 { 428, "LV", "LV", "LVA", /* 428 */"Latvia" },
1511 { 434, "LAR", "LY", "LBY", /* 434 */
1512 "Libyan Arab Jamahiriya" },
1513 { 504, "MA", "MA", "MAR", /* 504 */"Morocco" },
1514 { 492, "MC", "MC", "MCO", /* 492 */"Monaco" },
1515 { 498, "MD", "MD", "MDA", /* 498 */
1516 "Moldova, Republic of" },
1517 { 499, "MNE", "ME", "MNE", /* 499 */"Montenegro" },
1518 { 663, NULL, "MF", "MAF", /* 663 */
1519 "Saint Martin (French part)" },
1520 { 450, "RM", "MG", "MDG", /* 450 */"Madagascar" },
1521 { 584, "MH", "MH", "MHL", /* 584 */"Marshall Islands" },
1522 { 807, "MK", "MK", "MKD", /* 807 */
1523 "Macedonia, the former Yugoslav Republic of" },
1524 { 466, "RMM", "ML", "MLI", /* 466 */"Mali" },
1525 { 104, "MYA", "MM", "MMR", /* 104 */"Myanmar" },
1526 { 496, "MGL", "MN", "MNG", /* 496 */"Mongolia" },
1527 { 446, NULL, "MO", "MAC", /* 446 */"Macao" },
1528 { 580, NULL, "MP", "MNP", /* 580 */
1529 "Northern Mariana Islands" },
1530 { 474, NULL, "MQ", "MTQ", /* 474 */"Martinique" },
1531 { 478, "RIM", "MR", "MRT", /* 478 */"Mauritania" },
1532 { 500, NULL, "MS", "MSR", /* 500 */"Montserrat" },
1533 { 470, "M", "MT", "MLT", /* 470 */"Malta" },
1534 { 480, "MS", "MU", "MUS", /* 480 */"Mauritius" },
1535 { 462, "MV", "MV", "MDV", /* 462 */"Maldives" },
1536 { 454, "MW", "MW", "MWI", /* 454 */"Malawi" },
1537 { 484, "MEX", "MX", "MEX", /* 484 */"Mexico" },
1538 { 458, "MAL", "MY", "MYS", /* 458 */"Malaysia" },
1539 { 508, "MOC", "MZ", "MOZ", /* 508 */"Mozambique" },
1540 { 516, "NAM", "NA", "NAM", /* 516 */"Namibia" },
1541 { 540, "NCL", "NC", "NCL", /* 540 */"New Caledonia" },
1542 { 562, "RN", "NE", "NER", /* 562 */"Niger" },
1543 { 574, NULL, "NF", "NFK", /* 574 */"Norfolk Island" },
1544 { 566, "NGR", "NG", "NGA", /* 566 */"Nigeria" },
1545 { 558, "NIC", "NI", "NIC", /* 558 */"Nicaragua" },
1546 { 528, "NL", "NL", "NLD", /* 528 */"Netherlands" },
1547 { 578, "N", "NO", "NOR", /* 578 */"Norway" },
1548 { 524, "NEP", "NP", "NPL", /* 524 */"Nepal" },
1549 { 520, "NAU", "NR", "NRU", /* 520 */"Nauru" },
1550 { 570, NULL, "NU", "NIU", /* 570 */"Niue" },
1551 { 554, "NZ", "NZ", "NZL", /* 554 */"New Zealand" },
1552 { 512, "OM", "OM", "OMN", /* 512 */"Oman" },
1553 { 591, "PA", "PA", "PAN", /* 591 */"Panama" },
1554 { 604, "PE", "PE", "PER", /* 604 */"Peru" },
1555 { 258, NULL, "PF", "PYF", /* 258 */"French Polynesia" },
1556 { 598, "PNG", "PG", "PNG", /* 598 */"Papua New Guinea" },
1557 { 608, "RP", "PH", "PHL", /* 608 */"Philippines" },
1558 { 586, "PK", "PK", "PAK", /* 586 */"Pakistan" },
1559 { 616, "PL", "PL", "POL", /* 616 */"Poland" },
1560 { 666, NULL, "PM", "SPM", /* 666 */
1561 "Saint Pierre and Miquelon" },
1562 { 612, NULL, "PN", "PCN", /* 612 */"Pitcairn" },
1563 { 630, "PRI", "PR", "PRI", /* 630 */"Puerto Rico" },
1564 { 275, "AUT", "PS", "PSE", /* 275 */
1565 "Palestinian Territory, Occupied" },
1566 { 620, "P", "PT", "PRT", /* 620 */"Portugal" },
1567 { 585, "PAL", "PW", "PLW", /* 585 */"Palau" },
1568 { 600, "PY", "PY", "PRY", /* 600 */"Paraguay" },
1569 { 634, "Q", "QA", "QAT", /* 634 */"Qatar" },
1570 { 638, NULL, "RE", "REU", /* 638 */"Reunion" },
1571 { 642, "RO", "RO", "ROU", /* 642 */"Romania" },
1572 { 688, "SRB", "RS", "SRB", /* 688 */"Serbia" },
1573 { 643, "RUS", "RU", "RUS", /* 643 */
1574 "Russian Federation" },
1575 { 646, "RWA", "RW", "RWA", /* 646 */"Rwanda" },
1576 { 682, "KSA", "SA", "SAU", /* 682 */"Saudi Arabia" },
1577 { 90, "SOL", "SB", "SLB", /* 090 */"Solomon Islands" },
1578 { 690, "SY", "SC", "SYC", /* 690 */"Seychelles" },
1579 { 736, "SUD", "SD", "SDN", /* 736 */"Sudan" },
1580 { 752, "S", "SE", "SWE", /* 752 */"Sweden" },
1581 { 702, "SGP", "SG", "SGP", /* 702 */"Singapore" },
1582 { 654, NULL, "SH", "SHN", /* 654 */"Saint Helena" },
1583 { 705, "SLO", "SI", "SVN", /* 705 */"Slovenia" },
1584 { 744, NULL, "SJ", "SJM", /* 744 */
1585 "Svalbard and Jan Mayen" },
1586 { 703, "SK", "SK", "SVK", /* 703 */"Slovakia" },
1587 { 694, "WAL", "SL", "SLE", /* 694 */"Sierra Leone" },
1588 { 674, "RSM", "SM", "SMR", /* 674 */"San Marino" },
1589 { 686, "SN", "SN", "SEN", /* 686 */"Senegal" },
1590 { 706, "SO", "SO", "SOM", /* 706 */"Somalia" },
1591 { 740, "SME", "SR", "SUR", /* 740 */"Suriname" },
1592 { 678, "STP", "ST", "STP", /* 678 */
1593 "Sao Tome and Principe" },
1594 { 222, "ES", "SV", "SLV", /* 222 */"El Salvador" },
1595 { 760, "SYR", "SY", "SYR", /* 760 */
1596 "Syrian Arab Republic" },
1597 { 748, "SD", "SZ", "SWZ", /* 748 */"Swaziland" },
1598 { 796, NULL, "TC", "TCA", /* 796 */
1599 "Turks and Caicos Islands" },
1600 { 148, "TD", "TD", "TCD", /* 148 */"Chad" },
1601 { 260, "ARK", "TF", "ATF", /* 260 */
1602 "French Southern Territories" },
1603 { 768, "RT", "TG", "TGO", /* 768 */"Togo" },
1604 { 764, "T", "TH", "THA", /* 764 */"Thailand" },
1605 { 762, "TJ", "TJ", "TJK", /* 762 */"Tajikistan" },
1606 { 772, NULL, "TK", "TKL", /* 772 */"Tokelau" },
1607 { 626, "TL", "TL", "TLS", /* 626 */"Timor-Leste" },
1608 { 795, "TM", "TM", "TKM", /* 795 */"Turkmenistan" },
1609 { 788, "TN", "TN", "TUN", /* 788 */"Tunisia" },
1610 { 776, "TON", "TO", "TON", /* 776 */"Tonga" },
1611 { 792, "TR", "TR", "TUR", /* 792 */"Turkey" },
1612 { 780, "TT", "TT", "TTO", /* 780 */
1613 "Trinidad and Tobago" },
1614 { 798, "TUV", "TV", "TUV", /* 798 */"Tuvalu" },
1615 { 158, NULL, "TW", "TWN", /* 158 */
1616 "Taiwan, Province of China" },
1617 { 834, "EAT", "TZ", "TZA", /* 834 */
1618 "Tanzania, United Republic of" },
1619 { 804, "UA", "UA", "UKR", /* 804 */"Ukraine" },
1620 { 800, "EAU", "UG", "UGA", /* 800 */"Uganda" },
1621 { 581, NULL, "UM", "UMI", /* 581 */
1622 "United States Minor Outlying Islands" },
1623 { 840, "USA", "US", "USA", /* 840 */"United States" },
1624 { 858, "ROU", "UY", "URY", /* 858 */"Uruguay" },
1625 { 860, "UZ", "UZ", "UZB", /* 860 */"Uzbekistan" },
1626 { 336, "SCV", "VA", "VAT", /* 336 */
1627 "Holy See (Vatican City State)" },
1628 { 670, "WV", "VC", "VCT", /* 670 */"Saint Vincent and the Grenadines" },
1629 { 862, "YV", "VE", "VEN", /* 862 */"Venezuela" },
1630 { 92, NULL, "VG", "VGB", /* 092 */ "Virgin Islands, British" },
1631 { 850, NULL, "VI", "VIR", /* 850 */ "Virgin Islands, U.S." },
1632 { 704, "VN", "VN", "VNM", /* 704 */"Viet Nam" },
1633 { 548, "VAN", "VU", "VUT", /* 548 */"Vanuatu" },
1634 { 876, NULL, "WF", "WLF", /* 876 */"Wallis and Futuna" },
1635 { 882, "WS", "WS", "WSM", /* 882 */"Samoa" },
1636 { 887, "YAR", "YE", "YEM", /* 887 */"Yemen" },
1637 { 175, NULL, "YT", "MYT", /* 175 */"Mayotte" },
1638 { 710, "ZA", "ZA", "ZAF", /* 710 */"South Africa" },
1639 { 894, "Z", "ZM", "ZMB", /* 894 */"Zambia" },
1640 { 716, "ZW", "ZW", "ZWE", /* 716 */"Zimbabwe" },
1641 { 999, "*", "*", "*", /* 999 */"Unknown" }, };
1642
1643 static int ascii_cmp_local(char *name, char *match, int partial)
1644 {
1645 char *s1 = linguistics_casefold(name);
1646 char *s2 = linguistics_casefold(match);
1647 int ret = linguistics_compare(s1, s2, partial);
1648 g_free(s1);
1649 g_free(s2);
1650 return ret;
1651 }
1652
1653 struct navit *global_navit;
1654
1655 void search_full_world(char *addr, int partial, int search_order, struct jni_object *jni, struct coord_geo *search_center, int search_radius)
1656 {
1657 struct item *item;
1658 struct map_rect *mr = NULL;
1659 struct mapset *ms;
1660 struct mapset_handle *msh;
1661 struct map* map = NULL;
1662 struct attr map_name_attr;
1663 struct attr attr;
1664
1665 char *str = search_fix_spaces(addr);
1666 GList *phrases = search_split_phrases(str);
1667 GList *phrases_first;
1668 phrases_first = phrases;
1669
1670 ms = global_navit->mapsets->data;
1671 msh = mapset_open(ms);
1672
1673 struct pcoord center99;
1674 int search_radius_this = 0;
1675 dbg(0, "in lat=%f,lng=%f\n", search_center->lat, search_center->lng);
1676 if ((search_center->lat == 0) && (search_center->lng == 0))
1677 {
1678 center99.x = 0;
1679 center99.y = 0;
1680 search_radius_this = 21000000;
1681 }
1682 else
1683 {
1684 struct coord c99;
1685 transform_from_geo(projection_mg, search_center, &c99);
1686 center99.x = c99.x;
1687 center99.y = c99.y;
1688 search_radius_this = search_radius;
1689 }
1690 dbg(0, "out x=%d,y=%d,r=%d\n", center99.x, center99.y, search_radius_this);
1691
1692 struct map_selection *sel = map_selection_rect_new(&center99, search_radius_this, search_order);
1693 sel->range.min = type_town_label;
1694 sel->range.max = type_area;
1695
1696 while (msh && (map = mapset_next(msh, 0)))
1697 {
1698 if (map_get_attr(map, attr_name, &map_name_attr, NULL))
1699 {
1700 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
1701 {
1702 if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/navitmap", map_name_attr.u.str, 38) == 0)
1703 {
1704 // its an sdcard map
1705 //dbg(0,"map name=%s",map_name_attr.u.str);
1706 // mr=map_rect_new(map, NULL);
1707 mr = map_rect_new(map, sel);
1708 if (mr)
1709 {
1710 char *streetname_last = NULL;
1711
1712 while ((item = map_rect_get_item(mr)))
1713 {
1714
1715 if (offline_search_break_searching == 1)
1716 {
1717 break;
1718 }
1719
1720 if ((item_is_town(*item)) || (item_is_district(*item)))
1721 {
1722 struct search_list_town *p = NULL;
1723
1724 if (item_attr_get(item, attr_town_name, &attr))
1725 {
1726 p = search_list_town_new(item);
1727 char *buffer = NULL;
1728 // coords of result
1729 struct coord_geo g;
1730 struct coord c;
1731 c.x = p->common.c->x;
1732 c.y = p->common.c->y;
1733 int calc_geo = 0;
1734
1735 // dbg(0,"town name=%s\n", attr.u.str);
1736
1737 phrases = phrases_first;
1738 while (phrases)
1739 {
1740
1741 if (offline_search_break_searching == 1)
1742 {
1743 break;
1744 }
1745
1746 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1747 {
1748 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1749 if (calc_geo == 0)
1750 {
1751 transform_to_geo(p->common.c->pro, &c, &g);
1752 // TWN -> town
1753 calc_geo = 1;
1754 }
1755 if (p->common.postal == NULL)
1756 {
1757 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);
1758 }
1759 else
1760 {
1761 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);
1762 }
1763 #ifdef HAVE_API_ANDROID
1764 // return results to android as they come in ...
1765 android_return_search_result(jni,buffer);
1766 #endif
1767 }
1768 phrases = g_list_next(phrases);
1769
1770 }
1771 if (buffer)
1772 {
1773 g_free(buffer);
1774 }
1775 search_list_town_destroy(p);
1776 }
1777
1778 if (item_attr_get(item, attr_town_name_match, &attr))
1779 {
1780 p = search_list_town_new(item);
1781 char *buffer = NULL;
1782 // coords of result
1783 struct coord_geo g;
1784 struct coord c;
1785 c.x = p->common.c->x;
1786 c.y = p->common.c->y;
1787 int calc_geo = 0;
1788
1789 // dbg(0,"town name=%s\n", attr.u.str);
1790
1791 phrases = phrases_first;
1792 while (phrases)
1793 {
1794 if (offline_search_break_searching == 1)
1795 {
1796 break;
1797 }
1798
1799 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1800 {
1801 // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1802 if (calc_geo == 0)
1803 {
1804 transform_to_geo(p->common.c->pro, &c, &g);
1805 // TWN -> town
1806 calc_geo = 1;
1807 }
1808 if (p->common.postal == NULL)
1809 {
1810 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);
1811 }
1812 else
1813 {
1814 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);
1815 }
1816 #ifdef HAVE_API_ANDROID
1817 // return results to android as they come in ...
1818 android_return_search_result(jni,buffer);
1819 #endif
1820 }
1821 phrases = g_list_next(phrases);
1822
1823 }
1824 if (buffer)
1825 {
1826 g_free(buffer);
1827 }
1828 search_list_town_destroy(p);
1829 }
1830 }
1831 else if (item_is_street(*item))
1832 {
1833
1834 struct search_list_street *p = NULL;
1835
1836 if (item_attr_get(item, attr_label, &attr))
1837 {
1838 // dbg(0,"street1=%s\n",map_convert_string(item->map, attr.u.str));
1839 if ((streetname_last == NULL) || (strcmp(streetname_last, attr.u.str) != 0))
1840 {
1841 // dbg(0,"street2=%s\n",map_convert_string(item->map, attr.u.str));
1842 streetname_last = g_strdup_printf("%s", attr.u.str);
1843
1844 p = search_list_street_new(item);
1845 char *buffer = NULL;
1846 // coords of result
1847 struct coord_geo g;
1848 struct coord c;
1849 c.x = p->common.c->x;
1850 c.y = p->common.c->y;
1851 int calc_geo = 0;
1852
1853 phrases = phrases_first;
1854 while (phrases)
1855 {
1856 if (offline_search_break_searching == 1)
1857 {
1858 break;
1859 }
1860
1861 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1862 {
1863 if (calc_geo == 0)
1864 {
1865 transform_to_geo(p->common.c->pro, &c, &g);
1866 calc_geo = 1;
1867 }
1868 if (p->common.postal == NULL)
1869 {
1870 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);
1871 }
1872 else
1873 {
1874 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);
1875 }
1876 //dbg(0,"street3=%s\n",buffer);
1877 #ifdef HAVE_API_ANDROID
1878 // return results to android as they come in ...
1879 android_return_search_result(jni,buffer);
1880 #endif
1881 }
1882 phrases = g_list_next(phrases);
1883 }
1884 if (buffer)
1885 {
1886 g_free(buffer);
1887 }
1888 search_list_street_destroy(p);
1889 }
1890 }
1891
1892 if (item_attr_get(item, attr_street_name_match, &attr))
1893 {
1894 //dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
1895
1896 p = search_list_street_new(item);
1897 char *buffer = NULL;
1898 // coords of result
1899 struct coord_geo g;
1900 struct coord c;
1901 c.x = p->common.c->x;
1902 c.y = p->common.c->y;
1903 int calc_geo = 0;
1904
1905 phrases = phrases_first;
1906 while (phrases)
1907 {
1908 if (offline_search_break_searching == 1)
1909 {
1910 break;
1911 }
1912
1913 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1914 {
1915 if (calc_geo == 0)
1916 {
1917 transform_to_geo(p->common.c->pro, &c, &g);
1918 calc_geo = 1;
1919 }
1920 if (p->common.postal == NULL)
1921 {
1922 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);
1923 }
1924 else
1925 {
1926 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);
1927 }
1928 #ifdef HAVE_API_ANDROID
1929 // return results to android as they come in ...
1930 android_return_search_result(jni,buffer);
1931 #endif
1932 }
1933 phrases = g_list_next(phrases);
1934 }
1935 if (buffer)
1936 {
1937 g_free(buffer);
1938 }
1939 search_list_street_destroy(p);
1940
1941 }
1942
1943 if (item_attr_get(item, attr_street_name_systematic, &attr))
1944 {
1945 //dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
1946
1947 p = search_list_street_new(item);
1948 char *buffer = NULL;
1949 // coords of result
1950 struct coord_geo g;
1951 struct coord c;
1952 c.x = p->common.c->x;
1953 c.y = p->common.c->y;
1954 int calc_geo = 0;
1955
1956 phrases = phrases_first;
1957 while (phrases)
1958 {
1959 if (offline_search_break_searching == 1)
1960 {
1961 break;
1962 }
1963
1964 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1965 {
1966 if (calc_geo == 0)
1967 {
1968 transform_to_geo(p->common.c->pro, &c, &g);
1969 calc_geo = 1;
1970 }
1971 if (p->common.postal == NULL)
1972 {
1973 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);
1974 }
1975 else
1976 {
1977 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);
1978 }
1979 #ifdef HAVE_API_ANDROID
1980 // return results to android as they come in ...
1981 android_return_search_result(jni,buffer);
1982 #endif
1983 }
1984 phrases = g_list_next(phrases);
1985 }
1986 if (buffer)
1987 {
1988 g_free(buffer);
1989 }
1990 search_list_street_destroy(p);
1991
1992 }
1993 }
1994 }
1995 g_free(streetname_last);
1996 map_rect_destroy(mr);
1997 }
1998 }
1999 }
2000 }
2001 }
2002
2003 map_selection_destroy(sel);
2004
2005 if (phrases)
2006 {
2007 g_list_free(phrases);
2008 }
2009 g_free(str);
2010
2011 mapset_close(msh);
2012 }
2013
2014 GList *
2015 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)
2016 {
2017 char *str = search_fix_spaces(addr);
2018 GList *tmp, *phrases = search_split_phrases(str);
2019 GList *phrases_first;
2020 GList *ret = NULL;
2021 struct search_list *sl;
2022 struct attr attr;
2023 attr.type = attr_country_all;
2024 tmp = phrases;
2025 phrases_first = phrases;
2026 sl = search_list_new(ms);
2027
2028 dbg(0, "-- START --\n");
2029
2030 // normal search stuff -------- START ----------
2031 if (search_country_flags == 1)
2032 {
2033 dbg(0, "-- country default start --\n");
2034 //while (phrases)
2035 //{
2036 // dbg(0,"s=%s\n",phrases->data);
2037 // set default country
2038 search_list_search(sl, country_default(), 0);
2039 ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2040 // phrases=g_list_next(phrases);
2041 //}
2042 dbg(0, "-- country default end --\n");
2043 }
2044 else if (search_country_flags == 2)
2045 {
2046 dbg(0, "-- country sel:%s start --\n", search_country_string);
2047 // set a country
2048 struct attr country;
2049 country.type = attr_country_iso2;
2050 country.u.str = search_country_string;
2051 //while (phrases)
2052 //{
2053 // dbg(0,"s=%s\n",phrases->data);
2054 search_list_search(sl, &country, 0);
2055 // set a country
2056 ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2057 //phrases=g_list_next(phrases);
2058 //}
2059 dbg(0, "-- country sel:%s end --\n", search_country_string);
2060 }
2061 else // flags==3
2062 {
2063 dbg(0, "-- country all start --\n");
2064 // search all countries!! could take a really long time!!
2065 struct attr country;
2066 int j2 = sizeof(all_country_list) / sizeof(all_country_list[0]);
2067 int j1;
2068 for (j1 = 0; j1 < j2; j1++)
2069 {
2070 if (all_country_list[j1].iso2 != NULL)
2071 {
2072 phrases = phrases_first;
2073 //while (phrases)
2074 //{
2075 // dbg(0,"s country=%s\n",all_country_list[j1].iso2);
2076 // dbg(0,"s=%s\n",phrases->data);
2077 country.type = attr_country_iso2;
2078 country.u.str = all_country_list[j1].iso2;
2079 search_list_search(sl, &country, 0);
2080 ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2081 //phrases=g_list_next(phrases);
2082 //}
2083
2084 if (offline_search_break_searching == 1)
2085 {
2086 break;
2087 }
2088 }
2089 }
2090 dbg(0, "-- country all end --\n");
2091 }
2092 // normal search stuff -------- END ----------
2093
2094 if (phrases_first)
2095 {
2096 g_list_free(phrases_first);
2097 }
2098
2099 dbg(0, "-- END --\n");
2100
2101 g_free(str);
2102 return ret;
2103 }
2104

   
Visit the ZANavi Wiki