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.
23 #include "projection.h"
30 struct search_list_level {
36 struct mapset_search *search;
38 GList *list,*curr,*last;
44 struct search_list_level levels[4];
45 struct search_list_result result;
49 search_item_hash_hash(gconstpointer key)
51 const struct item *itm=key;
52 gconstpointer hashkey=(gconstpointer)(itm->id_hi^itm->id_lo);
53 return g_direct_hash(hashkey);
57 search_item_hash_equal(gconstpointer a, gconstpointer b)
59 const struct item *itm_a=a;
60 const struct item *itm_b=b;
61 if (item_is_equal_id(*itm_a, *itm_b))
67 search_list_new(struct mapset *ms)
69 struct search_list *ret;
71 ret=g_new0(struct search_list, 1);
77 static void search_list_search_free(struct search_list *sl, int level);
80 search_list_level(enum attr_type attr_type)
83 case attr_country_all:
85 case attr_country_iso2:
86 case attr_country_iso3:
87 case attr_country_car:
88 case attr_country_name:
90 case attr_town_postal:
94 case attr_street_name:
102 search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
104 struct search_list_level *le;
105 int level=search_list_level(search_attr->type);
106 dbg(0,"level=%d\n", level);
110 le=&this_->levels[level];
111 le->attr=*search_attr;
112 if (search_attr->type != attr_country_id)
113 le->attr.u.str=g_strdup(search_attr->u.str);
114 search_list_search_free(this_, level);
117 le=&this_->levels[level-1];
120 dbg(1,"le=%p partial=%d\n", le, partial);
124 struct search_list_common *
125 search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode)
127 int level=search_list_level(attr_type);
129 struct search_list_level *le;
130 struct search_list_common *slc;
132 le=&this_->levels[level];
136 dbg(1,"enter level=%d %d %d %p\n", level, id, mode, curr);
139 if (! id || num == id) {
147 curr=g_list_next(curr);
149 dbg(1,"not found\n");
153 static struct search_list_country *
154 search_list_country_new(struct item *item)
156 struct search_list_country *ret=g_new0(struct search_list_country, 1);
160 if (item_attr_get(item, attr_country_car, &attr))
161 ret->car=g_strdup(attr.u.str);
162 if (item_attr_get(item, attr_country_iso2, &attr)) {
163 ret->iso2=g_strdup(attr.u.str);
164 ret->flag=g_strdup_printf("country_%s", ret->iso2);
166 if (item_attr_get(item, attr_country_iso3, &attr))
167 ret->iso3=g_strdup(attr.u.str);
168 if (item_attr_get(item, attr_country_name, &attr))
169 ret->name=g_strdup(attr.u.str);
174 search_list_country_destroy(struct search_list_country *this_)
184 static struct search_list_town *
185 search_list_town_new(struct item *item)
187 struct search_list_town *ret=g_new0(struct search_list_town, 1);
192 if (item_attr_get(item, attr_town_streets_item, &attr)) {
193 dbg(1,"town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
194 ret->item=*attr.u.item;
198 if (item_attr_get(item, attr_town_name, &attr))
199 ret->name=map_convert_string(item->map,attr.u.str);
200 if (item_attr_get(item, attr_town_postal, &attr))
201 ret->postal=map_convert_string(item->map,attr.u.str);
202 if (item_attr_get(item, attr_district_name, &attr))
203 ret->district=map_convert_string(item->map,attr.u.str);
204 if (item_coord_get(item, &c, 1)) {
205 ret->c=g_new(struct pcoord, 1);
208 ret->c->pro = map_projection(item->map);
214 search_list_town_destroy(struct search_list_town *this_)
216 map_convert_free(this_->name);
217 map_convert_free(this_->postal);
223 static struct search_list_street *
224 search_list_street_new(struct item *item)
226 struct search_list_street *ret=g_new0(struct search_list_street, 1);
231 if (item_attr_get(item, attr_street_name, &attr))
232 ret->name=map_convert_string(item->map, attr.u.str);
233 if (item_coord_get(item, &c, 1)) {
234 ret->c=g_new(struct pcoord, 1);
237 ret->c->pro = map_projection(item->map);
243 search_list_street_destroy(struct search_list_street *this_)
245 map_convert_free(this_->name);
253 search_list_result_destroy(int level, void *p)
257 search_list_country_destroy(p);
260 search_list_town_destroy(p);
263 search_list_street_destroy(p);
269 search_list_search_free(struct search_list *sl, int level)
271 struct search_list_level *le=&sl->levels[level];
274 mapset_search_destroy(le->search);
279 g_hash_table_destroy(le->hash);
285 search_list_result_destroy(level, curr->data);
286 next=g_list_next(curr);
289 g_list_free(le->list);
297 search_add_result(struct search_list_level *le, void *p)
299 if (! g_hash_table_lookup(le->hash, p)) {
300 g_hash_table_insert(le->hash, p, (void *)1);
301 le->list=g_list_append(le->list, p);
307 struct search_list_result *
308 search_list_get_result(struct search_list *this_)
310 struct search_list_level *le,*leu;
312 int level=this_->level;
315 le=&this_->levels[level];
316 dbg(1,"le=%p\n", le);
318 dbg(1,"le->search=%p\n", le->search);
320 dbg(1,"partial=%d level=%d\n", le->partial, level);
324 leu=&this_->levels[level-1];
325 dbg(1,"leu->curr=%p\n", leu->curr);
327 struct search_list_common *slc;
330 le->parent=leu->curr->data;
332 leu->curr=g_list_next(leu->curr);
333 slc=(struct search_list_common *)(le->parent);
336 if (slc->selected == leu->selected)
341 dbg(1,"mapset_search_new with item(%d,%d)\n", le->parent->id_hi, le->parent->id_lo);
342 dbg(1,"attr=%s\n", attr_to_name(le->attr.type));
343 le->search=mapset_search_new(this_->ms, le->parent, &le->attr, le->partial);
344 le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
346 dbg(1,"le->search=%p\n", le->search);
347 item=mapset_search_get_item(le->search);
348 dbg(1,"item=%p\n", item);
351 dbg(1,"id_hi=%d id_lo=%d\n", item->id_hi, item->id_lo);
352 this_->result.country=NULL;
353 this_->result.town=NULL;
354 this_->result.street=NULL;
355 this_->result.c=NULL;
358 p=search_list_country_new(item);
359 this_->result.country=p;
362 p=search_list_town_new(item);
363 this_->result.country=this_->levels[0].last->data;
364 this_->result.town=p;
365 this_->result.c=this_->result.town->c;
368 p=search_list_street_new(item);
369 this_->result.country=this_->levels[0].last->data;
370 this_->result.town=this_->levels[1].last->data;
371 this_->result.street=p;
372 this_->result.c=this_->result.street->c;
376 if (search_add_result(le, p)) {
378 return &this_->result;
380 search_list_result_destroy(level, p);
383 mapset_search_destroy(le->search);
385 g_hash_table_destroy(le->hash);
394 search_list_destroy(struct search_list *this_)