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

Contents of /navit/navit/search.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Mon Feb 4 17:41:59 2013 UTC (7 years, 7 months ago) by zoff99
File MIME type: text/plain
File size: 90800 byte(s)
new map version, lots of fixes and experimental new features
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3     * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     #include <stdlib.h>
40     #include <glib.h>
41     #include <string.h>
42     #include <math.h>
43     #include "debug.h"
44     #include "projection.h"
45     #include "item.h"
46     #include "map.h"
47     #include "mapset.h"
48     #include "coord.h"
49     #include "transform.h"
50     #include "search.h"
51     #include "country.h"
52     #include "navit.h"
53    
54     #if HAVE_API_ANDROID
55     #include "android.h"
56     #endif
57     #include "layout.h"
58     #include "map.h"
59     #include "linguistics.h"
60    
61 zoff99 27 struct search_list_level
62     {
63 zoff99 2 struct mapset *ms;
64     struct search_list_common *parent;
65     struct attr *attr;
66     int partial;
67     int selected;
68     struct mapset_search *search;
69     GHashTable *hash;
70 zoff99 27 GList *list, *curr, *last;
71 zoff99 2 };
72    
73 zoff99 27 struct interpolation
74     {
75 zoff99 2 int side, mode, rev;
76     char *first, *last, *curr;
77     };
78    
79 zoff99 27 struct search_list
80     {
81 zoff99 2 struct mapset *ms;
82     struct item *item;
83     int level;
84     struct search_list_level levels[4];
85     struct search_list_result result;
86     struct search_list_result last_result;
87     int last_result_valid;
88     char *postal;
89     struct interpolation inter;
90     };
91    
92 zoff99 31 // func definition
93     static int ascii_cmp_local_faster(char *name, char *match, int partial);
94     // func definition
95    
96 zoff99 27 static guint search_item_hash_hash(gconstpointer key)
97 zoff99 2 {
98 zoff99 27 const struct item *itm = key;
99     gconstpointer hashkey = (gconstpointer) GINT_TO_POINTER(itm->id_hi ^ itm->id_lo);
100 zoff99 2 return g_direct_hash(hashkey);
101     }
102    
103 zoff99 27 static gboolean search_item_hash_equal(gconstpointer a, gconstpointer b)
104 zoff99 2 {
105 zoff99 27 const struct item *itm_a = a;
106     const struct item *itm_b = b;
107 zoff99 2 if (item_is_equal_id(*itm_a, *itm_b))
108     return TRUE;
109     return FALSE;
110     }
111    
112     struct search_list *
113     search_list_new(struct mapset *ms)
114     {
115     struct search_list *ret;
116    
117     ret=g_new0(struct search_list, 1);
118 zoff99 27 ret->ms = ms;
119    
120 zoff99 2 return ret;
121     }
122    
123     static void search_list_search_free(struct search_list *sl, int level);
124    
125 zoff99 27 static int search_list_level(enum attr_type attr_type)
126 zoff99 2 {
127 zoff99 27 switch (attr_type)
128     {
129     case attr_country_all:
130     case attr_country_id:
131     case attr_country_iso2:
132     case attr_country_iso3:
133     case attr_country_car:
134     case attr_country_name:
135     return 0;
136     case attr_town_postal:
137     return 1;
138     case attr_town_name:
139     case attr_district_name:
140     case attr_town_or_district_name:
141     return 1;
142     case attr_street_name:
143     return 2;
144     case attr_house_number:
145     return 3;
146     case attr_postal:
147     return -1;
148     default:
149 zoff99 30 // // dbg(0, "unknown search '%s'\n", attr_to_name(attr_type));
150 zoff99 27 return -1;
151 zoff99 2 }
152     }
153    
154 zoff99 27 static void interpolation_clear(struct interpolation *inter)
155 zoff99 2 {
156 zoff99 27 inter->mode = inter->side = 0;
157 zoff99 2 g_free(inter->first);
158     g_free(inter->last);
159     g_free(inter->curr);
160 zoff99 27 inter->first = inter->last = inter->curr = NULL;
161 zoff99 2 }
162    
163 zoff99 27 void search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
164 zoff99 2 {
165     struct search_list_level *le;
166 zoff99 27 int level = search_list_level(search_attr->type);
167     this_->item = NULL;
168 zoff99 2 interpolation_clear(&this_->inter);
169 zoff99 30 //// // dbg(0,"## enter\n");
170     //// dbg(0,"## level=%d\n", level);
171 zoff99 15 if (level != -1)
172     {
173 zoff99 27 this_->result.id = 0;
174     this_->level = level;
175     le = &this_->levels[level];
176 zoff99 2 search_list_search_free(this_, level);
177 zoff99 27 le->attr = attr_dup(search_attr);
178     le->partial = partial;
179 zoff99 15 if (level > 0)
180     {
181 zoff99 27 le = &this_->levels[level - 1];
182     le->curr = le->list;
183 zoff99 2 }
184 zoff99 30 //// dbg(0,"## le=%p partial=%d\n", le, partial);
185 zoff99 15 }
186     else if (search_attr->type == attr_postal)
187     {
188 zoff99 2 g_free(this_->postal);
189 zoff99 27 this_->postal = g_strdup(search_attr->u.str);
190 zoff99 2 }
191 zoff99 30 //// dbg(0,"## return\n");
192 zoff99 2 }
193    
194     struct search_list_common *
195     search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode)
196     {
197 zoff99 27 int level = search_list_level(attr_type);
198     int num = 0;
199 zoff99 2 struct search_list_level *le;
200     struct search_list_common *slc;
201     GList *curr;
202 zoff99 27 le = &this_->levels[level];
203     curr = le->list;
204 zoff99 2 if (mode > 0 || !id)
205 zoff99 27 le->selected = mode;
206 zoff99 30 //// dbg(0,"enter level=%d %d %d %p\n", level, id, mode, curr);
207 zoff99 27 while (curr)
208     {
209 zoff99 2 num++;
210 zoff99 27 if (!id || num == id)
211     {
212     slc = curr->data;
213     slc->selected = mode;
214     if (id)
215     {
216     le->last = curr;
217 zoff99 30 //// dbg(0,"found\n");
218 zoff99 2 return slc;
219     }
220     }
221 zoff99 27 curr = g_list_next(curr);
222 zoff99 2 }
223 zoff99 30 //// dbg(0,"not found\n");
224 zoff99 2 return NULL;
225     }
226    
227 zoff99 27 static void search_list_common_new(struct item *item, struct search_list_common *common)
228 zoff99 2 {
229     struct attr attr;
230     if (item_attr_get(item, attr_town_name, &attr))
231 zoff99 27 common->town_name = map_convert_string(item->map, attr.u.str);
232 zoff99 2 else
233 zoff99 27 common->town_name = NULL;
234 zoff99 2 if (item_attr_get(item, attr_county_name, &attr))
235 zoff99 27 common->county_name = map_convert_string(item->map, attr.u.str);
236 zoff99 2 else
237 zoff99 27 common->county_name = NULL;
238 zoff99 2 if (item_attr_get(item, attr_district_name, &attr))
239 zoff99 27 common->district_name = map_convert_string(item->map, attr.u.str);
240 zoff99 2 else
241 zoff99 27 common->district_name = NULL;
242 zoff99 2 if (item_attr_get(item, attr_postal, &attr))
243 zoff99 27 common->postal = map_convert_string(item->map, attr.u.str);
244 zoff99 2 else if (item_attr_get(item, attr_town_postal, &attr))
245 zoff99 27 common->postal = map_convert_string(item->map, attr.u.str);
246 zoff99 2 else
247 zoff99 27 common->postal = NULL;
248     if (item_attr_get(item, attr_postal_mask, &attr))
249     common->postal_mask = map_convert_string(item->map, attr.u.str);
250     else
251     common->postal_mask = NULL;
252 zoff99 2 }
253    
254 zoff99 27 static void search_list_common_destroy(struct search_list_common *common)
255 zoff99 2 {
256     map_convert_free(common->town_name);
257     map_convert_free(common->district_name);
258     map_convert_free(common->county_name);
259     map_convert_free(common->postal);
260     map_convert_free(common->postal_mask);
261     }
262    
263     static struct search_list_country *
264     search_list_country_new(struct item *item)
265     {
266     struct search_list_country *ret=g_new0(struct search_list_country, 1);
267     struct attr attr;
268    
269 zoff99 27 ret->common.item = ret->common.unique = *item;
270 zoff99 2 if (item_attr_get(item, attr_country_car, &attr))
271 zoff99 27 ret->car = g_strdup(attr.u.str);
272     if (item_attr_get(item, attr_country_iso2, &attr))
273     {
274 zoff99 2 #if HAVE_API_ANDROID
275     ret->iso2=g_malloc(strlen(attr.u.str)+1);
276     strtolower(ret->iso2, attr.u.str);
277     #else
278 zoff99 27 ret->iso2 = g_strdup(attr.u.str);
279 zoff99 2 #endif
280 zoff99 27 ret->flag = g_strdup_printf("country_%s", ret->iso2);
281 zoff99 2 }
282     if (item_attr_get(item, attr_country_iso3, &attr))
283 zoff99 27 ret->iso3 = g_strdup(attr.u.str);
284 zoff99 2 if (item_attr_get(item, attr_country_name, &attr))
285 zoff99 27 ret->name = g_strdup(attr.u.str);
286 zoff99 2 return ret;
287     }
288    
289 zoff99 27 static void search_list_country_destroy(struct search_list_country *this_)
290 zoff99 2 {
291     g_free(this_->car);
292     g_free(this_->iso2);
293     g_free(this_->iso3);
294     g_free(this_->flag);
295     g_free(this_->name);
296     g_free(this_);
297     }
298    
299     static struct search_list_town *
300     search_list_town_new(struct item *item)
301     {
302     struct search_list_town *ret=g_new0(struct search_list_town, 1);
303     struct attr attr;
304     struct coord c;
305 zoff99 27
306     ret->itemt = *item;
307     ret->common.item = ret->common.unique = *item;
308    
309     if (item_attr_get(item, attr_town_streets_item, &attr))
310     {
311 zoff99 30 //// dbg(1, "town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
312 zoff99 27 ret->common.unique = *attr.u.item;
313 zoff99 2 }
314 zoff99 27
315 zoff99 2 search_list_common_new(item, &ret->common);
316 zoff99 27
317 zoff99 2 if (item_attr_get(item, attr_county_name, &attr))
318 zoff99 27 {
319     ret->county = map_convert_string(item->map, attr.u.str);
320     }
321 zoff99 2 else
322 zoff99 27 {
323     ret->county = NULL;
324     }
325    
326     if (item_coord_get(item, &c, 1))
327     {
328 zoff99 2 ret->common.c=g_new(struct pcoord, 1);
329 zoff99 27 ret->common.c->x = c.x;
330     ret->common.c->y = c.y;
331 zoff99 2 ret->common.c->pro = map_projection(item->map);
332     }
333 zoff99 27 else
334     {
335     // some error with lat/lng !!
336     // but still return something, or app will crash
337     ret->common.c=g_new(struct pcoord, 1);
338     ret->common.c->x = 0;
339     ret->common.c->y = 0;
340     ret->common.c->pro = map_projection(item->map);
341     }
342 zoff99 2 return ret;
343     }
344    
345 zoff99 27 static void search_list_town_destroy(struct search_list_town *this_)
346 zoff99 2 {
347     map_convert_free(this_->county);
348     search_list_common_destroy(&this_->common);
349     if (this_->common.c)
350     g_free(this_->common.c);
351     g_free(this_);
352     }
353    
354     static struct search_list_street *
355     search_list_street_new(struct item *item)
356     {
357     struct search_list_street *ret=g_new0(struct search_list_street, 1);
358     struct attr attr;
359     struct coord c;
360 zoff99 27
361     ret->common.item = ret->common.unique = *item;
362 zoff99 2 if (item_attr_get(item, attr_street_name, &attr))
363 zoff99 27 {
364     ret->name = map_convert_string(item->map, attr.u.str);
365     }
366 zoff99 2 else
367 zoff99 27 {
368     ret->name = NULL;
369     }
370 zoff99 2 search_list_common_new(item, &ret->common);
371 zoff99 27 if (item_coord_get(item, &c, 1))
372     {
373 zoff99 2 ret->common.c=g_new(struct pcoord, 1);
374 zoff99 27 ret->common.c->x = c.x;
375     ret->common.c->y = c.y;
376 zoff99 2 ret->common.c->pro = map_projection(item->map);
377     }
378 zoff99 27 else
379     {
380     // some error with lat/lng !!
381     // but still return something, or app will crash
382     ret->common.c=g_new(struct pcoord, 1);
383     ret->common.c->x = 0;
384     ret->common.c->y = 0;
385     ret->common.c->pro = map_projection(item->map);
386     }
387 zoff99 2 return ret;
388     }
389    
390 zoff99 27 static void search_list_street_destroy(struct search_list_street *this_)
391 zoff99 2 {
392     map_convert_free(this_->name);
393     search_list_common_destroy(&this_->common);
394     if (this_->common.c)
395     {
396     g_free(this_->common.c);
397     }
398     g_free(this_);
399     }
400    
401     static char *
402     search_interpolate(struct interpolation *inter)
403     {
404 zoff99 30 // dbg(1, "interpolate %s-%s %s\n", inter->first, inter->last, inter->curr);
405 zoff99 2 if (!inter->first || !inter->last)
406     return NULL;
407 zoff99 27 if (!inter->curr)
408     inter->curr = g_strdup(inter->first);
409     else
410     {
411     if (strcmp(inter->curr, inter->last))
412     {
413     int next = atoi(inter->curr) + (inter->mode ? 2 : 1);
414 zoff99 2 g_free(inter->curr);
415     if (next == atoi(inter->last))
416 zoff99 27 inter->curr = g_strdup(inter->last);
417 zoff99 2 else
418 zoff99 27 inter->curr = g_strdup_printf("%d", next);
419     }
420     else
421     {
422 zoff99 2 g_free(inter->curr);
423 zoff99 27 inter->curr = NULL;
424 zoff99 2 }
425     }
426 zoff99 30 // dbg(1, "interpolate result %s\n", inter->curr);
427 zoff99 2 return inter->curr;
428     }
429    
430 zoff99 27 static void search_interpolation_split(char *str, struct interpolation *inter)
431 zoff99 2 {
432 zoff99 27 char *pos = strchr(str, '-');
433     char *first, *last;
434 zoff99 2 int len;
435 zoff99 27 if (!pos)
436     {
437     inter->first = g_strdup(str);
438     inter->last = g_strdup(str);
439     inter->rev = 0;
440 zoff99 2 return;
441     }
442 zoff99 27 len = pos - str;
443     first = g_malloc(len + 1);
444 zoff99 2 strncpy(first, str, len);
445 zoff99 27 first[len] = '\0';
446     last = g_strdup(pos + 1);
447 zoff99 30 // dbg(1, "%s = %s - %s\n", str, first, last);
448 zoff99 27 if (atoi(first) > atoi(last))
449     {
450     inter->first = last;
451     inter->last = first;
452     inter->rev = 1;
453 zoff99 2 }
454 zoff99 27 else
455     {
456     inter->first = first;
457     inter->last = last;
458     inter->rev = 0;
459     }
460 zoff99 2 }
461    
462 zoff99 27 static int search_setup_interpolation(struct item *item, enum attr_type i0, enum attr_type i1, enum attr_type i2, struct interpolation *inter)
463 zoff99 2 {
464     struct attr attr;
465     g_free(inter->first);
466     g_free(inter->last);
467     g_free(inter->curr);
468 zoff99 27 inter->first = inter->last = inter->curr = NULL;
469 zoff99 30 // dbg(1, "setup %s\n", attr_to_name(i0));
470 zoff99 27 if (item_attr_get(item, i0, &attr))
471     {
472 zoff99 2 search_interpolation_split(attr.u.str, inter);
473 zoff99 27 inter->mode = 0;
474     }
475     else if (item_attr_get(item, i1, &attr))
476     {
477 zoff99 2 search_interpolation_split(attr.u.str, inter);
478 zoff99 27 inter->mode = 1;
479     }
480     else if (item_attr_get(item, i2, &attr))
481     {
482 zoff99 2 search_interpolation_split(attr.u.str, inter);
483 zoff99 27 inter->mode = 2;
484     }
485     else
486 zoff99 2 return 0;
487     return 1;
488     }
489    
490 zoff99 27 static int search_match(char *str, char *search, int partial)
491 zoff99 2 {
492     if (!partial)
493     return (!g_strcasecmp(str, search));
494     else
495     return (!g_strncasecmp(str, search, strlen(search)));
496     }
497    
498     static struct pcoord *
499     search_house_number_coordinate(struct item *item, struct interpolation *inter)
500     {
501     struct pcoord *ret=g_new(struct pcoord, 1);
502     ret->pro = map_projection(item->map);
503 zoff99 29
504 zoff99 30 // // dbg(0,"001t: %s\n", item_to_name(item->type));
505 zoff99 29
506 zoff99 27 if (item_is_point(*item))
507     {
508 zoff99 2 struct coord c;
509 zoff99 27 if (item_coord_get(item, &c, 1))
510     {
511     ret->x = c.x;
512     ret->y = c.y;
513     }
514     else
515     {
516 zoff99 2 g_free(ret);
517 zoff99 27 ret = NULL;
518 zoff99 2 }
519 zoff99 27 }
520     else
521     {
522     int count, max = 1024;
523     int hn_pos, hn_length;
524     struct coord *c = g_alloca(sizeof(struct coord) * max);
525 zoff99 2 item_coord_rewind(item);
526 zoff99 27 count = item_coord_get(item, c, max);
527     hn_length = atoi(inter->last) - atoi(inter->first);
528 zoff99 2 if (inter->rev)
529 zoff99 27 hn_pos = atoi(inter->last) - atoi(inter->curr);
530 zoff99 2 else
531 zoff99 27 hn_pos = atoi(inter->curr) - atoi(inter->first);
532 zoff99 29
533 zoff99 27 if (count)
534     {
535     int i, distance_sum = 0, hn_distance;
536     int *distances = g_alloca(sizeof(int) * (count - 1));
537 zoff99 30 // 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);
538 zoff99 27 if (!hn_length)
539     {
540     hn_length = 2;
541     hn_pos = 1;
542 zoff99 2 }
543 zoff99 27 if (count == max)
544 zoff99 30 // dbg(0, "coordinate overflow\n");
545 zoff99 31 for (i = 0; i < count - 1; i++)
546     {
547     distances[i] = navit_sqrt(transform_distance_sq(&c[i], &c[i + 1]));
548     distance_sum += distances[i];
549     // dbg(1, "distance[%d]=%d\n", i, distances[i]);
550     }
551 zoff99 30 // dbg(1, "sum=%d\n", distance_sum);
552 zoff99 27 hn_distance = distance_sum * hn_pos / hn_length;
553 zoff99 30 // dbg(1, "hn_distance=%d\n", hn_distance);
554 zoff99 27 i = 0;
555     while (i < count - 1 && hn_distance > distances[i])
556     hn_distance -= distances[i++];
557 zoff99 30 // dbg(1, "remaining distance=%d from %d\n", hn_distance, distances[i]);
558 zoff99 27 ret->x = (c[i + 1].x - c[i].x) * hn_distance / distances[i] + c[i].x;
559     ret->y = (c[i + 1].y - c[i].y) * hn_distance / distances[i] + c[i].y;
560 zoff99 2 }
561     }
562     return ret;
563     }
564    
565     static struct search_list_house_number *
566     search_list_house_number_new(struct item *item, struct interpolation *inter, char *inter_match, int inter_partial)
567     {
568     struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1);
569     struct attr attr;
570     char *hn;
571    
572 zoff99 30 //// dbg(0,"@@@@ enter @@@@\n");
573 zoff99 2
574 zoff99 27 ret->common.item = ret->common.unique = *item;
575 zoff99 2 //if (item_attr_get(item, attr_street_name, &attr))
576 zoff99 30 // // dbg(0,"xx1 %s\n",attr.u.str);
577 zoff99 2 if (item_attr_get(item, attr_house_number, &attr))
578 zoff99 29 {
579 zoff99 27 ret->house_number = map_convert_string(item->map, attr.u.str);
580 zoff99 29 }
581 zoff99 27 else
582     {
583 zoff99 2 //if (item_attr_get(item, attr_street_name, &attr))
584 zoff99 30 // // dbg(0,"xx2 %s\n",attr.u.str);
585 zoff99 27 for (;;)
586     {
587 zoff99 30 //// dbg(0,"interpolate 11");
588 zoff99 27 ret->interpolation = 1;
589     switch (inter->side)
590     {
591     case 0:
592 zoff99 30 //// dbg(0,"interpolate 11 0");
593 zoff99 27 inter->side = -1;
594     search_setup_interpolation(item, attr_house_number_left, attr_house_number_left_odd, attr_house_number_left_even, inter);
595     case -1:
596 zoff99 30 //// dbg(0,"interpolate 11 -1");
597 zoff99 27 if ((hn = search_interpolate(inter)))
598     break;
599     inter->side = 1;
600     search_setup_interpolation(item, attr_house_number_right, attr_house_number_right_odd, attr_house_number_right_even, inter);
601     case 1:
602 zoff99 30 //// dbg(0,"interpolate 11 1");
603 zoff99 27 if ((hn = search_interpolate(inter)))
604     break;
605     default:
606 zoff99 30 //// dbg(0,"interpolate 11 default");
607 zoff99 27 g_free(ret);
608     return NULL;
609 zoff99 2 }
610     if (search_match(hn, inter_match, inter_partial))
611     {
612 zoff99 30 //// dbg(0,"interpolate 22");
613     //// dbg(0,"match %s %s-%s\n",hn, inter->first, inter->last);
614 zoff99 27 ret->house_number = map_convert_string(item->map, hn);
615 zoff99 2 break;
616     }
617     }
618     }
619     search_list_common_new(item, &ret->common);
620 zoff99 27 ret->common.c = search_house_number_coordinate(item, ret->interpolation ? inter : NULL);
621 zoff99 2 return ret;
622     }
623    
624 zoff99 27 static void search_list_house_number_destroy(struct search_list_house_number *this_)
625 zoff99 2 {
626     map_convert_free(this_->house_number);
627     search_list_common_destroy(&this_->common);
628     if (this_->common.c)
629     g_free(this_->common.c);
630     g_free(this_);
631     }
632    
633 zoff99 27 static void search_list_result_destroy(int level, void *p)
634 zoff99 2 {
635 zoff99 27 switch (level)
636     {
637     case 0:
638     search_list_country_destroy(p);
639     break;
640     case 1:
641     search_list_town_destroy(p);
642     break;
643     case 2:
644     search_list_street_destroy(p);
645     break;
646     case 3:
647     search_list_house_number_destroy(p);
648     break;
649 zoff99 2 }
650     }
651    
652 zoff99 27 static void search_list_search_free(struct search_list *sl, int level)
653 zoff99 2 {
654 zoff99 30 //// dbg(0,"enter\n");
655 zoff99 2
656 zoff99 27 struct search_list_level *le = &sl->levels[level];
657     GList *next, *curr;
658 zoff99 2 if (le->search)
659     {
660     mapset_search_destroy(le->search);
661 zoff99 27 le->search = NULL;
662 zoff99 2 }
663     #if 0 /* FIXME */
664 zoff99 27 if (le->hash)
665     {
666 zoff99 2 g_hash_table_destroy(le->hash);
667     le->hash=NULL;
668     }
669     #endif
670 zoff99 27 curr = le->list;
671 zoff99 2 while (curr)
672     {
673     search_list_result_destroy(level, curr->data);
674 zoff99 27 next = g_list_next(curr);
675     curr = next;
676 zoff99 2 }
677     attr_free(le->attr);
678     g_list_free(le->list);
679 zoff99 27 le->list = NULL;
680     le->curr = NULL;
681     le->last = NULL;
682 zoff99 2
683 zoff99 30 //// dbg(0,"return\n");
684 zoff99 2 }
685    
686     char *
687     search_postal_merge(char *mask, char *new)
688     {
689     int i;
690 zoff99 27 char *ret = NULL;
691 zoff99 30 // dbg(1, "enter %s %s\n", mask, new);
692 zoff99 2 if (!new)
693     return NULL;
694     if (!mask)
695     return g_strdup(new);
696 zoff99 27 i = 0;
697     while (mask[i] && new[i])
698     {
699 zoff99 2 if (mask[i] != '.' && mask[i] != new[i])
700     break;
701     i++;
702 zoff99 27
703 zoff99 2 }
704 zoff99 27 if (mask[i])
705     {
706     ret = g_strdup(mask);
707     while (mask[i])
708     ret[i++] = '.';
709 zoff99 2 }
710 zoff99 30 // dbg(1, "merged %s with %s as %s\n", mask, new, ret);
711 zoff99 2 return ret;
712     }
713    
714     char *
715     search_postal_merge_replace(char *mask, char *new)
716     {
717 zoff99 27 char *ret = search_postal_merge(mask, new);
718 zoff99 2 if (!ret)
719     return mask;
720     g_free(mask);
721     return ret;
722     }
723    
724 zoff99 27 static int postal_match(char *postal, char *mask)
725 zoff99 2 {
726 zoff99 27 for (;;)
727     {
728 zoff99 2 if ((*postal != *mask) && (*mask != '.'))
729     return 0;
730 zoff99 27 if (!*postal)
731     {
732 zoff99 2 if (!*mask)
733     return 1;
734     else
735     return 0;
736     }
737     postal++;
738     mask++;
739     }
740     }
741    
742 zoff99 27 static int search_add_result(struct search_list_level *le, struct search_list_common *slc)
743 zoff99 2 {
744     struct search_list_common *slo;
745     char *merged;
746 zoff99 15
747 zoff99 30 //// dbg(0,"enter\n");
748 zoff99 15
749     //slo=g_hash_table_lookup(le->hash, &slc->unique);
750     //if (!slo) {
751 zoff99 27 //g_hash_table_insert(le->hash, &slc->unique, slc);
752     if (slc->postal && !slc->postal_mask)
753     {
754     slc->postal_mask = g_strdup(slc->postal);
755     }
756     // ******
757     g_list_free(le->list);
758     le->list = NULL;
759     // ******
760     le->list = g_list_append(le->list, slc);
761     return 1;
762 zoff99 15 //}
763 zoff99 27 merged = search_postal_merge(slo->postal_mask, slc->postal);
764 zoff99 15 if (merged)
765     {
766 zoff99 2 g_free(slo->postal_mask);
767 zoff99 27 slo->postal_mask = merged;
768 zoff99 2 }
769     return 0;
770     }
771    
772     struct search_list_result *
773     search_list_get_result(struct search_list *this_)
774     {
775 zoff99 27 struct search_list_level *le, *leu;
776     int level = this_->level;
777 zoff99 2 struct attr attr2;
778 zoff99 27 int has_street_name = 0;
779 zoff99 2
780 zoff99 30 //// dbg(0,"******* enter *******\n");
781 zoff99 27 le = &this_->levels[level];
782 zoff99 30 //// dbg(0,"le=%p\n", le);
783 zoff99 2 for (;;)
784     {
785 zoff99 30 //// dbg(0,"le->search=%p\n", le->search);
786 zoff99 27 if (!le->search)
787 zoff99 2 {
788 zoff99 30 //// dbg(0,"partial=%d level=%d\n", le->partial, level);
789 zoff99 27 if (!level)
790     le->parent = NULL;
791 zoff99 2 else
792     {
793 zoff99 27 leu = &this_->levels[level - 1];
794 zoff99 30 //// dbg(0,"leu->curr=%p\n", leu->curr);
795 zoff99 2 for (;;)
796     {
797 zoff99 30 //// dbg(0,"*********########");
798 zoff99 2
799     struct search_list_common *slc;
800 zoff99 27 if (!leu->curr)
801 zoff99 2 {
802     return NULL;
803     }
804 zoff99 27 le->parent = leu->curr->data;
805     leu->last = leu->curr;
806     leu->curr = g_list_next(leu->curr);
807     slc = (struct search_list_common *) (le->parent);
808 zoff99 2 if (!slc)
809     break;
810     if (slc->selected == leu->selected)
811     break;
812     }
813     }
814 zoff99 15 #if 0
815     if (le->parent)
816     {
817 zoff99 30 // dbg(0,"mapset_search_new with item(%d,%d)\n", le->parent->item.id_hi, le->parent->item.id_lo);
818 zoff99 15 }
819     else
820     {
821 zoff99 30 // dbg(0,"NO parent!!\n");
822 zoff99 15 }
823 zoff99 30 // dbg(0,"############## attr=%s\n", attr_to_name(le->attr->type));
824 zoff99 15 #endif
825 zoff99 27 le->search = mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial);
826 zoff99 11 // ** DOC ** mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
827 zoff99 27 le->hash = g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
828 zoff99 2 }
829 zoff99 15
830 zoff99 30 //// dbg(0,"le->search=%p\n", le->search);
831 zoff99 15
832 zoff99 2 if (!this_->item)
833     {
834 zoff99 30 //// dbg(0,"sssss 1");
835 zoff99 27 this_->item = mapset_search_get_item(le->search);
836 zoff99 30 //// dbg(0,"sssss 1 %p\n",this_->item);
837 zoff99 2 }
838 zoff99 15
839 zoff99 2 if (this_->item)
840     {
841 zoff99 27 void *p = NULL;
842 zoff99 30 //// dbg(0,"id_hi=%d id_lo=%d\n", this_->item->id_hi, this_->item->id_lo);
843 zoff99 2 if (this_->postal)
844     {
845     struct attr postal;
846 zoff99 27 if (item_attr_get(this_->item, attr_postal_mask, &postal))
847     {
848 zoff99 2 if (!postal_match(this_->postal, postal.u.str))
849     continue;
850 zoff99 27 }
851     else if (item_attr_get(this_->item, attr_postal, &postal))
852     {
853 zoff99 2 if (strcmp(this_->postal, postal.u.str))
854     continue;
855     }
856     }
857 zoff99 27 this_->result.country = NULL;
858     this_->result.town = NULL;
859     this_->result.street = NULL;
860     this_->result.c = NULL;
861 zoff99 30 //// dbg(0,"case x LEVEL start %d\n",level);
862 zoff99 2 switch (level)
863     {
864 zoff99 27 case 0:
865 zoff99 30 //// dbg(0,"case 0 COUNTRY");
866 zoff99 27 p = search_list_country_new(this_->item);
867     this_->result.country = p;
868     this_->result.country->common.parent = NULL;
869     this_->item = NULL;
870     break;
871     case 1:
872 zoff99 30 //// dbg(0,"case 1 TOWN");
873 zoff99 27 p = search_list_town_new(this_->item);
874     this_->result.town = p;
875     this_->result.town->common.parent = this_->levels[0].last->data;
876     this_->result.country = this_->result.town->common.parent;
877     this_->result.c = this_->result.town->common.c;
878     this_->item = NULL;
879     break;
880     case 2:
881 zoff99 30 //// dbg(0,"case 2 STREET");
882 zoff99 27 p = search_list_street_new(this_->item);
883     this_->result.street = p;
884     this_->result.street->common.parent = this_->levels[1].last->data;
885     this_->result.town = this_->result.street->common.parent;
886     this_->result.country = this_->result.town->common.parent;
887     this_->result.c = this_->result.street->common.c;
888     this_->item = NULL;
889     break;
890     case 3:
891 zoff99 30 //// dbg(0,"case 3 HOUSENUMBER");
892 zoff99 27 has_street_name = 0;
893 zoff99 2
894 zoff99 27 // if this housenumber has a streetname tag, set the name now
895     if (item_attr_get(this_->item, attr_street_name, &attr2))
896     {
897 zoff99 30 // // dbg(0,"streetname: %s\n",attr2.u.str);
898 zoff99 27 has_street_name = 1;
899     }
900 zoff99 2
901 zoff99 30 //// dbg(0,"case 3 XXXX 1\n");
902 zoff99 27 p = search_list_house_number_new(this_->item, &this_->inter, le->attr->u.str, le->partial);
903 zoff99 30 //// dbg(0,"case 3 XXXX 2\n");
904 zoff99 27 if (!p)
905     {
906     interpolation_clear(&this_->inter);
907     this_->item = NULL;
908     continue;
909     }
910 zoff99 30 //// dbg(0,"case 3 XXXX 3\n");
911 zoff99 27 this_->result.house_number = p;
912     if (!this_->result.house_number->interpolation)
913     {
914     this_->item = NULL;
915     }
916 zoff99 2
917 zoff99 27 this_->result.house_number->common.parent = this_->levels[2].last->data;
918     this_->result.street = this_->result.house_number->common.parent;
919     this_->result.town = this_->result.street->common.parent;
920     this_->result.country = this_->result.town->common.parent;
921     this_->result.c = this_->result.house_number->common.c;
922 zoff99 2
923 zoff99 30 //// dbg(0,"case 3 XXXX 4\n");
924 zoff99 27 if (has_street_name == 1)
925     {
926     gchar *tmp_name = g_strdup(attr2.u.str);
927     this_->result.street->name = tmp_name;
928 zoff99 30 //// dbg(0,"res streetname=%s\n",this_->result.street->name);
929 zoff99 27 }
930     else
931     {
932     //
933     // this crashes all the time -> so dont use!
934     //static struct search_list_street null_street;
935     //this_->result.street=&null_street;
936     // this crashes all the time -> so dont use!
937     //
938     this_->result.street->name = NULL;
939     }
940 zoff99 30 //// dbg(0,"case 3 XXXX 5\n");
941 zoff99 27 break;
942 zoff99 2 }
943 zoff99 15 // CASE END *********
944    
945 zoff99 30 //// dbg(0,"case end\n");
946 zoff99 15
947 zoff99 2 if (p)
948     {
949     if (search_add_result(le, p))
950     {
951 zoff99 15 //** this_->result.id++;
952 zoff99 27 this_->result.id = 0;
953 zoff99 30 //// dbg(0,"++++ return result\n");
954 zoff99 2 return &this_->result;
955     }
956     else
957     {
958     search_list_result_destroy(level, p);
959 zoff99 15 // return &this_->result;
960 zoff99 2 }
961     }
962 zoff99 15 }
963     else
964     {
965 zoff99 2 mapset_search_destroy(le->search);
966 zoff99 27 le->search = NULL;
967 zoff99 2 g_hash_table_destroy(le->hash);
968 zoff99 27 if (!level)
969 zoff99 15 {
970 zoff99 2 break;
971 zoff99 15 }
972 zoff99 2 }
973     }
974     return NULL;
975     }
976    
977 zoff99 27 void search_list_destroy(struct search_list *this_)
978 zoff99 2 {
979     g_free(this_->postal);
980     g_free(this_);
981     }
982    
983 zoff99 27 void search_init(void)
984 zoff99 2 {
985     }
986    
987     static char *
988     search_fix_spaces(char *str)
989     {
990     int i;
991 zoff99 27 int len = strlen(str);
992     char c, *s, *d, *ret = g_strdup(str);
993 zoff99 2
994 zoff99 27 for (i = 0; i < len; i++)
995     {
996 zoff99 2 if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/')
997 zoff99 27 ret[i] = ' ';
998 zoff99 2 }
999 zoff99 27 s = ret;
1000     d = ret;
1001     len = 0;
1002     do
1003     {
1004     c = *s++;
1005     if (c != ' ' || len != 0)
1006     {
1007     *d++ = c;
1008 zoff99 2 len++;
1009     }
1010     while (c == ' ' && *s == ' ')
1011     s++;
1012 zoff99 27 if (c == ' ' && *s == '\0')
1013     {
1014 zoff99 2 d--;
1015     len--;
1016     }
1017 zoff99 27 }
1018     while (c);
1019 zoff99 2 return ret;
1020     }
1021    
1022     static GList *
1023     search_split_phrases(char *str)
1024     {
1025 zoff99 27 char *tmp, *s, *d;
1026     GList *ret = NULL;
1027     s = str;
1028     do
1029     {
1030     tmp = g_strdup(s);
1031     d = tmp + strlen(s) - 1;
1032     ret = g_list_append(ret, g_strdup(s));
1033     while (d >= tmp)
1034     {
1035     if (*d == ' ')
1036     {
1037 zoff99 2 *d = '\0';
1038 zoff99 27 ret = g_list_append(ret, g_strdup(tmp));
1039 zoff99 2 }
1040     d--;
1041     }
1042     g_free(tmp);
1043 zoff99 27 do
1044     {
1045 zoff99 2 s++;
1046 zoff99 27 if (*s == ' ')
1047     {
1048 zoff99 2 s++;
1049     break;
1050     }
1051 zoff99 27 }
1052     while (*s != '\0');
1053     }
1054     while (*s != '\0');
1055 zoff99 2 return ret;
1056     }
1057    
1058 zoff99 31 static void search_address_housenumber_for_street(char *hn_name_match, char *street_name_match, char *town_string, struct coord *c, int partial, struct jni_object *jni)
1059     {
1060     struct item *item;
1061     struct map_rect *mr = NULL;
1062     struct mapset *ms;
1063     struct mapset_handle *msh;
1064     struct map* map = NULL;
1065     struct attr map_name_attr;
1066     struct attr attr;
1067     struct pcoord center99;
1068     struct map_selection *sel;
1069     int search_radius_this;
1070     int search_order;
1071     struct attr att;
1072     struct attr att2;
1073     char *town_string2;
1074     char *hn_fold = NULL;
1075     char *street_name_fold = NULL;
1076    
1077     ms = global_navit->mapsets->data;
1078     msh = mapset_open(ms);
1079    
1080     search_order = 18;
1081     search_radius_this = 20;
1082    
1083     hn_fold = linguistics_fold_and_prepare_complete(hn_name_match, 0);
1084     street_name_fold = linguistics_fold_and_prepare_complete(street_name_match, 0);
1085    
1086     if (!street_name_fold)
1087     {
1088     return;
1089     }
1090    
1091     if (!hn_fold)
1092     {
1093     return;
1094     }
1095    
1096     if (strlen(street_name_fold) < 1)
1097     {
1098     if (hn_fold)
1099     {
1100     g_free(hn_fold);
1101     }
1102    
1103     if (street_name_fold)
1104     {
1105     g_free(street_name_fold);
1106     }
1107     return;
1108     }
1109    
1110     if (strlen(hn_fold) < 1)
1111     {
1112     if (hn_fold)
1113     {
1114     g_free(hn_fold);
1115     }
1116    
1117     if (street_name_fold)
1118     {
1119     g_free(street_name_fold);
1120     }
1121     return;
1122     }
1123    
1124     if (strlen(town_string) > 100)
1125     {
1126     town_string2 = town_string;
1127     town_string2[101] = '\0';
1128     town_string2 = linguistics_check_utf8_string(town_string2);
1129     }
1130     else
1131     {
1132     town_string2 = town_string;
1133     }
1134    
1135    
1136     center99.x = c->x;
1137     center99.y = c->y;
1138     sel = map_selection_rect_new(&center99, search_radius_this, search_order);
1139     sel->range.min = type_house_number;
1140     sel->range.max = type_house_number;
1141     sel->u.c_rect.lu.x = center99.x - search_radius_this;
1142     sel->u.c_rect.lu.y = center99.y + search_radius_this;
1143     sel->u.c_rect.rl.x = center99.x + search_radius_this;
1144     sel->u.c_rect.rl.y = center99.y - search_radius_this;
1145    
1146     // dbg(0, "hn=%s sn=%s\n", hn_name_match, street_name_match);
1147     // dbg(0, "cx=%d cy=%d\n", c->x, c->y);
1148    
1149     while (msh && (map = mapset_next(msh, 0)))
1150     {
1151     if (offline_search_break_searching == 1)
1152     {
1153     break;
1154     }
1155    
1156     if (map_get_attr(map, attr_name, &map_name_attr, NULL))
1157     {
1158     if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
1159     {
1160     if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/navitmap", map_name_attr.u.str, 38) == 0)
1161     {
1162     // its an sdcard map
1163     mr = map_rect_new(map, sel);
1164     if (mr)
1165     {
1166     while ((item = map_rect_get_item(mr)))
1167     {
1168     if (offline_search_break_searching == 1)
1169     {
1170     break;
1171     }
1172    
1173     #ifdef DEBUG_GLIB_MEM_FUNCTIONS
1174     g_mem_profile();
1175     #endif
1176    
1177     if (item->type == type_house_number)
1178     {
1179     // does it have a housenumber?
1180     if (item_attr_get(item, attr_house_number, &att))
1181     {
1182     // match housenumber to our string
1183     if (!ascii_cmp_local_faster(att.u.str, hn_fold, partial))
1184     {
1185     // if this housenumber has a streetname tag, compare it now
1186     if (item_attr_get(item, attr_street_name, &att2))
1187     {
1188     if (!ascii_cmp_local_faster(att2.u.str, street_name_fold, partial))
1189     {
1190     // coords of result
1191     struct coord c2;
1192     char *buffer;
1193    
1194     if (item_coord_get(item, &c2, 1))
1195     {
1196     // SHN -> street with house number
1197     // return a string like: "SHN:H111L5555:16.766:48.76:full address name is at the end"
1198     // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 max. 15 chars -> this sould be max. about 335 chars long
1199     if (town_string)
1200     {
1201     buffer = g_strdup_printf("SHN:H0L0:%d:%d:%s %s, %.101s", c2.y, c2.x, att2.u.str, att.u.str, town_string);
1202     }
1203     else
1204     {
1205     buffer = g_strdup_printf("SHN:H0L0:%d:%d:%s %s", c2.y, c2.x, att2.u.str, att.u.str);
1206     }
1207    
1208     #ifdef HAVE_API_ANDROID
1209     // return results to android as they come in ...
1210     android_return_search_result(jni,buffer);
1211     #endif
1212     g_free(buffer);
1213     }
1214     }
1215     }
1216     }
1217     }
1218     }
1219     }
1220     map_rect_destroy(mr);
1221     }
1222     }
1223     }
1224     }
1225     }
1226     map_selection_destroy(sel);
1227     mapset_close(msh);
1228    
1229     if (hn_fold)
1230     {
1231     g_free(hn_fold);
1232     }
1233    
1234     if (street_name_fold)
1235     {
1236     g_free(street_name_fold);
1237     }
1238    
1239    
1240     #ifdef DEBUG_GLIB_MEM_FUNCTIONS
1241     g_mem_profile();
1242     #endif
1243     }
1244    
1245 zoff99 2 static GList *
1246     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)
1247     {
1248     struct search_list_result *slr;
1249     struct coord_geo g;
1250     struct coord c;
1251    
1252 zoff99 30 //// dbg(0,"enter\n");
1253 zoff99 2
1254 zoff99 27 while ((slr = search_list_get_result(sl)))
1255 zoff99 2 {
1256 zoff99 29
1257 zoff99 27 if (offline_search_break_searching == 1)
1258 zoff99 15 {
1259     break;
1260     }
1261    
1262 zoff99 2 // does the streetname of the housenumber match the street we want?
1263     if (slr != NULL)
1264     {
1265     if (slr->street != NULL)
1266 zoff99 29 {
1267 zoff99 27 if ((street_name != NULL) && (slr->street->name != NULL))
1268     {
1269     if (strcmp(slr->street->name, street_name) == 0)
1270 zoff99 2 {
1271 zoff99 27 char *buffer;
1272     // coords of result
1273     c.x = slr->house_number->common.c->x;
1274     c.y = slr->house_number->common.c->y;
1275     transform_to_geo(slr->house_number->common.c->pro, &c, &g);
1276     // SHN -> street with house number
1277     // return a string like: "SHN:H111L5555:16.766:48.76:full address name is at the end"
1278     // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 max. 15 chars -> this sould be max. about 335 chars long
1279     if (slr->town->common.postal == NULL)
1280     {
1281     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);
1282     }
1283     else
1284     {
1285 zoff99 31 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, slr->house_number->house_number);
1286 zoff99 27 }
1287 zoff99 2
1288 zoff99 30 //// dbg(0,"res=%s\n",buffer);
1289 zoff99 2
1290 zoff99 27 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1291     #ifdef HAVE_API_ANDROID
1292     // return results to android as they come in ...
1293     android_return_search_result(jni,buffer);
1294     #endif
1295     g_free(buffer);
1296     }
1297 zoff99 2 }
1298 zoff99 29 }
1299 zoff99 2 }
1300     }
1301    
1302     return result_list;
1303     }
1304    
1305     static GList *
1306     search_address__street(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, GList *exclude3, int partial, struct jni_object *jni)
1307     {
1308 zoff99 30 //// dbg(0,"enter\n");
1309 zoff99 2
1310     struct search_list_result *slr = NULL;
1311 zoff99 27 GList *tmp = phrases;
1312     int count = 0;
1313 zoff99 2 struct coord_geo g;
1314     struct coord c;
1315     struct attr attr2;
1316    
1317 zoff99 15 struct item *save_item;
1318     int save_level;
1319     int save_last_result_valid;
1320 zoff99 2
1321 zoff99 27 while ((slr = search_list_get_result(sl)))
1322 zoff99 2 {
1323     char *buffer;
1324     char *buffer2;
1325    
1326 zoff99 27 if (offline_search_break_searching == 1)
1327 zoff99 15 {
1328     break;
1329     }
1330    
1331 zoff99 2 if (slr->street)
1332     {
1333     // coords of result
1334 zoff99 27 c.x = slr->street->common.c->x;
1335     c.y = slr->street->common.c->y;
1336 zoff99 2 transform_to_geo(slr->street->common.c->pro, &c, &g);
1337    
1338     // STR -> street
1339     // return a string like: "STR:H1111L5555:16.766:-48.76:full address name is at the end"
1340     // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 chars -> this sould be max. about 320 chars long
1341     if (slr->town->common.postal == NULL)
1342     {
1343 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s,%.101s, %.101s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.town_name, slr->street->name);
1344 zoff99 2 }
1345     else
1346     {
1347 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s,%.7s %.101s, %.101s", slr->street->common.item.id_hi, slr->street->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.postal, slr->town->common.town_name, slr->street->name);
1348 zoff99 2 }
1349     // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1350    
1351 zoff99 30 //// dbg(0,"res=%s\n",buffer);
1352 zoff99 2
1353 zoff99 27 #ifdef HAVE_API_ANDROID
1354 zoff99 2 // return results to android as they come in ...
1355     android_return_search_result(jni,buffer);
1356 zoff99 27 #endif
1357 zoff99 2 count++;
1358    
1359 zoff99 27 buffer2 = g_strdup_printf("%s", slr->street->name);
1360 zoff99 30 //// dbg(0,"b2:%s\n",buffer2);
1361 zoff99 2
1362 zoff99 15
1363 zoff99 27 save_item = sl->item;
1364     save_level = sl->level;
1365     save_last_result_valid = sl->last_result_valid;
1366 zoff99 15
1367     #if 1
1368     // put words back to start!!
1369 zoff99 27 tmp = phrases;
1370 zoff99 2 while (tmp)
1371     {
1372 zoff99 28 if (offline_search_break_searching == 1)
1373     {
1374     break;
1375     }
1376    
1377 zoff99 30 //// dbg(0,"s0=%s\n",tmp->data);
1378 zoff99 2 if (tmp != exclude1 && tmp != exclude2 && tmp != exclude3)
1379     {
1380 zoff99 30 //// dbg(0,"s=%s\n",tmp->data);
1381 zoff99 2
1382 zoff99 27 attr2.type = attr_house_number;
1383     attr2.u.str = tmp->data;
1384 zoff99 2 search_list_search(sl, &attr2, partial);
1385 zoff99 27 result_list = search_address_housenumber_real(result_list, sl, buffer2, phrases, exclude1, exclude2, exclude3, partial, jni);
1386 zoff99 2 }
1387 zoff99 27 tmp = g_list_next(tmp);
1388 zoff99 2 }
1389 zoff99 15 #endif
1390    
1391     // restore again
1392 zoff99 27 sl->item = save_item;
1393     sl->level = save_level;
1394     sl->last_result_valid = save_last_result_valid;
1395 zoff99 15
1396 zoff99 2 }
1397    
1398     if (buffer2)
1399     {
1400     g_free(buffer2);
1401     }
1402    
1403     if (buffer)
1404     {
1405     g_free(buffer);
1406     }
1407     }
1408    
1409 zoff99 30 //// dbg(0,"return 2\n");
1410 zoff99 2 return result_list;
1411     }
1412    
1413     static GList *
1414     search_address__town(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, int partial, struct jni_object *jni)
1415     {
1416 zoff99 30 //// dbg(0,"enter\n");
1417 zoff99 2 struct search_list_result *slr;
1418 zoff99 27 GList *tmp = phrases;
1419     int count = 0;
1420 zoff99 2 struct coord_geo g;
1421     struct coord c;
1422     struct attr attr;
1423 zoff99 15 struct attr attrx;
1424     // struct search_list *sl2=search_list_new(sl->ms);
1425     struct item *save_item;
1426     int save_level;
1427     int save_last_result_valid;
1428     // int first=1;
1429 zoff99 2
1430 zoff99 27 while ((slr = search_list_get_result(sl)))
1431 zoff99 2 {
1432     char *buffer;
1433 zoff99 15
1434 zoff99 27 if (offline_search_break_searching == 1)
1435 zoff99 15 {
1436     break;
1437     }
1438    
1439 zoff99 2 // coords of result
1440 zoff99 27 c.x = slr->town->common.c->x;
1441     c.y = slr->town->common.c->y;
1442 zoff99 2 transform_to_geo(slr->town->common.c->pro, &c, &g);
1443    
1444     // TWN -> town
1445     if (slr->town->common.postal == NULL)
1446     {
1447 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s,%.101s", slr->town->common.item.id_hi, slr->town->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.town_name);
1448 zoff99 2 }
1449     else
1450     {
1451 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s,%.7s %.101s", slr->town->common.item.id_hi, slr->town->common.item.id_lo, g.lat, g.lng, slr->country->name, slr->town->common.postal, slr->town->common.town_name);
1452 zoff99 2 }
1453    
1454 zoff99 30 //// dbg(0,"**res=%s\n",buffer);
1455 zoff99 2
1456     // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1457     #ifdef HAVE_API_ANDROID
1458     // return results to android as they come in ...
1459     android_return_search_result(jni,buffer);
1460     #endif
1461    
1462     count++;
1463 zoff99 15 if (buffer)
1464 zoff99 31 {
1465 zoff99 15 g_free(buffer);
1466 zoff99 31 }
1467 zoff99 2
1468 zoff99 27 save_item = sl->item;
1469     save_level = sl->level;
1470     save_last_result_valid = sl->last_result_valid;
1471 zoff99 15
1472     // put words back to start!!
1473 zoff99 27 tmp = phrases;
1474 zoff99 15
1475 zoff99 2 while (tmp)
1476     {
1477 zoff99 28 if (offline_search_break_searching == 1)
1478     {
1479     break;
1480     }
1481    
1482 zoff99 2 if (tmp != exclude1 && tmp != exclude2)
1483     {
1484 zoff99 30 //// dbg(0,"s=%s\n",tmp->data);
1485 zoff99 27 attr.type = attr_street_name;
1486     attr.u.str = tmp->data;
1487 zoff99 2 search_list_search(sl, &attr, partial);
1488 zoff99 27 result_list = search_address__street(result_list, sl, phrases, exclude1, exclude2, tmp, partial, jni);
1489 zoff99 2 }
1490 zoff99 27 tmp = g_list_next(tmp);
1491 zoff99 2 }
1492    
1493 zoff99 15 // restore again
1494 zoff99 27 sl->item = save_item;
1495     sl->level = save_level;
1496     sl->last_result_valid = save_last_result_valid;
1497 zoff99 2 }
1498    
1499 zoff99 30 //// dbg(0,"return 2\n");
1500 zoff99 2 return result_list;
1501     }
1502    
1503     static GList *
1504     search_address__country(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude, int partial, struct jni_object *jni)
1505     {
1506 zoff99 27 GList *tmp = phrases;
1507     int count = 0;
1508 zoff99 2 struct attr attr;
1509     struct search_list_result *slr;
1510 zoff99 30 //// dbg(0,"enter\n");
1511 zoff99 2
1512 zoff99 27 while ((slr = search_list_get_result(sl)))
1513 zoff99 2 {
1514 zoff99 30 //// dbg(0,"1 slr=%p\n",slr->country);
1515     //// dbg(0,"2 slr=%s\n",slr->country->name);
1516     //// dbg(0,"3 slr=%s\n",slr->country->iso2);
1517 zoff99 2 count++;
1518     }
1519 zoff99 30 //// dbg(0,"count %d\n",count);
1520 zoff99 2 if (!count)
1521     {
1522 zoff99 30 //// dbg(0,"return 1");
1523 zoff99 2 return result_list;
1524     }
1525    
1526     while (tmp)
1527     {
1528     if (tmp != exclude)
1529     {
1530 zoff99 30 //// dbg(0,"Is=%s\n",tmp->data);
1531 zoff99 27 attr.type = attr_town_or_district_name;
1532     attr.u.str = tmp->data;
1533 zoff99 2 search_list_search(sl, &attr, partial);
1534 zoff99 27 result_list = search_address__town(result_list, sl, phrases, exclude, tmp, partial, jni);
1535 zoff99 2 }
1536 zoff99 15 //else
1537     //{
1538 zoff99 30 //// dbg(0,"Xs=%s\n",tmp->data);
1539 zoff99 15 //}
1540 zoff99 27 tmp = g_list_next(tmp);
1541 zoff99 2 }
1542 zoff99 30 //// dbg(0,"return 2");
1543 zoff99 2 return result_list;
1544     }
1545    
1546 zoff99 27 struct country2
1547     {
1548 zoff99 2 int id;
1549     char *car;
1550     char *iso2;
1551     char *iso3;
1552     char *name;
1553     };
1554    
1555 zoff99 31 static struct country2
1556     all_country_list[] =
1557     { { 20, "AND", "AD", "AND", /* 020 */"Andorra" }, { 784, "UAE", "AE", "ARE", /* 784 */
1558     "United Arab Emirates" }, { 4, "AFG", "AF", "AFG", /* 004 */"Afghanistan" }, { 28, "AG", "AG", "ATG", /* 028 */"Antigua and Barbuda" }, { 660, NULL, "AI", "AIA", /* 660 */"Anguilla" }, { 8, "AL", "AL", "ALB", /* 008 */"Albania" }, { 51, "ARM", "AM", "ARM", /* 051 */"Armenia" }, { 530, "NA", "AN", "ANT", /* 530 */
1559     "Netherlands Antilles" }, { 24, "ANG", "AO", "AGO", /* 024 */"Angola" }, { 10, NULL, "AQ", "ATA", /* 010 */"Antarctica" }, { 32, "RA", "AR", "ARG", /* 032 */"Argentina" }, { 16, NULL, "AS", "ASM", /* 016 */"American Samoa" }, { 40, "A", "AT", "AUT", /* 040 */"Austria" }, { 36, "AUS", "AU", "AUS", /* 036 */"Australia" }, { 533, "ARU", "AW", "ABW", /* 533 */"Aruba" }, { 248, "AX", "AX", "ALA", /* 248 */"Aland Islands" }, { 31, "AZ", "AZ", "AZE", /* 031 */"Azerbaijan" }, { 70, "BiH", "BA", "BIH", /* 070 */
1560     "Bosnia and Herzegovina" }, { 52, "BDS", "BB", "BRB", /* 052 */"Barbados" }, { 50, "BD", "BD", "BGD", /* 050 */"Bangladesh" }, { 56, "B", "BE", "BEL", /* 056 */"Belgium" }, { 854, "BF", "BF", "BFA", /* 854 */"Burkina Faso" }, { 100, "BG", "BG", "BGR", /* 100 */"Bulgaria" }, { 48, "BRN", "BH", "BHR", /* 048 */"Bahrain" }, { 108, "RU", "BI", "BDI", /* 108 */"Burundi" }, { 204, "BJ", "BJ", "BEN", /* 204 */"Benin" }, { 652, NULL, "BL", "BLM", /* 652 */"Saint Barthelemy" }, { 60, NULL, "BM", "BMU", /* 060 */"Bermuda" }, { 96, "BRU", "BN", "BRN", /* 096 */"Brunei Darussalam" }, { 68, "BOL", "BO", "BOL", /* 068 */"Bolivia" }, { 76, "BR", "BR", "BRA", /* 076 */"Brazil" }, { 44, "BS", "BS", "BHS", /* 044 */"Bahamas" }, { 64, "BHT", "BT", "BTN", /* 064 */"Bhutan" }, { 74, NULL, "BV", "BVT", /* 074 */"Bouvet Island" }, { 72, "RB", "BW", "BWA", /* 072 */"Botswana" }, { 112, "BY", "BY", "BLR", /* 112 */"Belarus" }, { 84, "BZ", "BZ", "BLZ", /* 084 */"Belize" }, { 124, "CDN", "CA", "CAN", /* 124 */"Canada" }, { 166, NULL, "CC", "CCK", /* 166 */
1561     "Cocos (Keeling) Islands" }, { 180, "CGO", "CD", "COD", /* 180 */
1562     "Congo, Democratic Republic of the" }, { 140, "RCA", "CF", "CAF", /* 140 */
1563     "Central African Republic" }, { 178, NULL, "CG", "COG", /* 178 */"Congo" }, { 756, "CH", "CH", "CHE", /* 756 */"Switzerland" }, { 384, "CI", "CI", "CIV", /* 384 */"Cote d'Ivoire" }, { 184, NULL, "CK", "COK", /* 184 */"Cook Islands" }, { 152, "RCH", "CL", "CHL", /* 152 */"Chile" }, { 120, "CAM", "CM", "CMR", /* 120 */"Cameroon" }, { 156, "RC", "CN", "CHN", /* 156 */"China" }, { 170, "CO", "CO", "COL", /* 170 */"Colombia" }, { 188, "CR", "CR", "CRI", /* 188 */"Costa Rica" }, { 192, "C", "CU", "CUB", /* 192 */"Cuba" }, { 132, "CV", "CV", "CPV", /* 132 */"Cape Verde" }, { 162, NULL, "CX", "CXR", /* 162 */"Christmas Island" }, { 196, "CY", "CY", "CYP", /* 196 */"Cyprus" }, { 203, "CZ", "CZ", "CZE", /* 203 */"Czech Republic" }, { 276, "D", "DE", "DEU", /* 276 */"Germany" }, { 262, "DJI", "DJ", "DJI", /* 262 */"Djibouti" }, { 208, "DK", "DK", "DNK", /* 208 */"Denmark" }, { 212, "WD", "DM", "DMA", /* 212 */"Dominica" }, { 214, "DOM", "DO", "DOM", /* 214 */
1564     "Dominican Republic" }, { 12, "DZ", "DZ", "DZA", /* 012 */"Algeria" }, { 218, "EC", "EC", "ECU", /* 218 */"Ecuador" }, { 233, "EST", "EE", "EST", /* 233 */"Estonia" }, { 818, "ET", "EG", "EGY", /* 818 */"Egypt" }, { 732, "WSA", "EH", "ESH", /* 732 */"Western Sahara" }, { 232, "ER", "ER", "ERI", /* 232 */"Eritrea" }, { 724, "E", "ES", "ESP", /* 724 */"Spain" }, { 231, "ETH", "ET", "ETH", /* 231 */"Ethiopia" }, { 246, "FIN", "FI", "FIN", /* 246 */"Finland" }, { 242, "FJI", "FJ", "FJI", /* 242 */"Fiji" }, { 238, NULL, "FK", "FLK", /* 238 */
1565     "Falkland Islands (Malvinas)" }, { 583, "FSM", "FM", "FSM", /* 583 */
1566     "Micronesia, Federated States of" }, { 234, "FO", "FO", "FRO", /* 234 */"Faroe Islands" }, { 250, "F", "FR", "FRA", /* 250 */"France" }, { 266, "G", "GA", "GAB", /* 266 */"Gabon" }, { 826, "GB", "GB", "GBR", /* 826 */"United Kingdom" }, { 308, "WG", "GD", "GRD", /* 308 */"Grenada" }, { 268, "GE", "GE", "GEO", /* 268 */"Georgia" }, { 254, NULL, "GF", "GUF", /* 254 */"French Guiana" }, { 831, NULL, "GG", "GGY", /* 831 */"Guernsey" }, { 288, "GH", "GH", "GHA", /* 288 */"Ghana" }, { 292, "GBZ", "GI", "GIB", /* 292 */"Gibraltar" }, { 304, "KN", "GL", "GRL", /* 304 */"Greenland" }, { 270, "WAG", "GM", "GMB", /* 270 */"Gambia" }, { 324, "RG", "GN", "GIN", /* 324 */"Guinea" }, { 312, NULL, "GP", "GLP", /* 312 */"Guadeloupe" }, { 226, "GQ", "GQ", "GNQ", /* 226 */"Equatorial Guinea" }, { 300, "GR", "GR", "GRC", /* 300 */"Greece" }, { 239, NULL, "GS", "SGS", /* 239 */
1567     "South Georgia and the South Sandwich Islands" }, { 320, "GCA", "GT", "GTM", /* 320 */"Guatemala" }, { 316, NULL, "GU", "GUM", /* 316 */"Guam" }, { 624, "GUB", "GW", "GNB", /* 624 */"Guinea-Bissau" }, { 328, "GUY", "GY", "GUY", /* 328 */"Guyana" }, { 344, "HK", "HK", "HKG", /* 344 */"Hong Kong" }, { 334, NULL, "HM", "HMD", /* 334 */
1568     "Heard Island and McDonald Islands" }, { 340, "HN", "HN", "HND", /* 340 */"Honduras" }, { 191, "HR", "HR", "HRV", /* 191 */"Croatia" }, { 332, "RH", "HT", "HTI", /* 332 */"Haiti" }, { 348, "H", "HU", "HUN", /* 348 */"Hungary" }, { 360, "RI", "ID", "IDN", /* 360 */"Indonesia" }, { 372, "IRL", "IE", "IRL", /* 372 */"Ireland" }, { 376, "IL", "IL", "ISR", /* 376 */"Israel" }, { 833, NULL, "IM", "IMN", /* 833 */"Isle of Man" }, { 356, "IND", "IN", "IND", /* 356 */"India" }, { 86, NULL, "IO", "IOT", /* 086 */
1569     "British Indian Ocean Territory" }, { 368, "IRQ", "IQ", "IRQ", /* 368 */"Iraq" }, { 364, "IR", "IR", "IRN", /* 364 */
1570     "Iran, Islamic Republic of" }, { 352, "IS", "IS", "ISL", /* 352 */"Iceland" }, { 380, "I", "IT", "ITA", /* 380 */"Italy" }, { 832, NULL, "JE", "JEY", /* 832 */"Jersey" }, { 388, "JA", "JM", "JAM", /* 388 */"Jamaica" }, { 400, "JOR", "JO", "JOR", /* 400 */"Jordan" }, { 392, "J", "JP", "JPN", /* 392 */"Japan" }, { 404, "EAK", "KE", "KEN", /* 404 */"Kenya" }, { 417, "KS", "KG", "KGZ", /* 417 */"Kyrgyzstan" }, { 116, "K", "KH", "KHM", /* 116 */"Cambodia" }, { 296, "KIR", "KI", "KIR", /* 296 */"Kiribati" }, { 174, "COM", "KM", "COM", /* 174 */"Comoros" }, { 659, "KAN", "KN", "KNA", /* 659 */
1571     "Saint Kitts and Nevis" }, { 408, "KP", "KP", "PRK", /* 408 */
1572     "Korea, Democratic People's Republic of" }, { 410, "ROK", "KR", "KOR", /* 410 */
1573     "Korea, Republic of" }, { 414, "KWT", "KW", "KWT", /* 414 */"Kuwait" }, { 136, NULL, "KY", "CYM", /* 136 */"Cayman Islands" }, { 398, "KZ", "KZ", "KAZ", /* 398 */"Kazakhstan" }, { 418, "LAO", "LA", "LAO", /* 418 */
1574     "Lao People's Democratic Republic" }, { 422, "RL", "LB", "LBN", /* 422 */"Lebanon" }, { 662, "WL", "LC", "LCA", /* 662 */"Saint Lucia" }, { 438, "FL", "LI", "LIE", /* 438 */"Liechtenstein" }, { 144, "CL", "LK", "LKA", /* 144 */"Sri Lanka" }, { 430, "LB", "LR", "LBR", /* 430 */"Liberia" }, { 426, "LS", "LS", "LSO", /* 426 */"Lesotho" }, { 440, "LT", "LT", "LTU", /* 440 */"Lithuania" }, { 442, "L", "LU", "LUX", /* 442 */"Luxembourg" }, { 428, "LV", "LV", "LVA", /* 428 */"Latvia" }, { 434, "LAR", "LY", "LBY", /* 434 */
1575     "Libyan Arab Jamahiriya" }, { 504, "MA", "MA", "MAR", /* 504 */"Morocco" }, { 492, "MC", "MC", "MCO", /* 492 */"Monaco" }, { 498, "MD", "MD", "MDA", /* 498 */
1576     "Moldova, Republic of" }, { 499, "MNE", "ME", "MNE", /* 499 */"Montenegro" }, { 663, NULL, "MF", "MAF", /* 663 */
1577     "Saint Martin (French part)" }, { 450, "RM", "MG", "MDG", /* 450 */"Madagascar" }, { 584, "MH", "MH", "MHL", /* 584 */"Marshall Islands" }, { 807, "MK", "MK", "MKD", /* 807 */
1578     "Macedonia, the former Yugoslav Republic of" }, { 466, "RMM", "ML", "MLI", /* 466 */"Mali" }, { 104, "MYA", "MM", "MMR", /* 104 */"Myanmar" }, { 496, "MGL", "MN", "MNG", /* 496 */"Mongolia" }, { 446, NULL, "MO", "MAC", /* 446 */"Macao" }, { 580, NULL, "MP", "MNP", /* 580 */
1579     "Northern Mariana Islands" }, { 474, NULL, "MQ", "MTQ", /* 474 */"Martinique" }, { 478, "RIM", "MR", "MRT", /* 478 */"Mauritania" }, { 500, NULL, "MS", "MSR", /* 500 */"Montserrat" }, { 470, "M", "MT", "MLT", /* 470 */"Malta" }, { 480, "MS", "MU", "MUS", /* 480 */"Mauritius" }, { 462, "MV", "MV", "MDV", /* 462 */"Maldives" }, { 454, "MW", "MW", "MWI", /* 454 */"Malawi" }, { 484, "MEX", "MX", "MEX", /* 484 */"Mexico" }, { 458, "MAL", "MY", "MYS", /* 458 */"Malaysia" }, { 508, "MOC", "MZ", "MOZ", /* 508 */"Mozambique" }, { 516, "NAM", "NA", "NAM", /* 516 */"Namibia" }, { 540, "NCL", "NC", "NCL", /* 540 */"New Caledonia" }, { 562, "RN", "NE", "NER", /* 562 */"Niger" }, { 574, NULL, "NF", "NFK", /* 574 */"Norfolk Island" }, { 566, "NGR", "NG", "NGA", /* 566 */"Nigeria" }, { 558, "NIC", "NI", "NIC", /* 558 */"Nicaragua" }, { 528, "NL", "NL", "NLD", /* 528 */"Netherlands" }, { 578, "N", "NO", "NOR", /* 578 */"Norway" }, { 524, "NEP", "NP", "NPL", /* 524 */"Nepal" }, { 520, "NAU", "NR", "NRU", /* 520 */"Nauru" }, { 570, NULL, "NU", "NIU", /* 570 */"Niue" }, { 554, "NZ", "NZ", "NZL", /* 554 */"New Zealand" }, { 512, "OM", "OM", "OMN", /* 512 */"Oman" }, { 591, "PA", "PA", "PAN", /* 591 */"Panama" }, { 604, "PE", "PE", "PER", /* 604 */"Peru" }, { 258, NULL, "PF", "PYF", /* 258 */"French Polynesia" }, { 598, "PNG", "PG", "PNG", /* 598 */"Papua New Guinea" }, { 608, "RP", "PH", "PHL", /* 608 */"Philippines" }, { 586, "PK", "PK", "PAK", /* 586 */"Pakistan" }, { 616, "PL", "PL", "POL", /* 616 */"Poland" }, { 666, NULL, "PM", "SPM", /* 666 */
1580     "Saint Pierre and Miquelon" }, { 612, NULL, "PN", "PCN", /* 612 */"Pitcairn" }, { 630, "PRI", "PR", "PRI", /* 630 */"Puerto Rico" }, { 275, "AUT", "PS", "PSE", /* 275 */
1581     "Palestinian Territory, Occupied" }, { 620, "P", "PT", "PRT", /* 620 */"Portugal" }, { 585, "PAL", "PW", "PLW", /* 585 */"Palau" }, { 600, "PY", "PY", "PRY", /* 600 */"Paraguay" }, { 634, "Q", "QA", "QAT", /* 634 */"Qatar" }, { 638, NULL, "RE", "REU", /* 638 */"Reunion" }, { 642, "RO", "RO", "ROU", /* 642 */"Romania" }, { 688, "SRB", "RS", "SRB", /* 688 */"Serbia" }, { 643, "RUS", "RU", "RUS", /* 643 */
1582     "Russian Federation" }, { 646, "RWA", "RW", "RWA", /* 646 */"Rwanda" }, { 682, "KSA", "SA", "SAU", /* 682 */"Saudi Arabia" }, { 90, "SOL", "SB", "SLB", /* 090 */"Solomon Islands" }, { 690, "SY", "SC", "SYC", /* 690 */"Seychelles" }, { 736, "SUD", "SD", "SDN", /* 736 */"Sudan" }, { 752, "S", "SE", "SWE", /* 752 */"Sweden" }, { 702, "SGP", "SG", "SGP", /* 702 */"Singapore" }, { 654, NULL, "SH", "SHN", /* 654 */"Saint Helena" }, { 705, "SLO", "SI", "SVN", /* 705 */"Slovenia" }, { 744, NULL, "SJ", "SJM", /* 744 */
1583     "Svalbard and Jan Mayen" }, { 703, "SK", "SK", "SVK", /* 703 */"Slovakia" }, { 694, "WAL", "SL", "SLE", /* 694 */"Sierra Leone" }, { 674, "RSM", "SM", "SMR", /* 674 */"San Marino" }, { 686, "SN", "SN", "SEN", /* 686 */"Senegal" }, { 706, "SO", "SO", "SOM", /* 706 */"Somalia" }, { 740, "SME", "SR", "SUR", /* 740 */"Suriname" }, { 678, "STP", "ST", "STP", /* 678 */
1584     "Sao Tome and Principe" }, { 222, "ES", "SV", "SLV", /* 222 */"El Salvador" }, { 760, "SYR", "SY", "SYR", /* 760 */
1585     "Syrian Arab Republic" }, { 748, "SD", "SZ", "SWZ", /* 748 */"Swaziland" }, { 796, NULL, "TC", "TCA", /* 796 */
1586     "Turks and Caicos Islands" }, { 148, "TD", "TD", "TCD", /* 148 */"Chad" }, { 260, "ARK", "TF", "ATF", /* 260 */
1587     "French Southern Territories" }, { 768, "RT", "TG", "TGO", /* 768 */"Togo" }, { 764, "T", "TH", "THA", /* 764 */"Thailand" }, { 762, "TJ", "TJ", "TJK", /* 762 */"Tajikistan" }, { 772, NULL, "TK", "TKL", /* 772 */"Tokelau" }, { 626, "TL", "TL", "TLS", /* 626 */"Timor-Leste" }, { 795, "TM", "TM", "TKM", /* 795 */"Turkmenistan" }, { 788, "TN", "TN", "TUN", /* 788 */"Tunisia" }, { 776, "TON", "TO", "TON", /* 776 */"Tonga" }, { 792, "TR", "TR", "TUR", /* 792 */"Turkey" }, { 780, "TT", "TT", "TTO", /* 780 */
1588     "Trinidad and Tobago" }, { 798, "TUV", "TV", "TUV", /* 798 */"Tuvalu" }, { 158, NULL, "TW", "TWN", /* 158 */
1589     "Taiwan, Province of China" }, { 834, "EAT", "TZ", "TZA", /* 834 */
1590     "Tanzania, United Republic of" }, { 804, "UA", "UA", "UKR", /* 804 */"Ukraine" }, { 800, "EAU", "UG", "UGA", /* 800 */"Uganda" }, { 581, NULL, "UM", "UMI", /* 581 */
1591     "United States Minor Outlying Islands" }, { 840, "USA", "US", "USA", /* 840 */"United States" }, { 858, "ROU", "UY", "URY", /* 858 */"Uruguay" }, { 860, "UZ", "UZ", "UZB", /* 860 */"Uzbekistan" }, { 336, "SCV", "VA", "VAT", /* 336 */
1592     "Holy See (Vatican City State)" }, { 670, "WV", "VC", "VCT", /* 670 */"Saint Vincent and the Grenadines" }, { 862, "YV", "VE", "VEN", /* 862 */"Venezuela" }, { 92, NULL, "VG", "VGB", /* 092 */"Virgin Islands, British" }, { 850, NULL, "VI", "VIR", /* 850 */"Virgin Islands, U.S." }, { 704, "VN", "VN", "VNM", /* 704 */"Viet Nam" }, { 548, "VAN", "VU", "VUT", /* 548 */"Vanuatu" }, { 876, NULL, "WF", "WLF", /* 876 */"Wallis and Futuna" }, { 882, "WS", "WS", "WSM", /* 882 */"Samoa" }, { 887, "YAR", "YE", "YEM", /* 887 */"Yemen" }, { 175, NULL, "YT", "MYT", /* 175 */"Mayotte" }, { 710, "ZA", "ZA", "ZAF", /* 710 */"South Africa" }, { 894, "Z", "ZM", "ZMB", /* 894 */"Zambia" }, { 716, "ZW", "ZW", "ZWE", /* 716 */"Zimbabwe" }, { 999, "*", "*", "*", /* 999 */"Unknown" }, };
1593 zoff99 2
1594 zoff99 31 // @return =0 strings matched, =1 not matched
1595 zoff99 27 static int ascii_cmp_local(char *name, char *match, int partial)
1596 zoff99 2 {
1597 zoff99 31 char *s1_a;
1598     char *s2_a;
1599    
1600 zoff99 27 char *s1 = linguistics_casefold(name);
1601     char *s2 = linguistics_casefold(match);
1602 zoff99 31
1603     if (s1)
1604     {
1605     s1_a = linguistics_remove_all_specials(s1);
1606     if (s1_a)
1607     {
1608     g_free(s1);
1609     s1 = s1_a;
1610     }
1611     s1_a = linguistics_expand_special(s1, 1);
1612     if (s1_a)
1613     {
1614     g_free(s1);
1615     s1 = s1_a;
1616     }
1617     }
1618    
1619     if (s2)
1620     {
1621     s2_a = linguistics_remove_all_specials(s2);
1622     if (s2_a)
1623     {
1624     g_free(s2);
1625     s2 = s2_a;
1626     }
1627     s2_a = linguistics_expand_special(s2, 1);
1628     if (s2_a)
1629     {
1630     g_free(s2);
1631     s2 = s2_a;
1632     }
1633     }
1634    
1635 zoff99 27 int ret = linguistics_compare(s1, s2, partial);
1636 zoff99 31
1637     if (s1)
1638     {
1639     g_free(s1);
1640     }
1641    
1642     if (s2)
1643     {
1644     g_free(s2);
1645     }
1646    
1647 zoff99 2 return ret;
1648     }
1649    
1650 zoff99 31 // @return =0 strings matched, =1 not matched
1651     static int ascii_cmp_local_faster(char *name, char *match, int partial)
1652     {
1653     char *s1_a;
1654     char *s1 = name;
1655     int ret;
1656    
1657     s1_a = linguistics_fold_and_prepare_complete(s1, 0);
1658    
1659     if (!s1_a)
1660     {
1661     return 1;
1662     }
1663    
1664     // dbg(0,"s1=%s match=%s\n", s1_a, match);
1665    
1666     if (strlen(s1_a) == 0)
1667     {
1668     // only special chars in string, return "no match"
1669     return 1;
1670     }
1671    
1672    
1673     // --- old ---
1674     //ret = linguistics_compare(s1, match, partial);
1675     // --- old ---
1676    
1677     if (partial == 1)
1678     {
1679     ret = strncmp(s1_a, match, strlen(match));
1680     }
1681     else
1682     {
1683     if (strlen(s1_a) == strlen(match))
1684     {
1685     ret = strncmp(s1_a, match, strlen(match));
1686     }
1687     else
1688     {
1689     ret = 1;
1690     }
1691     }
1692    
1693    
1694     if (s1_a)
1695     {
1696     g_free(s1_a);
1697     }
1698    
1699     return ret;
1700     }
1701    
1702 zoff99 2 struct navit *global_navit;
1703    
1704 zoff99 27 void search_full_world(char *addr, int partial, int search_order, struct jni_object *jni, struct coord_geo *search_center, int search_radius)
1705 zoff99 2 {
1706     struct item *item;
1707 zoff99 27 struct map_rect *mr = NULL;
1708 zoff99 2 struct mapset *ms;
1709     struct mapset_handle *msh;
1710     struct map* map = NULL;
1711     struct attr map_name_attr;
1712     struct attr attr;
1713    
1714 zoff99 27 char *str = search_fix_spaces(addr);
1715     GList *phrases = search_split_phrases(str);
1716 zoff99 2 GList *phrases_first;
1717 zoff99 27 phrases_first = phrases;
1718 zoff99 2
1719 zoff99 27 ms = global_navit->mapsets->data;
1720     msh = mapset_open(ms);
1721 zoff99 2
1722     struct pcoord center99;
1723 zoff99 27 int search_radius_this = 0;
1724 zoff99 30 // dbg(0, "in lat=%f,lng=%f\n", search_center->lat, search_center->lng);
1725 zoff99 27 if ((search_center->lat == 0) && (search_center->lng == 0))
1726 zoff99 2 {
1727 zoff99 27 center99.x = 0;
1728     center99.y = 0;
1729     search_radius_this = 21000000;
1730 zoff99 2 }
1731     else
1732     {
1733     struct coord c99;
1734     transform_from_geo(projection_mg, search_center, &c99);
1735 zoff99 27 center99.x = c99.x;
1736     center99.y = c99.y;
1737     search_radius_this = search_radius;
1738 zoff99 2 }
1739 zoff99 30 // dbg(0, "out x=%d,y=%d,r=%d\n", center99.x, center99.y, search_radius_this);
1740 zoff99 2
1741 zoff99 27 struct map_selection *sel = map_selection_rect_new(&center99, search_radius_this, search_order);
1742     sel->range.min = type_town_label;
1743     sel->range.max = type_area;
1744 zoff99 2
1745 zoff99 27 while (msh && (map = mapset_next(msh, 0)))
1746 zoff99 2 {
1747 zoff99 31 if (offline_search_break_searching == 1)
1748     {
1749     break;
1750     }
1751    
1752 zoff99 27 if (map_get_attr(map, attr_name, &map_name_attr, NULL))
1753 zoff99 2 {
1754     if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
1755     {
1756     if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/navitmap", map_name_attr.u.str, 38) == 0)
1757     {
1758     // its an sdcard map
1759 zoff99 30 //// dbg(0,"map name=%s",map_name_attr.u.str);
1760 zoff99 2 // mr=map_rect_new(map, NULL);
1761 zoff99 27 mr = map_rect_new(map, sel);
1762 zoff99 2 if (mr)
1763     {
1764 zoff99 27 char *streetname_last = NULL;
1765 zoff99 2
1766 zoff99 27 while ((item = map_rect_get_item(mr)))
1767 zoff99 2 {
1768 zoff99 28
1769     if (offline_search_break_searching == 1)
1770     {
1771     break;
1772     }
1773    
1774 zoff99 31 #ifdef DEBUG_GLIB_MEM_FUNCTIONS
1775     g_mem_profile();
1776     #endif
1777    
1778 zoff99 27 if ((item_is_town(*item)) || (item_is_district(*item)))
1779     {
1780     struct search_list_town *p = NULL;
1781    
1782     if (item_attr_get(item, attr_town_name, &attr))
1783 zoff99 2 {
1784 zoff99 27 p = search_list_town_new(item);
1785     char *buffer = NULL;
1786     // coords of result
1787     struct coord_geo g;
1788     struct coord c;
1789     c.x = p->common.c->x;
1790     c.y = p->common.c->y;
1791     int calc_geo = 0;
1792 zoff99 2
1793 zoff99 30 // // dbg(0,"town name=%s\n", attr.u.str);
1794 zoff99 27
1795     phrases = phrases_first;
1796     while (phrases)
1797 zoff99 2 {
1798 zoff99 28
1799     if (offline_search_break_searching == 1)
1800     {
1801     break;
1802     }
1803    
1804 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1805 zoff99 2 {
1806 zoff99 30 // // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1807 zoff99 27 if (calc_geo == 0)
1808 zoff99 2 {
1809 zoff99 27 transform_to_geo(p->common.c->pro, &c, &g);
1810     // TWN -> town
1811     calc_geo = 1;
1812     }
1813     if (p->common.postal == NULL)
1814     {
1815     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);
1816     }
1817     else
1818     {
1819     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);
1820     }
1821 zoff99 12 #ifdef HAVE_API_ANDROID
1822 zoff99 27 // return results to android as they come in ...
1823     android_return_search_result(jni,buffer);
1824 zoff99 12 #endif
1825 zoff99 27 }
1826     phrases = g_list_next(phrases);
1827 zoff99 2
1828     }
1829 zoff99 31
1830 zoff99 27 if (buffer)
1831     {
1832     g_free(buffer);
1833     }
1834     search_list_town_destroy(p);
1835 zoff99 2 }
1836 zoff99 27
1837     if (item_attr_get(item, attr_town_name_match, &attr))
1838 zoff99 2 {
1839 zoff99 27 p = search_list_town_new(item);
1840     char *buffer = NULL;
1841     // coords of result
1842     struct coord_geo g;
1843     struct coord c;
1844     c.x = p->common.c->x;
1845     c.y = p->common.c->y;
1846     int calc_geo = 0;
1847 zoff99 2
1848 zoff99 30 // // dbg(0,"town name=%s\n", attr.u.str);
1849 zoff99 2
1850 zoff99 27 phrases = phrases_first;
1851     while (phrases)
1852 zoff99 2 {
1853 zoff99 28 if (offline_search_break_searching == 1)
1854     {
1855     break;
1856     }
1857    
1858 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1859 zoff99 2 {
1860 zoff99 30 // // dbg(0,"matched town name=%s want=%s\n", attr.u.str, phrases->data);
1861 zoff99 27 if (calc_geo == 0)
1862 zoff99 2 {
1863 zoff99 27 transform_to_geo(p->common.c->pro, &c, &g);
1864     // TWN -> town
1865     calc_geo = 1;
1866 zoff99 2 }
1867 zoff99 27 if (p->common.postal == NULL)
1868 zoff99 2 {
1869 zoff99 27 buffer = g_strdup_printf("TWN:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.town_name);
1870 zoff99 2 }
1871 zoff99 27 else
1872     {
1873     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);
1874     }
1875     #ifdef HAVE_API_ANDROID
1876     // return results to android as they come in ...
1877     android_return_search_result(jni,buffer);
1878     #endif
1879 zoff99 2 }
1880 zoff99 27 phrases = g_list_next(phrases);
1881    
1882 zoff99 2 }
1883 zoff99 31
1884 zoff99 27 if (buffer)
1885 zoff99 2 {
1886 zoff99 27 g_free(buffer);
1887     }
1888     search_list_town_destroy(p);
1889     }
1890     }
1891     else if (item_is_street(*item))
1892     {
1893 zoff99 2
1894 zoff99 27 struct search_list_street *p = NULL;
1895    
1896     if (item_attr_get(item, attr_label, &attr))
1897     {
1898 zoff99 30 // // dbg(0,"street1=%s\n",map_convert_string(item->map, attr.u.str));
1899 zoff99 27 if ((streetname_last == NULL) || (strcmp(streetname_last, attr.u.str) != 0))
1900     {
1901 zoff99 30 // // dbg(0,"street2=%s\n",map_convert_string(item->map, attr.u.str));
1902 zoff99 27 streetname_last = g_strdup_printf("%s", attr.u.str);
1903    
1904     p = search_list_street_new(item);
1905     char *buffer = NULL;
1906 zoff99 2 // coords of result
1907     struct coord_geo g;
1908     struct coord c;
1909 zoff99 27 c.x = p->common.c->x;
1910     c.y = p->common.c->y;
1911     int calc_geo = 0;
1912 zoff99 2
1913 zoff99 27 phrases = phrases_first;
1914 zoff99 2 while (phrases)
1915     {
1916 zoff99 28 if (offline_search_break_searching == 1)
1917     {
1918     break;
1919     }
1920    
1921 zoff99 2 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1922     {
1923 zoff99 27 if (calc_geo == 0)
1924 zoff99 2 {
1925     transform_to_geo(p->common.c->pro, &c, &g);
1926 zoff99 27 calc_geo = 1;
1927 zoff99 2 }
1928     if (p->common.postal == NULL)
1929     {
1930 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, attr.u.str);
1931 zoff99 2 }
1932     else
1933     {
1934 zoff99 27 buffer = g_strdup_printf("STR:H%dL%d:%f:%f:%.7s %.101s", p->common.item.id_hi, p->common.item.id_lo, g.lat, g.lng, p->common.postal, attr.u.str);
1935 zoff99 2 }
1936 zoff99 30 //// dbg(0,"street3=%s\n",buffer);
1937 zoff99 12 #ifdef HAVE_API_ANDROID
1938 zoff99 2 // return results to android as they come in ...
1939     android_return_search_result(jni,buffer);
1940 zoff99 12 #endif
1941 zoff99 2 }
1942 zoff99 27 phrases = g_list_next(phrases);
1943 zoff99 2 }
1944     if (buffer)
1945     {
1946     g_free(buffer);
1947     }
1948     search_list_street_destroy(p);
1949 zoff99 27 }
1950     }
1951 zoff99 2
1952 zoff99 27 if (item_attr_get(item, attr_street_name_match, &attr))
1953     {
1954 zoff99 30 //// dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
1955 zoff99 27
1956     p = search_list_street_new(item);
1957     char *buffer = NULL;
1958     // coords of result
1959     struct coord_geo g;
1960     struct coord c;
1961     c.x = p->common.c->x;
1962     c.y = p->common.c->y;
1963     int calc_geo = 0;
1964    
1965     phrases = phrases_first;
1966     while (phrases)
1967     {
1968 zoff99 28 if (offline_search_break_searching == 1)
1969     {
1970     break;
1971     }
1972    
1973 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
1974     {
1975     if (calc_geo == 0)
1976     {
1977     transform_to_geo(p->common.c->pro, &c, &g);
1978     calc_geo = 1;
1979     }
1980     if (p->common.postal == NULL)
1981     {
1982     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);
1983     }
1984     else
1985     {
1986     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);
1987     }
1988     #ifdef HAVE_API_ANDROID
1989     // return results to android as they come in ...
1990     android_return_search_result(jni,buffer);
1991     #endif
1992     }
1993     phrases = g_list_next(phrases);
1994 zoff99 2 }
1995 zoff99 27 if (buffer)
1996     {
1997     g_free(buffer);
1998     }
1999     search_list_street_destroy(p);
2000    
2001 zoff99 2 }
2002 zoff99 27
2003     if (item_attr_get(item, attr_street_name_systematic, &attr))
2004     {
2005 zoff99 30 //// dbg(0,"street systematic=%s\n",map_convert_string(item->map, attr.u.str));
2006 zoff99 27
2007     p = search_list_street_new(item);
2008     char *buffer = NULL;
2009     // coords of result
2010     struct coord_geo g;
2011     struct coord c;
2012     c.x = p->common.c->x;
2013     c.y = p->common.c->y;
2014     int calc_geo = 0;
2015    
2016     phrases = phrases_first;
2017     while (phrases)
2018     {
2019 zoff99 28 if (offline_search_break_searching == 1)
2020     {
2021     break;
2022     }
2023    
2024 zoff99 27 if (!ascii_cmp_local(attr.u.str, phrases->data, partial))
2025     {
2026     if (calc_geo == 0)
2027     {
2028     transform_to_geo(p->common.c->pro, &c, &g);
2029     calc_geo = 1;
2030     }
2031     if (p->common.postal == NULL)
2032     {
2033     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);
2034     }
2035     else
2036     {
2037     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);
2038     }
2039     #ifdef HAVE_API_ANDROID
2040     // return results to android as they come in ...
2041     android_return_search_result(jni,buffer);
2042     #endif
2043     }
2044     phrases = g_list_next(phrases);
2045     }
2046     if (buffer)
2047     {
2048     g_free(buffer);
2049     }
2050     search_list_street_destroy(p);
2051    
2052     }
2053     }
2054 zoff99 2 }
2055     g_free(streetname_last);
2056     map_rect_destroy(mr);
2057     }
2058     }
2059     }
2060     }
2061     }
2062    
2063     map_selection_destroy(sel);
2064    
2065     if (phrases)
2066     {
2067     g_list_free(phrases);
2068     }
2069     g_free(str);
2070    
2071     mapset_close(msh);
2072 zoff99 31
2073     #ifdef DEBUG_GLIB_MEM_FUNCTIONS
2074     g_mem_profile();
2075     #endif
2076 zoff99 2 }
2077    
2078     GList *
2079 zoff99 27 search_by_address(GList *result_list, struct mapset *ms, char *addr, int partial, struct jni_object *jni, int search_country_flags, char *search_country_string)
2080 zoff99 2 {
2081 zoff99 27 char *str = search_fix_spaces(addr);
2082     GList *tmp, *phrases = search_split_phrases(str);
2083 zoff99 2 GList *phrases_first;
2084     GList *ret = NULL;
2085     struct search_list *sl;
2086     struct attr attr;
2087 zoff99 27 attr.type = attr_country_all;
2088     tmp = phrases;
2089     phrases_first = phrases;
2090     sl = search_list_new(ms);
2091 zoff99 2
2092 zoff99 30 // dbg(0, "-- START --\n");
2093 zoff99 2
2094     // normal search stuff -------- START ----------
2095     if (search_country_flags == 1)
2096     {
2097 zoff99 30 // dbg(0, "-- country default start --\n");
2098 zoff99 15 //while (phrases)
2099     //{
2100 zoff99 30 // // dbg(0,"s=%s\n",phrases->data);
2101 zoff99 27 // set default country
2102     search_list_search(sl, country_default(), 0);
2103     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2104     // phrases=g_list_next(phrases);
2105 zoff99 15 //}
2106 zoff99 30 // dbg(0, "-- country default end --\n");
2107 zoff99 2 }
2108     else if (search_country_flags == 2)
2109     {
2110 zoff99 30 // dbg(0, "-- country sel:%s start --\n", search_country_string);
2111 zoff99 2 // set a country
2112     struct attr country;
2113 zoff99 27 country.type = attr_country_iso2;
2114     country.u.str = search_country_string;
2115 zoff99 15 //while (phrases)
2116     //{
2117 zoff99 30 // // dbg(0,"s=%s\n",phrases->data);
2118 zoff99 27 search_list_search(sl, &country, 0);
2119     // set a country
2120     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2121     //phrases=g_list_next(phrases);
2122 zoff99 15 //}
2123 zoff99 30 // dbg(0, "-- country sel:%s end --\n", search_country_string);
2124 zoff99 2 }
2125     else // flags==3
2126     {
2127 zoff99 30 // dbg(0, "-- country all start --\n");
2128 zoff99 2 // search all countries!! could take a really long time!!
2129     struct attr country;
2130 zoff99 27 int j2 = sizeof(all_country_list) / sizeof(all_country_list[0]);
2131 zoff99 2 int j1;
2132 zoff99 27 for (j1 = 0; j1 < j2; j1++)
2133 zoff99 2 {
2134     if (all_country_list[j1].iso2 != NULL)
2135     {
2136 zoff99 27 phrases = phrases_first;
2137 zoff99 15 //while (phrases)
2138     //{
2139 zoff99 30 // // dbg(0,"s country=%s\n",all_country_list[j1].iso2);
2140     // // dbg(0,"s=%s\n",phrases->data);
2141 zoff99 27 country.type = attr_country_iso2;
2142     country.u.str = all_country_list[j1].iso2;
2143     search_list_search(sl, &country, 0);
2144     ret = search_address__country(ret, sl, phrases, NULL, partial, jni);
2145     //phrases=g_list_next(phrases);
2146 zoff99 15 //}
2147    
2148 zoff99 27 if (offline_search_break_searching == 1)
2149 zoff99 15 {
2150     break;
2151 zoff99 2 }
2152     }
2153     }
2154 zoff99 30 // dbg(0, "-- country all end --\n");
2155 zoff99 2 }
2156     // normal search stuff -------- END ----------
2157    
2158     if (phrases_first)
2159     {
2160     g_list_free(phrases_first);
2161     }
2162    
2163 zoff99 30 // dbg(0, "-- END --\n");
2164 zoff99 2
2165     g_free(str);
2166     return ret;
2167     }
2168    
2169 zoff99 31 // IN_BUF_SIZE2 is the size of the file read buffer.
2170     // IN_BUF_SIZE2 must be >= 1
2171     //#define IN_BUF_SIZE2 (1024*16)
2172     int IN_BUF_SIZE2 = sizeof(struct streets_index_data_block) * 1024;
2173     int t_IN_BUF_SIZE2 = sizeof(struct town_index_data_block) * 1024;
2174     static uint8 s_inbuf[(sizeof(struct streets_index_data_block) * 1024)];
2175     static uint8 t_s_inbuf[(sizeof(struct town_index_data_block) * 1024)];
2176     //static uint8 s_inbuf[IN_BUF_SIZE2];
2177    
2178     // OUT_BUF_SIZE2 is the size of the output buffer used during decompression.
2179     // OUT_BUF_SIZE2 must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor
2180     // not only writes, but reads from the output buffer as it decompresses)
2181     //#define OUT_BUF_SIZE2 (TINFL_LZ_DICT_SIZE)
2182     //#define OUT_BUF_SIZE2 (1024*32)
2183     int OUT_BUF_SIZE2 = sizeof(struct streets_index_data_block) * 1024;
2184     int t_OUT_BUF_SIZE2 = sizeof(struct town_index_data_block) * 1024;
2185     static uint8 s_outbuf[(sizeof(struct streets_index_data_block) * 1024)];
2186     static uint8 t_s_outbuf[(sizeof(struct town_index_data_block) * 1024)];
2187     //static uint8 s_outbuf[OUT_BUF_SIZE2];
2188    
2189     static long long street_index_size = 0; // this is the offset for town index start
2190     // street index starts at "+sizeof(long long)"
2191    
2192     #define my_min(a,b) (((a) < (b)) ? (a) : (b))
2193     #define NUMBER_OF_TOWNS_TO_CACHE 10
2194    
2195     static struct town_index_data_block_c *town_lookup_cache = NULL;
2196     static struct town_index_data_block_c *town_lookup_cache_cur = NULL;
2197     static struct town_index_data_block_c *town_lookup_cache_found = NULL;
2198     static int town_lookup_cache_items = 0;
2199     static int town_lookup_cache_cur_item = 0;
2200    
2201     void town_index_init_cache()
2202     {
2203     int s = sizeof(struct town_index_data_block_c) * NUMBER_OF_TOWNS_TO_CACHE;
2204     // dbg(0, "cache size=%d\n", s);
2205    
2206     town_lookup_cache = g_malloc(s);
2207     town_lookup_cache_cur = town_lookup_cache;
2208     town_lookup_cache_found = NULL;
2209     town_lookup_cache_items = 0;
2210     town_lookup_cache_cur_item = 0;
2211     }
2212    
2213     void town_index_insert_cache(struct town_index_data_block* t, char* townname_long)
2214     {
2215     if (town_lookup_cache_items < NUMBER_OF_TOWNS_TO_CACHE)
2216     {
2217     // fill up cache until all slots are filled
2218     town_lookup_cache_cur->town_id = t->town_id;
2219     town_lookup_cache_cur->country_id = t->country_id;
2220     sprintf(town_lookup_cache_cur->town_name, "%s", townname_long);
2221     town_lookup_cache_items++;
2222     }
2223     else
2224     {
2225     // just fill cache and rotate if at end
2226     town_lookup_cache_cur->town_id = t->town_id;
2227     town_lookup_cache_cur->country_id = t->country_id;
2228     sprintf(town_lookup_cache_cur->town_name, "%s", townname_long);
2229     }
2230    
2231     if (town_lookup_cache_items == NUMBER_OF_TOWNS_TO_CACHE)
2232     {
2233     town_lookup_cache_cur_item = 0;
2234     town_lookup_cache_cur = town_lookup_cache;
2235     }
2236     else
2237     {
2238     town_lookup_cache_cur_item++;
2239     town_lookup_cache_cur++;
2240     }
2241     }
2242    
2243     int town_index_lookup_cache(long long townid)
2244     {
2245     int i;
2246     struct town_index_data_block_c* t;
2247    
2248     if (town_lookup_cache_items < 1)
2249     {
2250     return 0;
2251     }
2252    
2253     t = town_lookup_cache;
2254     for (i = 0; i < town_lookup_cache_items; i++)
2255     {
2256     if (t->town_id == townid)
2257     {
2258     // set pointer to found datablock
2259     town_lookup_cache_found = t;
2260     return 1;
2261     }
2262     t++;
2263     }
2264    
2265     return 0;
2266     }
2267    
2268     char* town_index_lookup(struct street_index_head *sih, long long townid)
2269     {
2270     char *townname = NULL;
2271     char *townname2 = NULL;
2272     int found = 0;
2273     int i;
2274     int split = 0;
2275     int split_count = 0;
2276     long long save_town_id;
2277     int save_country_id;
2278    
2279     if (townid == 0)
2280     {
2281     return townname;
2282     }
2283    
2284     if (town_lookup_cache == NULL)
2285     {
2286     town_index_init_cache();
2287     }
2288    
2289     if (town_index_lookup_cache(townid) == 1)
2290     {
2291     townname = g_strdup_printf("%s", town_lookup_cache_found->town_name);
2292     return townname;
2293     }
2294    
2295     sih->ti_ib = sih->ti_ib_mem;
2296    
2297     // find townid block
2298     found = sih->ti_ibs.count_of_index_blocks - 1; // set to last block
2299     for (i = 0; i < sih->ti_ibs.count_of_index_blocks; i++)
2300     {
2301     //dbg(0, "i=%d %lld %lld\n", i, townid, sih->ti_ib->first_id);
2302    
2303     if (townid < sih->ti_ib->first_id)
2304     {
2305     found = i - 1;
2306     break;
2307     }
2308    
2309     sih->ti_ib++;
2310     }
2311    
2312     if (found != -1)
2313     {
2314     //dbg(0, "found town block num=%d\n", found);
2315    
2316     town_index_setpos(sih, found); // move to correct index block
2317    
2318     while (town_index_read_data(sih))
2319     {
2320     if (offline_search_break_searching == 1)
2321     {
2322     break;
2323     }
2324    
2325     //dbg(0, "id=%lld\n", sih->ti_db_ptr->town_id);
2326    
2327     if (sih->ti_db_ptr->town_id == townid)
2328     {
2329     townname = g_strdup_printf("%s", sih->ti_db_ptr->town_name);
2330     //dbg(0,"found town:%s\n", townname);
2331     save_town_id = sih->ti_db_ptr->town_id;
2332     save_country_id = sih->ti_db_ptr->country_id;
2333     split = 1;
2334     split_count = 0;
2335     while ((town_index_read_data(sih))&&(split == 1))
2336     {
2337     split_count++;
2338     if ((split_count + 1) > MAX_TOWNNAME_SPLIT)
2339     {
2340     break;
2341     }
2342    
2343     if (sih->ti_db_ptr->town_id == 0)
2344     {
2345     //dbg(0," town-split:%s\n", sih->ti_db_ptr->town_name);
2346     townname2 = g_strdup_printf("%s%s", townname, sih->ti_db_ptr->town_name);
2347     g_free(townname);
2348     townname = townname2;
2349     }
2350     else
2351     {
2352     split = 0;
2353     }
2354     }
2355     break;
2356     }
2357     }
2358     }
2359    
2360     if (townname != NULL)
2361     {
2362     sih->ti_db_ptr->town_id = save_town_id; // set town and country to values before we read the "split"-blocks!
2363     sih->ti_db_ptr->country_id = save_country_id;
2364     town_index_insert_cache(sih->ti_db_ptr, townname);
2365     }
2366    
2367     //dbg(0, "return\n");
2368    
2369     return townname;
2370     }
2371    
2372     struct street_index_head* street_index_init(const char* idxfile_name)
2373     {
2374     struct street_index_head *ret=g_new0(struct street_index_head, 1);
2375     long s1;
2376     int b;
2377     char *index_file;
2378    
2379     index_file = g_strdup_printf("%s%s", navit_maps_dir, idxfile_name);
2380     ret->sif = fopen(index_file, "rb");
2381     g_free(index_file);
2382    
2383     fread(&street_index_size, sizeof(struct streets_index_index_block_start), 1, ret->sif);
2384     //dbg(0, "street_index_size=%lld\n", street_index_size);
2385    
2386     b = fread(&ret->si_ibs, sizeof(struct streets_index_index_block_start), 1, ret->sif);
2387     //dbg(0, "ftell=%d\n", ftell(ret->sif));
2388     //dbg(0, "items read=%d\n", b);
2389    
2390     //dbg(0, "struct size=%d\n", sizeof(struct streets_index_data_block));
2391    
2392     //dbg(0, "index entries=%d\n", ret->si_ibs.count_of_index_blocks);
2393     //dbg(0, "index entry size=%d\n", sizeof(struct streets_index_index_block));
2394     s1 = sizeof(struct streets_index_index_block) * ret->si_ibs.count_of_index_blocks;
2395     //dbg(0, "s1=%ld\n", s1);
2396    
2397     ret->si_ib_mem = g_malloc(s1);
2398     ret->si_ib = ret->si_ib_mem;
2399    
2400     ret->comp_status = 0;
2401     ret->t_comp_status = 0;
2402    
2403     //dbg(0, "ftell=%d\n", ftell(ret->sif));
2404     fread(ret->si_ib_mem, sizeof(struct streets_index_index_block), ret->si_ibs.count_of_index_blocks, ret->sif);
2405     //dbg(0, "ftell=%d\n", ftell(ret->sif));
2406    
2407     //dbg(0, "len=%lld\n", ret->si_ib->len);
2408     //dbg(0, "offset=%lld\n", ret->si_ib->offset);
2409    
2410     fseek(ret->sif, street_index_size + sizeof(long long), SEEK_SET); // seek to townindex header
2411     fread(&ret->ti_ibs, sizeof(struct town_index_index_block_start), 1, ret->sif);
2412     //dbg(0, "len=%lld\n", ret->ti_ibs.count_of_index_blocks);
2413    
2414     //dbg(0, "town index entries=%d\n", ret->ti_ibs.count_of_index_blocks);
2415     //dbg(0, "town index entry size=%d\n", sizeof(struct town_index_index_block));
2416     s1 = sizeof(struct town_index_index_block) * ret->ti_ibs.count_of_index_blocks;
2417     //dbg(0, "s1=%ld\n", s1);
2418    
2419     ret->ti_ib_mem = g_malloc(s1);
2420     ret->ti_ib = ret->ti_ib_mem;
2421    
2422     //dbg(0, "ftell=%d\n", ftell(ret->sif));
2423     fread(ret->ti_ib_mem, sizeof(struct town_index_index_block), ret->ti_ibs.count_of_index_blocks, ret->sif);
2424     //dbg(0, "ftell=%d\n", ftell(ret->sif));
2425    
2426     //dbg(0, "town len=%lld\n", ret->ti_ib->len);
2427     //dbg(0, "town offset=%lld\n", ret->ti_ib->offset);
2428    
2429     return ret;
2430     }
2431    
2432     void town_index_setpos(struct street_index_head *sih, int town_data_block_num)
2433     {
2434     if (sih->t_comp_status == 1)
2435     {
2436     town_index_close_compr(sih);
2437     }
2438    
2439     sih->ti_ib = (sih->ti_ib_mem + town_data_block_num);
2440    
2441     town_index_init_compr(sih, sih->ti_ib->len);
2442    
2443     //dbg(0, "len=%lld\n", sih->ti_ib->len);
2444     //dbg(0, "fid=%lld\n", sih->ti_ib->first_id);
2445     //dbg(0, "off=%lld\n", sih->ti_ib->offset);
2446    
2447     // if (sih->ti_ib->len >= sizeof(struct town_index_data_block))
2448     if (sih->ti_ib->len > 1)
2449     {
2450     //dbg(0, "fpos1=%d\n", ftell(sih->sif));
2451     fseek(sih->sif, sih->ti_ib->offset + sizeof(long long) + street_index_size, SEEK_SET);
2452     //dbg(0, "fpos2=%d\n", ftell(sih->sif));
2453    
2454     sih->t_data_count = 0;
2455     // move ptr to first data
2456     sih->ti_db_ptr = t_s_outbuf;
2457     }
2458    
2459     }
2460    
2461     void street_index_setpos(struct street_index_head *sih, int data_block_num)
2462     {
2463    
2464     if (sih->comp_status == 1)
2465     {
2466     street_index_close_compr(sih);
2467     }
2468    
2469     sih->si_ib = (sih->si_ib_mem + data_block_num);
2470    
2471     //dbg(0, "len=%lld\n", sih->si_ib->len);
2472     //dbg(0, "fl=%c off=%lld\n", sih->si_ib->first_letter, sih->si_ib->offset);
2473    
2474     street_index_init_compr(sih, sih->si_ib->len);
2475    
2476     //if (sih->si_ib->len >= sizeof(struct streets_index_data_block))
2477     if (sih->si_ib->len > 1) // what is the minimum compressed block size? (about 55 bytes now)
2478     {
2479     //dbg(0, "mem start=%d, cur pos=%d\n", sih->si_ib_mem, sih->si_ib);
2480     //dbg(0, "file offset=%d\n", sih->si_ib->offset);
2481     //dbg(0, "fpos s1=%d\n", ftell(sih->sif));
2482     fseek(sih->sif, sih->si_ib->offset + sizeof(long long), SEEK_SET); // add the "long long" from start of file to offset
2483     //dbg(0, "fpos s2=%d\n", ftell(sih->sif));
2484    
2485     sih->data_count = 0;
2486     // move ptr to first data
2487     sih->si_db_ptr = s_outbuf;
2488     }
2489     }
2490    
2491     int street_index_read_data(struct street_index_head *sih)
2492     {
2493     // fread(&sih->si_db, sizeof(struct streets_index_data_block), 1, sih->sif);
2494    
2495    
2496     //if (sih->si_ib->len < sizeof(struct streets_index_data_block))
2497     if (sih->si_ib->len <= 1) // minimum size of compressed block?
2498     {
2499     //dbg(0, "len=%d sof=%d\n", sih->si_ib->len, sizeof(struct streets_index_data_block));
2500     // no data for this letter
2501     return 0;
2502     }
2503    
2504     if (sih->data_count == 0)
2505     {
2506     // init
2507     sih->next_out = s_outbuf;
2508     sih->avail_out = OUT_BUF_SIZE2;
2509    
2510     // read data
2511     sih->data_count = street_index_decompress_data_block(sih);
2512     //dbg(0, "stat=%d\n", sih->data_count);
2513    
2514     if (sih->data_count <= 0)
2515     {
2516     // end of data
2517     return 0;
2518     }
2519    
2520     // move ptr to next data
2521     sih->si_db_ptr = s_outbuf;
2522     }
2523     else
2524     {
2525     sih->data_count = sih->data_count - sizeof(struct streets_index_data_block);
2526    
2527     if (sih->data_count > 0)
2528     {
2529     sih->si_db_ptr++;
2530     //dbg(0, "dc=%d ptr=%p\n", sih->data_count, sih->si_db_ptr);
2531     }
2532     else
2533     {
2534     // init
2535     sih->next_out = s_outbuf;
2536     sih->avail_out = OUT_BUF_SIZE2;
2537    
2538     // read data
2539     sih->data_count = street_index_decompress_data_block(sih);
2540     //dbg(0, "stat2=%d\n", sih->data_count);
2541    
2542     if (sih->data_count <= 0)
2543     {
2544     // end of data
2545     return 0;
2546     }
2547    
2548     // move ptr to next data
2549     sih->si_db_ptr = s_outbuf;
2550     }
2551     }
2552    
2553     //dbg(0, "data=%s, %d, %d, %lld\n", sih->si_db_ptr->street_name, sih->si_db_ptr->lat, sih->si_db_ptr->lon, sih->si_db_ptr->town_id);
2554    
2555     return 1;
2556    
2557     //if (ftell(sih->sif) > (sih->si_ib->offset + sih->si_ib->len))
2558     //{
2559     // // end of data
2560     // return 0;
2561     //}
2562    
2563     // more data found
2564     // return 1;
2565     }
2566    
2567     int town_index_read_data(struct street_index_head *sih)
2568     {
2569     // fread(&sih->si_db, sizeof(struct streets_index_data_block), 1, sih->sif);
2570    
2571    
2572     // if (sih->ti_ib->len < sizeof(struct town_index_data_block))
2573     if (sih->ti_ib->len <= 1)
2574     {
2575     // no data for this block
2576     //fprintf(stderr, "no data for this block\n");
2577     return 0;
2578     }
2579    
2580     if (sih->t_data_count == 0)
2581     {
2582     // init
2583     sih->t_next_out = t_s_outbuf;
2584     sih->t_avail_out = t_OUT_BUF_SIZE2;
2585    
2586     // read data
2587     sih->t_data_count = town_index_decompress_data_block(sih);
2588     //dbg(0, "stat=%d\n", sih->data_count);
2589    
2590     if (sih->t_data_count <= 0)
2591     {
2592     // end of data
2593     //fprintf(stderr, "end of data\n");
2594     return 0;
2595     }
2596    
2597     // move ptr to next data
2598     sih->ti_db_ptr = t_s_outbuf;
2599     }
2600     else
2601     {
2602     sih->t_data_count = sih->t_data_count - sizeof(struct town_index_data_block);
2603    
2604     if (sih->t_data_count > 0)
2605     {
2606     sih->ti_db_ptr++;
2607     //dbg(0, "dc=%d ptr=%p\n", sih->data_count, sih->si_db_ptr);
2608     }
2609     else
2610     {
2611     // init
2612     sih->t_next_out = t_s_outbuf;
2613     sih->t_avail_out = t_OUT_BUF_SIZE2;
2614    
2615     // read data
2616     sih->t_data_count = town_index_decompress_data_block(sih);
2617     //dbg(0, "stat2=%d\n", sih->data_count);
2618    
2619     if (sih->t_data_count <= 0)
2620     {
2621     // end of data
2622     //fprintf(stderr, "end of data (2)\n");
2623     return 0;
2624     }
2625    
2626     // move ptr to next data
2627     sih->ti_db_ptr = t_s_outbuf;
2628     }
2629     }
2630    
2631     //dbg(0, "data=%s, %d, %d, %lld\n", sih->si_db_ptr->street_name, sih->si_db_ptr->lat, sih->si_db_ptr->lon, sih->si_db_ptr->town_id);
2632    
2633     return 1;
2634    
2635     //if (ftell(sih->sif) > (sih->si_ib->offset + sih->si_ib->len))
2636     //{
2637     // // end of data
2638     // return 0;
2639     //}
2640    
2641     // more data found
2642     // return 1;
2643     }
2644    
2645     void street_index_close_compr(struct street_index_head *sih)
2646     {
2647     g_free(sih->inflator);
2648     sih->comp_status = 2;
2649     }
2650    
2651     void town_index_close_compr(struct street_index_head *sih)
2652     {
2653     g_free(sih->t_inflator);
2654     sih->t_comp_status = 2;
2655     }
2656    
2657     void street_index_init_compr(struct street_index_head *sih, long long size)
2658     {
2659     // decompress structure
2660     sih->inflator = g_new0(tinfl_decompressor, 1);
2661     sih->comp_status = 1;
2662     // decompress structure
2663    
2664     // Decompression.
2665     sih->infile_size = (uint) size;
2666     sih->infile_remaining = sih->infile_size;
2667    
2668     sih->next_in = s_inbuf;
2669     sih->avail_in = 0;
2670     sih->next_out = s_outbuf;
2671     sih->avail_out = OUT_BUF_SIZE2;
2672    
2673     sih->data_count = 0;
2674    
2675     tinfl_init(sih->inflator);
2676     }
2677    
2678     void town_index_init_compr(struct street_index_head *sih, long long size)
2679     {
2680     // decompress structure
2681     sih->t_inflator = g_new0(tinfl_decompressor, 1);
2682     sih->t_comp_status = 1;
2683     // decompress structure
2684    
2685     // Decompression.
2686     sih->t_infile_size = (uint) size;
2687     sih->t_infile_remaining = sih->t_infile_size;
2688    
2689     sih->t_next_in = t_s_inbuf;
2690     sih->t_avail_in = 0;
2691     sih->t_next_out = t_s_outbuf;
2692     sih->t_avail_out = t_OUT_BUF_SIZE2;
2693    
2694     sih->t_data_count = 0;
2695    
2696     tinfl_init(sih->t_inflator);
2697     }
2698    
2699     int street_index_decompress_data_block(struct street_index_head *sih)
2700     {
2701     // size_t total_in = 0, total_out = 0;
2702     // long file_loc;
2703    
2704     // Decompression.
2705     for (;;)
2706     {
2707     sih->in_bytes = 0;
2708     sih->out_bytes = 0;
2709     if (!sih->avail_in)
2710     {
2711     // Input buffer is empty, so read more bytes from input file.
2712     uint n = my_min(IN_BUF_SIZE2, sih->infile_remaining);
2713    
2714     //dbg(0, "reading bytes:%d remain=%d\n", n, sih->infile_remaining);
2715    
2716     if (fread(s_inbuf, 1, n, sih->sif) != n)
2717     {
2718     //printf("Failed reading from input file!\n");
2719     dbg(0, "Failed reading from input file!\n");
2720     //g_free(sih->inflator);
2721     return -1;
2722     }
2723    
2724     sih->next_in = s_inbuf;
2725     sih->avail_in = n;
2726    
2727     sih->infile_remaining -= n;
2728     }
2729    
2730     sih->in_bytes = sih->avail_in;
2731     sih->out_bytes = sih->avail_out;
2732     sih->miniz_status = tinfl_decompress(sih->inflator, (const mz_uint8 *) sih->next_in, &sih->in_bytes, s_outbuf, (mz_uint8 *) sih->next_out, &sih->out_bytes, (sih->infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER);
2733    
2734     sih->avail_in -= sih->in_bytes;
2735     sih->next_in = (const mz_uint8 *) sih->next_in + sih->in_bytes;
2736     //total_in += sih->in_bytes;
2737    
2738     sih->avail_out -= sih->out_bytes;
2739     sih->next_out = (mz_uint8 *) sih->next_out + sih->out_bytes;
2740     //total_out += sih->out_bytes;
2741    
2742     if ((sih->miniz_status <= TINFL_STATUS_DONE) || (!sih->avail_out))
2743     {
2744     // Output buffer is full, or decompression is done, so write buffer to output file.
2745     uint n = OUT_BUF_SIZE2 - (uint) sih->avail_out;
2746    
2747     //dbg(0, "decompr: start=%p len=%d\n", (void *) sih->next_out, (int) n);
2748     //dbg(0, "decompr: start=%p len=%d\n", (void *) s_outbuf, (int) n);
2749     //dbg(0, "decompr: av in=%d av out=%d\n", sih->avail_in, sih->avail_out);
2750     //dbg(0, "decompr: nx in=%d nx out=%d\n", sih->next_in, sih->next_out);
2751    
2752     //struct streets_index_data_block *tmp = (struct streets_index_data_block *)s_outbuf;
2753     //dbg(0,"data=%s, %d, %d, %lld\n", tmp->street_name, tmp->lat, tmp->lon, tmp->town_id);
2754    
2755     //sih->next_out = s_outbuf;
2756     //sih->avail_out = OUT_BUF_SIZE2;
2757    
2758     return (int) n;
2759    
2760     //if (fwrite(s_outbuf, 1, n, pOutfile) != n)
2761     //{
2762     // // printf("Failed writing to output file!\n");
2763     // //g_free(inflator);
2764     // return;
2765     //}
2766     }
2767    
2768     // If sih->miniz_status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong.
2769     if (sih->miniz_status <= TINFL_STATUS_DONE)
2770     {
2771     if (sih->miniz_status == TINFL_STATUS_DONE)
2772     {
2773     // Decompression completed successfully.
2774     //dbg(0, "Decompression completed successfully\n");
2775     //break;
2776     return -2;
2777     }
2778     else
2779     {
2780     // Decompression failed.
2781     //printf("tinfl_decompress() failed with status %i!\n", sih->miniz_status);
2782     dbg(0, "tinfl_decompress() failed with status %i!\n", sih->miniz_status);
2783    
2784     //g_free(inflator);
2785     return -1;
2786     }
2787     }
2788     }
2789    
2790     //g_free(inflator);
2791     return -3;
2792    
2793     }
2794    
2795     int town_index_decompress_data_block(struct street_index_head *sih)
2796     {
2797     // size_t total_in = 0, total_out = 0;
2798     // long file_loc;
2799    
2800     // Decompression.
2801     for (;;)
2802     {
2803     sih->t_in_bytes = 0;
2804     sih->t_out_bytes = 0;
2805     if (!sih->t_avail_in)
2806     {
2807     // Input buffer is empty, so read more bytes from input file.
2808     uint n = my_min(t_IN_BUF_SIZE2, sih->t_infile_remaining);
2809    
2810     //dbg(0, "reading bytes:%d remain=%d\n", n, sih->t_infile_remaining);
2811    
2812     if (fread(t_s_inbuf, 1, n, sih->sif) != n)
2813     {
2814     //printf("Failed reading from input file!\n");
2815     dbg(0, "Failed reading from input file!\n");
2816     //g_free(sih->inflator);
2817     return -1;
2818     }
2819    
2820     sih->t_next_in = t_s_inbuf;
2821     sih->t_avail_in = n;
2822    
2823     sih->t_infile_remaining -= n;
2824     }
2825    
2826     sih->t_in_bytes = sih->t_avail_in;
2827     sih->t_out_bytes = sih->t_avail_out;
2828     sih->t_miniz_status = tinfl_decompress(sih->t_inflator, (const mz_uint8 *) sih->t_next_in, &sih->t_in_bytes, t_s_outbuf, (mz_uint8 *) sih->t_next_out, &sih->t_out_bytes, (sih->t_infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER);
2829    
2830     sih->t_avail_in -= sih->t_in_bytes;
2831     sih->t_next_in = (const mz_uint8 *) sih->t_next_in + sih->t_in_bytes;
2832     //total_in += sih->in_bytes;
2833    
2834     sih->t_avail_out -= sih->t_out_bytes;
2835     sih->t_next_out = (mz_uint8 *) sih->t_next_out + sih->t_out_bytes;
2836     //total_out += sih->out_bytes;
2837    
2838     if ((sih->t_miniz_status <= TINFL_STATUS_DONE) || (!sih->t_avail_out))
2839     {
2840     // Output buffer is full, or decompression is done, so write buffer to output file.
2841     uint n = t_OUT_BUF_SIZE2 - (uint) sih->t_avail_out;
2842    
2843     //dbg(0, "decompr: start=%p len=%d\n", (void *) sih->next_out, (int) n);
2844     //dbg(0, "decompr: start=%p len=%d\n", (void *) s_outbuf, (int) n);
2845     //dbg(0, "decompr: av in=%d av out=%d\n", sih->avail_in, sih->avail_out);
2846     //dbg(0, "decompr: nx in=%d nx out=%d\n", sih->next_in, sih->next_out);
2847    
2848     //struct town_index_data_block *tmpt = (struct town_index_data_block *)t_s_outbuf;
2849     //dbg(0,"data=%lld %s\n", tmpt->town_id, tmpt->town_name);
2850    
2851     //sih->next_out = s_outbuf;
2852     //sih->avail_out = t_OUT_BUF_SIZE2;
2853    
2854     return (int) n;
2855    
2856     //if (fwrite(s_outbuf, 1, n, pOutfile) != n)
2857     //{
2858     // // printf("Failed writing to output file!\n");
2859     // //g_free(inflator);
2860     // return;
2861     //}
2862     }
2863    
2864     // If sih->miniz_status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong.
2865     if (sih->t_miniz_status <= TINFL_STATUS_DONE)
2866     {
2867     if (sih->t_miniz_status == TINFL_STATUS_DONE)
2868     {
2869     // Decompression completed successfully.
2870     //dbg(0, "Decompression completed successfully\n");
2871     //break;
2872     return -2;
2873     }
2874     else
2875     {
2876     // Decompression failed.
2877     //printf("tinfl_decompress() failed with status %i!\n", sih->miniz_status);
2878     dbg(0, "tinfl_decompress() failed with status %i!\n", sih->t_miniz_status);
2879    
2880     //g_free(inflator);
2881     return -1;
2882     }
2883     }
2884     }
2885    
2886     //g_free(inflator);
2887     return -3;
2888    
2889     }
2890    
2891     void street_index_close(struct street_index_head *sih)
2892     {
2893     g_free(sih->si_ib_mem);
2894     g_free(sih->ti_ib_mem);
2895     if (town_lookup_cache)
2896     {
2897     g_free(town_lookup_cache);
2898     town_lookup_cache = NULL;
2899     }
2900     fclose(sih->sif);
2901     g_free(sih);
2902     }
2903    
2904    
2905     // func defs
2906     void search_v2_work(char *addr, char *town, char* hn, int partial, struct jni_object *jni, const char* idxfile_name);
2907     void search_v2(char *addr, char *town, char* hn, int partial, struct jni_object *jni);
2908     // func defs
2909    
2910    
2911     #include <sys/types.h>
2912     #include <dirent.h>
2913    
2914     void search_v2(char *addr, char *town, char* hn, int partial, struct jni_object *jni)
2915     {
2916     int len;
2917     int len2;
2918     int len3;
2919     char *last_four;
2920     DIR* dirp;
2921     struct dirent *dp;
2922    
2923     len2 = strlen("navitmap_");
2924     len = len2 + 11; // should be 21 'navitmap_0%%.bin.idx'
2925    
2926     // look for all the navitmap_0**.bin.idx files in mapdir, then call search in all of them
2927     dirp = opendir(navit_maps_dir);
2928     while ((dp = readdir(dirp)) != NULL)
2929     {
2930     if ((strlen(dp->d_name) == len) && (!strncmp(dp->d_name, "navitmap_", len2)))
2931     {
2932     //dbg(0, "2 file=%s\n", dp->d_name);
2933     len3 = strlen(dp->d_name);
2934     last_four = &dp->d_name[len3-4];
2935     //dbg(0, "3 l4=%s\n", last_four);
2936     if (!strcmp(last_four, ".idx"))
2937     {
2938     search_v2_work(addr, town, hn, partial, jni, dp->d_name);
2939     }
2940     }
2941     }
2942     closedir(dirp);
2943    
2944     }
2945    
2946     void search_v2_work(char *addr, char *town, char* hn, int partial, struct jni_object *jni, const char* idxfile_name)
2947     {
2948     char *buffer = NULL;
2949     float lat;
2950     float lng;
2951     char *address;
2952     char *address2;
2953     char *townname = NULL;
2954     char *addr_copy;
2955     char *addr2;
2956     char *addr3;
2957     char *addr3a;
2958     char *town_fold;
2959     char *tt;
2960     int i;
2961     int j;
2962     int br;
2963     int charlen;
2964     int found;
2965     int starts_with_utf8 = 0;
2966     int nd_with_utf8 = 0;
2967     int want_result;
2968     struct coord c3;
2969     static const char *alpha = "abcdefghijklmnopqrstuvwxyz";
2970     char tmp_letter[STREET_INDEX_STREET_NAME_SIZE];
2971     struct street_index_head *sih;
2972    
2973    
2974     if ((!addr) || (strlen(addr) < 1))
2975     {
2976     return;
2977     }
2978    
2979     // prepare search string
2980     addr2 = linguistics_casefold(addr);
2981     if (addr2)
2982     {
2983     addr3 = linguistics_remove_all_specials(addr2);
2984     if (addr3)
2985     {
2986     g_free(addr2);
2987     addr2 = addr3;
2988     }
2989     addr3 = linguistics_expand_special(addr2, 1);
2990     if (addr3)
2991     {
2992     g_free(addr2);
2993     addr2 = addr3;
2994     }
2995     addr_copy = addr2;
2996     }
2997     else
2998     {
2999     addr2 = g_strdup(addr);
3000     addr_copy = addr2;
3001     }
3002    
3003     // prepare town search string
3004     town_fold = linguistics_fold_and_prepare_complete(town, 0);
3005    
3006    
3007     //dbg(0,"town=%s townfold=%s street=%s hn=%s\n", town, town_fold, addr_copy, hn);
3008    
3009     sih = street_index_init(idxfile_name);
3010    
3011     // is first letter ascii or UTF-8?
3012     addr3 = g_utf8_find_next_char(addr_copy, NULL);
3013     charlen = addr3 - addr_copy;
3014     if (charlen > 1)
3015     {
3016     starts_with_utf8 = 1;
3017     }
3018     //dbg(0, "charlen=%d starts_with_utf8=%d\n", charlen, starts_with_utf8);
3019    
3020     // is second letter ascii or UTF-8?
3021     addr3a = g_utf8_find_next_char(addr3, NULL);
3022     charlen = addr3a - addr3;
3023     if (charlen > 1)
3024     {
3025     nd_with_utf8 = 1;
3026     }
3027     //dbg(0, "charlen=%d nd_with_utf8=%d\n", charlen, nd_with_utf8);
3028    
3029    
3030     // find starting letter of search string
3031     found = (703 - 1); // 26+1 letters ((26+1)*26 + 1) = 703
3032     br = 0;
3033     if (starts_with_utf8 == 0)
3034     {
3035     // check the first letter
3036     for (i = 0; i < 26; i++)
3037     {
3038     if (addr_copy[0] == alpha[i])
3039     {
3040     if ((strlen(addr_copy) > 1) && (nd_with_utf8 == 0))
3041     {
3042     //dbg(0, "i=%d\n", i);
3043     // check the second letter
3044     for (j = 0; j < 26; j++)
3045     {
3046     //dbg(0, "j=%d\n", j);
3047     if (addr_copy[1] == alpha[j])
3048     {
3049     found = (27 * i) + j;
3050     br = 1;
3051     break;
3052     }
3053     }
3054     if (br == 0)
3055     {
3056     // second letter has no match, use generic first letter block
3057     found = (27 * i) + 26;
3058     }
3059     br = 1;
3060     break;
3061     }
3062     else
3063     {
3064     // use generic first letter block
3065     found = (27 * i) + 26;
3066     br = 1;
3067     break;
3068     }
3069     }
3070    
3071     if (br)
3072     {
3073     break;
3074     }
3075     }
3076     }
3077    
3078     //dbg(0, "found pos=%d\n", found);
3079    
3080     street_index_setpos(sih, found);
3081     int found_data = 0;
3082     //int ddd = 0;
3083    
3084     while (street_index_read_data(sih))
3085     {
3086     //ddd++;
3087    
3088     //if (ddd > 3)
3089     //{
3090     // break;
3091     //}
3092    
3093     if (offline_search_break_searching == 1)
3094     {
3095     break;
3096     }
3097    
3098     //dbg(0,"data=%s addr=%s\n", sih->si_db_ptr->street_name, addr_copy);
3099     if (!ascii_cmp_local_faster(sih->si_db_ptr->street_name, addr_copy, 1))
3100     {
3101     found_data = 1;
3102     if ((partial == 1) || (!ascii_cmp_local_faster(sih->si_db_ptr->street_name, addr_copy, partial)))
3103     {
3104     townname = town_index_lookup(sih, sih->si_db_ptr->town_id);
3105    
3106     // if we also have a search-town-name then check here
3107     if ((!town_fold)||(strlen(town_fold) < 1))
3108     {
3109     want_result = 1;
3110     }
3111     else
3112     {
3113     tt = linguistics_fold_and_prepare_complete(townname, 0);
3114     want_result = 1-(linguistics_compare_anywhere(tt, town_fold));
3115     //dbg(0, "want_result=%d tt=%s\n", want_result, tt);
3116     }
3117    
3118     if (want_result == 1)
3119     {
3120    
3121     // check for housenumber
3122     if ((hn != NULL) && (strlen(hn) > 0))
3123     {
3124     // now set coord of this item/street
3125     c3.y = sih->si_db_ptr->lat;
3126     c3.x = sih->si_db_ptr->lon;
3127     search_address_housenumber_for_street(hn, sih->si_db_ptr->street_name, townname, &c3, partial, jni);
3128     }
3129    
3130     if (townname != NULL)
3131     {
3132     address = g_strdup_printf("%s, %s", sih->si_db_ptr->street_name, townname);
3133     }
3134     else
3135     {
3136     address = g_strdup_printf("%s", sih->si_db_ptr->street_name);
3137     }
3138    
3139    
3140     if (strlen(address) > 100)
3141     {
3142     address2 = address;
3143     address2[101] = '\0';
3144     address2 = linguistics_check_utf8_string(address2);
3145     }
3146     else
3147     {
3148     address2 = address;
3149     }
3150     buffer = g_strdup_printf("STR:H0L0:%d:%d:%.101s", sih->si_db_ptr->lat, sih->si_db_ptr->lon, address2);
3151     #ifdef HAVE_API_ANDROID
3152     // return results to android as they come in ...
3153     android_return_search_result(jni, buffer);
3154     #endif
3155     if (townname)
3156     {
3157     g_free(townname);
3158     townname = NULL;
3159     }
3160    
3161     if (address)
3162     {
3163     g_free(address);
3164     address = NULL;
3165     }
3166    
3167     if (buffer)
3168     {
3169     g_free(buffer);
3170     buffer = NULL;
3171     }
3172     }
3173     }
3174     }
3175     else
3176     {
3177     if (found_data == 1)
3178     {
3179     // no more matching data, stop searching
3180     break;
3181     }
3182     }
3183     }
3184     g_free(addr_copy);
3185     street_index_close(sih);
3186    
3187     }
3188    

   
Visit the ZANavi Wiki