diff options
Diffstat (limited to 'navit/map/garmin/garmin.c')
| -rw-r--r-- | navit/map/garmin/garmin.c | 1628 |
1 files changed, 782 insertions, 846 deletions
diff --git a/navit/map/garmin/garmin.c b/navit/map/garmin/garmin.c index 2e7263081..00a6fa115 100644 --- a/navit/map/garmin/garmin.c +++ b/navit/map/garmin/garmin.c @@ -12,9 +12,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - + Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd. or one of its subsidiaries. @@ -50,948 +50,884 @@ static int map_id; struct map_priv { - int id; - char *filename; - struct gar2nav_conv *conv; - struct gar *g; + 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; - struct gar_search *search; + 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; + struct gar_search *search; }; int garmin_debug = 10; -void -logfn(char *file, int line, int level, char *fmt, ...) -{ - va_list ap; - char fileline[256]; - int sz; - if (level > garmin_debug) - return; - va_start(ap, fmt); - sz = sprintf(fileline, "%s:%d:%d|", file, line, level); - debug_vprintf(0, "", strlen(""), fileline, sz, - 1, fmt, ap); - va_end(ap); +void logfn(char *file, int line, int level, char *fmt, ...) { + va_list ap; + char fileline[256]; + int sz; + if (level > garmin_debug) + return; + va_start(ap, fmt); + sz = sprintf(fileline, "%s:%d:%d|", file, line, level); + debug_vprintf(0, "", strlen(""), fileline, sz, + 1, fmt, ap); + va_end(ap); } // need a base map and a map struct gscale { - char *label; - float scale; - int bits; + 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} + {"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; - char *codepage; - char *label; - if (!mr) { - dlog(1, "Error object do not have priv_data!!\n"); - return 0; - } - if (mr->label) { - free(mr->label); - } - label = gar_get_object_lbl(o); - if (label) { - codepage = gar_obj_codepage(o); - if (*codepage != 'a') { - mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL); - free(label); - } else - mr->label = label; - } else { - mr->label = NULL; - return 0; - } - if (mr->label) { - char *cp = mr->label; - /* FIXME Process label and give only the visible part */ - if (*mr->label == '@' || *mr->label == '^') - cp++; - /* FIXME: If zoomlevel is high convert ^ in the string to spaces */ - attr->u.str = cp; - return 1; - } - return 0; +static int garmin_object_label(struct gobject *o, struct attr *attr) { + struct map_rect_priv *mr = o->priv_data; + char *codepage; + char *label; + if (!mr) { + dlog(1, "Error object do not have priv_data!!\n"); + return 0; + } + if (mr->label) { + free(mr->label); + } + label = gar_get_object_lbl(o); + if (label) { + codepage = gar_obj_codepage(o); + if (*codepage != 'a') { + mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL); + free(label); + } else + mr->label = label; + } else { + mr->label = NULL; + return 0; + } + if (mr->label) { + char *cp = mr->label; + /* FIXME Process label and give only the visible part */ + if (*mr->label == '@' || *mr->label == '^') + cp++; + /* FIXME: If zoomlevel is high convert ^ in the string to spaces */ + 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 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) -{ - struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); - struct gar_search *gs; - int rc; - - dlog(1, "Called!\n"); - mr->mpriv=map; - gs = g_new0(struct gar_search,1); - if (!gs) { - dlog(1, "Can not init search \n"); - free(mr); - return NULL; - } - mr->search = gs; - switch (search->type) { - case attr_country_name: - gs->type = GS_COUNTRY; - break; - case attr_town_name: - gs->type = GS_CITY; - break; - case attr_town_postal: - gs->type = GS_ZIP; - break; - case attr_street_name: - gs->type = GS_ROAD; - break; +static struct map_search_priv *gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, + int partial) { + struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); + struct gar_search *gs; + int rc; + + dlog(1, "Called!\n"); + mr->mpriv=map; + gs = g_new0(struct gar_search,1); + if (!gs) { + dlog(1, "Can not init search \n"); + free(mr); + return NULL; + } + mr->search = gs; + switch (search->type) { + case attr_country_name: + gs->type = GS_COUNTRY; + break; + case attr_town_name: + gs->type = GS_CITY; + break; + case attr_town_postal: + gs->type = GS_ZIP; + break; + case attr_street_name: + gs->type = GS_ROAD; + break; #if 0 /* someday */ - case attr_region_name: - case attr_intersection: - case attr_housenumber: + case attr_region_name: + case attr_intersection: + case attr_housenumber: #endif - default: - dlog(1, "Don't know how to search for %d\n", search->type); - goto out_err; - } - gs->match = partial ? GM_START : GM_EXACT; - gs->needle = strdup(search->u.str); - dlog(5, "Needle: %s\n", gs->needle); - - mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH); - if (!mr->gmap) { - dlog(1, "Can not init search \n"); - goto out_err; - } - rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH); - if (rc < 0) { - dlog(1, "Error loading objects\n"); - goto out_err; - } - mr->cobj = mr->objs; - dlog(4, "Loaded %d objects\n", rc); - return (struct map_search_priv *)mr; + default: + dlog(1, "Don't know how to search for %d\n", search->type); + goto out_err; + } + gs->match = partial ? GM_START : GM_EXACT; + gs->needle = strdup(search->u.str); + dlog(5, "Needle: %s\n", gs->needle); + + mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH); + if (!mr->gmap) { + dlog(1, "Can not init search \n"); + goto out_err; + } + rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH); + if (rc < 0) { + dlog(1, "Error loading objects\n"); + goto out_err; + } + mr->cobj = mr->objs; + dlog(4, "Loaded %d objects\n", rc); + return (struct map_search_priv *)mr; out_err: - free(gs); - free(mr); - return NULL; + free(gs); + free(mr); + 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 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 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++; +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; + // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y)); + return 1; } -static int -coord_is_node(void *priv_data) -{ - struct gobject *g = priv_data; - struct map_rect_priv *mr = g->priv_data; +static int coord_is_node(void *priv_data) { + struct gobject *g = priv_data; + struct map_rect_priv *mr = g->priv_data; - return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord); + return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord); } -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)); +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++; - mr->last_coord ++; - } - return total; + c++; + 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; - case 2: - mr->last_attr++; - if (g->type == GO_POLYLINE) { - attr->type = attr_street_name; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - } - case 3: - mr->last_attr++; - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - return 0; - } - break; - case attr_label: - attr->type = attr_label; - return garmin_object_label(g, attr); - case attr_town_name: - attr->type = attr_town_name; - return garmin_object_label(g, attr); - case attr_street_name: - attr->type = attr_type; - return garmin_object_label(g, attr); - case attr_street_name_systematic: - /* TODO: Get secondary labels of roads */ - return 0; - case attr_flags: - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type)); - } - - return 0; +// 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; + case 2: + mr->last_attr++; + if (g->type == GO_POLYLINE) { + attr->type = attr_street_name; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + } + case 3: + mr->last_attr++; + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + return 0; + } + break; + case attr_label: + attr->type = attr_label; + return garmin_object_label(g, attr); + case attr_town_name: + attr->type = attr_town_name; + return garmin_object_label(g, attr); + case attr_street_name: + attr->type = attr_type; + return garmin_object_label(g, attr); + case attr_street_name_systematic: + /* TODO: Get secondary labels of roads */ + return 0; + case attr_flags: + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + dlog(1, "Don't 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, + 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, - coord_is_node, + coord_rewind, + poly_coord_get, + attr_rewind, // point_attr_rewind, + point_attr_get, // poly_attr_get, + coord_is_node, }; -static int -search_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; - case 2: - mr->last_attr++; - if (g->type == GO_POLYLINE) { - attr->type = attr_street_name; - rc = garmin_object_label(g, attr); - if (rc) - return rc; - } - case 3: - mr->last_attr++; - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - default: - return 0; - } - break; - case attr_label: - attr->type = attr_label; - return garmin_object_label(g, attr); - case attr_town_name: - attr->type = attr_town_name; - if (mr->label) - free(mr->label); - mr->label = gar_srch_get_city(g); - attr->u.str = mr->label; - if (attr->u.str) - return 1; - return 0; - case attr_town_id: - rc = gar_srch_get_cityid(g); - if (rc) { - attr->type = attr_town_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_town_postal: - attr->type = attr_town_postal; - attr->u.str = gar_srch_get_zip(g); - if (attr->u.str) - return 1; - return 0; - case attr_street_name: - attr->type = attr_street_name; - if (mr->label) - free(mr->label); - mr->label = gar_srch_get_roadname(g); - attr->u.str = mr->label; - if (attr->u.str) - return 1; - return 0; - case attr_street_id: - attr->type = attr_street_id; - attr->u.num = gar_srch_get_roadid(g); - if (attr->u.num) - return 1; - return 0; - case attr_flags: - attr->type = attr_flags; - attr->u.num = 0; - rc = gar_object_flags(g); - if (rc & F_ONEWAY) - attr->u.num |= AF_ONEWAY; - if (rc & F_SEGMENTED) - attr->u.num |= AF_SEGMENTED; - return 1; - case attr_country_id: - rc = gar_srch_get_countryid(g); - if (rc) { - attr->type = attr_country_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_country_name: - attr->type = attr_country_name; - attr->u.str = gar_srch_get_country(g); - if (attr->u.str) - return 1; - return 0; - case attr_district_id: - rc = gar_srch_get_regionid(g); - if (rc) { - attr->type = attr_district_id; - attr->u.num = rc; - return 1; - } - return 0; - case attr_district_name: - attr->type = attr_district_name; - attr->u.str = gar_srch_get_region(g); - if (attr->u.str) - return 1; - return 0; - case attr_town_streets_item: - return 0; - default: - dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", - attr_type,attr_type, attr_to_name(attr_type)); - } - - return 0; +static int search_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; + case 2: + mr->last_attr++; + if (g->type == GO_POLYLINE) { + attr->type = attr_street_name; + rc = garmin_object_label(g, attr); + if (rc) + return rc; + } + case 3: + mr->last_attr++; + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + default: + return 0; + } + break; + case attr_label: + attr->type = attr_label; + return garmin_object_label(g, attr); + case attr_town_name: + attr->type = attr_town_name; + if (mr->label) + free(mr->label); + mr->label = gar_srch_get_city(g); + attr->u.str = mr->label; + if (attr->u.str) + return 1; + return 0; + case attr_town_id: + rc = gar_srch_get_cityid(g); + if (rc) { + attr->type = attr_town_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_town_postal: + attr->type = attr_town_postal; + attr->u.str = gar_srch_get_zip(g); + if (attr->u.str) + return 1; + return 0; + case attr_street_name: + attr->type = attr_street_name; + if (mr->label) + free(mr->label); + mr->label = gar_srch_get_roadname(g); + attr->u.str = mr->label; + if (attr->u.str) + return 1; + return 0; + case attr_street_id: + attr->type = attr_street_id; + attr->u.num = gar_srch_get_roadid(g); + if (attr->u.num) + return 1; + return 0; + case attr_flags: + attr->type = attr_flags; + attr->u.num = 0; + rc = gar_object_flags(g); + if (rc & F_ONEWAY) + attr->u.num |= AF_ONEWAY; + if (rc & F_SEGMENTED) + attr->u.num |= AF_SEGMENTED; + return 1; + case attr_country_id: + rc = gar_srch_get_countryid(g); + if (rc) { + attr->type = attr_country_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_country_name: + attr->type = attr_country_name; + attr->u.str = gar_srch_get_country(g); + if (attr->u.str) + return 1; + return 0; + case attr_district_id: + rc = gar_srch_get_regionid(g); + if (rc) { + attr->type = attr_district_id; + attr->u.num = rc; + return 1; + } + return 0; + case attr_district_name: + attr->type = attr_district_name; + attr->u.str = gar_srch_get_region(g); + if (attr->u.str) + return 1; + return 0; + case attr_town_streets_item: + return 0; + default: + dlog(1, "Don't know about attribute %d[%04X]=%s yet\n", + attr_type,attr_type, attr_to_name(attr_type)); + } + + return 0; } -static int -search_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; - - if (gar_get_object_coord(mr->gmap, g, &gc)) { - c->x = gc.x; - c->y = gc.y; - mr->last_coord++; - return 1; - } - return 0; +static int search_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; + + if (gar_get_object_coord(mr->gmap, g, &gc)) { + c->x = gc.x; + c->y = gc.y; + mr->last_coord++; + return 1; + } + return 0; } static struct item_methods methods_garmin_search = { - coord_rewind, - search_coord_get, - attr_rewind, - search_attr_get, + coord_rewind, + search_coord_get, + attr_rewind, + search_attr_get, }; -static struct item * -garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype); - } - mr->item.meth = &methods_garmin_point; - return &mr->item; +static struct item *garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype); + } + mr->item.meth = &methods_garmin_point; + return &mr->item; } -static struct item * -garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype); - } - mr->item.meth = &methods_garmin_poly; - return &mr->item; +static struct item *garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype); + } + mr->item.meth = &methods_garmin_poly; + return &mr->item; } -static struct item * -garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - if (mr->mpriv->conv) { - int mask = gar_object_group(o) << G2N_KIND_SHIFT; - mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype); - } - mr->item.meth = &methods_garmin_poly; - return &mr->item; +static struct item *garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + if (mr->mpriv->conv) { + int mask = gar_object_group(o) << G2N_KIND_SHIFT; + mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype); + } + mr->item.meth = &methods_garmin_poly; + return &mr->item; } -static struct item * -garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) -{ - mr->item.type = type_country_label; - mr->item.meth = &methods_garmin_search; - return &mr->item; +static struct item *garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype) { + mr->item.type = type_country_label; + mr->item.meth = &methods_garmin_search; + return &mr->item; } -static struct item * -garmin_obj2item(struct map_rect_priv *mr, struct gobject *o) -{ - unsigned short otype; - otype = gar_obj_type(o); - mr->item.type = type_none; - switch (o->type) { - case GO_POINT: - return garmin_poi2item(mr, o, otype); - case GO_POLYLINE: - return garmin_pl2item(mr, o, otype); - case GO_POLYGON: - return garmin_pg2item(mr, o, otype); - case GO_ROAD: - return garmin_pl2item(mr, o, otype); +static struct item *garmin_obj2item(struct map_rect_priv *mr, struct gobject *o) { + unsigned short otype; + otype = gar_obj_type(o); + mr->item.type = type_none; + switch (o->type) { + case GO_POINT: + return garmin_poi2item(mr, o, otype); + case GO_POLYLINE: + return garmin_pl2item(mr, o, otype); + case GO_POLYGON: + return garmin_pg2item(mr, o, otype); + case GO_ROAD: + return garmin_pl2item(mr, o, otype); #if 0 - case GO_SEARCH: - return garmin_srch2item(mr, o, otype); + case GO_SEARCH: + return garmin_srch2item(mr, o, otype); #endif - default: - dlog(1, "Unknown garmin object type:%d\n", - o->type); - } - return NULL; + 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_by_id(mr->mpriv->g, id_hi, id_lo); - if (!o) { - dlog(1, "Can not find object\n"); - return NULL; - } - - mr->item.id_hi = id_hi; - mr->item.id_lo = id_lo; - 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_byid(struct map_rect_priv *mr, int id_hi, int id_lo) { + struct gobject *o; + o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo); + if (!o) { + dlog(1, "Can not find object\n"); + return NULL; + } + + mr->item.id_hi = id_hi; + mr->item.id_lo = id_lo; + 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; +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 = gar_object_mapid(o); - mr->item.id_lo = gar_object_index(o); - 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; + mr->cobj = mr->cobj->next; + if (o) { + mr->item.id_hi = gar_object_mapid(o); + mr->item.id_lo = gar_object_index(o); + 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; + 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_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", }, +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) -{ - return sel->order; +static int get_level(struct map_selection *sel) { + return sel->order; } -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->range.min == type_street_0 && sel->range.max == type_ferry) { - // Get all roads - flags = GO_GET_ROUTABLE; - } else if (sel) - flags = GO_GET_SORTED; - - if (sel) { - r.lulat = sel->u.c_rect.lu.y; - r.lulong = sel->u.c_rect.lu.x; - r.rllat = sel->u.c_rect.rl.y; - r.rllong = sel->u.c_rect.rl.x; - level = get_level(sel); +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->range.min == type_street_0 && sel->range.max == type_ferry) { + // Get all roads + flags = GO_GET_ROUTABLE; + } else if (sel) + flags = GO_GET_SORTED; + + if (sel) { + r.lulat = sel->u.c_rect.lu.y; + r.lulong = sel->u.c_rect.lu.x; + r.rllat = sel->u.c_rect.rl.y; + r.rllong = sel->u.c_rect.rl.x; + level = get_level(sel); // level = nl2gl[level].g; - dlog(2, "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, flags); - if (!gm) { - if (sel) { - dlog(1, "Can not find map data for the area: %f %f %f %f\n", - r.lulat, r.lulong, r.rllat, r.rllong); - } else { - 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(3, "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(3, "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(2, "Loaded %d objects\n", rc); - return rc; + dlog(2, "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, flags); + if (!gm) { + if (sel) { + dlog(1, "Can not find map data for the area: %f %f %f %f\n", + r.lulat, r.lulong, r.rllat, r.rllong); + } else { + dlog(1, "Can not find map data\n"); + } + return -1; + } + 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(3, "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(2, "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; - - if (!map) - return NULL; - mr = calloc(1, sizeof(*mr)); - if (!mr) - return mr; - mr->mpriv = map; - if (!sel) { - return mr; - } else { - while (ms) { - dlog(2, "order %d\n", ms->order); - if (garmin_get_selection(mr, ms) < 0) { - // free(mr); - // return NULL; - } - ms = ms->next; - } - } - return mr; +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; + + if (!map) + return NULL; + mr = calloc(1, sizeof(*mr)); + if (!mr) + return mr; + mr->mpriv = map; + if (!sel) { + return mr; + } else { + while (ms) { + dlog(2, "order %d\n", ms->order); + 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_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_search_destroy(struct map_search_priv *ms) -{ - gmap_rect_destroy((struct map_rect_priv *)ms); +static void gmap_search_destroy(struct map_search_priv *ms) { + gmap_rect_destroy((struct map_rect_priv *)ms); } -static void -gmap_destroy(struct map_priv *m) -{ - dlog(5, "garmin_map_destroy\n"); - if (m->g) - gar_free(m->g); - if (m->filename) - free(m->filename); - free(m); +static void gmap_destroy(struct map_priv *m) { + dlog(5, "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, - "utf-8", - gmap_destroy, - gmap_rect_new, - gmap_rect_destroy, - gmap_rect_get_item, - gmap_rect_get_item_byid, - gmap_search_new, - gmap_search_destroy, - NULL, + projection_garmin, + "utf-8", + gmap_destroy, + gmap_rect_new, + gmap_rect_destroy, + gmap_rect_get_item, + gmap_rect_get_item_byid, + gmap_search_new, + gmap_search_destroy, + NULL, }; -static struct map_priv * -gmap_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - struct attr *data; - struct attr *debug; - struct attr *flags; - char buf[PATH_MAX]; - struct stat st; - int dl = 1; - struct gar_config cfg; - int debugmask = 0; - - data=attr_search(attrs, NULL, attr_data); - if (! data) - return NULL; - debug=attr_search(attrs, NULL, attr_debug); - if (debug) { - dl = atoi(debug->u.str); - if (!dl) - dl = 1; - } - flags=attr_search(attrs, NULL, attr_flags); - if (flags) { - debugmask = flags->u.num; - } - 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; - } - memset(&cfg, 0, sizeof(struct gar_config)); - cfg.opm = OPM_GPS; - cfg.debuglevel = dl; - cfg.debugmask = debugmask; - garmin_debug = dl; - m->g = gar_init_cfg(NULL, logfn, &cfg); - 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; - } - m->conv = NULL; - snprintf(buf, sizeof(buf), "%s.types", m->filename); - if (!stat(buf, &st)) { - dlog(1, "Loading custom types from %s\n", buf); - m->conv = g2n_conv_load(buf); - } - if (!m->conv) { - dlog(1, "Using builtin types\n"); - m->conv = g2n_default_conv(); - } - if (!m->conv) { - dlog(1, "Failed to load map types\n"); - } - *meth=map_methods; - return m; +static struct map_priv *gmap_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + struct attr *data; + struct attr *debug; + struct attr *flags; + char buf[PATH_MAX]; + struct stat st; + int dl = 1; + struct gar_config cfg; + int debugmask = 0; + + data=attr_search(attrs, NULL, attr_data); + if (! data) + return NULL; + debug=attr_search(attrs, NULL, attr_debug); + if (debug) { + dl = atoi(debug->u.str); + if (!dl) + dl = 1; + } + flags=attr_search(attrs, NULL, attr_flags); + if (flags) { + debugmask = flags->u.num; + } + 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; + } + memset(&cfg, 0, sizeof(struct gar_config)); + cfg.opm = OPM_GPS; + cfg.debuglevel = dl; + cfg.debugmask = debugmask; + garmin_debug = dl; + m->g = gar_init_cfg(NULL, logfn, &cfg); + 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; + } + m->conv = NULL; + snprintf(buf, sizeof(buf), "%s.types", m->filename); + if (!stat(buf, &st)) { + dlog(1, "Loading custom types from %s\n", buf); + m->conv = g2n_conv_load(buf); + } + if (!m->conv) { + dlog(1, "Using builtin types\n"); + m->conv = g2n_default_conv(); + } + if (!m->conv) { + dlog(1, "Failed to load map types\n"); + } + *meth=map_methods; + return m; } -void -plugin_init(void) -{ - plugin_register_category_map("garmin", gmap_new); +void plugin_init(void) { + plugin_register_category_map("garmin", gmap_new); } |
