2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
25 #include "projection.h"
30 #include "transform.h"
33 #include "linguistics.h"
40 struct search_list_level {
42 struct search_list_common *parent;
46 struct mapset_search *search;
48 GList *list,*curr,*last;
51 struct interpolation {
53 char *first, *last, *curr;
60 struct search_list_level levels[4];
61 struct search_list_result result;
62 struct search_list_result last_result;
63 int last_result_valid;
65 struct interpolation inter;
69 search_item_hash_hash(gconstpointer key)
71 const struct item *itm=key;
72 gconstpointer hashkey=(gconstpointer)GINT_TO_POINTER(itm->id_hi^itm->id_lo);
73 return g_direct_hash(hashkey);
77 search_item_hash_equal(gconstpointer a, gconstpointer b)
79 const struct item *itm_a=a;
80 const struct item *itm_b=b;
81 if (item_is_equal_id(*itm_a, *itm_b))
87 * @brief Create new instance of search_list to run a search.
89 * @param ms mapset that is to be searched
90 * @returns new search_list
93 search_list_new(struct mapset *ms)
95 struct search_list *ret;
97 ret=g_new0(struct search_list, 1);
103 static void search_list_search_free(struct search_list *sl, int level);
106 * @brief Determine search list level for given attr_type.
107 * @param attr_type attribute value
108 * @return corresponding search list level (country=0, town=1, ...)
111 search_list_level(enum attr_type attr_type)
114 case attr_country_all:
115 case attr_country_id:
116 case attr_country_iso2:
117 case attr_country_iso3:
118 case attr_country_car:
119 case attr_country_name:
121 case attr_town_postal:
124 case attr_district_name:
125 case attr_town_or_district_name:
127 case attr_street_name:
129 case attr_house_number:
134 dbg(0,"unknown search '%s'\n",attr_to_name(attr_type));
140 interpolation_clear(struct interpolation *inter)
142 inter->mode=inter->side=0;
143 g_free(inter->first);
146 inter->first=inter->last=inter->curr=NULL;
150 * @brief Start a search.
152 * @param this search_list to use for the search
153 * @param search_attr attributes to use for the search
154 * @param partial do partial search? (1=yes,0=no)
157 search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
159 struct search_list_level *le;
160 int level=search_list_level(search_attr->type);
162 interpolation_clear(&this_->inter);
163 //dbg(0,"level=%d\n", level);
167 le=&this_->levels[level];
168 search_list_search_free(this_, level);
169 le->attr=attr_dup(search_attr);
172 le=&this_->levels[level-1];
175 //dbg(0,"le=%p partial=%d\n", le, partial);
176 } else if (search_attr->type == attr_postal) {
177 g_free(this_->postal);
178 this_->postal=g_strdup(search_attr->u.str);
182 struct search_list_common *
183 search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode)
185 int level=search_list_level(attr_type);
187 struct search_list_level *le;
188 struct search_list_common *slc;
190 le=&this_->levels[level];
194 //dbg(0,"enter level=%d %d %d %p\n", level, id, mode, curr);
197 if (! id || num == id) {
206 curr=g_list_next(curr);
208 //dbg(0,"not found\n");
213 search_list_common_new(struct item *item, struct search_list_common *common)
216 if (item_attr_get(item, attr_town_name, &attr))
217 common->town_name=map_convert_string(item->map, attr.u.str);
219 common->town_name=NULL;
220 if (item_attr_get(item, attr_county_name, &attr))
221 common->county_name=map_convert_string(item->map, attr.u.str);
223 common->county_name=NULL;
224 if (item_attr_get(item, attr_district_name, &attr))
225 common->district_name=map_convert_string(item->map, attr.u.str);
227 common->district_name=NULL;
228 if (item_attr_get(item, attr_postal, &attr))
229 common->postal=map_convert_string(item->map, attr.u.str);
230 else if (item_attr_get(item, attr_town_postal, &attr))
231 common->postal=map_convert_string(item->map, attr.u.str);
234 if (item_attr_get(item, attr_postal_mask, &attr))
235 common->postal_mask=map_convert_string(item->map, attr.u.str);
237 common->postal_mask=NULL;
241 search_list_common_destroy(struct search_list_common *common)
243 map_convert_free(common->town_name);
244 map_convert_free(common->district_name);
245 map_convert_free(common->county_name);
246 map_convert_free(common->postal);
247 map_convert_free(common->postal_mask);
250 static struct search_list_country *
251 search_list_country_new(struct item *item)
253 struct search_list_country *ret=g_new0(struct search_list_country, 1);
256 ret->common.item=ret->common.unique=*item;
257 if (item_attr_get(item, attr_country_car, &attr))
258 ret->car=g_strdup(attr.u.str);
259 if (item_attr_get(item, attr_country_iso2, &attr)) {
261 ret->iso2=g_malloc(strlen(attr.u.str)+1);
262 strtolower(ret->iso2, attr.u.str);
264 ret->iso2=g_strdup(attr.u.str);
266 ret->flag=g_strdup_printf("country_%s", ret->iso2);
268 if (item_attr_get(item, attr_country_iso3, &attr))
269 ret->iso3=g_strdup(attr.u.str);
270 if (item_attr_get(item, attr_country_name, &attr))
271 ret->name=g_strdup(attr.u.str);
276 search_list_country_destroy(struct search_list_country *this_)
286 static struct search_list_town *
287 search_list_town_new(struct item *item)
289 struct search_list_town *ret=g_new0(struct search_list_town, 1);
294 ret->common.item=ret->common.unique=*item;
295 if (item_attr_get(item, attr_town_streets_item, &attr)) {
296 dbg(1,"town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
297 ret->common.unique=*attr.u.item;
299 search_list_common_new(item, &ret->common);
300 if (item_attr_get(item, attr_county_name, &attr))
301 ret->county=map_convert_string(item->map,attr.u.str);
304 if (item_coord_get(item, &c, 1)) {
305 ret->common.c=g_new(struct pcoord, 1);
306 ret->common.c->x=c.x;
307 ret->common.c->y=c.y;
308 ret->common.c->pro = map_projection(item->map);
314 search_list_town_destroy(struct search_list_town *this_)
316 map_convert_free(this_->county);
317 search_list_common_destroy(&this_->common);
319 g_free(this_->common.c);
324 static struct search_list_street *
325 search_list_street_new(struct item *item)
327 struct search_list_street *ret=g_new0(struct search_list_street, 1);
331 ret->common.item=ret->common.unique=*item;
332 if (item_attr_get(item, attr_street_name, &attr))
333 ret->name=map_convert_string(item->map, attr.u.str);
336 search_list_common_new(item, &ret->common);
337 if (item_coord_get(item, &c, 1)) {
338 ret->common.c=g_new(struct pcoord, 1);
339 ret->common.c->x=c.x;
340 ret->common.c->y=c.y;
341 ret->common.c->pro = map_projection(item->map);
348 search_list_street_destroy(struct search_list_street *this_)
350 map_convert_free(this_->name);
351 search_list_common_destroy(&this_->common);
354 g_free(this_->common.c);
360 search_interpolate(struct interpolation *inter)
362 dbg(1,"interpolate %s-%s %s\n",inter->first,inter->last,inter->curr);
363 if (!inter->first || !inter->last)
366 inter->curr=g_strdup(inter->first);
368 if (strcmp(inter->curr, inter->last)) {
369 int next=atoi(inter->curr)+(inter->mode?2:1);
371 if (next == atoi(inter->last))
372 inter->curr=g_strdup(inter->last);
374 inter->curr=g_strdup_printf("%d",next);
380 dbg(1,"interpolate result %s\n",inter->curr);
385 search_interpolation_split(char *str, struct interpolation *inter)
387 char *pos=strchr(str,'-');
391 inter->first=g_strdup(str);
392 inter->last=g_strdup(str);
397 first=g_malloc(len+1);
398 strncpy(first, str, len);
400 last=g_strdup(pos+1);
401 dbg(1,"%s = %s - %s\n",str, first, last);
402 if (atoi(first) > atoi(last)) {
414 search_setup_interpolation(struct item *item, enum attr_type i0, enum attr_type i1, enum attr_type i2, struct interpolation *inter)
417 g_free(inter->first);
420 inter->first=inter->last=inter->curr=NULL;
421 dbg(1,"setup %s\n",attr_to_name(i0));
422 if (item_attr_get(item, i0, &attr)) {
423 search_interpolation_split(attr.u.str, inter);
425 } else if (item_attr_get(item, i1, &attr)) {
426 search_interpolation_split(attr.u.str, inter);
428 } else if (item_attr_get(item, i2, &attr)) {
429 search_interpolation_split(attr.u.str, inter);
437 search_match(char *str, char *search, int partial)
440 return (!g_strcasecmp(str, search));
442 return (!g_strncasecmp(str, search, strlen(search)));
445 static struct pcoord *
446 search_house_number_coordinate(struct item *item, struct interpolation *inter)
448 struct pcoord *ret=g_new(struct pcoord, 1);
449 ret->pro = map_projection(item->map);
450 dbg(0,"%s\n",item_to_name(item->type));
451 if (item->type<type_house_number_interpolation_even || item->type>type_house_number_interpolation_alphabetic) {
453 if (item_coord_get(item, &c, 1)) {
462 int hn_pos,hn_length;
463 struct coord *c=g_alloca(sizeof(struct coord)*max);
464 item_coord_rewind(item);
465 count=item_coord_get(item, c, max);
466 hn_length=atoi(inter->last)-atoi(inter->first);
468 hn_pos=atoi(inter->last)-atoi(inter->curr);
470 hn_pos=atoi(inter->curr)-atoi(inter->first);
472 int i,distance_sum=0,hn_distance;
473 int *distances=g_alloca(sizeof(int)*(count-1));
474 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);
480 dbg(0,"coordinate overflow\n");
481 for (i = 0 ; i < count-1 ; i++) {
482 distances[i]=navit_sqrt(transform_distance_sq(&c[i],&c[i+1]));
483 distance_sum+=distances[i];
484 dbg(1,"distance[%d]=%d\n",i,distances[i]);
486 dbg(1,"sum=%d\n",distance_sum);
487 hn_distance=distance_sum*hn_pos/hn_length;
488 dbg(1,"hn_distance=%d\n",hn_distance);
490 while (i < count-1 && hn_distance > distances[i])
491 hn_distance-=distances[i++];
492 dbg(1,"remaining distance=%d from %d\n",hn_distance,distances[i]);
493 ret->x=(c[i+1].x-c[i].x)*hn_distance/distances[i]+c[i].x;
494 ret->y=(c[i+1].y-c[i].y)*hn_distance/distances[i]+c[i].y;
502 static struct search_list_house_number *
503 search_list_house_number_new(struct item *item, struct interpolation *inter, char *inter_match, int inter_partial)
505 struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1);
509 ret->common.item=ret->common.unique=*item;
510 //if (item_attr_get(item, attr_street_name, &attr))
511 // dbg(0,"xx1 %s\n",attr.u.str);
512 if (item_attr_get(item, attr_house_number, &attr))
513 ret->house_number=map_convert_string(item->map, attr.u.str);
515 //if (item_attr_get(item, attr_street_name, &attr))
516 // dbg(0,"xx2 %s\n",attr.u.str);
518 //dbg(0,"interpolate 11");
519 ret->interpolation=1;
520 switch(inter->side) {
522 //dbg(0,"interpolate 11 0");
524 search_setup_interpolation(item, attr_house_number_left, attr_house_number_left_odd, attr_house_number_left_even, inter);
526 //dbg(0,"interpolate 11 -1");
527 if ((hn=search_interpolate(inter)))
530 search_setup_interpolation(item, attr_house_number_right, attr_house_number_right_odd, attr_house_number_right_even, inter);
532 //dbg(0,"interpolate 11 1");
533 if ((hn=search_interpolate(inter)))
536 //dbg(0,"interpolate 11 default");
540 if (search_match(hn, inter_match, inter_partial))
542 //dbg(0,"interpolate 22");
543 //dbg(0,"match %s %s-%s\n",hn, inter->first, inter->last);
544 ret->house_number=map_convert_string(item->map, hn);
549 //dbg(0,"interpolate 33");
550 search_list_common_new(item, &ret->common);
551 ret->common.c=search_house_number_coordinate(item, ret->interpolation?inter:NULL);
552 //dbg(0,"interpolate 44");
557 search_list_house_number_destroy(struct search_list_house_number *this_)
559 map_convert_free(this_->house_number);
560 search_list_common_destroy(&this_->common);
562 g_free(this_->common.c);
567 search_list_result_destroy(int level, void *p)
571 search_list_country_destroy(p);
574 search_list_town_destroy(p);
577 search_list_street_destroy(p);
580 search_list_house_number_destroy(p);
586 search_list_search_free(struct search_list *sl, int level)
588 struct search_list_level *le=&sl->levels[level];
592 mapset_search_destroy(le->search);
597 g_hash_table_destroy(le->hash);
604 search_list_result_destroy(level, curr->data);
605 next=g_list_next(curr);
609 g_list_free(le->list);
616 search_postal_merge(char *mask, char *new)
620 dbg(1,"enter %s %s\n", mask, new);
624 return g_strdup(new);
626 while (mask[i] && new[i]) {
627 if (mask[i] != '.' && mask[i] != new[i])
637 dbg(1,"merged %s with %s as %s\n", mask, new, ret);
642 search_postal_merge_replace(char *mask, char *new)
644 char *ret=search_postal_merge(mask, new);
653 postal_match(char *postal, char *mask)
656 if ((*postal != *mask) && (*mask != '.'))
670 search_add_result(struct search_list_level *le, struct search_list_common *slc)
672 struct search_list_common *slo;
674 slo=g_hash_table_lookup(le->hash, &slc->unique);
676 g_hash_table_insert(le->hash, &slc->unique, slc);
677 if (slc->postal && !slc->postal_mask) {
678 slc->postal_mask=g_strdup(slc->postal);
680 le->list=g_list_append(le->list, slc);
683 merged=search_postal_merge(slo->postal_mask, slc->postal);
685 g_free(slo->postal_mask);
686 slo->postal_mask=merged;
692 search_list_get_unique_truncate(char *common, char *result)
694 dbg(1,"%s vs %s\n",common,result);
696 if (g_utf8_get_char(common) != g_utf8_get_char(result)) {
697 dbg(1,"truncating at %s vs %s\n",common,result);
700 result=g_utf8_next_char(result);
701 common=g_utf8_next_char(common);
707 search_list_get_unique_append(char *list, char *append)
710 int llen=list?strlen(list):0;
711 int len=g_utf8_next_char(append)-append;
712 gunichar a=g_utf8_get_char(append);
714 if (g_utf8_get_char(c) == a)
716 c=g_utf8_next_char(c);
718 list=g_renew(char, list, llen+len+1);
719 strncpy(list+llen,append,len);
725 search_list_get_unique(struct search_list *this_, char *unique)
727 int level=this_->level;
728 struct search_list_level *le=&this_->levels[level];
729 struct search_list_country *slc;
730 struct search_list_town *slt;
731 struct search_list_street *sls;
732 struct search_list_house_number *slh;
733 char *retf=NULL,*ret=NULL;
734 char *strings[4]={NULL,};
735 char *search=g_utf8_casefold(unique?unique:le->attr->u.str,-1);
737 int search_len=strlen(search);
738 int i,count=sizeof(strings)/sizeof(char *);
741 dbg(0,"enter level=%d %s %s\n",level,search,unique);
747 strings[0]=g_strdup(slc->name);
748 strings[1]=g_strdup(slc->car);
749 strings[2]=g_strdup(slc->iso2);
750 strings[3]=g_strdup(slc->iso3);
754 name=slt->common.town_name;
755 for (i = 0 ; i < 3 ; i++)
756 strings[i]=linguistics_expand_special(name, i);
761 for (i = 0 ; i < 3 ; i++)
762 strings[i]=linguistics_expand_special(name, i);
766 name=slh->house_number;
767 for (i = 0 ; i < 3 ; i++)
768 strings[i]=linguistics_expand_special(name, i);
773 dbg(1,"entry %s %s %s %s\n",strings[0],strings[1],strings[2],strings[3]);
775 for (i = 0 ; i < count ; i++) {
776 char *str=strings[i];
778 char *strf=g_utf8_casefold(str,-1);
779 dbg(1,"word %s\n",strf);
780 if (!strncmp(strf, search, search_len)) {
783 dbg(1,"possible next %s %s ret %s\n",strf+search_len,str+search_len,ret);
784 ret=search_list_get_unique_append(ret, strf+search_len);
785 ret=search_list_get_unique_append(ret, str+search_len);
786 dbg(1,"ret now %s\n",ret);
790 retf=g_utf8_casefold(ret,-1);
791 dbg(1,"ret now %s\n",ret);
793 char *end=search_list_get_unique_truncate(retf,strf);
794 dbg(1,"%d characters\n",end-retf);
795 if (!max || max < end)
801 str=linguistics_next_word(str);
807 dbg(1,"max %s (%d characters)\n",max,max-retf);
813 dbg(1,"common %s\n",ret);
818 dbg(0,"return %s\n",ret);
823 * @brief Get (next) result from a search.
825 * @param this_ search_list representing the search
826 * @return next result
828 struct search_list_result *
829 search_list_get_result(struct search_list *this_)
831 struct search_list_level *le,*leu;
832 int level=this_->level;
834 int has_street_name=0;
837 le=&this_->levels[level];
838 //dbg(0,"le=%p\n", le);
841 //dbg(0,"le->search=%p\n", le->search);
844 //dbg(0,"partial=%d level=%d\n", le->partial, level);
849 leu=&this_->levels[level-1];
850 //dbg(0,"leu->curr=%p\n", leu->curr);
853 //dbg(0,"*********########");
855 struct search_list_common *slc;
860 le->parent=leu->curr->data;
862 leu->curr=g_list_next(leu->curr);
863 slc=(struct search_list_common *)(le->parent);
866 if (slc->selected == leu->selected)
872 //dbg(0,"mapset_search_new with item(%d,%d)\n", le->parent->item.id_hi, le->parent->item.id_lo);
874 //dbg(0,"############## attr=%s\n", attr_to_name(le->attr->type));
875 le->search=mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial);
876 le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
878 //dbg(0,"le->search=%p\n", le->search);
882 this_->item=mapset_search_get_item(le->search);
883 //dbg(0,"sssss 1 %p\n",this_->item);
888 //dbg(0,"id_hi=%d id_lo=%d\n", this_->item->id_hi, this_->item->id_lo);
892 if (item_attr_get(this_->item, attr_postal_mask, &postal)) {
893 if (!postal_match(this_->postal, postal.u.str))
895 } else if (item_attr_get(this_->item, attr_postal, &postal)) {
896 if (strcmp(this_->postal, postal.u.str))
900 this_->result.country=NULL;
901 this_->result.town=NULL;
902 this_->result.street=NULL;
903 this_->result.c=NULL;
904 //dbg(0,"case x LEVEL start %d\n",level);
908 //dbg(0,"case 0 COUNTRY");
909 p=search_list_country_new(this_->item);
910 this_->result.country=p;
911 this_->result.country->common.parent=NULL;
915 //dbg(0,"case 1 TOWN");
916 p=search_list_town_new(this_->item);
917 this_->result.town=p;
918 this_->result.town->common.parent=this_->levels[0].last->data;
919 this_->result.country=this_->result.town->common.parent;
920 this_->result.c=this_->result.town->common.c;
924 //dbg(0,"case 2 STREET");
925 p=search_list_street_new(this_->item);
926 this_->result.street=p;
927 this_->result.street->common.parent=this_->levels[1].last->data;
928 this_->result.town=this_->result.street->common.parent;
929 this_->result.country=this_->result.town->common.parent;
930 this_->result.c=this_->result.street->common.c;
934 dbg(1,"case 3 HOUSENUMBER\n");
937 // if this housenumber has a streetname tag, set the name now
938 if (item_attr_get(this_->item, attr_street_name, &attr2))
940 dbg(1,"streetname: %s\n",attr2.u.str);
944 p=search_list_house_number_new(this_->item, &this_->inter, le->attr->u.str, le->partial);
947 interpolation_clear(&this_->inter);
952 this_->result.house_number=p;
953 if (!this_->result.house_number->interpolation)
957 dbg(0,"interpolation!\n");
960 if(le->parent && has_street_name) {
961 struct search_list_street *street=this_->levels[level-1].last->data;
964 s1=g_utf8_casefold(street->name,-1);
965 s2=g_utf8_casefold(attr2.u.str,-1);
966 cmpres=strcmp(s1,s2);
967 dbg(1,"Compared %s with %s, got %d\n",s1,s2,cmpres);
971 search_list_house_number_destroy(p);
978 this_->result.house_number->common.parent=this_->levels[2].last->data;
979 this_->result.street=this_->result.house_number->common.parent;
980 this_->result.town=this_->result.street->common.parent;
981 this_->result.country=this_->result.town->common.parent;
982 this_->result.c=this_->result.house_number->common.c;
985 if(!has_street_name) {
986 static struct search_list_street null_street;
987 this_->result.street=&null_street;
993 if (search_add_result(le, p))
996 return &this_->result;
1000 search_list_result_destroy(level, p);
1004 mapset_search_destroy(le->search);
1006 g_hash_table_destroy(le->hash);
1015 search_list_destroy(struct search_list *this_)
1017 g_free(this_->postal);
1028 search_fix_spaces(const char *str)
1031 int len=strlen(str);
1032 char c,*s,*d,*ret=g_strdup(str);
1034 for (i = 0 ; i < len ; i++) {
1035 if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/')
1043 if (c != ' ' || len != 0) {
1047 while (c == ' ' && *s == ' ')
1049 if (c == ' ' && *s == '\0') {
1058 search_split_phrases(char *str)
1066 ret=g_list_append(ret, g_strdup(s));
1070 ret=g_list_append(ret, g_strdup(tmp));
1081 } while (*s != '\0');
1082 } while (*s != '\0');
1087 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)
1089 // here we search actually for the housenumber
1090 struct search_list_result *slr;
1094 dbg(1,"street:%s\n",street_name);
1095 while ((slr=search_list_get_result(sl)))
1097 // does the streetname of the housenumber match the street we want?
1098 if (slr->street != NULL)
1099 if ((street_name != NULL)&&(slr->street->name != NULL))
1101 //dbg(0,"ffffff 1.1 %s %s",street_name,slr->street->name);
1102 if (strcmp(slr->street->name, street_name)==0)
1106 c.x=slr->house_number->common.c->x;
1107 c.y=slr->house_number->common.c->y;
1108 transform_to_geo(slr->house_number->common.c->pro, &c, &g);
1109 //dbg(0,"g=%f %f\n",g.lat,g.lng);
1110 //dbg(0,"###### Result with housenumber: streetname=%s\n",slr->street->name);
1111 //dbg(0,"###### Result with housenumber: %s %s(%s) %s %s\n",slr->house_number->common.postal,slr->house_number->common.town_name, slr->house_number->common.district_name,slr->street->name,slr->house_number->house_number);
1112 // SHN -> street with house number
1113 // return a string like: "SHN:H111L5555:16.766:48.76:full address name is at the end"
1114 // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 max. 15 chars -> this sould be max. about 335 chars long
1115 if (slr->town->common.postal == NULL)
1117 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);
1121 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);
1123 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1124 #ifdef HAVE_API_ANDROID
1125 // return results to android as they come in ...
1126 android_return_search_result(jni,buffer);
1137 search_address_housenumber(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, GList *exclude3, int partial, struct jni_object *jni)
1140 // this is actually "street search" and "housenumber search" is at the bottom of this function
1142 // housenumbers are not found as of now (2011-02-28)
1146 struct search_list_result *slr;
1153 attr.type=attr_street_name;
1154 while ((slr=search_list_get_result(sl)))
1157 //dbg(0,"%p %p\n",slr->country,slr->town);
1158 //dbg(0,"%p\n",slr->street);
1159 // dbg(0,"###### Result without housenumber: country=%s country_name=%s town=%s street=%s\n",slr->country->iso2,slr->country->name,slr->town->common.town_name,slr->street->name);
1160 //dbg(0,"###### Result without housenumber: postal:%s\n",slr->town->common.postal);
1161 //dbg(0,"###### Result without housenumber: postal_mask:%s\n",slr->town->common.postal_mask);
1162 //dbg(0,"###### Result without housenumber: STR postal:%s\n",slr->street->common.postal);
1163 //dbg(0,"###### Result without housenumber: STR postal_mask:%s\n",slr->street->common.postal_mask);
1164 //dbg(0,"###### Result without housenumber: item id_hi:%d id_lo:%d\n",slr->street->common.item.id_hi,slr->street->common.item.id_lo);
1167 c.x=slr->street->common.c->x;
1168 c.y=slr->street->common.c->y;
1169 transform_to_geo(slr->street->common.c->pro, &c, &g);
1170 //dbg(0,"g=%f %f\n",g.lat,g.lng);
1174 // return a string like: "STR:H1111L5555:16.766:-48.76:full address name is at the end"
1175 // ca. 9 chars : ca. 9 chars : max. 100 max. 100 max. 100 chars -> this sould be max. about 320 chars long
1176 if (slr->town->common.postal == NULL)
1178 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);
1182 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);
1184 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1186 #ifdef HAVE_API_ANDROID
1187 // return results to android as they come in ...
1188 android_return_search_result(jni,buffer);
1194 if (tmp != exclude1 && tmp != exclude2 && tmp != exclude3 && slr->street)
1196 attr2.type=attr_house_number;
1197 attr2.u.str=tmp->data;
1198 search_list_search(sl, &attr2, partial);
1199 //dbg(0,"hn str=%s\n",attr2.u.str);
1200 result_list=search_address_housenumber_real(result_list, sl, slr->street->name, phrases, exclude1, exclude2, exclude3, partial, jni);
1202 tmp=g_list_next(tmp);
1214 search_address_street(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude1, GList *exclude2, int partial, struct jni_object *jni)
1217 // this is actually "town search" !!
1220 struct search_list_result *slr;
1226 attr.type=attr_street_name;
1227 while ((slr=search_list_get_result(sl)))
1230 //dbg(0,"##### sss1");
1231 // dbg(0,"###### Result town: country=%s country_name=%s town=%s",slr->country->iso2,slr->country->name,slr->town->common.town_name);
1232 // dbg(0,"###### Result town: postal=%s postal_mask=%s",slr->town->common.postal,slr->town->common.postal_mask);
1235 c.x=slr->town->common.c->x;
1236 c.y=slr->town->common.c->y;
1237 transform_to_geo(slr->town->common.c->pro, &c, &g);
1240 if (slr->town->common.postal == NULL)
1242 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);
1246 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);
1248 // deactivated now * result_list=g_list_prepend(result_list,g_strdup(buffer));
1249 #ifdef HAVE_API_ANDROID
1250 // return results to android as they come in ...
1251 android_return_search_result(jni,buffer);
1256 dbg(0,"%s %s %s %s",slr->country->car,slr->town->name,slr->town->district,slr->street->name);
1259 dbg(0,"%s %s %s\n",slr->country->iso2,slr->town->county,slr->street->name);
1261 if (item_attr_get(&slr->town->itemt, attr_label, &attr77))
1263 dbg(0,"***search result T=%s",attr77.u.str);
1271 //dbg(0,"count %d\n",count);
1274 if (tmp != exclude1 && tmp != exclude2)
1276 attr.u.str=tmp->data;
1277 search_list_search(sl, &attr, partial);
1278 result_list=search_address_housenumber(result_list, sl, phrases, exclude1, exclude2, tmp, partial, jni);
1280 tmp=g_list_next(tmp);
1286 search_address_town(GList *result_list, struct search_list *sl, GList *phrases, GList *exclude, int partial, struct jni_object *jni)
1291 struct search_list_result *slr;
1293 attr.type=attr_town_or_district_name;
1294 while ((slr=search_list_get_result(sl)))
1300 //dbg(0,"count %d\n",count);
1305 attr.u.str=tmp->data;
1306 search_list_search(sl, &attr, partial);
1307 result_list=search_address_street(result_list, sl, phrases, exclude, tmp, partial, jni);
1309 tmp=g_list_next(tmp);
1316 search_by_address(struct search_list *sl, const char *addr, int partial, struct jni_object *jni)
1318 char *str=search_fix_spaces(addr);
1319 GList *phrases=search_split_phrases(str);
1321 dbg(0,"enter %s\n",addr);
1322 ret=search_address_town(ret, sl, phrases, NULL, partial, jni);
1325 dbg(0,"leave %p\n",ret);