Add:Core:Experimental CH Routing
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 8 Nov 2009 20:44:14 +0000 (20:44 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 8 Nov 2009 20:44:14 +0000 (20:44 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@2729 ffa7fe5e-494d-0410-b361-a75ebd5db220

17 files changed:
navit/navit/Makefile.am
navit/navit/attr_def.h
navit/navit/coord.c
navit/navit/coord.h
navit/navit/item.c
navit/navit/item.h
navit/navit/item_def.h
navit/navit/map/binfile/binfile.c
navit/navit/maptool/Makefile.am
navit/navit/maptool/ch.c [new file with mode: 0644]
navit/navit/maptool/itembin.c
navit/navit/maptool/maptool.c
navit/navit/maptool/maptool.h
navit/navit/maptool/misc.c
navit/navit/maptool/tempfile.c
navit/navit/maptool/tile.c
navit/navit/navit.c

index 5c2bf0f..1797d27 100644 (file)
@@ -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\
index cad04f5..20f3322 100644 (file)
@@ -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)
index 4f77b89..af16946 100644 (file)
@@ -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;
+}
 /** @} */
index 355f63f..a8221fa 100644 (file)
@@ -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 */
index 7d39083..8d128d9 100644 (file)
@@ -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++)
index cfa7527..c9a145d 100644 (file)
@@ -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 */
 
index f62c5c0..fbd549d 100644 (file)
@@ -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)
index fb12d5e..93674e9 100644 (file)
@@ -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;
index 006c01d..358e982 100644 (file)
@@ -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/navit/maptool/ch.c b/navit/navit/maptool/ch.c
new file mode 100644 (file)
index 0000000..71f8e34
--- /dev/null
@@ -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;
+        }
+}
index 3e143bf..9b42b91 100644 (file)
@@ -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;
index 171dfbb..e0dd1a9 100644 (file)
@@ -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");
index 1a792c0..46a8586 100644 (file)
@@ -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);
index 1b4ecee..22ba974 100644 (file)
@@ -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)
 {
index e67dd76..8d8788a 100644 (file)
@@ -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
index 11f62e1..f96a1ae 100644 (file)
@@ -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);
index 72c2934..0bddcda 100644 (file)
@@ -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