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.
31 static struct country_isonum {
101 struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs);
105 static char *file[]={
106 [file_border_ply]="border.ply",
107 [file_bridge_ply]="bridge.ply",
108 [file_build_ply]="build.ply",
109 [file_golf_ply]="golf.ply",
110 [file_height_ply]="height.ply",
111 [file_natpark_ply]="natpark.ply",
112 [file_nature_ply]="nature.ply",
113 [file_other_ply]="other.ply",
114 [file_rail_ply]="rail.ply",
115 [file_sea_ply]="sea.ply",
116 [file_street_bti]="street.bti",
117 [file_street_str]="street.str",
118 [file_strname_stn]="strname.stn",
119 [file_town_twn]="town.twn",
120 [file_tunnel_ply]="tunnel.ply",
121 [file_water_ply]="water.ply",
122 [file_woodland_ply]="woodland.ply",
125 int mg_country_from_isonum(int isonum)
128 for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
129 if (country_isonums[i].isonum == isonum)
130 return country_isonums[i].country;
134 int mg_country_to_isonum(int country)
137 for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
138 if (country_isonums[i].country == country)
139 return country_isonums[i].isonum;
143 int mg_country_postal_len(int country)
146 for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
147 if (country_isonums[i].country == country)
148 return country_isonums[i].postal_len;
152 static char *mg_country_postal_prefix(int isonum)
155 for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
156 if (country_isonums[i].isonum == isonum)
157 return country_isonums[i].postal_prefix;
161 struct item_range town_ranges[]={
162 {type_town_label,type_port_label},
165 struct item_range street_ranges[]={
166 {type_street_nopass,type_street_unkn},
169 struct item_range poly_ranges[]={
170 {type_border_country,type_water_line},
171 {type_street_unkn,type_street_unkn},
172 {type_area,type_last},
177 file_next(struct map_rect_priv *mr)
183 if (mr->current_file >= file_end)
185 mr->file=mr->m->file[mr->current_file];
188 switch (mr->current_file) {
189 case file_strname_stn:
192 if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range)))
195 case file_street_str:
196 if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, street_ranges, sizeof(street_ranges)/sizeof(struct item_range)))
200 if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range)))
205 printf("current file: '%s'\n", file[mr->current_file]);
206 mr->cur_sel=mr->xsel;
213 map_destroy_mg(struct map_priv *m)
217 printf("mg_map_destroy\n");
218 for (i = 0 ; i < file_end ; i++) {
220 file_destroy(m->file[i]);
224 extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
226 struct map_rect_priv *
227 map_rect_new_mg(struct map_priv *map, struct map_selection *sel)
229 struct map_rect_priv *mr;
234 block_active_count=0;
237 mr=g_new0(struct map_rect_priv, 1);
241 if (sel && sel->next)
242 for (i=0 ; i < file_end ; i++)
243 mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal);
250 map_rect_get_item_mg(struct map_rect_priv *mr)
253 switch (mr->current_file) {
255 if (town_get(mr, &mr->town, &mr->item))
258 case file_border_ply:
259 case file_bridge_ply:
262 /* case file_height_ply: */
263 case file_natpark_ply:
264 case file_nature_ply:
268 /* case file_tunnel_ply: */
270 case file_woodland_ply:
271 if (poly_get(mr, &mr->poly, &mr->item))
274 case file_street_str:
275 if (street_get(mr, &mr->street, &mr->item))
285 if (mr->cur_sel->next) {
286 mr->cur_sel=mr->cur_sel->next;
292 dbg(1,"lin_count %d idx_count %d active_count %d %d kB (%d kB)\n", block_lin_count, block_idx_count, block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024);
298 map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo)
300 mr->current_file = (id_hi >> 16) & 0xff;
301 switch (mr->current_file) {
303 if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item))
306 case file_street_str:
307 if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item))
311 if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item))
320 map_rect_destroy_mg(struct map_rect_priv *mr)
323 for (i=0 ; i < file_end ; i++)
324 if (mr->block_hash[i])
325 g_hash_table_destroy(mr->block_hash[i]);
330 map_search_mg_convert_special(char *str)
332 char *ret,*c=g_malloc(strlen(str)*2+1);
336 switch ((unsigned char)(*str)) {
360 dbg(1,"0x%x\n", *str);
371 map_search_setup(struct map_rect_priv *mr)
374 dbg(1,"%s\n", attr_to_name(mr->search_type));
375 switch (mr->search_type) {
376 case attr_town_postal:
377 if (mr->search_item.type != type_country_label) {
378 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
381 prefix=mg_country_postal_prefix(mr->search_item.id_lo);
384 tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0);
385 mr->current_file=file_town_twn;
386 mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str);
387 dbg(0,"search_str='%s'\n",mr->search_str);
388 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
391 if (mr->search_item.type != type_country_label) {
392 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
395 tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000);
396 mr->current_file=file_town_twn;
397 mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str);
398 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
400 case attr_district_name:
401 if (mr->search_item.type != type_country_label) {
402 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
405 tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000);
406 mr->current_file=file_town_twn;
407 mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str);
408 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
410 case attr_street_name:
411 if (mr->search_item.type != type_town_streets) {
413 struct item *item=NULL;
415 struct map_rect_priv *mr2;
417 mr2=map_rect_new_mg(tmp->data, NULL);
418 item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo);
421 map_rect_destroy_mg(mr2);
422 tmp=g_list_next(tmp);
425 if (item_attr_get(item, attr_town_streets_item, &attr)) {
426 mr->search_item=*attr.u.item;
427 map_rect_destroy_mg(mr2);
429 map_rect_destroy_mg(mr2);
433 dbg(0,"wrong parent type %s %p 0x%x 0x%x\n", item_to_name(mr->search_item.type), item, mr->search_item.id_hi, mr->search_item.id_lo);
437 dbg(1,"street_assoc=0x%x\n", mr->search_item.id_lo);
438 tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0);
439 mr->current_file=file_strname_stn;
440 mr->search_str=g_strdup(mr->search_attr->u.str);
442 case attr_house_number:
443 if (!map_priv_is(mr->search_item.map, mr->m))
445 if (!housenumber_search_setup(mr)) {
446 dbg(0,"failed to search for attr_house_number\n");
451 dbg(0,"unknown search %s\n",attr_to_name(mr->search_type));
454 mr->file=mr->m->file[mr->current_file];
458 static void map_search_cleanup(struct map_rect_priv *mr);
460 static struct item * map_search_get_item_mg(struct map_search_priv *ms);
462 static struct map_search_priv *
463 map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial)
465 struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
466 dbg(1,"searching for %s '%s'\n", attr_to_name(search->type), search->u.str);
467 dbg(1,"id_lo=0x%x\n", item->id_lo);
468 dbg(1,"search=%s\n", search->u.str);
470 mr->search_attr=attr_dup(search);
471 mr->search_type=search->type;
472 mr->search_item=*item;
473 mr->search_partial=partial;
474 if (search->type == attr_town_or_district_name) {
475 mr->search_type=attr_town_name;
476 mr->search_type_next=attr_district_name;
478 if (!map_search_setup(mr)) {
479 dbg(1,"map_search_new_mg failed\n");
483 mr->search_mr_tmp=map_rect_new_mg(map, NULL);
485 return (struct map_search_priv *)mr;
489 map_search_cleanup(struct map_rect_priv *mr)
491 g_free(mr->search_str);
493 tree_search_free(&mr->ts);
496 mr->search_blk_count=0;
497 mr->search_blk_off=NULL;
502 map_search_destroy_mg(struct map_search_priv *ms)
504 struct map_rect_priv *mr=(struct map_rect_priv *)ms;
506 dbg(1,"mr=%p\n", mr);
509 map_search_cleanup(mr);
510 if (mr->search_mr_tmp)
511 map_rect_destroy_mg(mr->search_mr_tmp);
512 attr_free(mr->search_attr);
517 map_search_get_item_mg(struct map_search_priv *ms)
519 struct map_rect_priv *mr=(struct map_rect_priv *)ms;
520 struct item *ret=NULL;
524 switch (mr->search_type) {
525 case attr_town_postal:
527 case attr_district_name:
528 ret=town_search_get_item(mr);
530 case attr_street_name:
531 ret=street_search_get_item(mr);
533 case attr_house_number:
534 ret=housenumber_search_get_item(mr);
537 dbg(0,"unknown search %s\n",attr_to_name(mr->search_type));
540 if (!ret && mr->search_type_next != attr_none) {
541 mr->search_type=mr->search_type_next;
542 mr->search_type_next=attr_none;
543 map_search_cleanup(mr);
544 map_search_setup(mr);
545 return map_search_get_item_mg(ms);
550 static struct map_methods map_methods_mg = {
556 map_rect_get_item_mg,
557 map_rect_get_item_byid_mg,
559 map_search_destroy_mg,
560 map_search_get_item_mg,
565 map_new_mg(struct map_methods *meth, struct attr **attrs)
569 struct attr *data=attr_search(attrs, NULL, attr_data);
571 struct file_wordexp *wexp;
577 wexp=file_wordexp_new(data->u.str);
578 wexp_data=file_wordexp_get_array(wexp);
580 *meth=map_methods_mg;
581 data=attr_search(attrs, NULL, attr_data);
583 m=g_new(struct map_priv, 1);
585 m->dirname=g_strdup(wexp_data[0]);
586 file_wordexp_destroy(wexp);
587 for (i = 0 ; i < file_end ; i++) {
589 filename=g_strdup_printf("%s/%s", m->dirname, file[i]);
590 m->file[i]=file_create_caseinsensitive(filename, 0);
592 maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
594 dbg(0,"Failed to load %s\n", filename);
596 file_mmap(m->file[i]);
600 maps=g_list_append(maps, m);
608 plugin_register_map_type("mg", map_new_mg);