4 #include "projection.h"
11 struct search_list_level {
16 struct mapset_search *search;
18 GList *list,*curr,*last;
24 struct search_list_level levels[4];
25 struct search_list_result result;
29 search_item_hash_hash(gconstpointer key)
31 const struct item *itm=key;
32 gconstpointer hashkey=(gconstpointer)(itm->id_hi^itm->id_lo);
33 return g_direct_hash(hashkey);
37 search_item_hash_equal(gconstpointer a, gconstpointer b)
39 const struct item *itm_a=a;
40 const struct item *itm_b=b;
41 if (item_is_equal_id(*itm_a, *itm_b))
47 search_list_new(struct mapset *ms)
49 struct search_list *ret;
51 ret=g_new0(struct search_list, 1);
57 static void search_list_search_free(struct search_list *sl, int level);
59 search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
62 struct search_list_level *le;
63 switch(search_attr->type) {
64 case attr_country_all:
66 case attr_country_iso2:
67 case attr_country_iso3:
68 case attr_country_car:
69 case attr_country_name:
72 case attr_town_postal:
78 case attr_street_name:
84 dbg(0,"level=%d\n", level);
87 le=&this_->levels[level];
88 le->attr=*search_attr;
89 if (search_attr->type != attr_country_id)
90 le->attr.u.str=g_strdup(search_attr->u.str);
91 search_list_search_free(this_, level);
94 le=&this_->levels[level-1];
97 dbg(1,"le=%p partial=%d\n", le, partial);
101 static struct search_list_country *
102 search_list_country_new(struct item *item)
104 struct search_list_country *ret=g_new0(struct search_list_country, 1);
108 if (item_attr_get(item, attr_country_car, &attr))
109 ret->car=g_strdup(attr.u.str);
110 if (item_attr_get(item, attr_country_iso2, &attr))
111 ret->iso2=g_strdup(attr.u.str);
112 if (item_attr_get(item, attr_country_iso3, &attr))
113 ret->iso3=g_strdup(attr.u.str);
114 if (item_attr_get(item, attr_country_name, &attr))
115 ret->name=g_strdup(attr.u.str);
120 search_list_country_destroy(struct search_list_country *this_)
129 static struct search_list_town *
130 search_list_town_new(struct item *item)
132 struct search_list_town *ret=g_new0(struct search_list_town, 1);
137 if (item_attr_get(item, attr_town_streets_item, &attr)) {
138 dbg(1,"town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
139 ret->item=*attr.u.item;
143 if (item_attr_get(item, attr_town_name, &attr))
144 ret->name=map_convert_string(item->map,attr.u.str);
145 if (item_attr_get(item, attr_town_postal, &attr))
146 ret->postal=map_convert_string(item->map,attr.u.str);
147 if (item_attr_get(item, attr_district_name, &attr))
148 ret->district=map_convert_string(item->map,attr.u.str);
149 if (item_coord_get(item, &c, 1)) {
150 ret->c=g_new(struct pcoord, 1);
153 ret->c->pro = map_projection(item->map);
159 search_list_town_destroy(struct search_list_town *this_)
161 map_convert_free(this_->name);
162 map_convert_free(this_->postal);
168 static struct search_list_street *
169 search_list_street_new(struct item *item)
171 struct search_list_street *ret=g_new0(struct search_list_street, 1);
176 if (item_attr_get(item, attr_street_name, &attr))
177 ret->name=map_convert_string(item->map, attr.u.str);
178 if (item_coord_get(item, &c, 1)) {
179 ret->c=g_new(struct pcoord, 1);
182 ret->c->pro = map_projection(item->map);
188 search_list_street_destroy(struct search_list_street *this_)
190 map_convert_free(this_->name);
198 search_list_result_destroy(int level, void *p)
202 search_list_country_destroy(p);
205 search_list_town_destroy(p);
208 search_list_street_destroy(p);
214 search_list_search_free(struct search_list *sl, int level)
216 struct search_list_level *le=&sl->levels[level];
219 mapset_search_destroy(le->search);
224 g_hash_table_destroy(le->hash);
230 search_list_result_destroy(level, curr->data);
231 next=g_list_next(curr);
234 g_list_free(le->list);
242 search_add_result(struct search_list_level *le, void *p)
244 if (! g_hash_table_lookup(le->hash, p)) {
245 g_hash_table_insert(le->hash, p, (void *)1);
246 le->list=g_list_append(le->list, p);
252 struct search_list_result *
253 search_list_get_result(struct search_list *this_)
255 struct search_list_level *le,*leu;
257 int level=this_->level;
260 le=&this_->levels[level];
261 dbg(1,"le=%p\n", le);
263 dbg(1,"le->search=%p\n", le->search);
265 dbg(1,"partial=%d\n", le->partial);
269 leu=&this_->levels[level-1];
272 le->parent=leu->curr->data;
274 leu->curr=g_list_next(leu->curr);
277 dbg(1,"mapset_search_new with item(%d,%d)\n", le->parent->id_hi, le->parent->id_lo);
278 dbg(1,"attr=%s\n", attr_to_name(le->attr.type));
279 le->search=mapset_search_new(this_->ms, le->parent, &le->attr, le->partial);
280 le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
282 dbg(1,"le->search=%p\n", le->search);
283 item=mapset_search_get_item(le->search);
284 dbg(1,"item=%p\n", item);
287 dbg(1,"id_hi=%d id_lo=%d\n", item->id_hi, item->id_lo);
288 this_->result.country=NULL;
289 this_->result.town=NULL;
290 this_->result.street=NULL;
291 this_->result.c=NULL;
294 p=search_list_country_new(item);
295 this_->result.country=p;
298 p=search_list_town_new(item);
299 this_->result.country=this_->levels[0].last->data;
300 this_->result.town=p;
301 this_->result.c=this_->result.town->c;
304 p=search_list_street_new(item);
305 this_->result.country=this_->levels[0].last->data;
306 this_->result.town=this_->levels[1].last->data;
307 this_->result.street=p;
308 this_->result.c=this_->result.street->c;
312 if (search_add_result(le, p))
313 return &this_->result;
315 search_list_result_destroy(level, p);
318 mapset_search_destroy(le->search);
320 g_hash_table_destroy(le->hash);
329 search_list_destroy(struct search_list *this_)