diff options
author | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2005-11-27 20:48:30 +0000 |
---|---|---|
committer | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2005-11-27 20:48:30 +0000 |
commit | 9ee36f0e01cf426bc9cc8ba00ee17ce5a4aab719 (patch) | |
tree | f776c0225ff1baa5ca354d77f38ad8d0a88ffa21 /street.c | |
download | navit-svn-9ee36f0e01cf426bc9cc8ba00ee17ce5a4aab719.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches.
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'street.c')
-rw-r--r-- | street.c | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/street.c b/street.c new file mode 100644 index 00000000..f449f1e1 --- /dev/null +++ b/street.c @@ -0,0 +1,455 @@ +#include <assert.h> +#include <stdio.h> +#include <malloc.h> +#include <unistd.h> +#include <glib.h> +#include "container.h" +#include "coord.h" +#include "map_data.h" +#include "file.h" +#include "block.h" +#include "route.h" +#include "street.h" +#include "street_data.h" +#include "street_name.h" +#include "display.h" +#include "draw_info.h" +#include "data_window.h" +#include "data.h" +#include "tree.h" + + +static void +street_draw_segment(struct container *co, struct segment *seg, unsigned char **pos, unsigned char *end, struct coord *ref, int bytes, int include, int disp) +{ + int j,flags,limit; + struct coord f; + struct coord l[2]; + struct street_str *str=seg->data[0]; + char *label; + struct street_name name; + struct param_list param[100]; + struct route_path_segment *route; + struct display_list **displ=co->disp; + int max=10000; + struct point xpoints[max]; + + flags=0; + j=0; + while (! flags && *pos < end) { + flags=street_get_coord(pos, bytes, ref, &f); + if (! j) { + l[0]=f; + l[1]=f; + } else { + if (include || !flags) { + if (f.x < l[0].x) l[0].x=f.x; + if (f.x > l[1].x) l[1].x=f.x; + if (f.y > l[0].y) l[0].y=f.y; + if (f.y < l[1].y) l[1].y=f.y; + } + } + transform(co->trans, &f, &xpoints[j]); + if (! j) + flags=0; + j++; + assert(j < max); + } + if (! include) + j--; + if (is_visible(co->trans, l) && str->type) { + label=NULL; + if (str->nameid) { + street_name_get_by_id(&name, seg->blk_inf.mdata, str->nameid); + if (name.name2[0]) + label=name.name2; + else + label=name.name1; + } + if (str->nameid && name.townassoc < 0 ) { + char buffer[128]; + sprintf(buffer,"-0x%x", -name.townassoc); + label=g_strdup(buffer); + } + limit=0; + if (str->limit == 0x30) + limit=1; + if (str->limit == 0x03) + limit=-1; + if (str->type & 0x40) + limit=-limit; + display_add(&displ[disp], 2, limit, label, j, xpoints, NULL, seg, sizeof(*seg)); + if (co->route && (route=route_path_get(co->route, str->segid))) { + if (! route->offset) + display_add(&displ[display_street_route], 2, 0, label, j, xpoints, NULL, NULL, 0); + else if (route->offset > 0) + display_add(&displ[display_street_route], 2, 0, label, route->offset, xpoints, NULL, NULL, 0); + else + display_add(&displ[display_street_route], 2, 0, label, j+route->offset, xpoints-route->offset, NULL, NULL, 0); + } + if (co->data_window[data_window_type_street]) + data_window_add(co->data_window[data_window_type_street], param, street_get_param(seg, param, 100, 0)); + } + *pos-=2*bytes; +} + +void +street_safety_check(struct street_str *str) +{ +#if 0 + if (!((str->type & 0xf0) == 0x0 || (str->type & 0xf0) == 0x40)) { + printf("str->type=0x%x\n", str->type); + } + assert((str->type & 0xf0) == 0x0 || (str->type & 0xf0) == 0x40); +#endif + assert(str->type != 0xe && str->type != 0x4e && str->type != 0x40); + assert(str->unknown2 == str->unknown3); + assert(str->unknown2 == 0x40 || str->unknown2 == 0x44); +} + +struct street_header_type { + struct street_header *header; + int type_count; + struct street_type *type; +}; + +static void +street_header_type_get(struct block *blk, unsigned char **p_p, struct street_header_type *ret) +{ + unsigned char *p=*p_p; + ret->header=(struct street_header *)p; + p+=sizeof(struct street_header); + ret->type_count=blk->count; + ret->type=(struct street_type *)p; + p+=ret->type_count*sizeof(struct street_type); + assert(ret->header->count == blk->count); + *p_p=p; +} + +static void +street_coord_get_begin(unsigned char **p_p) +{ + unsigned char *p=*p_p; + struct street_str *str; + + str=(struct street_str *)p; + while (str->segid) { + str++; + } + p=(unsigned char *)str; + p+=4; + *p_p=p; +} + +void +street_draw_block(struct block_info *blk_inf, unsigned char *p, unsigned char *end, void *data) +{ + struct street_str *str; + struct street_header_type header_type; + struct street_type *str_type; + int include,count,ncount,bytes,offset; + struct draw_info *drw_inf=data; + struct segment seg; + + seg.blk_inf=*blk_inf; + + street_header_type_get(blk_inf->block, &p, &header_type); + if (header_type.header->order >= drw_inf->limit) + return; + + str_type=header_type.type; + bytes=street_get_bytes(blk_inf->block); + str=(struct street_str *)p; + count=0; + ncount=0; + street_coord_get_begin(&p); + str_type--; + while (str->segid) { + include=1; + if (str[1].segid < 0) { + include=0; + str_type++; + } + seg.data[0]=str; + seg.data[1]=str_type; + seg.data[2]=p; + seg.data[3]=header_type.header; + street_safety_check(str); + offset=0; + if (header_type.header->order < 0x2) + offset=3; + else if (header_type.header->order < 0x4 && str->type != 0x6 && str->type != 0x46) + offset=2; + else if (header_type.header->order < 0x6) + offset=1; + if (str->limit == 0x33) + offset=4; + street_draw_segment(drw_inf->co, &seg, &p, end-4, blk_inf->block->c, bytes, include, drw_inf->display+offset); + str++; + } +} + +void +street_bti_draw_block(struct block_info *blk_inf, unsigned char *p, unsigned char *end, void *data) +{ + struct draw_info *drw_inf=data; + struct street_bti *str; + struct point pnt; + struct param_list param[100]; + struct segment seg; + + while (p < end) { + str=(struct street_bti *)p; + seg.data[0]=str; + p+=sizeof(*str); + if (transform(drw_inf->co->trans, &str->c, &pnt)) { + display_add(&drw_inf->co->disp[display_bti], 4, 0, NULL, 1, &pnt, NULL, &seg, sizeof(seg)); + if (drw_inf->co->data_window[data_window_type_point]) + data_window_add(drw_inf->co->data_window[data_window_type_point], param, street_bti_get_param(&seg, param, 100)); + } + } +} + +void +street_route_draw(struct container *co) +{ + struct route_path_segment *route=NULL; + struct point xpoints[2]; + + if (co->route) + route=route_path_get_all(co->route); + while (route) { + if (!route->segid) { + transform(co->trans, &route->c[0], &xpoints[0]); + transform(co->trans, &route->c[1], &xpoints[1]); + display_add(&co->disp[display_street_route], 2, 0, NULL, 2, xpoints, NULL, NULL, 0); + } + route=route->next; + } +} + +struct street_coord * +street_coord_get(struct block_info *blk_inf, struct street_str *str) +{ + struct block *blk; + unsigned char *p=(unsigned char *)(blk_inf->block),*end,*p_sav; + struct street_header_type hdr_type; + struct street_str *str_curr; + struct coord f,*c; + struct street_coord *ret; + int bytes,num,points,include; + int debug=0; + + end=p; + blk=block_get(&p); + end+=blk->size; + + street_header_type_get(blk, &p, &hdr_type); + str_curr=(struct street_str *)p; + num=str-str_curr; + street_coord_get_begin(&p); + bytes=street_get_bytes(blk); + if (debug) { + printf("num=%d\n", num); + } + street_get_coord(&p, bytes, blk->c, &f); + while (num && str_curr->segid) { + while (! street_get_coord(&p, bytes, blk->c, &f) && p < end); + str_curr++; + num--; + } + include=(str[1].segid > 0); + p_sav=p-2*bytes; + points=1+include; + while (! street_get_coord(&p, bytes, blk->c, &f) && p < end) + points++; + + if (debug) + printf("p=%p points=%d\n",p_sav, points); + p=p_sav; + ret=malloc(sizeof(struct street_coord)+points*sizeof(struct coord)); + ret->count=points; + c=ret->c; + while (points) { + street_get_coord(&p, bytes, blk->c, c); + c++; + points--; + } + return ret; +} + +#if 0 +struct street_nearest * +street_find_nearest(struct map_data *mdata, struct coord *c) +{ + struct street_nearest *ret=g_new0(struct street_nearest,1); + struct transformation t; + int max_dist=1000; + + transform_setup_source_rect_limit(&t,c,max_dist); + + ret->click.xy=*c; + ret->dist=INT_MAX; + ret->mode=0; + + map_data_foreach(mdata, file_street_str, &t, 48, route_process_street_block, ret); + + ret->mode=1; + ret->dist=INT_MAX; + + return ret; +} + +#endif + +int +street_get_by_id(struct map_data *mdat, int id, struct block_info *res_blk_inf, struct street_str **res_str) +{ + int debug=0; + int res,block,num; + struct map_data *mdat_res; + struct block *blk; + unsigned char *p; + struct street_header_type hdr_type; + struct street_str *str; + + if (tree_search_hv_map(mdat, file_street_str, (id >> 8) | 0x31000000, id & 0xff, &res, &mdat_res)) { + return 1; + } + + block=res >> 12; + num=res & 0xfff; + if (debug) { + printf("block=0x%x\n", block); + printf("num=0x%x\n", num); + } + blk=block_get_byindex(mdat_res->file[file_street_str], block, &p); + res_blk_inf->mdata=mdat_res; + res_blk_inf->file=mdat_res->file[file_street_str]; + res_blk_inf->block=blk; + if (debug) { + printf("blk->count=0x%x\n", blk->count); + } + street_header_type_get(blk, &p, &hdr_type); + str=(struct street_str *)p; + str+=num; + *res_str=str; + return 0; +} + +int +street_get_param(struct segment *seg, struct param_list *param, int count, int verbose) +{ + char buffer[1024]; + int i=count,j; + struct street_str *str=seg->data[0]; + struct street_type *type=seg->data[1]; + struct street_name name; + struct street_name_info name_info; +#if 0 + struct street_name_number_info name_number_info; +#endif + + param_add_hex("Type-Addr", (unsigned char *)type-seg->blk_inf.file->begin, ¶m, &count); + param_add_hex("Order", type->order, ¶m, &count); + param_add_hex("Country", type->country, ¶m, &count); + + param_add_hex("Addr", (unsigned char *)str-seg->blk_inf.file->begin, ¶m, &count); + param_add_hex_sig("Seg-Id", str->segid, ¶m, &count); + param_add_hex("Limit", str->limit, ¶m, &count); + param_add_hex("Unknown2", str->unknown2, ¶m, &count); + param_add_hex("Unknown3", str->unknown3, ¶m, &count); + param_add_hex("Type", str->type, ¶m, &count); + param_add_hex("Name-Id", str->nameid, ¶m, &count); + if (str->segid) { + street_name_get_by_id(&name, seg->blk_inf.mdata, str->nameid); + + param_add_hex("Len", name.len, ¶m, &count); + param_add_hex("Country", name.country, ¶m, &count); + param_add_hex_sig("TownAssoc", name.townassoc, ¶m, &count); + printf("TownAssoc 0x%lx\n", name.townassoc+str->segid); + param_add_string("Name1", name.name1, ¶m, &count); + param_add_string("Name2", name.name2, ¶m, &count); + param_add_hex("Segments", name.segment_count, ¶m, &count); + if (verbose) { + for (j = 0 ; j < name.segment_count ; j++) { + sprintf(buffer,"0x%x 0x%x", name.segments[j].country, name.segments[j].segid); + param_add_string("Segment", buffer, ¶m, &count); + } + param_add_hex("Len", name.aux_len, ¶m, &count); + while (street_name_get_info(&name_info, &name)) { + param_add_hex("Len", name_info.len, ¶m, &count); + param_add_hex("Tag", name_info.tag, ¶m, &count); + param_add_hex("Dist", name_info.dist, ¶m, &count); + param_add_hex("Country", name_info.country, ¶m, &count); + param_add_hex("X", name_info.c->x, ¶m, &count); + param_add_hex("Y", name_info.c->y, ¶m, &count); + param_add_dec("First", name_info.first, ¶m, &count); + param_add_dec("Last", name_info.last, ¶m, &count); + param_add_hex("Segments", name_info.segment_count, ¶m, &count); + } +#if 0 + int tag; + int k, segs; + printf("\n"); + printf("Len 0x%x\n",get_short(&stn)); + tag=*stn++; + printf("Tag 0x%x\n",tag); + if (tag == 0xc0 || tag == 0xd0 || tag == 0xe0) { + printf("DistAssoc 0x%lx\n",get_long(&stn)); + printf("Country 0x%lx\n",get_long(&stn)); + printf("X 0x%lx\n",get_long(&stn)); + printf("Y 0x%lx\n",get_long(&stn)); + printf("First %ld\n",get_triple(&stn)); + printf("Last %ld\n",get_triple(&stn)); + segs=get_long(&stn); + printf("Segs 0x%x\n",segs); + for (k = 0 ; k < 0 ; k++) { + printf("SegId 0x%lx\n", get_long(&stn)); + printf("Country 0x%lx\n",get_long(&stn)); + } + } else if (tag == 0x8f || tag == 0xaa || tag == 0xab || tag == 0xae || tag == 0xaf || tag == 0x9a || tag == 0x9e || tag == 0x9f) { + printf("X 0x%lx\n",get_long(&stn)); + printf("Y 0x%lx\n",get_long(&stn)); + printf("First %ld\n",get_triple(&stn)); + printf("Last %ld\n",get_triple(&stn)); + printf("SegId 0x%lx\n",get_long(&stn)); + printf("Country 0x%lx\n",get_long(&stn)); + } else { + printf("Unknown tag 0x%x\n", tag); + break; + } + } +#endif + } + } else { + if (!verbose) { + param_add_string("Len", "", ¶m, &count); + param_add_string("Country", "", ¶m, &count); + param_add_string("TownAssoc", "", ¶m, &count); + param_add_string("Name1", "", ¶m, &count); + param_add_string("Name2", "", ¶m, &count); + param_add_string("Segments", "", ¶m, &count); + } + } + return i-count; +} + +int +street_bti_get_param(struct segment *seg, struct param_list *param, int count) +{ + int i=count; + struct street_bti *str=seg->data[0]; + + param_add_hex("Addr", (unsigned char *)str-seg->blk_inf.file->begin, ¶m, &count); + param_add_hex("Unknown1", str->unknown1, ¶m, &count); + param_add_hex("Segid1", str->segid1, ¶m, &count); + param_add_hex("Country1", str->country1, ¶m, &count); + param_add_hex("Segid2", str->segid2, ¶m, &count); + param_add_hex("Country2", str->country2, ¶m, &count); + param_add_hex("Unknown5", str->unknown5, ¶m, &count); + param_add_hex("X", str->c.x, ¶m, &count); + param_add_hex("Y", str->c.y, ¶m, &count); + + return i-count; +} |