diff options
-rw-r--r-- | navit/Makefile.am | 2 | ||||
-rw-r--r-- | navit/attr_def.h | 1 | ||||
-rw-r--r-- | navit/coord.c | 16 | ||||
-rw-r--r-- | navit/coord.h | 23 | ||||
-rw-r--r-- | navit/item.c | 29 | ||||
-rw-r--r-- | navit/item.h | 13 | ||||
-rw-r--r-- | navit/item_def.h | 1 | ||||
-rw-r--r-- | navit/map/binfile/binfile.c | 4 | ||||
-rw-r--r-- | navit/maptool/Makefile.am | 2 | ||||
-rw-r--r-- | navit/maptool/ch.c | 495 | ||||
-rw-r--r-- | navit/maptool/itembin.c | 13 | ||||
-rw-r--r-- | navit/maptool/maptool.c | 77 | ||||
-rw-r--r-- | navit/maptool/maptool.h | 8 | ||||
-rw-r--r-- | navit/maptool/misc.c | 12 | ||||
-rw-r--r-- | navit/maptool/tempfile.c | 22 | ||||
-rw-r--r-- | navit/maptool/tile.c | 17 | ||||
-rw-r--r-- | navit/navit.c | 3 |
17 files changed, 667 insertions, 71 deletions
diff --git a/navit/Makefile.am b/navit/Makefile.am index 5c2bf0f3e..1797d2783 100644 --- a/navit/Makefile.am +++ b/navit/Makefile.am @@ -34,7 +34,7 @@ EXTRA_DIST = navit_shipped.xml navit.dtd libnavit_la_SOURCES = announcement.c atom.c attr.c cache.c callback.c command.c compass.c config_.c coord.c country.c data_window.c debug.c \ event.c event_glib.h file.c graphics.c gui.c item.c layout.c log.c main.c map.c \ linguistics.c mapset.c maptype.c menu.c messages.c navit.c navigation.c osd.c param.c phrase.c plugin.c popup.c \ - profile.c projection.c roadprofile.c route.c search.c speech.c start_real.c transform.c track.c \ + profile.c projection.c roadprofile.c route.c routech.c search.c speech.c start_real.c transform.c track.c \ util.c vehicle.c vehicleprofile.c xmlconfig.c announcement.h atom.h attr.h attr_def.h cache.h callback.h color.h command.h compass.h config_.h coord.h country.h \ data.h data_window.h data_window_int.h debug.h destination.h draw_info.h endianess.h event.h \ file.h graphics.h gtkext.h gui.h item.h item_def.h keys.h log.h layer.h layout.h linguistics.h main.h map-share.h map.h\ diff --git a/navit/attr_def.h b/navit/attr_def.h index cad04f50f..20f3322ef 100644 --- a/navit/attr_def.h +++ b/navit/attr_def.h @@ -269,6 +269,7 @@ ATTR(sequence_range) ATTR(angle_range) ATTR(speed_range) ATTR(attr_types) +ATTR(ch_edge) ATTR2(0x0004ffff,type_special_end) ATTR2(0x00050000,type_double_begin) ATTR(position_height) diff --git a/navit/coord.c b/navit/coord.c index 4f77b891d..af169465d 100644 --- a/navit/coord.c +++ b/navit/coord.c @@ -364,4 +364,20 @@ void coord_format(float lat,float lng, enum coord_format fmt, char * buffer, int } +unsigned int +coord_hash(const void *key) +{ + const struct coord *c=key; + return c->x^c->y; +} + +int +coord_equal(const void *a, const void *b) +{ + const struct coord *c_a=a; + const struct coord *c_b=b; + if (c_a->x == c_b->x && c_a->y == c_b->y) + return TRUE; + return FALSE; +} /** @} */ diff --git a/navit/coord.h b/navit/coord.h index 355f63f0a..a8221fa23 100644 --- a/navit/coord.h +++ b/navit/coord.h @@ -132,3 +132,26 @@ void coord_rect_extend(struct coord_rect *r, struct coord *c); void coord_format(float lat,float lng, enum coord_format, char * buffer, int size); #endif +/* prototypes */ +enum coord_format; +enum projection; +struct attr; +struct coord; +struct coord_rect; +struct pcoord; +struct coord *coord_get(unsigned char **p); +struct coord *coord_new(int x, int y); +struct coord *coord_new_from_attrs(struct attr *parent, struct attr **attrs); +void coord_destroy(struct coord *c); +struct coord_rect *coord_rect_new(struct coord *lu, struct coord *rl); +void coord_rect_destroy(struct coord_rect *r); +int coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2); +int coord_rect_contains(struct coord_rect *r, struct coord *c); +void coord_rect_extend(struct coord_rect *r, struct coord *c); +int coord_parse(const char *c_str, enum projection pro, struct coord *c_ret); +int pcoord_parse(const char *c_str, enum projection pro, struct pcoord *pc_ret); +void coord_print(enum projection pro, struct coord *c, FILE *out); +void coord_format(float lat, float lng, enum coord_format fmt, char *buffer, int size); +unsigned int coord_hash(const void *key); +int coord_equal(const void *a, const void *b); +/* end of prototypes */ diff --git a/navit/item.c b/navit/item.c index 7d39083c7..8d128d98b 100644 --- a/navit/item.c +++ b/navit/item.c @@ -246,6 +246,21 @@ item_hash_equal(gconstpointer a, gconstpointer b) return FALSE; } +unsigned int +item_id_hash(const void *key) +{ + const struct item_id *id=key; + return id->id_hi^id->id_lo; +} + +int +item_id_equal(const void *a, const void *b) +{ + const struct item_id *id_a=a; + const struct item_id *id_b=b; + return (id_a->id_hi == id_b->id_hi && id_a->id_lo == id_b->id_lo); +} + struct item_hash * @@ -310,19 +325,25 @@ item_range_contains_item(struct item_range *range, enum item_type type) } void +item_dump_attr(struct item *item, struct map *map, FILE *out) +{ + struct attr attr; + fprintf(out,"type=%s", item_to_name(item->type)); + while (item_attr_get(item, attr_any, &attr)) + fprintf(out," %s='%s'", attr_to_name(attr.type), attr_to_text(&attr, map, 1)); +} + +void item_dump_filedesc(struct item *item, struct map *map, FILE *out) { int i,count,max=16384; struct coord ca[max]; - struct attr attr; count=item_coord_get(item, ca, item->type < type_line ? 1: max); if (item->type < type_line) fprintf(out,"mg:0x%x 0x%x ", ca[0].x, ca[0].y); - fprintf(out,"type=%s", item_to_name(item->type)); - while (item_attr_get(item, attr_any, &attr)) - fprintf(out," %s='%s'", attr_to_name(attr.type), attr_to_text(&attr, map, 1)); + item_dump_attr(item, map, out); fprintf(out,"\n"); if (item->type >= type_line) for (i = 0 ; i < count ; i++) diff --git a/navit/item.h b/navit/item.h index cfa7527cf..c9a145d7e 100644 --- a/navit/item.h +++ b/navit/item.h @@ -79,6 +79,9 @@ struct item_id { int id_lo; }; +#define ITEM_ID_FMT "(0x%x,0x%x)" +#define ITEM_ID_ARGS(x) (x).id_hi,(x).id_lo + struct item { enum item_type type; int id_hi; @@ -94,19 +97,22 @@ extern struct item_range { /* prototypes */ enum attr_type; +enum change_mode; enum item_type; +enum projection; struct attr; struct coord; struct item; struct item_hash; +struct item_range; +struct map; struct map_selection; int *item_get_default_flags(enum item_type type); void item_coord_rewind(struct item *it); int item_coord_get(struct item *it, struct coord *c, int count); int item_coord_set(struct item *it, struct coord *c, int count, enum change_mode mode); int item_coord_get_within_selection(struct item *it, struct coord *c, int count, struct map_selection *sel); -int item_coord_get_pro(struct item *it, struct coord *c, int count, enum projection pro); -/* does the next returned coordinate mark a node */ +int item_coord_get_pro(struct item *it, struct coord *c, int count, enum projection to); int item_coord_is_node(struct item *it); void item_attr_rewind(struct item *it); int item_attr_get(struct item *it, enum attr_type attr_type, struct attr *attr); @@ -114,6 +120,8 @@ int item_attr_set(struct item *it, struct attr *attr, enum change_mode mode); struct item *item_new(char *type, int zoom); enum item_type item_from_name(const char *name); char *item_to_name(enum item_type item); +unsigned int item_id_hash(const void *key); +int item_id_equal(const void *a, const void *b); struct item_hash *item_hash_new(void); void item_hash_insert(struct item_hash *h, struct item *item, void *val); int item_hash_remove(struct item_hash *h, struct item *item); @@ -121,6 +129,7 @@ void *item_hash_lookup(struct item_hash *h, struct item *item); void item_hash_destroy(struct item_hash *h); int item_range_intersects_range(struct item_range *range1, struct item_range *range2); int item_range_contains_item(struct item_range *range, enum item_type type); +void item_dump_attr(struct item *item, struct map *map, FILE *out); void item_dump_filedesc(struct item *item, struct map *map, FILE *out); /* end of prototypes */ diff --git a/navit/item_def.h b/navit/item_def.h index f62c5c032..fbd549da7 100644 --- a/navit/item_def.h +++ b/navit/item_def.h @@ -328,6 +328,7 @@ ITEM(poi_shop_furniture) ITEM(poi_shop_parfum) ITEM(poi_shop_drugstore) ITEM(poi_shop_photo) +ITEM(ch_node) /* Line */ ITEM2(0x80000000,line) ITEM2(0x80000001,line_unspecified) diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c index fb12d5e51..93674e980 100644 --- a/navit/map/binfile/binfile.c +++ b/navit/map/binfile/binfile.c @@ -1014,8 +1014,10 @@ static struct item * map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo) { struct tile *t; - if (mr->m->eoc) + if (mr->m->eoc) { + while (pop_tile(mr)); push_zipfile_tile(mr, id_hi); + } t=mr->t; t->pos=t->start+id_lo; mr->item.id_hi=id_hi; diff --git a/navit/maptool/Makefile.am b/navit/maptool/Makefile.am index 006c01db0..358e98229 100644 --- a/navit/maptool/Makefile.am +++ b/navit/maptool/Makefile.am @@ -4,5 +4,5 @@ if !SUPPORT_ANDROID endif AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit @ZLIB_CFLAGS@ @POSTGRESQL_CFLAGS@ -maptool_SOURCES = buffer.c coastline.c geom.c itembin.c maptool.c misc.c osm.c sourcesink.c tempfile.c tile.c zip.c maptool.h +maptool_SOURCES = buffer.c ch.c coastline.c geom.c itembin.c maptool.c misc.c osm.c sourcesink.c tempfile.c tile.c zip.c maptool.h maptool_LDADD = ../libnavit.la @NAVIT_LIBS@ @WORDEXP_LIBS@ @ZLIB_LIBS@ @POSTGRESQL_LIBS@ @INTLLIBS@ @LIBC_LIBS@ diff --git a/navit/maptool/ch.c b/navit/maptool/ch.c new file mode 100644 index 000000000..71f8e341d --- /dev/null +++ b/navit/maptool/ch.c @@ -0,0 +1,495 @@ +#include <math.h> +#include <stdlib.h> +#include "maptool.h" +#include "coord.h" +#include "file.h" +#include "debug.h" + +struct ch_edge { + int flags; + int weight; + struct item_id target,middle; +}; + +struct node { + int first_edge; + int dummy; +} *nodes; +int node_count; + +struct edge { + unsigned target:26; + unsigned scedge1:6; + unsigned weight:28; + unsigned type:2; + unsigned flags:2; + unsigned int edge_count; + unsigned scedge2:6; + unsigned scmiddle:26; +} *edges; + +int edge_count; + +struct newnode { + int newnode; +} *newnodes; + +int newnode_count; + +GHashTable *newnode_hash; + +struct edge_hash_item { + int first,last; +}; + + +GHashTable *edge_hash; + +struct file *sgr,*ddsg_node_index; + +struct coord *node_index; + +GHashTable *sgr_nodes_hash; + +static int ch_levels=14; + +static int +road_speed(enum item_type type) +{ + switch (type) { + case type_street_0: + case type_street_1_city: + case type_living_street: + case type_street_service: + case type_track_gravelled: + case type_track_unpaved: + return 10; + case type_street_2_city: + case type_track_paved: + return 30; + case type_street_3_city: + return 40; + case type_street_4_city: + return 50; + case type_highway_city: + return 80; + case type_street_1_land: + return 60; + case type_street_2_land: + return 65; + case type_street_3_land: + return 70; + case type_street_4_land: + return 80; + case type_street_n_lanes: + return 120; + case type_highway_land: + return 120; + case type_ramp: + return 40; + case type_roundabout: + return 10; + case type_ferry: + return 40; + default: + return 0; + } +} + +static GHashTable * +coord_hash_new(void) +{ + return g_hash_table_new_full(coord_hash, coord_equal, g_free, NULL); +} + +#define sq(x) ((double)(x)*(x)) + +static void +add_node_to_hash(FILE *idx, GHashTable *hash, struct coord *c, int *nodes) +{ + if (! g_hash_table_lookup(hash, c)) { + struct coord *ct=g_new(struct coord, 1); + *ct=*c; + fwrite(c, sizeof(*c), 1, idx); + (*nodes)++; + g_hash_table_insert(hash, ct, (void *)(*nodes)); + } + +} + +static guint +edge_hash_hash(gconstpointer key) +{ + const struct edge_hash_item *itm=key; + return itm->first*2654435761UL+itm->last; +} + +static gboolean +edge_hash_equal(gconstpointer a, gconstpointer b) +{ + const struct edge_hash_item *itm_a=a; + const struct edge_hash_item *itm_b=b; + return (itm_a->first == itm_b->first && itm_a->last == itm_b->last); +} + + + +static void +ch_generate_ddsg(FILE *in, FILE *ref, FILE *idx, FILE *ddsg) +{ + GHashTable *hash=coord_hash_new(); + struct item_bin *ib; + int nodes=0,edges=0; + + while ((ib=read_item(in))) { + int ccount=ib->clen/2; + struct coord *c=(struct coord *)(ib+1); + if (road_speed(ib->type)) { + add_node_to_hash(idx, hash, &c[0], &nodes); + add_node_to_hash(idx, hash, &c[ccount-1], &nodes); + edges++; + } + } + edge_hash=g_hash_table_new_full(edge_hash_hash, edge_hash_equal, g_free, g_free); + fseek(in, 0, SEEK_SET); + fprintf(ddsg,"d\n"); + fprintf(ddsg,"%d %d\n", nodes, edges); + while ((ib=read_item(in))) { + int i,ccount=ib->clen/2; + struct coord *c=(struct coord *)(ib+1); + int n1,n2,speed=road_speed(ib->type); + struct item_id road_id; + double l; + fread(&road_id, sizeof(road_id), 1, ref); + if (speed) { + struct edge_hash_item *hi=g_new(struct edge_hash_item, 1); + struct item_id *id=g_new(struct item_id, 1); + *id=road_id; + dbg_assert((n1=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[0]))) != 0); + dbg_assert((n2=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[ccount-1]))) != 0); + l=0; + for (i = 0 ; i < ccount-1 ; i++) { + l+=sqrt(sq(c[i+1].x-c[i].x)+sq(c[i+1].y-c[i].y)); + } + fprintf(ddsg,"%d %d %d 0\n", n1-1, n2-1, (int)(l*36/speed)); + hi->first=n1-1; + hi->last=n2-1; + g_hash_table_insert(edge_hash, hi, id); + } + } + g_hash_table_destroy(hash); +} + +static void +ch_generate_sgr(char *suffix) +{ + char command[1024]; + sprintf(command,"./contraction-hierarchies-20080621/main -s -p -f ddsg_%s.tmp -o hcn_%s.tmp -l hcn_log_%s.tmp -x 190 -y 1 -e 600 -p 1000 -k 1,3.3,2,10,3,10,5",suffix,suffix,suffix); + printf("%s\n",command); + system(command); + sprintf(command,"./contraction-hierarchies-20080621/main -c -f ddsg_%s.tmp -h hcn_%s.tmp -k 1,3.3,2,10,3,10,5 -C ch_%s.tmp -O 1 -z sgr_%s.tmp",suffix,suffix,suffix,suffix); + printf("%s\n",command); + system(command); +} + +static void +ch_process_node(FILE *out, int node, int resolve) +{ + int first_edge_id=nodes[node].first_edge; + int last_edge_id=nodes[node+1].first_edge; + int edge_id; + struct ch_edge ch_edge; + memset(&ch_edge, 0, sizeof(ch_edge)); + struct edge_hash_item fwd,rev; + item_bin_init(item_bin, type_ch_node); + int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER(node))); +#if 0 + dbg(0,"0x%x,0x%x\n",node_index[oldnode].x,node_index[oldnode].y); +#endif + item_bin_add_coord(item_bin, &node_index[oldnode], 1); + fwd.first=oldnode; + rev.last=oldnode; + for (edge_id = first_edge_id ; edge_id < last_edge_id ; edge_id++) { + if (resolve) { + struct edge *edge=&edges[edge_id]; + int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER((int)edge->target))); + struct item_id *id; + ch_edge.weight=edge->weight; + fwd.last=oldnode; + rev.first=oldnode; + ch_edge.flags=edge->flags & 3; + if (edge->scmiddle == 67108863) { + id=g_hash_table_lookup(edge_hash, &fwd); + if (!id) { + ch_edge.flags|=8; + id=g_hash_table_lookup(edge_hash, &rev); + } + if (id == NULL) { + fprintf(stderr,"Shortcut %d Weight %d\n",edge->scmiddle,edge->weight); + fprintf(stderr,"Neither %d-%d nor %d-%d exists\n",fwd.first,fwd.last,rev.first,rev.last); + exit(1); + } else { + ch_edge.middle=*id; +#if 0 + dbg(0,"middle street id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); +#endif + } + } else { + ch_edge.flags|=4; + id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->scmiddle)); + dbg_assert(id != NULL); + ch_edge.middle=*id; +#if 0 + dbg(0,"middle node id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); +#endif + } + id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->target)); + if (id == NULL) { + fprintf(stderr,"Failed to look up target %d\n",edge->target); + } +#if 0 + dbg(0,"id for %d is "ITEM_ID_FMT"\n",edge->target,ITEM_ID_ARGS(*id)); +#endif + ch_edge.target=*id; + } + item_bin_add_attr_data(item_bin,attr_ch_edge,&ch_edge,sizeof(ch_edge)); + } + item_bin_write(item_bin, out); +} + +static void +ch_process_nodes(FILE *out, int pos, int count, int resolve) +{ + int i; + printf("count %d sum=%d newnode_count=%d\n",count,pos,newnode_count); + for (i = 0 ; i < count ; i++) + ch_process_node(out, pos+i, resolve); +} + + +static void +ch_process(FILE **files, int depth, int resolve) +{ + int count=newnode_count; + int pos=0; + + while (depth > 0 && pos < newnode_count) { + count=(count+1)/2; + ch_process_nodes(files[depth], pos, count, resolve); + pos+=count; + depth--; + } + ch_process_nodes(files[depth], pos, newnode_count-pos, resolve); +} + +static void +ch_setup(char *suffix) +{ + int i; + if (!sgr) { + int *data,size,offset=0; + char *filename=tempfile_name(suffix,"sgr"); + printf("filename=%s\n",filename); + sgr=file_create(filename,0); + g_free(filename); + dbg_assert(sgr != NULL); + file_mmap(sgr); + + size=sizeof(int); + data=(int *)file_data_read(sgr, offset, size); + node_count=*data; + offset+=size; + + size=node_count*sizeof(struct node); + nodes=(struct node *)file_data_read(sgr, offset, size); + offset+=size; + + size=sizeof(int); + data=(int *)file_data_read(sgr, offset, size); + edge_count=*data; + offset+=size; + + size=edge_count*sizeof(struct edge); + edges=(struct edge *)file_data_read(sgr, offset, size); + offset+=size; + + size=sizeof(int); + data=(int *)file_data_read(sgr, offset, size); + newnode_count=*data; + offset+=size; + + size=edge_count*sizeof(struct newnode); + newnodes=(struct newnode *)file_data_read(sgr, offset, size); + offset+=size; + + newnode_hash=g_hash_table_new(NULL, NULL); + + for (i = 0 ; i < newnode_count ; i++) { + g_hash_table_insert(newnode_hash, GINT_TO_POINTER(newnodes[i].newnode), GINT_TO_POINTER(i)); + } + } + if (!ddsg_node_index) { + char *filename=tempfile_name(suffix,"ddsg_coords"); + ddsg_node_index=file_create(filename,0); + g_free(filename); + dbg_assert(ddsg_node_index != NULL); + file_mmap(ddsg_node_index); + node_index=(struct coord *)file_data_read(ddsg_node_index, 0, file_size(ddsg_node_index)); + } +} + +static void +ch_create_tempfiles(char *suffix, FILE **files, int count, int mode) +{ + char name[256]; + int i; + + for (i = 0 ; i <= count ; i++) { + sprintf(name,"graph_%d",i); + files[i]=tempfile(suffix, name, mode); + } +} + +static void +ch_close_tempfiles(FILE **files, int count) +{ + int i; + + for (i = 0 ; i <= count ; i++) { + fclose(files[i]); + } +} + +static void +ch_remove_tempfiles(char *suffix, int count) +{ + char name[256]; + int i; + + for (i = 0 ; i <= count ; i++) { + sprintf(name,"graph_%d",i); + tempfile_unlink(suffix, name); + } +} + +static void +ch_copy_to_tiles(char *suffix, int count, struct tile_info *info, FILE *ref) +{ + char name[256]; + int i; + FILE *f; + struct item_bin *item_bin; + + for (i = count ; i >= 0 ; i--) { + sprintf(name,"graph_%d",i); + f=tempfile(suffix, name, 0); + while ((item_bin = read_item(f))) { + tile_write_item_minmax(info, item_bin, ref, i, i); + } + fclose(f); + } +} + +void +ch_generate_tiles(char *map_suffix, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info) +{ + struct tile_info info; + FILE *in,*ref,*ddsg_coords,*ddsg; + info.write=0; + info.maxlen=0; + info.suffix=suffix; + info.tiles_list=NULL; + info.tilesdir_out=tilesdir_out; + FILE *graphfiles[ch_levels+1]; + + ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); + in=tempfile(map_suffix,"ways_split",0); + ref=tempfile(map_suffix,"ways_split_ref",0); + ddsg_coords=tempfile(suffix,"ddsg_coords",1); + ddsg=tempfile(suffix,"ddsg",1); + ch_generate_ddsg(in, ref, ddsg_coords, ddsg); + fclose(in); + fclose(ref); + fclose(ddsg_coords); + fclose(ddsg); + ch_generate_sgr(suffix); + ch_setup(suffix); + ch_process(graphfiles, ch_levels, 0); + ch_close_tempfiles(graphfiles, ch_levels); + + tile_hash=g_hash_table_new(g_str_hash, g_str_equal); + ch_copy_to_tiles(suffix, ch_levels, &info, NULL); + merge_tiles(&info); + + write_tilesdir(&info, zip_info, tilesdir_out); +} + +void +ch_assemble_map(char *map_suffix, char *suffix, struct zip_info *zip_info) +{ + struct tile_info info; + struct tile_head *th; + FILE *graphfiles[ch_levels+1]; + + info.write=1; + info.maxlen=zip_info->maxnamelen; + info.suffix=suffix; + info.tiles_list=NULL; + info.tilesdir_out=NULL; + FILE *ref=tempfile(suffix,"sgr_ref",1); + struct item_id id; + int nodeid=0; + + create_tile_hash(); + th=tile_head_root; + while (th) { + th->zip_data=malloc(th->total_size); + th->process=1; + th=th->next; + } + + ch_setup(suffix); + ch_copy_to_tiles(suffix, ch_levels, &info, ref); + fclose(ref); + ref=tempfile(suffix,"sgr_ref",0); + sgr_nodes_hash=g_hash_table_new_full(NULL, NULL, NULL, g_free); + while (fread(&id, sizeof(id), 1, ref)) { + struct item_id *id2=g_new(struct item_id, 1); + *id2=id; +#if 0 + dbg(0,"%d is "ITEM_ID_FMT"\n",nodeid,ITEM_ID_ARGS(*id2)); +#endif + g_hash_table_insert(sgr_nodes_hash, GINT_TO_POINTER(nodeid), id2); + nodeid++; + } + th=tile_head_root; + while (th) { + th->zip_data=malloc(th->total_size); + th->total_size_used=0; + th=th->next; + } + ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); + ch_process(graphfiles, ch_levels, 1); + ch_close_tempfiles(graphfiles, ch_levels); + + g_hash_table_destroy(newnode_hash); + g_hash_table_destroy(edge_hash); + g_hash_table_destroy(sgr_nodes_hash); + + ch_copy_to_tiles(suffix, ch_levels, &info, NULL); + write_tilesdir(&info, zip_info, NULL); + + th=tile_head_root; + while (th) { + if (th->name[0]) { + if (th->total_size != th->total_size_used) { + fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used); + exit(1); + } + write_zipmember(zip_info, th->name, zip_info->maxnamelen, th->zip_data, th->total_size); + } else { + fwrite(th->zip_data, th->total_size, 1, zip_info->index); + } + th=th->next; + } +} diff --git a/navit/maptool/itembin.c b/navit/maptool/itembin.c index 3e143bf51..9b42b91c2 100644 --- a/navit/maptool/itembin.c +++ b/navit/maptool/itembin.c @@ -94,19 +94,24 @@ item_bin_add_coord_rect(struct item_bin *ib, struct rect *r) } void -item_bin_add_attr(struct item_bin *ib, struct attr *attr) +item_bin_add_attr_data(struct item_bin *ib, enum attr_type type, void *data, int size) { struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1); - int size=attr_data_size(attr); int pad=(4-(size%4))%4; - ab->type=attr->type; - memcpy(ab+1, attr_data_get(attr), size); + ab->type=type; + memcpy(ab+1, data, size); memset((unsigned char *)(ab+1)+size, 0, pad); ab->len=(size+pad)/4+1; ib->len+=ab->len+1; } void +item_bin_add_attr(struct item_bin *ib, struct attr *attr) +{ + item_bin_add_attr_data(ib, attr->type, attr_data_get(attr), attr_data_size(attr)); +} + +void item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val) { struct attr attr; diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c index 171dfbb96..e0dd1a94f 100644 --- a/navit/maptool/maptool.c +++ b/navit/maptool/maptool.c @@ -158,10 +158,11 @@ int main(int argc, char **argv) struct map *map_handle=NULL; #if 0 char *suffixes[]={"m0l0", "m0l1","m0l2","m0l3","m0l4","m0l5","m0l6"}; + char *suffixes[]={"m","r"}; #else char *suffixes[]={""}; #endif - char *suffix=""; + char *suffix=suffixes[0]; int suffix_count=sizeof(suffixes)/sizeof(char *); int i; @@ -453,21 +454,25 @@ int main(int argc, char **argv) } zipnum=zip_info.zipnum; fprintf(stderr,"PROGRESS: Phase 4: generating tiles %s\n",suffix); - for (f = 0 ; f < 3 ; f++) - files[f]=NULL; - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) - files[1]=tempfile(suffix,"ways_split",0); - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); tilesdir=tempfile(suffix,"tilesdir",1); - phase4(files,3,suffix,tilesdir,&zip_info); - fclose(tilesdir); - for (f = 0 ; f < 3 ; f++) { - if (files[f]) - fclose(files[f]); + if (!strcmp(suffix,"r")) { + ch_generate_tiles(suffixes[0],suffix,tilesdir,&zip_info); + } else { + for (f = 0 ; f < 3 ; f++) + files[f]=NULL; + if (process_relations) + files[0]=tempfile(suffix,"relations",0); + if (process_ways) + files[1]=tempfile(suffix,"ways_split",0); + if (process_nodes) + files[2]=tempfile(suffix,"nodes",0); + phase4(files,3,suffix,tilesdir,&zip_info); + for (f = 0 ; f < 3 ; f++) { + if (files[f]) + fclose(files[f]); + } } + fclose(tilesdir); zip_info.zipnum=zipnum; } if (end == 4) @@ -475,18 +480,6 @@ int main(int argc, char **argv) if (start <= 5) { phase=4; fprintf(stderr,"PROGRESS: Phase 5: assembling map %s\n",suffix); - for (f = 0 ; f < 3 ; f++) { - files[f]=NULL; - references[f]=NULL; - } - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) { - files[1]=tempfile(suffix,"ways_split",0); - references[1]=tempfile(suffix,"ways_split_ref",1); - } - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); if (i == 0) { zip_info.dir_size=0; zip_info.offset=0; @@ -498,14 +491,30 @@ int main(int argc, char **argv) zip_info.res=fopen(result,"wb+"); index_init(&zip_info, 1); } - fprintf(stderr,"Slice %d\n",i); - - phase5(files,references,3,suffix,&zip_info); - for (f = 0 ; f < 3 ; f++) { - if (files[f]) - fclose(files[f]); - if (references[f]) - fclose(references[f]); + if (!strcmp(suffix,"r")) { + ch_assemble_map(suffixes[0],suffix,&zip_info); + } else { + for (f = 0 ; f < 3 ; f++) { + files[f]=NULL; + references[f]=NULL; + } + if (process_relations) + files[0]=tempfile(suffix,"relations",0); + if (process_ways) { + files[1]=tempfile(suffix,"ways_split",0); + references[1]=tempfile(suffix,"ways_split_ref",1); + } + if (process_nodes) + files[2]=tempfile(suffix,"nodes",0); + fprintf(stderr,"Slice %d\n",i); + + phase5(files,references,3,suffix,&zip_info); + for (f = 0 ; f < 3 ; f++) { + if (files[f]) + fclose(files[f]); + if (references[f]) + fclose(references[f]); + } } if(!keep_tmpfiles) { tempfile_unlink(suffix,"relations"); diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h index 1a792c020..46a858633 100644 --- a/navit/maptool/maptool.h +++ b/navit/maptool/maptool.h @@ -92,6 +92,11 @@ struct buffer { void save_buffer(char *filename, struct buffer *b, long long offset); void load_buffer(char *filename, struct buffer *b, long long offset, long long size); +/* ch.c */ + +void ch_generate_tiles(char *map_suffix, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info); +void ch_assemble_map(char *map_suffix, char *suffix, struct zip_info *zip_info); + /* coastline.c */ void process_coastlines(FILE *in, FILE *out); @@ -135,6 +140,7 @@ void item_bin_add_coord(struct item_bin *ib, struct coord *c, int count); void item_bin_bbox(struct item_bin *ib, struct rect *r); void item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir); void item_bin_add_coord_rect(struct item_bin *ib, struct rect *r); +void item_bin_add_attr_data(struct item_bin *ib, enum attr_type type, void *data, int size); void item_bin_add_attr(struct item_bin *ib, struct attr *attr); void item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val); void *item_bin_get_attr(struct item_bin *ib, enum attr_type type, void *last); @@ -209,6 +215,7 @@ struct item_bin_sink_func *tile_collector_new(struct item_bin_sink *out); /* tempfile.c */ +char *tempfile_name(char *suffix, char *name); FILE *tempfile(char *suffix, char *name, int mode); void tempfile_unlink(char *suffix, char *name); void tempfile_rename(char *suffix, char *from, char *to); @@ -228,6 +235,7 @@ int tile(struct rect *r, char *suffix, char *ret, int max, int overlap, struct r void tile_bbox(char *tile, struct rect *r, int overlap); int tile_len(char *tile); void tile_write_item_to_tile(struct tile_info *info, struct item_bin *ib, FILE *reference, char *name); +void tile_write_item_minmax(struct tile_info *info, struct item_bin *ib, FILE *reference, int min, int max); int add_aux_tile(struct zip_info *zip_info, char *name, char *filename, int size); int write_aux_tiles(struct zip_info *zip_info); int create_tile_hash(void); diff --git a/navit/maptool/misc.c b/navit/maptool/misc.c index 1b4ecee29..22ba9745d 100644 --- a/navit/maptool/misc.c +++ b/navit/maptool/misc.c @@ -119,18 +119,6 @@ phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes) map_rect_destroy(mr); } - -static void -tile_write_item_minmax(struct tile_info *info, struct item_bin *ib, FILE *reference, int min, int max) -{ - struct rect r; - char buffer[1024]; - bbox((struct coord *)(ib+1), ib->clen/2, &r); - buffer[0]='\0'; - tile(&r, info->suffix, buffer, max, overlap, NULL); - tile_write_item_to_tile(info, ib, reference, buffer); -} - static void phase34_process_file(struct tile_info *info, FILE *in, FILE *reference) { diff --git a/navit/maptool/tempfile.c b/navit/maptool/tempfile.c index e67dd766e..8d8788a00 100644 --- a/navit/maptool/tempfile.c +++ b/navit/maptool/tempfile.c @@ -2,21 +2,29 @@ #include "maptool.h" #include "debug.h" +char * +tempfile_name(char *suffix, char *name) +{ + return g_strdup_printf("%s_%s.tmp",name, suffix); +} FILE * tempfile(char *suffix, char *name, int mode) { - char buffer[4096]; - sprintf(buffer,"%s_%s.tmp",name, suffix); + char *buffer=tempfile_name(suffix, name); + FILE *ret=NULL; switch (mode) { case 0: - return fopen(buffer, "rb"); + ret=fopen(buffer, "rb"); + break; case 1: - return fopen(buffer, "wb+"); + ret=fopen(buffer, "wb+"); + break; case 2: - return fopen(buffer, "ab"); - default: - return NULL; + ret=fopen(buffer, "ab"); + break; } + g_free(buffer); + return ret; } void diff --git a/navit/maptool/tile.c b/navit/maptool/tile.c index 11f62e1d5..f96a1ae40 100644 --- a/navit/maptool/tile.c +++ b/navit/maptool/tile.c @@ -310,8 +310,9 @@ write_item(char *tile, struct item_bin *ib, FILE *reference) return; } if (reference) { + int offset=th->total_size_used/4; fwrite(&th->zipnum, sizeof(th->zipnum), 1, reference); - fwrite(&th->total_size_used, sizeof(th->total_size_used), 1, reference); + fwrite(&offset, sizeof(th->total_size_used), 1, reference); } memcpy(th->zip_data+th->total_size_used, ib, size); th->total_size_used+=size; @@ -330,7 +331,7 @@ tile_write_item_to_tile(struct tile_info *info, struct item_bin *ib, FILE *refer tile_extend(name, ib, info->tiles_list); } -static void +void tile_write_item_minmax(struct tile_info *info, struct item_bin *ib, FILE *reference, int min, int max) { struct rect r; @@ -499,7 +500,7 @@ write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out) fprintf(out,"\n"); } - if (th->name[0]) + if (th->name[strlen(info->suffix)]) index_submap_add(info, th); zip_info->zipnum++; processed_tiles++; @@ -508,6 +509,13 @@ write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out) } len--; } + if (info->suffix[0] && info->write) { + item_bin_init(item_bin, type_submap); + item_bin_add_coord_rect(item_bin, &world_bbox); + item_bin_add_attr_range(item_bin, attr_order, 0, 255); + item_bin_add_attr_int(item_bin, attr_zipfile_ref, zip_info->zipnum-1); + item_bin_write(item_bin, zip_info->index); + } } void @@ -603,8 +611,7 @@ index_submap_add(struct tile_info *info, struct tile_head *th) else len=0; index_tile[len]=0; - if (tlen) - strcat(index_tile, info->suffix); + strcat(index_tile, info->suffix); tile_bbox(th->name, &r, overlap); item_bin_init(item_bin, type_submap); diff --git a/navit/navit.c b/navit/navit.c index 72c2934a2..0bddcda67 100644 --- a/navit/navit.c +++ b/navit/navit.c @@ -1381,6 +1381,9 @@ navit_init(struct navit *this_) dbg(2,"ready=%d\n",this_->ready); if (this_->ready == 3) navit_draw(this_); +#if 0 + routech_test(this_); +#endif } void |