11 struct item_id target,middle;
26 unsigned int edge_count;
39 GHashTable *newnode_hash;
41 struct edge_hash_item {
46 GHashTable *edge_hash;
48 struct file *sgr,*ddsg_node_index;
50 struct coord *node_index;
52 GHashTable *sgr_nodes_hash;
54 static int ch_levels=14;
57 road_speed(enum item_type type)
61 case type_street_1_city:
62 case type_living_street:
63 case type_street_service:
64 case type_track_gravelled:
65 case type_track_unpaved:
67 case type_street_2_city:
68 case type_track_paved:
70 case type_street_3_city:
72 case type_street_4_city:
74 case type_highway_city:
76 case type_street_1_land:
78 case type_street_2_land:
80 case type_street_3_land:
82 case type_street_4_land:
84 case type_street_n_lanes:
86 case type_highway_land:
100 coord_slice_free(void *data)
102 g_slice_free(struct coord, data);
109 return g_hash_table_new_full(coord_hash, coord_equal, coord_slice_free, NULL);
113 item_id_slice_free(void *data)
115 g_slice_free(struct item_id, data);
118 #define sq(x) ((double)(x)*(x))
121 add_node_to_hash(FILE *idx, GHashTable *hash, struct coord *c, int *nodes)
123 if (! g_hash_table_lookup(hash, c)) {
124 struct coord *ct=g_slice_new(struct coord);
126 fwrite(c, sizeof(*c), 1, idx);
128 g_hash_table_insert(hash, ct, (void *)(*nodes));
134 edge_hash_slice_free(void *data)
136 g_slice_free(struct edge_hash_item, data);
140 edge_hash_hash(gconstpointer key)
142 const struct edge_hash_item *itm=key;
143 return itm->first*2654435761UL+itm->last;
147 edge_hash_equal(gconstpointer a, gconstpointer b)
149 const struct edge_hash_item *itm_a=a;
150 const struct edge_hash_item *itm_b=b;
151 return (itm_a->first == itm_b->first && itm_a->last == itm_b->last);
157 ch_generate_ddsg(FILE *in, FILE *ref, FILE *idx, FILE *ddsg)
159 GHashTable *hash=coord_hash_new();
163 while ((ib=read_item(in))) {
164 int ccount=ib->clen/2;
165 struct coord *c=(struct coord *)(ib+1);
166 if (road_speed(ib->type)) {
167 add_node_to_hash(idx, hash, &c[0], &nodes);
168 add_node_to_hash(idx, hash, &c[ccount-1], &nodes);
172 edge_hash=g_hash_table_new_full(edge_hash_hash, edge_hash_equal, edge_hash_slice_free, item_id_slice_free);
173 fseek(in, 0, SEEK_SET);
175 fprintf(ddsg,"%d %d\n", nodes, edges);
176 while ((ib=read_item(in))) {
177 int i,ccount=ib->clen/2;
178 struct coord *c=(struct coord *)(ib+1);
179 int n1,n2,speed=road_speed(ib->type);
180 struct item_id road_id;
182 fread(&road_id, sizeof(road_id), 1, ref);
184 struct edge_hash_item *hi=g_slice_new(struct edge_hash_item);
185 struct item_id *id=g_slice_new(struct item_id);
187 dbg_assert((n1=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[0]))) != 0);
188 dbg_assert((n2=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[ccount-1]))) != 0);
190 for (i = 0 ; i < ccount-1 ; i++) {
191 l+=sqrt(sq(c[i+1].x-c[i].x)+sq(c[i+1].y-c[i].y));
193 fprintf(ddsg,"%d %d %d 0\n", n1-1, n2-1, (int)(l*36/speed));
196 g_hash_table_insert(edge_hash, hi, id);
199 g_hash_table_destroy(hash);
203 ch_generate_sgr(char *suffix)
205 #ifndef HAVE_API_WIN32_CE
207 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);
208 printf("%s\n",command);
210 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);
211 printf("%s\n",command);
217 ch_process_node(FILE *out, int node, int resolve)
219 int first_edge_id=nodes[node].first_edge;
220 int last_edge_id=nodes[node+1].first_edge;
222 struct ch_edge ch_edge;
223 struct item_bin *item_bin;
224 memset(&ch_edge, 0, sizeof(ch_edge));
225 struct edge_hash_item fwd,rev;
226 item_bin=init_item(type_ch_node);
227 int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER(node)));
229 dbg(0,"0x%x,0x%x\n",node_index[oldnode].x,node_index[oldnode].y);
231 item_bin_add_coord(item_bin, &node_index[oldnode], 1);
234 for (edge_id = first_edge_id ; edge_id < last_edge_id ; edge_id++) {
236 struct edge *edge=&edges[edge_id];
237 int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER((int)edge->target)));
239 ch_edge.weight=edge->weight;
242 ch_edge.flags=edge->flags & 3;
243 if (edge->scmiddle == 67108863) {
244 id=g_hash_table_lookup(edge_hash, &fwd);
247 id=g_hash_table_lookup(edge_hash, &rev);
250 fprintf(stderr,"Shortcut %d Weight %d\n",edge->scmiddle,edge->weight);
251 fprintf(stderr,"Neither %d-%d nor %d-%d exists\n",fwd.first,fwd.last,rev.first,rev.last);
256 dbg(0,"middle street id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id));
261 id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->scmiddle));
262 dbg_assert(id != NULL);
265 dbg(0,"middle node id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id));
268 id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->target));
270 dbg(0,"id for %d is "ITEM_ID_FMT"\n",edge->target,ITEM_ID_ARGS(*id));
273 fprintf(stderr,"Failed to look up target %d\n",edge->target);
278 item_bin_add_attr_data(item_bin,attr_ch_edge,&ch_edge,sizeof(ch_edge));
280 item_bin_write(item_bin, out);
284 ch_process_nodes(FILE *out, int pos, int count, int resolve)
287 printf("count %d sum=%d newnode_count=%d\n",count,pos,newnode_count);
288 for (i = 0 ; i < count ; i++)
289 ch_process_node(out, pos+i, resolve);
294 ch_process(FILE **files, int depth, int resolve)
296 int count=newnode_count;
299 while (depth > 0 && pos < newnode_count) {
301 ch_process_nodes(files[depth], pos, count, resolve);
305 ch_process_nodes(files[depth], pos, newnode_count-pos, resolve);
309 ch_setup(char *suffix)
313 int *data,size,offset=0;
314 char *filename=tempfile_name(suffix,"sgr");
315 printf("filename=%s\n",filename);
316 sgr=file_create(filename,0);
318 dbg_assert(sgr != NULL);
322 data=(int *)file_data_read(sgr, offset, size);
326 size=node_count*sizeof(struct node);
327 nodes=(struct node *)file_data_read(sgr, offset, size);
331 data=(int *)file_data_read(sgr, offset, size);
335 size=edge_count*sizeof(struct edge);
336 edges=(struct edge *)file_data_read(sgr, offset, size);
340 data=(int *)file_data_read(sgr, offset, size);
344 size=edge_count*sizeof(struct newnode);
345 newnodes=(struct newnode *)file_data_read(sgr, offset, size);
348 newnode_hash=g_hash_table_new(NULL, NULL);
350 for (i = 0 ; i < newnode_count ; i++) {
351 g_hash_table_insert(newnode_hash, GINT_TO_POINTER(newnodes[i].newnode), GINT_TO_POINTER(i));
354 if (!ddsg_node_index) {
355 char *filename=tempfile_name(suffix,"ddsg_coords");
356 ddsg_node_index=file_create(filename,0);
358 dbg_assert(ddsg_node_index != NULL);
359 file_mmap(ddsg_node_index);
360 node_index=(struct coord *)file_data_read(ddsg_node_index, 0, file_size(ddsg_node_index));
365 ch_create_tempfiles(char *suffix, FILE **files, int count, int mode)
370 for (i = 0 ; i <= count ; i++) {
371 sprintf(name,"graph_%d",i);
372 files[i]=tempfile(suffix, name, mode);
377 ch_close_tempfiles(FILE **files, int count)
381 for (i = 0 ; i <= count ; i++) {
387 ch_remove_tempfiles(char *suffix, int count)
392 for (i = 0 ; i <= count ; i++) {
393 sprintf(name,"graph_%d",i);
394 tempfile_unlink(suffix, name);
399 ch_copy_to_tiles(char *suffix, int count, struct tile_info *info, FILE *ref)
404 struct item_bin *item_bin;
406 for (i = count ; i >= 0 ; i--) {
407 sprintf(name,"graph_%d",i);
408 f=tempfile(suffix, name, 0);
409 while ((item_bin = read_item(f))) {
410 tile_write_item_minmax(info, item_bin, ref, i, i);
417 ch_generate_tiles(char *map_suffix, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info)
419 struct tile_info info;
420 FILE *in,*ref,*ddsg_coords,*ddsg;
424 info.tiles_list=NULL;
425 info.tilesdir_out=tilesdir_out;
426 FILE *graphfiles[ch_levels+1];
428 ch_create_tempfiles(suffix, graphfiles, ch_levels, 1);
429 in=tempfile(map_suffix,"ways_split",0);
430 ref=tempfile(map_suffix,"ways_split_ref",0);
431 ddsg_coords=tempfile(suffix,"ddsg_coords",1);
432 ddsg=tempfile(suffix,"ddsg",1);
433 ch_generate_ddsg(in, ref, ddsg_coords, ddsg);
438 ch_generate_sgr(suffix);
440 ch_process(graphfiles, ch_levels, 0);
441 ch_close_tempfiles(graphfiles, ch_levels);
443 tile_hash=g_hash_table_new(g_str_hash, g_str_equal);
444 ch_copy_to_tiles(suffix, ch_levels, &info, NULL);
447 write_tilesdir(&info, zip_info, tilesdir_out);
451 ch_assemble_map(char *map_suffix, char *suffix, struct zip_info *zip_info)
453 struct tile_info info;
454 struct tile_head *th;
455 FILE *graphfiles[ch_levels+1];
458 info.maxlen=zip_info->maxnamelen;
460 info.tiles_list=NULL;
461 info.tilesdir_out=NULL;
462 FILE *ref=tempfile(suffix,"sgr_ref",1);
476 ch_copy_to_tiles(suffix, ch_levels, &info, ref);
478 ref=tempfile(suffix,"sgr_ref",0);
479 sgr_nodes_hash=g_hash_table_new_full(NULL, NULL, NULL, item_id_slice_free);
480 while (fread(&id, sizeof(id), 1, ref)) {
481 struct item_id *id2=g_slice_new(struct item_id);
484 dbg(0,"%d is "ITEM_ID_FMT"\n",nodeid,ITEM_ID_ARGS(*id2));
486 g_hash_table_insert(sgr_nodes_hash, GINT_TO_POINTER(nodeid), id2);
491 th->zip_data=malloc(th->total_size);
492 th->total_size_used=0;
495 ch_create_tempfiles(suffix, graphfiles, ch_levels, 1);
496 ch_process(graphfiles, ch_levels, 1);
497 ch_close_tempfiles(graphfiles, ch_levels);
499 g_hash_table_destroy(newnode_hash);
500 g_hash_table_destroy(edge_hash);
501 g_hash_table_destroy(sgr_nodes_hash);
503 ch_copy_to_tiles(suffix, ch_levels, &info, NULL);
504 write_tilesdir(&info, zip_info, NULL);
509 if (th->total_size != th->total_size_used) {
510 fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used);
513 write_zipmember(zip_info, th->name, zip_info->maxnamelen, th->zip_data, th->total_size);
515 fwrite(th->zip_data, th->total_size, 1, zip_info->index);
517 g_free(th->zip_data);