diff options
author | zaxl <zaxl@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2007-10-25 09:23:14 +0000 |
---|---|---|
committer | zaxl <zaxl@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2007-10-25 09:23:14 +0000 |
commit | ccd79b531ac482cafbaf35ebf4beb5cf98177557 (patch) | |
tree | 08bff01053507f0fd17326a9085499eaebe799d1 /data | |
parent | 3c8319f750d1b2d2eb9c6f5663ca72366c5786e5 (diff) | |
download | navit-svn-ccd79b531ac482cafbaf35ebf4beb5cf98177557.tar.gz |
Add garmin driver
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit/src@470 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'data')
-rw-r--r-- | data/garmin/Makefile.am | 7 | ||||
-rw-r--r-- | data/garmin/gar2navit.c | 267 | ||||
-rw-r--r-- | data/garmin/gar2navit.h | 30 | ||||
-rw-r--r-- | data/garmin/garmin.c | 661 | ||||
-rw-r--r-- | data/garmin/garmin.h | 10 | ||||
-rw-r--r-- | data/garmin/garmintypes.txt | 412 |
6 files changed, 1387 insertions, 0 deletions
diff --git a/data/garmin/Makefile.am b/data/garmin/Makefile.am new file mode 100644 index 00000000..fa1801c3 --- /dev/null +++ b/data/garmin/Makefile.am @@ -0,0 +1,7 @@ +include $(top_srcdir)/Makefile.inc +AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=\"data_garmin\" +AM_CPPFLAGS+= @LIBGARMIN_CFLAGS@ +INCLUDES=-I$(top_srcdir)/src/data/garmin/libgarmin +moduledata_LTLIBRARIES = libdata_garmin.la +libdata_garmin_la_SOURCES = garmin.c garmin.h gar2navit.c gar2navit.h +libdata_garmin_la_LIBADD = @LIBGARMIN_LIBS@ diff --git a/data/garmin/gar2navit.c b/data/garmin/gar2navit.c new file mode 100644 index 00000000..33838bee --- /dev/null +++ b/data/garmin/gar2navit.c @@ -0,0 +1,267 @@ +/* + Street's are routable by: + ALL - by all + W pedestrian (1<<0) + B bycycle (1<<1) + M motorcycle (1<<2) + C car (1<<3) + T truck (1<<4) + L largetruck (1<<5) +File format is: + +POINT +0x0100 = town_label_1e5, Megapolis (10M +) +0x0200 = town_label_5e4, Megapolis (5-10M) +... +0x1e00-0x1e3f = district_label, District, Province, State Name +... +POLYLINE +0x00 = ALL, street_1_land, Road +0x01 = MCTL, highway_land, Major HWY thick +0x02 = MCTL, street_4_land, Principal HWY-thick +0x03 = MCTL, street_2_land, Principal HWY-medium +.... +POLYGONE +0x01 = town_poly, City (>200k) +0x02 = town_poly, City (<200k) +0x03 = town_poly, Village + + */ + +#include <stdio.h> +#include <string.h> +#include <malloc.h> +#include "item.h" +#include "attr.h" +#include "garmin.h" +#include "gar2navit.h" + +static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid, + unsigned short maxid, unsigned int routable, char *ntype, + char *descr) +{ + enum item_type it; + struct gar2navit *g2n; + dlog(11, "type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n", + type, routable, minid, maxid, ntype, descr); + it = item_from_name(ntype); + if (it==type_none) { + dlog(1, "Please define: %s\n", ntype); + } + g2n = calloc(1, sizeof(*g2n)); + if (!g2n) + return -1; + g2n->id = minid; + g2n->maxid = maxid; + g2n->ntype = it; + g2n->descr = strdup(descr); + g2n->routable = routable; + if (type == 1) { + g2n->next = conv->points; + conv->points = g2n; + } else if (type == 2) { + g2n->next = conv->polylines; + conv->polylines = g2n; + } else if (type == 3) { + g2n->next = conv->polygons; + conv->polygons = g2n; + } + return 0; +} + +static unsigned int get_rtmask(char *p) +{ + char *cp; + unsigned int mask = 0; + cp = p; + while (*cp) { + if (!strcasecmp(cp, "none")) + return 0; + if (!strcasecmp(cp, "all")) { + mask = ~0; + break; + } if (*cp == 'W') + mask |= RT_PEDESTRIAN; + else if (*cp == 'B') + mask |= RT_BYCYCLE; + else if (*cp == 'M') + mask |= RT_MOTORCYCLE; + else if (*cp == 'C') + mask |= RT_CAR; + else if (*cp == 'T') + mask |= RT_TRUCK; + else if (*cp == 'L') + mask |= RT_LONGTRUCK; + cp++; + } + return mask; +} + +static int load_types_file(char *file, struct gar2nav_conv *conv) +{ + char buf[4096]; + char descr[4096]; + char ntype[4096]; + char rtby[4096]; + FILE *fp; + unsigned int minid, maxid, routable; + int rc; + int type = -1; + + fp = fopen(file, "r"); + if (!fp) + return -1; + while (fgets(buf, sizeof(buf), fp)) { + if (*buf == '#' || *buf == '\n') + continue; + routable = 0; + if (!strncasecmp(buf, "POINT", 5)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POI", 3)) { + type = 1; + continue; + } else if (!strncasecmp(buf, "POLYLINE", 8)) { + type = 2; + continue; + } else if (!strncasecmp(buf, "POLYGONE", 8)) { + type = 3; + continue; + } + // assume only lines are routable + if (type == 2) { + rc = sscanf(buf, "0x%04X = %[^\t, ] , %[^\t, ], %[^\n]", + &minid, rtby, ntype, descr); + if (rc != 4) { + dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); + dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", + minid, ntype, descr); + continue; + } + routable = get_rtmask(rtby); + } else { + rc = sscanf(buf, "0x%04X - 0x%04X = %[^\t , ] , %[^\n]", + &minid, &maxid, ntype, descr); + if (rc != 4) { + maxid = 0; + rc = sscanf(buf, "0x%04X = %[^\t, ], %[^\n]", + &minid, ntype, descr); + if (rc != 3) { + dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf); + dlog(1, "minid=%04X ntype=[%s] des=[%s]\n", + minid, ntype, descr); + continue; + } + } + } + add_def(conv, type, minid, maxid, routable, ntype, descr); + } + fclose(fp); + return 1; +} + +struct gar2nav_conv *g2n_conv_load(char *file) +{ + struct gar2nav_conv *c; + int rc; + + c = calloc(1, sizeof(*c)); + if (!c) + return c; + rc = load_types_file(file, c); + if (rc < 0) { + dlog(1, "Failed to load: [%s]\n", file); + free(c); + return NULL; + } + return c; +} + +enum item_type g2n_get_type(struct gar2nav_conv *c, int type, unsigned short id) +{ + struct gar2navit *def = NULL; + if (type == G2N_POINT) + def = c->points; + else if (type == G2N_POLYLINE) + def = c->polylines; + else if (type == G2N_POLYGONE) + def = c->polygons; + else { + dlog(1, "Unknown conversion type:%d\n", type); + return type_none; + } + + if (!def) { + dlog(5, "No conversion data for %d\n", type); + return type_none; + } + + while (def) { + if ((!def->maxid && def->id == id) || + (def->id <= id && def->maxid)) + return def->ntype; + def = def->next; + } + dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); + return type_none; +} + +int g2n_get_routable(struct gar2nav_conv *c, int type, unsigned short id) +{ + struct gar2navit *def = NULL; + if (type == G2N_POINT) + def = c->points; + else if (type == G2N_POLYLINE) + def = c->polylines; + else if (type == G2N_POLYGONE) + def = c->polygons; + else { + dlog(1, "Unknown conversion type:%d\n", type); + return type_none; + } + + if (!def) { + dlog(5, "No conversion data for %d\n", type); + return type_none; + } + + while (def) { + if ((!def->maxid && def->id == id) || + (def->id <= id && def->maxid)) + return def->routable; + def = def->next; + } + dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); + return 0; +} + +char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id) +{ + struct gar2navit *def = NULL; + if (type == G2N_POINT) + def = c->points; + else if (type == G2N_POLYLINE) + def = c->polylines; + else if (type == G2N_POLYGONE) + def = c->polygons; + else { + dlog(1, "Unknown conversion type:%d\n", type); + return NULL; + } + while (def) { + if ((!def->maxid && def->id == id) || + (def->id <= id && def->maxid)) + return def->descr; + def = def->next; + } + dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id); + return NULL; +} + +#if 0 +int main(int argc, char **argv) +{ + load_types_file(argv[1], NULL); + return 0; +} +#endif diff --git a/data/garmin/gar2navit.h b/data/garmin/gar2navit.h new file mode 100644 index 00000000..3292b1a9 --- /dev/null +++ b/data/garmin/gar2navit.h @@ -0,0 +1,30 @@ +#define RT_PEDESTRIAN (1<<0) +#define RT_BYCYCLE (1<<1) +#define RT_MOTORCYCLE (1<<2) +#define RT_CAR (1<<3) +#define RT_TRUCK (1<<4) +#define RT_LONGTRUCK (1<<5) + +struct gar2navit { + unsigned short id; + unsigned short maxid; + enum item_type ntype; + int routable; + char *descr; + struct gar2navit *next; +}; + +#define G2N_POINT 1 +#define G2N_POLYLINE 2 +#define G2N_POLYGONE 3 + +struct gar2nav_conv { + struct gar2navit *points; + struct gar2navit *polylines; + struct gar2navit *polygons; +}; + +struct gar2nav_conv *g2n_conv_load(char *file); +enum item_type g2n_get_type(struct gar2nav_conv *c, int type, unsigned short id); +char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id); +int g2n_get_routable(struct gar2nav_conv *c, int type, unsigned short id); diff --git a/data/garmin/garmin.c b/data/garmin/garmin.c new file mode 100644 index 00000000..f30e3133 --- /dev/null +++ b/data/garmin/garmin.c @@ -0,0 +1,661 @@ +#include <glib.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include "plugin.h" +#include "data.h" +#include "projection.h" +#include "map.h" +#include "maptype.h" +#include "item.h" +#include "attr.h" +#include "coord.h" +#include "transform.h" +#include <stdio.h> +#include "attr.h" +#include "coord.h" +#include <libgarmin.h> +#include "garmin.h" +#include "gar2navit.h" + + +static int map_id; + +struct map_priv { + int id; + char *filename; + struct gar2nav_conv *conv; + struct gar *g; +}; + +struct map_rect_priv { + int id; + struct coord_rect r; + char *label; // FIXME: Register all strings for searches + int limit; + struct map_priv *mpriv; + struct gmap *gmap; + struct gobject *cobj; + struct gobject *objs; + struct item item; + unsigned int last_coord; + void *last_itterated; + struct coord last_c; + void *last_oattr; + unsigned int last_attr; +}; + +int garmin_debug = 10; +void +logfn(char *file, int line, int level, char *fmt, ...) +{ + va_list ap; + if (level > garmin_debug) + return; + va_start(ap, fmt); + fprintf(stdout, "%s:%d:%d|", file, line, level); + vfprintf(stdout, fmt, ap); + va_end(ap); +} +// need a base map and a map +struct gscale { + char *label; + float scale; + int bits; +}; + +static struct gscale mapscales[] = { + {"7000 km", 70000.0, 8} + ,{"5000 km", 50000.0, 8} + ,{"3000 km", 30000.0, 9} + ,{"2000 km", 20000.0, 9} + ,{"1500 km", 15000.0, 10} + ,{"1000 km", 10000.0, 10} + ,{"700 km", 7000.0, 11} + ,{"500 km", 5000.0, 11} + ,{"300 km", 3000.0, 13} + ,{"200 km", 2000.0, 13} + ,{"150 km", 1500.0, 13} + ,{"100 km", 1000.0, 14} + ,{"70 km", 700.0, 15} + ,{"50 km", 500.0, 16} + ,{"30 km", 300.0, 16} + ,{"20 km", 200.0, 17} + ,{"15 km", 150.0, 17} + ,{"10 km", 100.0, 18} + ,{"7 km", 70.0, 18} + ,{"5 km", 50.0, 19} + ,{"3 km", 30.0, 19} + ,{"2 km", 20.0, 20} + ,{"1.5 km", 15.0, 22} + ,{"1 km", 10.0, 24} + ,{"700 m", 7.0, 24} + ,{"500 m", 5.0, 24} + ,{"300 m", 3.0, 24} + ,{"200 m", 2.0, 24} + ,{"150 m", 1.5, 24} + ,{"100 m", 1.0, 24} + ,{"70 m", 0.7, 24} + ,{"50 m", 0.5, 24} + ,{"30 m", 0.3, 24} + ,{"20 m", 0.2, 24} + ,{"15 m", 0.1, 24} + ,{"10 m", 0.15, 24} +}; + + +static int +garmin_object_label(struct gobject *o, struct attr *attr) +{ + struct map_rect_priv *mr = o->priv_data; + if (!mr) { + dlog(1, "Error object do not have priv_data!!\n"); + return 0; + } + if (mr->label) + free(mr->label); + mr->label = gar_get_object_lbl(o); +#warning FIXME Process label and give only the visible part + if (mr->label) { + char *cp = mr->label; + if (*mr->label == '@' || *mr->label == '^') + cp++; + attr->u.str = cp; + return 1; + } + return 0; +} + +static int +garmin_object_debug(struct gobject *o, struct attr *attr) +{ + struct map_rect_priv *mr = o->priv_data; + if (!mr) { + dlog(1, "Error object do not have priv_data!!\n"); + return 0; + } + if (mr->label) + free(mr->label); + mr->label = gar_object_debug_str(o); + if (mr->label) { + attr->u.str = mr->label; + return 1; + } + return 0; +} + + +static struct map_search_priv * +gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial) +{ + return NULL; +} + +static void +gmap_search_destroy(struct map_search_priv *ms) +{ +} + +static struct item * +gmap_search_get_item(struct map_search_priv *ms) +{ + return NULL; +} + + +/* Assumes that only one item will be itterated at time! */ +static void +coord_rewind(void *priv_data) +{ + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + mr->last_coord = 0; +}; + +static void +attr_rewind(void *priv_data) +{ + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + mr->last_attr = 0; +}; + +static int +point_coord_get(void *priv_data, struct coord *c, int count) +{ + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + struct gcoord gc; + if (!count) + return 0; + if (g != mr->last_itterated) { + mr->last_itterated = g; + mr->last_coord = 0; + } + + if (mr->last_coord > 0) + return 0; + + gar_get_object_coord(mr->gmap, g, &gc); + c->x = gc.x; + c->y = gc.y; + mr->last_coord++; +// dlog(1,"point: x=%d y=%d\n", c->x, c->y); + // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); + return 1; +} + +static int +poly_coord_get(void *priv_data, struct coord *c, int count) +{ + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + int ndeltas = 0, total = 0; + struct gcoord dc; + + if (!count) + return 0; + + if (g != mr->last_itterated) { + mr->last_itterated = g; + mr->last_coord = 0; + } + ndeltas = gar_get_object_deltas(g); + if (mr->last_coord > ndeltas + 1) + return 0; + while (count --) { + if (mr->last_coord == 0) { + gar_get_object_coord(mr->gmap, g, &dc); + mr->last_c.x = dc.x; + mr->last_c.y = dc.y; + } else { + if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) { + mr->last_coord = ndeltas + 2; + return total; + } + mr->last_c.x += dc.x; + mr->last_c.y += dc.y; + } + c->x = mr->last_c.x; + c->y = mr->last_c.y; + ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); +// dlog(1,"poly: x=%d y=%d\n", c->x, c->y); + c++; + total++; + total++; + mr->last_coord ++; + } + return total; +} + +// for _any we must return one by one +static int +point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) +{ + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; + int rc; + switch (attr_type) { + case attr_any: + if (g != mr->last_oattr) { + mr->last_oattr = g; + mr->last_attr = 0; + } + switch(mr->last_attr) { + case 0: + mr->last_attr++; + attr->type = attr_label; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + case 1: + mr->last_attr++; + attr->type = attr_debug; + rc = garmin_object_debug(g, attr); + if (rc) + return rc; + default: + return 0; + } + break; + case attr_label: + attr->type = attr_label; + return garmin_object_label(g, attr); + case attr_limit: + return 0; + default: + dlog(1, "Dont know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type)); + } + + return 0; +} + +static struct item_methods methods_garmin_point = { + coord_rewind, + point_coord_get, + attr_rewind, + point_attr_get, +}; + +static struct item_methods methods_garmin_poly = { + coord_rewind, + poly_coord_get, + attr_rewind, // point_attr_rewind, + point_attr_get, // poly_attr_get, +}; + +static struct item * +garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned char otype) +{ + int subtype; + + subtype = gar_object_subtype(o); + mr->item.id_hi = otype << 8 | subtype; + if (mr->mpriv->conv) + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT, mr->item.id_hi); + mr->item.meth = &methods_garmin_point; + return &mr->item; +} + +static struct item * +garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned char otype) +{ + mr->item.id_hi = otype; + if (mr->mpriv->conv) + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE, otype); + mr->item.meth = &methods_garmin_poly; + return &mr->item; +} + +static struct item * +garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned char otype) +{ + mr->item.id_hi = otype; + if (mr->mpriv->conv) + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE, otype); + mr->item.meth = &methods_garmin_poly; + return &mr->item; +} + +static struct item * +garmin_obj2item(struct map_rect_priv *mr, struct gobject *o) +{ + unsigned char otype; + otype = gar_obj_type(o); + mr->item.type = type_none; + switch (o->type) { + case GO_POINT: + case GO_POI: + return garmin_poi2item(mr, o, otype); + case GO_POLYLINE: + return garmin_pl2item(mr, o, otype); + case GO_POLYGON: + return garmin_pg2item(mr, o, otype); + default: + dlog(1, "Unknown garmin object type:%d\n", + o->type); + } + return NULL; +} + +static struct item * +gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) +{ + struct gobject *o; + o = mr->objs = gar_get_object(mr->mpriv->g, (void *)id_lo); + if (!o) { + dlog(1, "Can not find object\n"); + return NULL; + } + + mr->item.id_hi = (int)mr; + mr->item.id_lo = (int)o->gptr; + mr->item.priv_data = o; + mr->item.type = type_none; + o->priv_data = mr; + if (!garmin_obj2item(mr, o)) + return NULL; + return &mr->item; +} + +static struct item * +gmap_rect_get_item(struct map_rect_priv *mr) +{ + struct gobject *o; + if (!mr->objs) + return NULL; + if (!mr->cobj) + return NULL; + // mr->cobj = mr->objs; + o = mr->cobj; +// dlog(1, "gi:o=%p\n", o); + mr->cobj = mr->cobj->next; + if (o) { + mr->item.id_hi = (int)mr; + mr->item.id_lo = (int)o->gptr; + mr->item.priv_data = o; + mr->item.type = type_none; + o->priv_data = mr; + if (!garmin_obj2item(mr, o)) + return NULL; + return &mr->item; + } + return NULL; +} + +#define max(a,b) ((a) > (b) ? (a) : (b)) +struct nl2gl_t { + int g; + int bits; + char *descr; +}; + +struct nl2gl_t nl2gl_1[] = { + { /* 0 */ .g = 12, .descr = "0-120m", }, + { /* 1 */ .g = 11, .descr = "0-120m", }, + { /* 2 */ .g = 10, .descr = "0-120m", }, + { /* 3 */ .g = 9, .descr = "0-120m", }, + { /* 4 */ .g = 8, .descr = "0-120m", }, + { /* 5 */ .g = 7, .descr = "0-120m", }, + { /* 6 */ .g = 6, .descr = "0-120m", }, + { /* 7 */ .g = 5, .descr = "0-120m", }, + { /* 8 */ .g = 4, .descr = "0-120m", }, + { /* 9 */ .g = 4, .descr = "0-120m", }, + { /* 10 */ .g = 3, .descr = "0-120m", }, + { /* 11 */ .g = 3, .descr = "0-120m", }, + { /* 12 */ .g = 2, .descr = "0-120m", }, + { /* 13 */ .g = 2, .descr = "0-120m", }, + { /* 14 */ .g = 2, .descr = "0-120m", }, + { /* 15 */ .g = 1, .descr = "0-120m", }, + { /* 16 */ .g = 1, .descr = "0-120m", }, + { /* 17 */ .g = 1, .descr = "0-120m", }, + { /* 18 */ .g = 0, .descr = "0-120m", }, +}; + +struct nl2gl_t nl2gl[] = { + { /* 0 */ .g = 9, .descr = "0-120m", }, + { /* 1 */ .g = 9, .descr = "0-120m", }, + { /* 2 */ .g = 8, .descr = "0-120m", }, + { /* 3 */ .g = 8, .descr = "0-120m", }, + { /* 4 */ .g = 7, .descr = "0-120m", }, + { /* 5 */ .g = 7, .descr = "0-120m", }, + { /* 6 */ .g = 6, .descr = "0-120m", }, + { /* 7 */ .g = 6, .descr = "0-120m", }, + { /* 8 */ .g = 5, .descr = "0-120m", }, + { /* 9 */ .g = 5, .descr = "0-120m", }, + { /* 10 */ .g = 4, .descr = "0-120m", }, + { /* 11 */ .g = 4, .descr = "0-120m", }, + { /* 12 */ .g = 3, .descr = "0-120m", }, + { /* 13 */ .g = 3, .descr = "0-120m", }, + { /* 14 */ .g = 2, .descr = "0-120m", }, + { /* 15 */ .g = 2, .descr = "0-120m", }, + { /* 16 */ .g = 1, .descr = "0-120m", }, + { /* 17 */ .g = 1, .descr = "0-120m", }, + { /* 18 */ .g = 0, .descr = "0-120m", }, +}; + +static int +get_level(struct map_selection *sel) +{ + int l; + l = max(sel->order[layer_town], sel->order[layer_street]); + l = max(l, sel->order[layer_poly]); + return l; +} + +static int +garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel) +{ + struct gar_rect r; + struct gmap *gm; + struct gobject **glast = NULL; + int rc; + int sl, el; + int level = 0; // 18; /* max level for maps, overview maps can have bigger + /* levels we do not deal w/ them + */ + int flags = 0; + if (sel && sel->order[layer_town] == 0 && sel->order[layer_poly] == 0 + && sel->order[layer_street]) { + // Get all roads + flags = GO_GET_ROUTABLE; + } else if (sel) + flags = GO_GET_SORTED; + + if (sel) { + r.lulat = sel->rect.lu.y; + r.lulong = sel->rect.lu.x; + r.rllat = sel->rect.rl.y; + r.rllong = sel->rect.rl.x; + level = get_level(sel); +// level = nl2gl[level].g; + printf("Looking level=%d for %f %f %f %f\n", + level, r.lulat, r.lulong, r.rllat, r.rllong); + } + gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL); + if (!gm) { + dlog(1, "Can not find map data\n"); + return -1; + } +#if 0 + sl = (18-(gm->maxlevel - gm->minlevel))/2; + el = sl + (gm->maxlevel - gm->minlevel); + if (level < sl) + level = sl; + if (level > el) + level = el; + level = level - sl; + level = (gm->maxlevel - gm->minlevel) - level; + dlog(1, "sl=%d el=%d level=%d\n", sl, el, level); +#endif + sl = (18-gm->zoomlevels)/2; + el = sl + gm->zoomlevels; + if (level < sl) + level = sl; + if (level > el) + level = el; + level = level - sl; + level = gm->basebits + level; + dlog(1, "sl=%d el=%d level=%d\n", sl, el, level); + map->gmap = gm; + glast = &map->objs; + while (*glast) { + if ((*glast)->next) { + *glast = (*glast)->next; + } else + break; + } + rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags); + if (rc < 0) { + dlog(1, "Error loading objects\n"); + return -1; + } + map->cobj = map->objs; + dlog(1, "Loaded %d objects\n", rc); + return rc; +} +// Can not return NULL, navit segfaults +static struct map_rect_priv * +gmap_rect_new(struct map_priv *map, struct map_selection *sel) +{ + struct map_selection *ms = sel; + struct map_rect_priv *mr; + + mr = calloc(1, sizeof(*mr)); + if (!mr) + return mr; + mr->mpriv = map; + if (!sel) { + return mr; + } else { + while (ms) { + dlog(1, "order town:%d street=%d poly=%d\n", + ms->order[layer_town], + ms->order[layer_street], + ms->order[layer_poly]); + if (garmin_get_selection(mr, ms) < 0) { + // free(mr); + // return NULL; + } + ms = ms->next; + } + } + return mr; +} + +static void +gmap_rect_destroy(struct map_rect_priv *mr) +{ + dlog(11,"destroy maprect\n"); + if (mr->gmap) + gar_free_gmap(mr->gmap); + if (mr->objs) + gar_free_objects(mr->objs); + if (mr->label) + free(mr->label); + free(mr); +} + +static void +gmap_destroy(struct map_priv *m) +{ + dlog(1, "garmin_map_destroy\n"); + if (m->g) + gar_free(m->g); + if (m->filename) + free(m->filename); + free(m); +} + +static struct map_methods map_methods = { + projection_garmin, + NULL, +// "iso8859-1", // update from the map + gmap_destroy, // + gmap_rect_new, + gmap_rect_destroy, + gmap_rect_get_item, + gmap_rect_get_item_byid, + gmap_search_new, + gmap_search_destroy, + gmap_search_get_item, +}; + +static struct map_priv * +gmap_new(struct map_methods *meth, struct attr **attrs) +{ + struct map_priv *m; + struct attr *data; + char buf[PATH_MAX]; + + data=attr_search(attrs, NULL, attr_data); + if (! data) + return NULL; + m=g_new(struct map_priv, 1); + m->id=++map_id; + m->filename = strdup(data->u.str); + if (!m->filename) { + g_free(m); + return NULL; + } + m->g = gar_init(NULL, logfn); + if (!m->g) { + g_free(m->filename); + g_free(m); + return NULL; + } + // we want the data now, later we can load only what's necessery + if (gar_img_load(m->g, m->filename, 1) < 0) { + gar_free(m->g); + g_free(m->filename); + g_free(m); + return NULL; + } + snprintf(buf, sizeof(buf), "%s.types", m->filename); + dlog(1, "Looking for types in %s\n", buf); + m->conv = g2n_conv_load(buf); + if (!m->conv) { + char *cp; + strcpy(buf, m->filename); + cp = strrchr(buf ,'/'); + if (cp) { + cp ++; + *cp = '\0'; + strcat(buf, "garmintypes.txt"); + dlog(1, "Looking for types in %s\n", buf); + m->conv = g2n_conv_load(buf); + } + } + if (!m->conv) { + dlog(1, "Failed to load map types\n"); + } + *meth=map_methods; + return m; +} + +void +plugin_init(void) +{ + plugin_register_map_type("garmin", gmap_new); +} diff --git a/data/garmin/garmin.h b/data/garmin/garmin.h new file mode 100644 index 00000000..50935b05 --- /dev/null +++ b/data/garmin/garmin.h @@ -0,0 +1,10 @@ +#define dlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y) +#ifdef HARDDEBUG +#define ddlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y) +#else +#define ddlog(x,y ...) +#endif + +extern int garmin_debug; +void logfn(char *file, int line, int level, char *fmt, ...); + diff --git a/data/garmin/garmintypes.txt b/data/garmin/garmintypes.txt new file mode 100644 index 00000000..be6054c8 --- /dev/null +++ b/data/garmin/garmintypes.txt @@ -0,0 +1,412 @@ +# +# +# +POINT +0x0000 = label_unkn, Unknown label +0x0100 = town_label_1e5, Megapolis (10M +) +0x0200 = town_label_5e4, Megapolis (5-10M) +0x0300 = town_label_2e4, Big City (2-5M) +0x0400 = town_label_1e4, Big City (1-2M) +0x0500 = town_label_5e3, Big City (0.5-1M) +0x0600 = town_label_2e3, City (200-500k) +0x0700 = town_label_1e3, City (100-200k) +0x0800 = town_label_5e2, City (50-100k) +0x0900 = town_label_2e2, City (20-50k) +0x0a00 = town_label_1e2, City (10-20k) +0x0b00 = town_label_5e1, Small City (5-10k) +0x0c00 = town_label_2e1, Small City (2-5k) +0x0d00 = town_label_1e1, Village (1-2k) +0x0e00 = town_label_5e0, Village (500-1000) +0x0f00 = town_label_2e0, Village (200-500) +0x1000 = town_label_1e0, Village (100-200) +0x1100 = town_label_0e0, Village (0-100) + +0x1200 = port_label, Port with services +0x1300 = label_unkn, Unknown label2 +0x1400-0x14FF = country_label, Large Country Name +0x1500-0x15FF = country_label, Country Name +0x1c00 = poi_wreck, Unclassified Obstruction +0x1c01 = poi_wreck, Wreck +0x1c02 = poi_dangerous, submerged wreck, dangerous +0x1c03 = poi_nondangerous, submerged wreck, non-dangerous +0x1c04 = poi_wreck, Wreck, cleared by wire drag +0x1c05 = poi_rock, Obstruction, visible at high water +0x1c06 = poi_rock, Obstruction, awash +0x1c07 = poi_rock, Obstruction, submerged +0x1c08 = poi_rock, Obstruction, cleared by wire drag +0x1c09 = poi_rock, Rock, awash +0x1c0a = poi_rock, Rock, submerged at low Water +0x1c0b = poi_sounding, Sounding +0x1d00 = poi_tide, Tide Prediction + +0x1e00-0x1e3f = district_label, District, Province, State Name +0x1f00 = district_label_0e0, Region, District Name + +# Fixme if it has label how to change to highway_exit_with_label ?? +0x2000-0x203F = highway_exit, Exit +0x2100-0x213F = highway_exit, Exit with Services +0x2200-0x223F = highway_exit, Exit with Restroom +0x2300-0x233F = highway_exit, Exit with Convinience Store +0x2400-0x243F = highway_exit, Exit with Weight Station +0x2500-0x253F = highway_exit, Exit with Toolbooth Booth +0x2600-0x263F = highway_exit, Exit with Information +0x2700-0x273F = highway_exit, Exit + +0x2800-0x283F = district_label_1e0, Region Name + +0x2900 = poi_public_utilities, Services + +0x2A00 = poi_dining, Dining(Other) +0x2A01 = poi_dining, Dining(American) +0x2A02 = poi_dining, Dining(Asian) +0x2A03 = poi_dining, Dining(Barbecue) +0x2A04 = poi_dining, Dining(Chinese) +0x2A05 = poi_dining, Dining(Deli/Bakery) +0x2A06 = poi_dining, Dining(International) +0x2A07 = poi_fastfood, Fast Food +0x2A08 = poi_dining, Dining(Italian) +0x2A09 = poi_dining, Dining(Mexican) +0x2A0A = poi_dining, Dining(Pizza) +0x2A0B = poi_dining, Dining(Sea Food) +0x2A0C = poi_dining, Dining(Steak/Grill) +0x2A0D = poi_dining, Dining(Bagel/Donut) +0x2A0E = poi_dining, Dining(Cafe/Diner) +0x2A0F = poi_dining, Dining(French) +0x2A10 = poi_dining, Dining(German) +0x2A11 = poi_dining, Dining(British Isles) +0x2A12 = poi_dining, Dining(Special Foods) + +0x2B00 = poi_hotel, Hotel(Other) +0x2B01 = poi_hotel, Hotel/Motel +0x2B02 = poi_hotel, Bed & Breakfast inn +0x2B03 = poi_camp_rv, Camping/RV-Park +0x2B04 = poi_resort, Resort + +0x2C00 = poi_attraction, Amusement Park +0x2C01 = poi_attraction, Amusement Park +0x2C02 = poi_museum_history, Museum/History +0x2C03 = poi_library, Libraries +0x2C04 = poi_landmark, Land Mark +0x2C05 = poi_school, School +0x2C06 = poi_park, Park +0x2C07 = poi_zoo, Zoo +0x2C08 = poi_stadium, Sportpark, Stadium,(point) +0x2C09 = poi_fair, Fair, Conference(point) +0x2C0A = poi_wine, Wine restaurant(point) +0x2C0B = poi_worship, Place of Worship +0x2C0C = poi_hotspring, Hot Spring + +0x2D00 = poi_theater, Theater +0x2D01 = poi_theater, Theater +0x2D02 = poi_bar, Bar +0x2D03 = poi_cinema, Cinema +0x2D04 = poi_casino, Casino +0x2D05 = poi_golf, Golf +0x2D06 = poi_skiing, Skiing Center +0x2D07 = poi_bowling, Bowling +0x2D08 = poi_icesport, Ice/Sporting +0x2D09 = poi_swimming, Swimming +0x2D0A = poi_sport, Sports(point) +0x2D0B = poi_sailing, Sailing Airport + +0x2E00 = poi_shopping, Shoping general +0x2E01 = poi_shop_department, Department Store +0x2E02 = poi_shop_grocery, Grocery +0x2E03 = poi_shop_merchandise, General Merchandiser +0x2E04 = poi_mall, Shopping Center +0x2E05 = poi_pharmacy, Pharmacy +0x2E06 = poi_shopping, Convenience +0x2E07 = poi_shop_apparel, Apparel +0x2E08 = poi_shop_handg, House and Garden +0x2E09 = poi_shop_furnish, Home Furnishing +0x2E0a = poi_shop_retail, Special Retail +0x2E0b = poi_shop_computer, Computer/Software + +0x2F00 = poi_service, generic service +0x2F01 = poi_fuel, Fuel/Gas +0x2F02 = poi_car_rent, Car Rental +0x2F03 = poi_autoservice, Car Repair +0x2F04 = poi_airport, Airport +0x2F05 = poi_post, Post Office +0x2F06 = poi_bank, Bank +0x2F07 = poi_car_dealer_parts, Car Dealer(point) +0x2F08 = poi_bus_station, Bus Station +0x2F09 = poi_marina, Marina +0x2F0A = poi_wrecker, Wrecker Service +0x2F0B = poi_car_parking, Parking +0x2F0C = poi_rest_room, Restroom +0x2F0D = poi_auto_club, Automobile Club +0x2F0E = poi_car_wash, Car Wash +0x2F0F = poi_garmin, Garmin Dealer +0x2F10 = poi_personal_service, Personal Service +0x2F11 = poi_bussines_service, Business Service +0x2F12 = poi_communication, Communication +0x2F13 = poi_repair_service, Repair Service +0x2F14 = poi_social_service, Social Service +0x2F15 = poi_public_utilities, Utility +0x2F16 = poi_truck_stop, Truck Stop +0x2F17 = poi_bus_stop, Bus Stop + +0x3000 = poi_emergency, generic emergency/government +0x3001 = poi_police, Police Station +0x3002 = poi_hospital, Hospital +0x3003 = poi_public_office, Public Office +0x3004 = poi_justice, Justice +0x3005 = poi_concert, Concert hall(point) +0x3006 = poi_border_station, Border Station(point) +0x3007 = poi_goverment_building, Goverment Building +0x3008 = poi_firebrigade, FireFighters Station + +0x4000-0x403F = poi_golf, Golf +0x4100-0x413F = poi_fish, Fish +0x4200-0x423F = poi_wreck, Wreck +0x4300-0x433F = poi_marina, Marina +0x4400-0x443F = poi_fuel, Gas +0x4500-0x453F = poi_restaurant, Restaurant +0x4600-0x463F = poi_bar, Bar +0x4700-0x473F = poi_boat_ramp, Boat Ramp +0x4800-0x483F = poi_camping, Camping +0x4900-0x493F = poi_park, Park +0x4A00-0x4A3F = poi_picnic, Picnic Area +0x4B00-0x4B3F = poi_hospital, Hospital +0x4C00-0x4C3F = poi_information, Information +0x4D00-0x4D3F = poi_car_parking, Parking +0x4E00-0x4E3F = poi_restroom, Restroom +0x4F00-0x4F3F = poi_shower, Shower +0x5000-0x503F = poi_drinking_water, Drinking Water +0x5100-0x513F = poi_telephone, Telephone +0x5200-0x523F = poi_scenic_area, Scenic Area +0x5300-0x533F = poi_skiing, Skiing +0x5400-0x543F = poi_swimming, Swimming +0x5500-0x553F = poi_dam, Dam + +0x5600-0x563F = poi_forbiden_area, Forbiden Area +0x5700-0x573F = poi_danger_area, Danger Area +0x5800-0x583F = poi_restricted_area, Restricted Area + +0x5900 = poi_airport, Generic Airport +0x5901 = poi_airport, Large Airport +0x5902 = poi_airport, Medium Airport +0x5903 = poi_airport, Small Airport +0x5904 = poi_heliport, Heliport +0x5905-0x593F = poi_airport, Airport + +0x5a00 = poi_mark, Kilometer Pole +0x5b00 = poi_mark, Kolokol +0x5c00 = poi_diving, Diving Place + +0x5D00-0x5D3F = poi_daymark, Daymark,Green Square +0x5E00-0x5E3F = poi_daymark, Daymark,Red Triangle + +0x6000 = poi_loudspeaker, LoudSpeaker +0x6100 = poi_building, House + +0x6200 = poi_height, Height with point in feet one decimal place +0x6300 = poi_height, Height without point in feet no decimal place +0x6400 = poi_manmade_feature, Manmade Feature +0x6401 = poi_bridge, Bridge +0x6402 = poi_building, Building +0x6403 = poi_cemetery, Cemetery +0x6404 = poi_church, Church +0x6405 = poi_civil, Civil +0x6406 = poi_crossing, Crossing +0x6407 = poi_dam, Dam +0x6408 = poi_hospital, Hospital +0x6409 = poi_levee, Levee +0x640A = poi_locale, Locale +0x640B = poi_military, Military +0x640C = poi_mine, Mine +0x640D = poi_oil_field, Oil Field +0x640E = poi_park, Park +0x640F = poi_post, Post +0x6410 = poi_school, School +0x6411 = poi_tower, Tower +0x6412 = poi_trail, Trail +0x6413 = poi_tunnel, Tunnel +0x6414 = poi_drinking_water, Drink water +0x6415 = town_ghost, Ghost Town +0x6416 = poi_subdivision, Subdivision + +0x6500 = poi_water_feature, Water Feature +0x6501 = poi_water_feature, Arroyo +0x6502 = poi_water_feature, Sand Bar +0x6503 = poi_bay, Bay +0x6504 = poi_bend, Bend +0x6505 = poi_water_feature, Canal +0x6506 = poi_water_feature, Channel +0x6507 = poi_cove, Cove +0x6508 = poi_water_feature, Falls +0x6509 = poi_water_feature, Geyser +0x650A = poi_water_feature, Glacier +0x650B = poi_marine, Harbour +0x650C = poi_island, Island +0x650D = poi_water_feature, Lake +0x650E = poi_water_feature, Rapids +0x650F = poi_water_feature, Reservoir +0x6510 = poi_water_feature, Sea +0x6511 = poi_water_feature, Spring +0x6512 = poi_water_feature, Stream +0x6513 = poi_water_feature, Swamp + +0x6600 = poi_land_feature, Land Feature +0x6601 = poi_land_feature, Arch +0x6602 = poi_land_feature, Area +0x6603 = poi_land_feature, Basin +0x6604 = poi_land_feature, Beach +0x6605 = poi_land_feature, Bench +0x6606 = poi_land_feature, Cape +0x6607 = poi_land_feature, Cliff +0x6608 = poi_land_feature, Crater +0x6609 = poi_land_feature, Flat +0x660A = poi_land_feature, Forest +0x660B = poi_land_feature, Gap +0x660C = poi_land_feature, Gut +0x660D = poi_land_feature, Isthmus +0x660E = poi_land_feature, Lava +0x660F = poi_land_feature, Pillar +0x6610 = poi_land_feature, Plain +0x6611 = poi_land_feature, Range +0x6612 = poi_land_feature, Reserve +0x6613 = poi_land_feature, Ridge +0x6614 = poi_land_feature, Rock +0x6615 = poi_land_feature, Slope +0x6616 = poi_land_feature, Summit +0x6617 = poi_land_feature, Valley +0x6618 = poi_land_feature, Woods + +# This are dublicated to 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00 +# fix them if you need them +0x1600 = poi_marine_type, Beakon +0x1601 = poi_marine_type, Fog Horn +0x1602 = poi_marine_type, Radio Beacon +0x1603 = poi_marine_type, Racon +0x1604 = poi_marine_type, Day Beacon, red triangle +0x1605 = poi_marine_type, Day Beacon, green square +0x1606 = poi_marine_type, Day Beacon, white diamond +0x1607 = poi_marine_type, unlit Navaid, white +0x1608 = poi_marine_type, unlit Navaid, red +0x1609 = poi_marine_type, unlit Navaid, green +0x160a = poi_marine_type, unlit Navaid, black +0x160b = poi_marine_type, unlit Navaid, yellow or amber +0x160c = poi_marine_type, unlit Navaid, orange +0x160d = poi_marine_type, unlit Navaid, multi colored +0x160e = poi_marine_type, Navaid, unknown +0x160f = poi_marine_type, lighted Navaid, white +0x1610 = poi_marine_type, lighted Navaid, red +0x1611 = poi_marine_type, lighted Navaid, green +0x1612 = poi_marine_type, lighted Navaid, yellow or amber +0x1613 = poi_marine_type, lighted Navaid, orange +0x1614 = poi_marine_type, lighted Navaid, violet +0x1615 = poi_marine_type, lighted Navaid, blue +0x1616 = poi_marine_type, lighted Navaid, multi colored + +# +# Street's are routable by: +# ALL - by all +# W pedestrian +# B bycycle +# M motorcycle +# C car +# T truck +# L largetruck +# this is probably, encoded into the map + +POLYLINE +0x00 = ALL, street_1_land, Road +0x01 = MCTL, highway_land, Major HWY thick +0x02 = MCTL, street_4_land, Principal HWY-thick +0x03 = MCTL, street_2_land, Principal HWY-medium +0x04 = MCTL, street_3_city, Arterial Road-medium +0x05 = MCTL, street_4_city, Arterial Road-thick +0x06 = MCTL, street_2_city, Road-thin +0x07 = MCTL, street_1_city, Alley-thick +0x08 = MCTL, ramp, Ramp +0x09 = MCTL, ramp, Ramp highspeed +0x0a = MCTL, street_0, Unpaved Road-thin +0x0b = MCTL, ramp, Major HWY Connector-thick +0x0c = MCTL, roundabout, Roundabout +0x0d = MCTL, street_unkn, Reservation/Zapovednik? +0x0e = MCTL, street_unkn, Unknown Element 0x0e +0x0f = NONE, street_unkn, Unknown Element 0x0f +0x10 = NONE, street_unkn, Unknown Element 0x10 +0x11 = NONE, street_unkn, Unknown Element 0x11 +0x12 = NONE, street_unkn, Unknown Element 0x12 +0x13 = NONE, street_unkn, Unknown Element 0x13 +0x14 = NONE, rail, Railroad +0x15 = NONE, water_line, Shoreline +0x16 = W, street_nopass, Trail +0x18 = NONE, water_line, Stream-thin +0x19 = NONE, time_zone, Time-Zone +0x1a = ALL, ferry, Ferry +0x1b = ALL, ferry, Ferry +0x1c = NONE, border_country, Political Boundary +0x1d = NONE, border_country, County Boundary +0x1e = NONE, border_country, Intl. Boundary +0x1f = NONE, water_line, River +0x20 = NONE, height_line_1, Land Contour (thin) Height in feet +0x21 = NONE, height_line_2, Land Contour (medium) Height in feet +0x22 = NONE, height_line_3, Land Contour (thick) Height in feet +0x23 = NONE, depth_line_1, Depth Contour (thin) Depth in feet +0x24 = NONE, depth_line_2, Depth Contour (medium) Depth in feet +0x25 = NONE, depth_line_3, Depth Contour (thick) Depth in feet +0x26 = NONE, water_line, Intermittent River +0x27 = NONE, street_nopass, Airport Runway +0x28 = NONE, pipeline, Pipeline +0x29 = NONE, powerline, Powerline +0x2a = NONE, marine_boundary, Marine Boundary (no line) +0x2b = NONE, marine_hazard, Marine Hazard (no line) + +POLYGONE +0x01 = town_poly, City (>200k) +0x02 = town_poly, City (<200k) +0x03 = town_poly, Village +0x04 = military_zone, Military +0x05 = parking_lot_poly, Parking Lot +0x06 = parking_lot_poly, Parking Garage +0x07 = airport_poly, Airport +0x08 = commercial_center, Shopping Center +0x09 = marine_poly, Marina +0x0a = university, University/College +0x0b = hospital_poly, Hospital +0x0c = industry_poly, Industrial +0x0d = area, Reservation +0x0e = airport_poly, Airport Runway +0x13 = area_unspecified, Man made area +0x14 = park_poly, National park +0x15 = park_poly, National park +0x16 = park_poly, National park +0x17 = park_poly, City Park +0x18 = golf_course, Golf +0x19 = sport_poly, Sport +0x1a = cemetery_poly, Cemetery +0x1e = park_poly, State Park +0x1f = park_poly, State Park +0x20 = park_poly, State Park +0x28 = water_poly, Ocean +0x29 = water_poly, Water Reservour +0x32 = water_poly, Sea +0x3b = water_poly, Water Reservour +0x3c = water_poly, Lake (250-600 km2) +0x3d = water_poly, Lake (77-250 km2) +0x3e = water_poly, Lake (25-77 km2) +0x3f = water_poly, Lake (11-25 km2) +0x40 = water_poly, Lake (0.25-11 km2) +0x41 = water_poly, Lake (<0.25 km2) +0x42 = water_poly, Lake (>3.3k km2) +0x43 = water_poly, Lake (1.1-3.3k km2) +0x44 = water_poly, Lake (0.6-1.1k km2) +0x45 = water_poly, Water Reservour +0x46 = water_poly, River (>1km) +0x47 = water_poly, River (200m-1km) +0x48 = water_poly, River (40-200m) +0x49 = water_poly, River (<40m) +0x4a = area, Definition Area +0x4b = area, Background +0x4c = water_poly, Intermittent River/Lake +0x4d = water_poly, Glaciers +0x4e = plantation, Orchard or plantation +0x4f = scrub, Scrub +0x50 = wood, Woods +0x51 = water_poly, Wetland +0x52 = tundra, Tundra +0x53 = flats, Flats |