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

Contents of /navit/navit/map/garmin/garmin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 22439 byte(s)
import files
1 /*
2 Copyright (C) 2007 Alexander Atanasov <aatanasov@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301 USA
17
18 Garmin and MapSource are registered trademarks or trademarks
19 of Garmin Ltd. or one of its subsidiaries.
20
21 */
22
23 #include <glib.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <math.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include "config.h"
32 #include "plugin.h"
33 #include "data.h"
34 #include "projection.h"
35 #include "item.h"
36 #include "debug.h"
37 #include "map.h"
38 #include "maptype.h"
39 #include "attr.h"
40 #include "coord.h"
41 #include "transform.h"
42 #include <stdio.h>
43 #include "attr.h"
44 #include "coord.h"
45 #include <libgarmin.h>
46 #include "garmin.h"
47 #include "gar2navit.h"
48
49
50 static int map_id;
51
52 struct map_priv {
53 int id;
54 char *filename;
55 struct gar2nav_conv *conv;
56 struct gar *g;
57 };
58
59 struct map_rect_priv {
60 int id;
61 struct coord_rect r;
62 char *label; // FIXME: Register all strings for searches
63 int limit;
64 struct map_priv *mpriv;
65 struct gmap *gmap;
66 struct gobject *cobj;
67 struct gobject *objs;
68 struct item item;
69 unsigned int last_coord;
70 void *last_itterated;
71 struct coord last_c;
72 void *last_oattr;
73 unsigned int last_attr;
74 struct gar_search *search;
75 };
76
77 int garmin_debug = 10;
78
79 void
80 logfn(char *file, int line, int level, char *fmt, ...)
81 {
82 va_list ap;
83 char fileline[256];
84 int sz;
85 if (level > garmin_debug)
86 return;
87 va_start(ap, fmt);
88 sz = sprintf(fileline, "%s:%d:%d|", file, line, level);
89 debug_vprintf(0, "", strlen(""), fileline, sz,
90 1, fmt, ap);
91 va_end(ap);
92 }
93 // need a base map and a map
94 struct gscale {
95 char *label;
96 float scale;
97 int bits;
98 };
99
100 static struct gscale mapscales[] = {
101 {"7000 km", 70000.0, 8}
102 ,{"5000 km", 50000.0, 8}
103 ,{"3000 km", 30000.0, 9}
104 ,{"2000 km", 20000.0, 9}
105 ,{"1500 km", 15000.0, 10}
106 ,{"1000 km", 10000.0, 10}
107 ,{"700 km", 7000.0, 11}
108 ,{"500 km", 5000.0, 11}
109 ,{"300 km", 3000.0, 13}
110 ,{"200 km", 2000.0, 13}
111 ,{"150 km", 1500.0, 13}
112 ,{"100 km", 1000.0, 14}
113 ,{"70 km", 700.0, 15}
114 ,{"50 km", 500.0, 16}
115 ,{"30 km", 300.0, 16}
116 ,{"20 km", 200.0, 17}
117 ,{"15 km", 150.0, 17}
118 ,{"10 km", 100.0, 18}
119 ,{"7 km", 70.0, 18}
120 ,{"5 km", 50.0, 19}
121 ,{"3 km", 30.0, 19}
122 ,{"2 km", 20.0, 20}
123 ,{"1.5 km", 15.0, 22}
124 ,{"1 km", 10.0, 24}
125 ,{"700 m", 7.0, 24}
126 ,{"500 m", 5.0, 24}
127 ,{"300 m", 3.0, 24}
128 ,{"200 m", 2.0, 24}
129 ,{"150 m", 1.5, 24}
130 ,{"100 m", 1.0, 24}
131 ,{"70 m", 0.7, 24}
132 ,{"50 m", 0.5, 24}
133 ,{"30 m", 0.3, 24}
134 ,{"20 m", 0.2, 24}
135 ,{"15 m", 0.1, 24}
136 ,{"10 m", 0.15, 24}
137 };
138
139
140 static int
141 garmin_object_label(struct gobject *o, struct attr *attr)
142 {
143 struct map_rect_priv *mr = o->priv_data;
144 char *codepage;
145 char *label;
146 if (!mr) {
147 dlog(1, "Error object do not have priv_data!!\n");
148 return 0;
149 }
150 if (mr->label) {
151 free(mr->label);
152 }
153 label = gar_get_object_lbl(o);
154 if (label) {
155 codepage = gar_obj_codepage(o);
156 if (*codepage != 'a') {
157 mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL);
158 free(label);
159 } else
160 mr->label = label;
161 } else {
162 mr->label = NULL;
163 return 0;
164 }
165 if (mr->label) {
166 char *cp = mr->label;
167 #warning FIXME Process label and give only the visible part
168 if (*mr->label == '@' || *mr->label == '^')
169 cp++;
170 /* FIXME: If zoomlevel is high convert ^ in the string to spaces */
171 attr->u.str = cp;
172 return 1;
173 }
174 return 0;
175 }
176
177 static int
178 garmin_object_debug(struct gobject *o, struct attr *attr)
179 {
180 struct map_rect_priv *mr = o->priv_data;
181 if (!mr) {
182 dlog(1, "Error object do not have priv_data!!\n");
183 return 0;
184 }
185 if (mr->label)
186 free(mr->label);
187 mr->label = gar_object_debug_str(o);
188 if (mr->label) {
189 attr->u.str = mr->label;
190 return 1;
191 }
192 return 0;
193 }
194
195
196 static struct map_search_priv *
197 gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
198 {
199 struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
200 struct gar_search *gs;
201 int rc;
202
203 dlog(1, "Called!\n");
204 mr->mpriv=map;
205 gs = g_new0(struct gar_search,1);
206 if (!gs) {
207 dlog(1, "Can not init search \n");
208 free(mr);
209 return NULL;
210 }
211 mr->search = gs;
212 switch (search->type) {
213 case attr_country_name:
214 gs->type = GS_COUNTRY;
215 break;
216 case attr_town_name:
217 gs->type = GS_CITY;
218 break;
219 case attr_town_postal:
220 gs->type = GS_ZIP;
221 break;
222 case attr_street_name:
223 gs->type = GS_ROAD;
224 break;
225 #if someday
226 case attr_region_name:
227 case attr_intersection:
228 case attr_housenumber:
229 #endif
230 default:
231 dlog(1, "Don't know how to search for %d\n", search->type);
232 goto out_err;
233 }
234 gs->match = partial ? GM_START : GM_EXACT;
235 gs->needle = strdup(search->u.str);
236 dlog(5, "Needle: %s\n", gs->needle);
237
238 mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH);
239 if (!mr->gmap) {
240 dlog(1, "Can not init search \n");
241 goto out_err;
242 }
243 rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH);
244 if (rc < 0) {
245 dlog(1, "Error loading objects\n");
246 goto out_err;
247 }
248 mr->cobj = mr->objs;
249 dlog(4, "Loaded %d objects\n", rc);
250 return (struct map_search_priv *)mr;
251
252 out_err:
253 free(gs);
254 free(mr);
255 return NULL;
256 }
257
258 /* Assumes that only one item will be itterated at time! */
259 static void
260 coord_rewind(void *priv_data)
261 {
262 struct gobject *g = priv_data;
263 struct map_rect_priv *mr = g->priv_data;
264 mr->last_coord = 0;
265 };
266
267 static void
268 attr_rewind(void *priv_data)
269 {
270 struct gobject *g = priv_data;
271 struct map_rect_priv *mr = g->priv_data;
272 mr->last_attr = 0;
273 };
274
275 static int
276 point_coord_get(void *priv_data, struct coord *c, int count)
277 {
278 struct gobject *g = priv_data;
279 struct map_rect_priv *mr = g->priv_data;
280 struct gcoord gc;
281 if (!count)
282 return 0;
283 if (g != mr->last_itterated) {
284 mr->last_itterated = g;
285 mr->last_coord = 0;
286 }
287
288 if (mr->last_coord > 0)
289 return 0;
290
291 gar_get_object_coord(mr->gmap, g, &gc);
292 c->x = gc.x;
293 c->y = gc.y;
294 mr->last_coord++;
295 // dlog(1,"point: x=%d y=%d\n", c->x, c->y);
296 // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
297 return 1;
298 }
299
300 static int
301 coord_is_node(void *priv_data)
302 {
303 struct gobject *g = priv_data;
304 struct map_rect_priv *mr = g->priv_data;
305
306 return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord);
307 }
308
309 static int
310 poly_coord_get(void *priv_data, struct coord *c, int count)
311 {
312 struct gobject *g = priv_data;
313 struct map_rect_priv *mr = g->priv_data;
314 int ndeltas = 0, total = 0;
315 struct gcoord dc;
316
317 if (!count)
318 return 0;
319
320 if (g != mr->last_itterated) {
321 mr->last_itterated = g;
322 mr->last_coord = 0;
323 }
324 ndeltas = gar_get_object_deltas(g);
325 if (mr->last_coord > ndeltas + 1)
326 return 0;
327 while (count --) {
328 if (mr->last_coord == 0) {
329 gar_get_object_coord(mr->gmap, g, &dc);
330 mr->last_c.x = dc.x;
331 mr->last_c.y = dc.y;
332 } else {
333 if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) {
334 mr->last_coord = ndeltas + 2;
335 return total;
336 }
337 mr->last_c.x += dc.x;
338 mr->last_c.y += dc.y;
339 }
340 c->x = mr->last_c.x;
341 c->y = mr->last_c.y;
342 ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
343 // dlog(1,"poly: x=%d y=%d\n", c->x, c->y);
344 c++;
345 total++;
346 mr->last_coord ++;
347 }
348 return total;
349 }
350
351 // for _any we must return one by one
352 static int
353 point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
354 {
355 struct gobject *g = priv_data;
356 struct map_rect_priv *mr = g->priv_data;
357 int rc;
358 switch (attr_type) {
359 case attr_any:
360 if (g != mr->last_oattr) {
361 mr->last_oattr = g;
362 mr->last_attr = 0;
363 }
364 switch(mr->last_attr) {
365 case 0:
366 mr->last_attr++;
367 attr->type = attr_label;
368 rc = garmin_object_label(g, attr);
369 if (rc)
370 return rc;
371 case 1:
372 mr->last_attr++;
373 attr->type = attr_debug;
374 rc = garmin_object_debug(g, attr);
375 if (rc)
376 return rc;
377 case 2:
378 mr->last_attr++;
379 if (g->type == GO_POLYLINE) {
380 attr->type = attr_street_name;
381 rc = garmin_object_label(g, attr);
382 if (rc)
383 return rc;
384 }
385 case 3:
386 mr->last_attr++;
387 attr->type = attr_flags;
388 attr->u.num = 0;
389 rc = gar_object_flags(g);
390 if (rc & F_ONEWAY)
391 attr->u.num |= AF_ONEWAY;
392 if (rc & F_SEGMENTED)
393 attr->u.num |= AF_SEGMENTED;
394 return 1;
395 default:
396 return 0;
397 }
398 break;
399 case attr_label:
400 attr->type = attr_label;
401 return garmin_object_label(g, attr);
402 case attr_town_name:
403 attr->type = attr_town_name;
404 return garmin_object_label(g, attr);
405 case attr_street_name:
406 attr->type = attr_type;
407 return garmin_object_label(g, attr);
408 case attr_street_name_systematic:
409 /* TODO: Get secondary labels of roads */
410 return 0;
411 case attr_flags:
412 attr->type = attr_flags;
413 attr->u.num = 0;
414 rc = gar_object_flags(g);
415 if (rc & F_ONEWAY)
416 attr->u.num |= AF_ONEWAY;
417 if (rc & F_SEGMENTED)
418 attr->u.num |= AF_SEGMENTED;
419 return 1;
420 default:
421 dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type));
422 }
423
424 return 0;
425 }
426
427 static struct item_methods methods_garmin_point = {
428 coord_rewind,
429 point_coord_get,
430 attr_rewind,
431 point_attr_get,
432 };
433
434 static struct item_methods methods_garmin_poly = {
435 coord_rewind,
436 poly_coord_get,
437 attr_rewind, // point_attr_rewind,
438 point_attr_get, // poly_attr_get,
439 coord_is_node,
440 };
441
442 static int
443 search_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
444 {
445 struct gobject *g = priv_data;
446 struct map_rect_priv *mr = g->priv_data;
447 int rc;
448 switch (attr_type) {
449 case attr_any:
450 if (g != mr->last_oattr) {
451 mr->last_oattr = g;
452 mr->last_attr = 0;
453 }
454 switch(mr->last_attr) {
455 case 0:
456 mr->last_attr++;
457 attr->type = attr_label;
458 rc = garmin_object_label(g, attr);
459 if (rc)
460 return rc;
461 case 1:
462 mr->last_attr++;
463 attr->type = attr_debug;
464 rc = garmin_object_debug(g, attr);
465 if (rc)
466 return rc;
467 case 2:
468 mr->last_attr++;
469 if (g->type == GO_POLYLINE) {
470 attr->type = attr_street_name;
471 rc = garmin_object_label(g, attr);
472 if (rc)
473 return rc;
474 }
475 case 3:
476 mr->last_attr++;
477 attr->type = attr_flags;
478 attr->u.num = 0;
479 rc = gar_object_flags(g);
480 if (rc & F_ONEWAY)
481 attr->u.num |= AF_ONEWAY;
482 if (rc & F_SEGMENTED)
483 attr->u.num |= AF_SEGMENTED;
484 return 1;
485 default:
486 return 0;
487 }
488 break;
489 case attr_label:
490 attr->type = attr_label;
491 return garmin_object_label(g, attr);
492 case attr_town_name:
493 attr->type = attr_town_name;
494 if (mr->label)
495 free(mr->label);
496 mr->label = gar_srch_get_city(g);
497 attr->u.str = mr->label;
498 if (attr->u.str)
499 return 1;
500 return 0;
501 case attr_town_id:
502 rc = gar_srch_get_cityid(g);
503 if (rc) {
504 attr->type = attr_town_id;
505 attr->u.num = rc;
506 return 1;
507 }
508 return 0;
509 case attr_town_postal:
510 attr->type = attr_town_postal;
511 attr->u.str = gar_srch_get_zip(g);
512 if (attr->u.str)
513 return 1;
514 return 0;
515 case attr_street_name:
516 attr->type = attr_street_name;
517 if (mr->label)
518 free(mr->label);
519 mr->label = gar_srch_get_roadname(g);
520 attr->u.str = mr->label;
521 if (attr->u.str)
522 return 1;
523 return 0;
524 case attr_street_id:
525 attr->type = attr_street_id;
526 attr->u.num = gar_srch_get_roadid(g);
527 if (attr->u.num)
528 return 1;
529 return 0;
530 case attr_flags:
531 attr->type = attr_flags;
532 attr->u.num = 0;
533 rc = gar_object_flags(g);
534 if (rc & F_ONEWAY)
535 attr->u.num |= AF_ONEWAY;
536 if (rc & F_SEGMENTED)
537 attr->u.num |= AF_SEGMENTED;
538 return 1;
539 case attr_country_id:
540 rc = gar_srch_get_countryid(g);
541 if (rc) {
542 attr->type = attr_country_id;
543 attr->u.num = rc;
544 return 1;
545 }
546 return 0;
547 case attr_country_name:
548 attr->type = attr_country_name;
549 attr->u.str = gar_srch_get_country(g);
550 if (attr->u.str)
551 return 1;
552 return 0;
553 case attr_district_id:
554 rc = gar_srch_get_regionid(g);
555 if (rc) {
556 attr->type = attr_district_id;
557 attr->u.num = rc;
558 return 1;
559 }
560 return 0;
561 case attr_district_name:
562 attr->type = attr_district_name;
563 attr->u.str = gar_srch_get_region(g);
564 if (attr->u.str)
565 return 1;
566 return 0;
567 case attr_town_streets_item:
568 return 0;
569 default:
570 dlog(1, "Don't know about attribute %d[%04X]=%s yet\n",
571 attr_type,attr_type, attr_to_name(attr_type));
572 }
573
574 return 0;
575 }
576
577 static int
578 search_coord_get(void *priv_data, struct coord *c, int count)
579 {
580 struct gobject *g = priv_data;
581 struct map_rect_priv *mr = g->priv_data;
582 struct gcoord gc;
583 if (!count)
584 return 0;
585 if (g != mr->last_itterated) {
586 mr->last_itterated = g;
587 mr->last_coord = 0;
588 }
589
590 if (mr->last_coord > 0)
591 return 0;
592
593 if (gar_get_object_coord(mr->gmap, g, &gc)) {
594 c->x = gc.x;
595 c->y = gc.y;
596 mr->last_coord++;
597 return 1;
598 }
599 return 0;
600 }
601
602 static struct item_methods methods_garmin_search = {
603 coord_rewind,
604 search_coord_get,
605 attr_rewind,
606 search_attr_get,
607 };
608
609
610 static struct item *
611 garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
612 {
613 if (mr->mpriv->conv) {
614 int mask = gar_object_group(o) << G2N_KIND_SHIFT;
615 mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype);
616 }
617 mr->item.meth = &methods_garmin_point;
618 return &mr->item;
619 }
620
621 static struct item *
622 garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
623 {
624 if (mr->mpriv->conv) {
625 int mask = gar_object_group(o) << G2N_KIND_SHIFT;
626 mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype);
627 }
628 mr->item.meth = &methods_garmin_poly;
629 return &mr->item;
630 }
631
632 static struct item *
633 garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
634 {
635 if (mr->mpriv->conv) {
636 int mask = gar_object_group(o) << G2N_KIND_SHIFT;
637 mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype);
638 }
639 mr->item.meth = &methods_garmin_poly;
640 return &mr->item;
641 }
642
643 static struct item *
644 garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
645 {
646 mr->item.type = type_country_label;
647 mr->item.meth = &methods_garmin_search;
648 return &mr->item;
649 }
650
651 static struct item *
652 garmin_obj2item(struct map_rect_priv *mr, struct gobject *o)
653 {
654 unsigned short otype;
655 otype = gar_obj_type(o);
656 mr->item.type = type_none;
657 switch (o->type) {
658 case GO_POINT:
659 return garmin_poi2item(mr, o, otype);
660 case GO_POLYLINE:
661 return garmin_pl2item(mr, o, otype);
662 case GO_POLYGON:
663 return garmin_pg2item(mr, o, otype);
664 case GO_ROAD:
665 return garmin_pl2item(mr, o, otype);
666 #if 0
667 case GO_SEARCH:
668 return garmin_srch2item(mr, o, otype);
669 #endif
670 default:
671 dlog(1, "Unknown garmin object type:%d\n",
672 o->type);
673 }
674 return NULL;
675 }
676
677 static struct item *
678 gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
679 {
680 struct gobject *o;
681 o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo);
682 if (!o) {
683 dlog(1, "Can not find object\n");
684 return NULL;
685 }
686
687 mr->item.id_hi = id_hi;
688 mr->item.id_lo = id_lo;
689 mr->item.priv_data = o;
690 mr->item.type = type_none;
691 o->priv_data = mr;
692 if (!garmin_obj2item(mr, o))
693 return NULL;
694 return &mr->item;
695 }
696
697 static struct item *
698 gmap_rect_get_item(struct map_rect_priv *mr)
699 {
700 struct gobject *o;
701 if (!mr->objs)
702 return NULL;
703 if (!mr->cobj)
704 return NULL;
705 // mr->cobj = mr->objs;
706 o = mr->cobj;
707 // dlog(1, "gi:o=%p\n", o);
708 mr->cobj = mr->cobj->next;
709 if (o) {
710 mr->item.id_hi = gar_object_mapid(o);
711 mr->item.id_lo = gar_object_index(o);
712 mr->item.priv_data = o;
713 mr->item.type = type_none;
714 o->priv_data = mr;
715 if (!garmin_obj2item(mr, o))
716 return NULL;
717 return &mr->item;
718 }
719 return NULL;
720 }
721
722 #define max(a,b) ((a) > (b) ? (a) : (b))
723 struct nl2gl_t {
724 int g;
725 int bits;
726 char *descr;
727 };
728
729 struct nl2gl_t nl2gl_1[] = {
730 { /* 0 */ .g = 12, .descr = "0-120m", },
731 { /* 1 */ .g = 11, .descr = "0-120m", },
732 { /* 2 */ .g = 10, .descr = "0-120m", },
733 { /* 3 */ .g = 9, .descr = "0-120m", },
734 { /* 4 */ .g = 8, .descr = "0-120m", },
735 { /* 5 */ .g = 7, .descr = "0-120m", },
736 { /* 6 */ .g = 6, .descr = "0-120m", },
737 { /* 7 */ .g = 5, .descr = "0-120m", },
738 { /* 8 */ .g = 4, .descr = "0-120m", },
739 { /* 9 */ .g = 4, .descr = "0-120m", },
740 { /* 10 */ .g = 3, .descr = "0-120m", },
741 { /* 11 */ .g = 3, .descr = "0-120m", },
742 { /* 12 */ .g = 2, .descr = "0-120m", },
743 { /* 13 */ .g = 2, .descr = "0-120m", },
744 { /* 14 */ .g = 2, .descr = "0-120m", },
745 { /* 15 */ .g = 1, .descr = "0-120m", },
746 { /* 16 */ .g = 1, .descr = "0-120m", },
747 { /* 17 */ .g = 1, .descr = "0-120m", },
748 { /* 18 */ .g = 0, .descr = "0-120m", },
749 };
750
751 struct nl2gl_t nl2gl[] = {
752 { /* 0 */ .g = 9, .descr = "0-120m", },
753 { /* 1 */ .g = 9, .descr = "0-120m", },
754 { /* 2 */ .g = 8, .descr = "0-120m", },
755 { /* 3 */ .g = 8, .descr = "0-120m", },
756 { /* 4 */ .g = 7, .descr = "0-120m", },
757 { /* 5 */ .g = 7, .descr = "0-120m", },
758 { /* 6 */ .g = 6, .descr = "0-120m", },
759 { /* 7 */ .g = 6, .descr = "0-120m", },
760 { /* 8 */ .g = 5, .descr = "0-120m", },
761 { /* 9 */ .g = 5, .descr = "0-120m", },
762 { /* 10 */ .g = 4, .descr = "0-120m", },
763 { /* 11 */ .g = 4, .descr = "0-120m", },
764 { /* 12 */ .g = 3, .descr = "0-120m", },
765 { /* 13 */ .g = 3, .descr = "0-120m", },
766 { /* 14 */ .g = 2, .descr = "0-120m", },
767 { /* 15 */ .g = 2, .descr = "0-120m", },
768 { /* 16 */ .g = 1, .descr = "0-120m", },
769 { /* 17 */ .g = 1, .descr = "0-120m", },
770 { /* 18 */ .g = 0, .descr = "0-120m", },
771 };
772
773 static int
774 get_level(struct map_selection *sel)
775 {
776 return sel->order;
777 }
778
779 static int
780 garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel)
781 {
782 struct gar_rect r;
783 struct gmap *gm;
784 struct gobject **glast = NULL;
785 int rc;
786 int sl, el;
787 int level = 0; // 18; /* max level for maps, overview maps can have bigger
788 /* levels we do not deal w/ them
789 */
790 int flags = 0;
791 if (sel && sel->range.min == type_street_0 && sel->range.max == type_ferry) {
792 // Get all roads
793 flags = GO_GET_ROUTABLE;
794 } else if (sel)
795 flags = GO_GET_SORTED;
796
797 if (sel) {
798 r.lulat = sel->u.c_rect.lu.y;
799 r.lulong = sel->u.c_rect.lu.x;
800 r.rllat = sel->u.c_rect.rl.y;
801 r.rllong = sel->u.c_rect.rl.x;
802 level = get_level(sel);
803 // level = nl2gl[level].g;
804 dlog(2, "Looking level=%d for %f %f %f %f\n",
805 level, r.lulat, r.lulong, r.rllat, r.rllong);
806 }
807 gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags);
808 if (!gm) {
809 if (sel) {
810 dlog(1, "Can not find map data for the area: %f %f %f %f\n",
811 r.lulat, r.lulong, r.rllat, r.rllong);
812 } else {
813 dlog(1, "Can not find map data\n");
814 }
815 return -1;
816 }
817 #if 0
818 sl = (18-(gm->maxlevel - gm->minlevel))/2;
819 el = sl + (gm->maxlevel - gm->minlevel);
820 if (level < sl)
821 level = sl;
822 if (level > el)
823 level = el;
824 level = level - sl;
825 level = (gm->maxlevel - gm->minlevel) - level;
826 dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
827 #endif
828 sl = (18-gm->zoomlevels)/2;
829 el = sl + gm->zoomlevels;
830 if (level < sl)
831 level = sl;
832 if (level > el)
833 level = el;
834 level = level - sl;
835 level = gm->basebits + level;
836 dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
837 map->gmap = gm;
838 glast = &map->objs;
839 while (*glast) {
840 if ((*glast)->next) {
841 *glast = (*glast)->next;
842 } else
843 break;
844 }
845 rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags);
846 if (rc < 0) {
847 dlog(1, "Error loading objects\n");
848 return -1;
849 }
850 map->cobj = map->objs;
851 dlog(2, "Loaded %d objects\n", rc);
852 return rc;
853 }
854 // Can not return NULL, navit segfaults
855 static struct map_rect_priv *
856 gmap_rect_new(struct map_priv *map, struct map_selection *sel)
857 {
858 struct map_selection *ms = sel;
859 struct map_rect_priv *mr;
860
861 if (!map)
862 return NULL;
863 mr = calloc(1, sizeof(*mr));
864 if (!mr)
865 return mr;
866 mr->mpriv = map;
867 if (!sel) {
868 return mr;
869 } else {
870 while (ms) {
871 dlog(2, "order %d\n", ms->order);
872 if (garmin_get_selection(mr, ms) < 0) {
873 // free(mr);
874 // return NULL;
875 }
876 ms = ms->next;
877 }
878 }
879 return mr;
880 }
881
882 static void
883 gmap_rect_destroy(struct map_rect_priv *mr)
884 {
885 dlog(11,"destroy maprect\n");
886 if (mr->gmap)
887 gar_free_gmap(mr->gmap);
888 if (mr->objs)
889 gar_free_objects(mr->objs);
890 if (mr->label)
891 free(mr->label);
892 free(mr);
893 }
894
895 static void
896 gmap_search_destroy(struct map_search_priv *ms)
897 {
898 gmap_rect_destroy((struct map_rect_priv *)ms);
899 }
900
901 static void
902 gmap_destroy(struct map_priv *m)
903 {
904 dlog(5, "garmin_map_destroy\n");
905 if (m->g)
906 gar_free(m->g);
907 if (m->filename)
908 free(m->filename);
909 free(m);
910 }
911
912 static struct map_methods map_methods = {
913 projection_garmin,
914 "utf-8",
915 gmap_destroy,
916 gmap_rect_new,
917 gmap_rect_destroy,
918 gmap_rect_get_item,
919 gmap_rect_get_item_byid,
920 gmap_search_new,
921 gmap_search_destroy,
922 NULL,
923 };
924
925 static struct map_priv *
926 gmap_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
927 {
928 struct map_priv *m;
929 struct attr *data;
930 struct attr *debug;
931 struct attr *flags;
932 char buf[PATH_MAX];
933 struct stat st;
934 int dl = 1;
935 struct gar_config cfg;
936 int debugmask = 0;
937
938 data=attr_search(attrs, NULL, attr_data);
939 if (! data)
940 return NULL;
941 debug=attr_search(attrs, NULL, attr_debug);
942 if (debug) {
943 dl = atoi(debug->u.str);
944 if (!dl)
945 dl = 1;
946 }
947 flags=attr_search(attrs, NULL, attr_flags);
948 if (flags) {
949 debugmask = flags->u.num;
950 }
951 m=g_new(struct map_priv, 1);
952 m->id=++map_id;
953 m->filename = strdup(data->u.str);
954 if (!m->filename) {
955 g_free(m);
956 return NULL;
957 }
958 memset(&cfg, 0, sizeof(struct gar_config));
959 cfg.opm = OPM_GPS;
960 cfg.debuglevel = dl;
961 cfg.debugmask = debugmask;
962 garmin_debug = dl;
963 m->g = gar_init_cfg(NULL, logfn, &cfg);
964 if (!m->g) {
965 g_free(m->filename);
966 g_free(m);
967 return NULL;
968 }
969 // we want the data now, later we can load only what's necessery
970 if (gar_img_load(m->g, m->filename, 1) < 0) {
971 gar_free(m->g);
972 g_free(m->filename);
973 g_free(m);
974 return NULL;
975 }
976 m->conv = NULL;
977 snprintf(buf, sizeof(buf), "%s.types", m->filename);
978 if (!stat(buf, &st)) {
979 dlog(1, "Loading custom types from %s\n", buf);
980 m->conv = g2n_conv_load(buf);
981 }
982 if (!m->conv) {
983 dlog(1, "Using builtin types\n");
984 m->conv = g2n_default_conv();
985 }
986 if (!m->conv) {
987 dlog(1, "Failed to load map types\n");
988 }
989 *meth=map_methods;
990 return m;
991 }
992
993 void
994 plugin_init(void)
995 {
996 plugin_register_map_type("garmin", gmap_new);
997 }

   
Visit the ZANavi Wiki