/[zanavi_public1]/navit/navit/map/mg/map.c
ZANavi

Contents of /navit/navit/map/mg/map.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (9 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 14396 byte(s)
import files
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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 #include <stdio.h>
21 #include <string.h>
22 #include "config.h"
23 #include "debug.h"
24 #include "plugin.h"
25 #include "maptype.h"
26 #include "mg.h"
27
28
29 GList *maps;
30
31 static struct country_isonum {
32 int country;
33 int isonum;
34 int postal_len;
35 char *postal_prefix;
36 } country_isonums[]={
37 { 1,203},
38 { 2,703},
39 { 7,674},
40 { 11,233},
41 { 12,268},
42 { 13,428},
43 { 14,440},
44 { 15,498},
45 { 16,643},
46 { 17,804},
47 { 18,112},
48 { 20,818},
49 { 30,300},
50 { 31,528},
51 { 32, 56},
52 { 33,250},
53 { 34,724},
54 { 36,348},
55 { 39,380},
56 { 40,642},
57 { 41,756},
58 { 43, 40},
59 { 44,826},
60 { 45,208},
61 { 46,752},
62 { 47,578},
63 { 48,616},
64 { 49,276,5,"D@@"},
65 { 50,292},
66 { 51,620},
67 { 52,442},
68 { 53,372},
69 { 54,352},
70 { 55, 8},
71 { 56,470},
72 { 57,196},
73 { 58,246},
74 { 59,100},
75 { 61,422},
76 { 62, 20},
77 { 63,760},
78 { 66,682},
79 { 71,434},
80 { 72,376},
81 { 73,275},
82 { 75,438},
83 { 76,504},
84 { 77, 12},
85 { 78,788},
86 { 81,688},
87 { 83,400},
88 { 85,191},
89 { 86,705},
90 { 87, 70},
91 { 89,807},
92 { 90,792},
93 { 93,492},
94 { 94, 31},
95 { 95, 51},
96 { 98,234},
97 { 99,732},
98 {336,774},
99 };
100
101 struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl);
102
103 static int map_id;
104
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",
123 };
124
125 int mg_country_from_isonum(int isonum)
126 {
127 int i;
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;
131 return 0;
132 }
133
134 int mg_country_to_isonum(int country)
135 {
136 int i;
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;
140 return 0;
141 }
142
143 int mg_country_postal_len(int country)
144 {
145 int i;
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;
149 return 0;
150 }
151
152 static char *mg_country_postal_prefix(int isonum)
153 {
154 int i;
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;
158 return NULL;
159 }
160
161 struct item_range town_ranges[]={
162 {type_town_label,type_port_label},
163 };
164
165 struct item_range street_ranges[]={
166 {type_street_nopass,type_street_unkn},
167 };
168
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},
173 };
174
175
176 static int
177 file_next(struct map_rect_priv *mr)
178 {
179 int debug=0;
180
181 for (;;) {
182 mr->current_file++;
183 if (mr->current_file >= file_end)
184 return 0;
185 mr->file=mr->m->file[mr->current_file];
186 if (! mr->file)
187 continue;
188 switch (mr->current_file) {
189 case file_strname_stn:
190 continue;
191 case file_town_twn:
192 if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range)))
193 continue;
194 break;
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)))
197 continue;
198 break;
199 default:
200 if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range)))
201 continue;
202 break;
203 }
204 if (debug)
205 printf("current file: '%s'\n", file[mr->current_file]);
206 mr->cur_sel=mr->xsel;
207 if (block_init(mr))
208 return 1;
209 }
210 }
211
212 static void
213 map_destroy_mg(struct map_priv *m)
214 {
215 int i;
216
217 printf("mg_map_destroy\n");
218 for (i = 0 ; i < file_end ; i++) {
219 if (m->file[i])
220 file_destroy(m->file[i]);
221 }
222 }
223
224 extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
225
226 struct map_rect_priv *
227 map_rect_new_mg(struct map_priv *map, struct map_selection *sel)
228 {
229 struct map_rect_priv *mr;
230 int i;
231
232 block_lin_count=0;
233 block_idx_count=0;
234 block_active_count=0;
235 block_mem=0;
236 block_active_mem=0;
237 mr=g_new0(struct map_rect_priv, 1);
238 mr->m=map;
239 mr->xsel=sel;
240 mr->current_file=-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);
244 file_next(mr);
245 return mr;
246 }
247
248
249 static struct item *
250 map_rect_get_item_mg(struct map_rect_priv *mr)
251 {
252 for (;;) {
253 switch (mr->current_file) {
254 case file_town_twn:
255 if (town_get(mr, &mr->town, &mr->item))
256 return &mr->item;
257 break;
258 case file_border_ply:
259 case file_bridge_ply:
260 case file_build_ply:
261 case file_golf_ply:
262 /* case file_height_ply: */
263 case file_natpark_ply:
264 case file_nature_ply:
265 case file_other_ply:
266 case file_rail_ply:
267 case file_sea_ply:
268 /* case file_tunnel_ply: */
269 case file_water_ply:
270 case file_woodland_ply:
271 if (poly_get(mr, &mr->poly, &mr->item))
272 return &mr->item;
273 break;
274 case file_street_str:
275 if (street_get(mr, &mr->street, &mr->item))
276 return &mr->item;
277 break;
278 case file_end:
279 return NULL;
280 default:
281 break;
282 }
283 if (block_next(mr))
284 continue;
285 if (mr->cur_sel->next) {
286 mr->cur_sel=mr->cur_sel->next;
287 if (block_init(mr))
288 continue;
289 }
290 if (file_next(mr))
291 continue;
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);
293 return NULL;
294 }
295 }
296
297 struct item *
298 map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo)
299 {
300 mr->current_file = (id_hi >> 16) & 0xff;
301 switch (mr->current_file) {
302 case file_town_twn:
303 if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item))
304 return &mr->item;
305 break;
306 case file_street_str:
307 if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item))
308 return &mr->item;
309 break;
310 case file_strname_stn:
311 if (street_name_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item))
312 return &mr->item;
313 break;
314 default:
315 if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item))
316 return &mr->item;
317 break;
318 }
319 return NULL;
320 }
321
322
323 void
324 map_rect_destroy_mg(struct map_rect_priv *mr)
325 {
326 int i;
327 for (i=0 ; i < file_end ; i++)
328 if (mr->block_hash[i])
329 g_hash_table_destroy(mr->block_hash[i]);
330 g_free(mr);
331 }
332
333 static char *
334 map_search_mg_convert_special(char *str)
335 {
336 char *ret,*c=g_malloc(strlen(str)*2+1);
337
338 ret=c;
339 for (;;) {
340 switch ((unsigned char)(*str)) {
341 case 0xc4:
342 *c++='A';
343 break;
344 case 0xd6:
345 *c++='O';
346 break;
347 case 0xdc:
348 *c++='U';
349 break;
350 case 0xdf:
351 *c++='s';
352 *c++='s';
353 break;
354 case 0xe4:
355 *c++='a';
356 break;
357 case 0xf6:
358 *c++='o';
359 break;
360 case 0xfc:
361 *c++='u';
362 break;
363 default:
364 dbg(1,"0x%x\n", *str);
365 *c++=*str;
366 break;
367 }
368 if (! *str)
369 return ret;
370 str++;
371 }
372 }
373
374 static int
375 map_search_setup(struct map_rect_priv *mr)
376 {
377 char *prefix;
378 dbg(1,"%s\n", attr_to_name(mr->search_type));
379 switch (mr->search_type) {
380 case attr_town_postal:
381 if (mr->search_item.type != type_country_label) {
382 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
383 return 0;
384 }
385 prefix=mg_country_postal_prefix(mr->search_item.id_lo);
386 if (! prefix)
387 return 0;
388 tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0);
389 mr->current_file=file_town_twn;
390 mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str);
391 dbg(0,"search_str='%s'\n",mr->search_str);
392 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
393 break;
394 case attr_town_name:
395 if (mr->search_item.type != type_country_label) {
396 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
397 return 0;
398 }
399 tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000);
400 mr->current_file=file_town_twn;
401 mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str);
402 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
403 break;
404 case attr_district_name:
405 if (mr->search_item.type != type_country_label) {
406 dbg(0,"wrong parent type %s\n", item_to_name(mr->search_item.type));
407 return 0;
408 }
409 tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000);
410 mr->current_file=file_town_twn;
411 mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str);
412 mr->search_country=mg_country_from_isonum(mr->search_item.id_lo);
413 break;
414 case attr_street_name:
415 if (mr->search_item.type != type_town_streets) {
416 GList *tmp=maps;
417 struct item *item=NULL;
418 struct attr attr;
419 struct map_rect_priv *mr2;
420 while (tmp) {
421 mr2=map_rect_new_mg(tmp->data, NULL);
422 item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo);
423 if (item)
424 break;
425 map_rect_destroy_mg(mr2);
426 tmp=g_list_next(tmp);
427 }
428 if (item) {
429 if (item_attr_get(item, attr_town_streets_item, &attr)) {
430 mr->search_item=*attr.u.item;
431 map_rect_destroy_mg(mr2);
432 } else {
433 map_rect_destroy_mg(mr2);
434 return 0;
435 }
436 } else {
437 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);
438 return 0;
439 }
440 }
441 dbg(1,"street_assoc=0x%x\n", mr->search_item.id_lo);
442 tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0);
443 mr->current_file=file_strname_stn;
444 mr->search_str=g_strdup(mr->search_attr->u.str);
445 break;
446 case attr_house_number:
447 if (!map_priv_is(mr->search_item.map, mr->m))
448 return 0;
449 if (!housenumber_search_setup(mr)) {
450 dbg(0,"failed to search for attr_house_number\n");
451 return 0;
452 }
453 break;
454 default:
455 dbg(0,"unknown search %s\n",attr_to_name(mr->search_type));
456 return 0;
457 }
458 mr->file=mr->m->file[mr->current_file];
459 block_init(mr);
460 return 1;
461 }
462 static void map_search_cleanup(struct map_rect_priv *mr);
463
464 static struct item * map_search_get_item_mg(struct map_search_priv *ms);
465
466 static struct map_search_priv *
467 map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial)
468 {
469 struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
470 dbg(1,"searching for %s '%s'\n", attr_to_name(search->type), search->u.str);
471 dbg(1,"id_lo=0x%x\n", item->id_lo);
472 dbg(1,"search=%s\n", search->u.str);
473 mr->m=map;
474 mr->search_attr=attr_dup(search);
475 mr->search_type=search->type;
476 mr->search_item=*item;
477 mr->search_partial=partial;
478 if (search->type == attr_town_or_district_name) {
479 mr->search_type=attr_town_name;
480 mr->search_type_next=attr_district_name;
481 }
482 if (!map_search_setup(mr)) {
483 dbg(1,"map_search_new_mg failed\n");
484 g_free(mr);
485 return NULL;
486 }
487 mr->search_mr_tmp=map_rect_new_mg(map, NULL);
488
489 return (struct map_search_priv *)mr;
490 }
491
492 static void
493 map_search_cleanup(struct map_rect_priv *mr)
494 {
495 g_free(mr->search_str);
496 mr->search_str=NULL;
497 tree_search_free(&mr->ts);
498 mr->search_linear=0;
499 mr->search_p=NULL;
500 mr->search_blk_count=0;
501 mr->search_blk_off=NULL;
502 mr->search_block=0;
503 }
504
505 static void
506 map_search_destroy_mg(struct map_search_priv *ms)
507 {
508 struct map_rect_priv *mr=(struct map_rect_priv *)ms;
509
510 dbg(1,"mr=%p\n", mr);
511 if (! mr)
512 return;
513 map_search_cleanup(mr);
514 if (mr->search_mr_tmp)
515 map_rect_destroy_mg(mr->search_mr_tmp);
516 attr_free(mr->search_attr);
517 g_free(mr);
518 }
519
520 static struct item *
521 map_search_get_item_mg(struct map_search_priv *ms)
522 {
523 struct map_rect_priv *mr=(struct map_rect_priv *)ms;
524 struct item *ret=NULL;
525
526 if (! mr)
527 return NULL;
528 switch (mr->search_type) {
529 case attr_town_postal:
530 case attr_town_name:
531 case attr_district_name:
532 ret=town_search_get_item(mr);
533 break;
534 case attr_street_name:
535 ret=street_search_get_item(mr);
536 break;
537 case attr_house_number:
538 ret=housenumber_search_get_item(mr);
539 break;
540 default:
541 dbg(0,"unknown search %s\n",attr_to_name(mr->search_type));
542 break;
543 }
544 if (!ret && mr->search_type_next != attr_none) {
545 mr->search_type=mr->search_type_next;
546 mr->search_type_next=attr_none;
547 map_search_cleanup(mr);
548 map_search_setup(mr);
549 return map_search_get_item_mg(ms);
550 }
551 return ret;
552 }
553
554 static struct map_methods map_methods_mg = {
555 projection_mg,
556 "iso8859-1",
557 map_destroy_mg,
558 map_rect_new_mg,
559 map_rect_destroy_mg,
560 map_rect_get_item_mg,
561 map_rect_get_item_byid_mg,
562 map_search_new_mg,
563 map_search_destroy_mg,
564 map_search_get_item_mg,
565 };
566
567
568 struct map_priv *
569 map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
570 {
571 struct map_priv *m;
572 int i,maybe_missing;
573 struct attr *data=attr_search(attrs, NULL, attr_data);
574 char *filename;
575 struct file_wordexp *wexp;
576 char **wexp_data;
577
578 if (! data)
579 return NULL;
580
581 wexp=file_wordexp_new(data->u.str);
582 wexp_data=file_wordexp_get_array(wexp);
583
584 *meth=map_methods_mg;
585 data=attr_search(attrs, NULL, attr_data);
586
587 m=g_new(struct map_priv, 1);
588 m->id=++map_id;
589 m->dirname=g_strdup(wexp_data[0]);
590 file_wordexp_destroy(wexp);
591 for (i = 0 ; i < file_end ; i++) {
592 if (file[i]) {
593 filename=g_strdup_printf("%s/%s", m->dirname, file[i]);
594 m->file[i]=file_create_caseinsensitive(filename, 0);
595 if (! m->file[i]) {
596 maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
597 if (! maybe_missing)
598 dbg(0,"Failed to load %s\n", filename);
599 } else
600 file_mmap(m->file[i]);
601 g_free(filename);
602 }
603 }
604 maps=g_list_append(maps, m);
605
606 return m;
607 }
608
609 void
610 plugin_init(void)
611 {
612 plugin_register_map_type("mg", map_new_mg);
613 }

   
Visit the ZANavi Wiki