… | |
… | |
30 | #define g_slice_new0(x) g_new0(x,1) |
30 | #define g_slice_new0(x) g_new0(x,1) |
31 | #define g_slice_free(x,y) g_free(y) |
31 | #define g_slice_free(x,y) g_free(y) |
32 | #define g_slice_free1(x,y) g_free(y) |
32 | #define g_slice_free1(x,y) g_free(y) |
33 | #endif |
33 | #endif |
34 | |
34 | |
35 | struct ch_edge { |
35 | struct ch_edge |
|
|
36 | { |
36 | int flags; |
37 | int flags; |
37 | int weight; |
38 | int weight; |
38 | struct item_id target,middle; |
39 | struct item_id target, middle; |
39 | }; |
40 | }; |
40 | |
41 | |
41 | struct node { |
42 | struct node |
|
|
43 | { |
42 | int first_edge; |
44 | int first_edge; |
43 | int dummy; |
45 | int dummy; |
44 | } *nodes; |
46 | }*nodes; |
45 | int node_count; |
47 | int node_count; |
46 | |
48 | |
47 | struct edge { |
49 | struct edge |
|
|
50 | { |
48 | unsigned target:26; |
51 | unsigned target :26; |
49 | unsigned scedge1:6; |
52 | unsigned scedge1 :6; |
50 | unsigned weight:28; |
53 | unsigned weight :28; |
51 | unsigned type:2; |
54 | unsigned type :2; |
52 | unsigned flags:2; |
55 | unsigned flags :2; |
53 | unsigned int edge_count; |
56 | unsigned int edge_count; |
54 | unsigned scedge2:6; |
57 | unsigned scedge2 :6; |
55 | unsigned scmiddle:26; |
58 | unsigned scmiddle :26; |
56 | } *edges; |
59 | }*edges; |
57 | |
60 | |
58 | int edge_count; |
61 | int edge_count; |
59 | |
62 | |
60 | struct newnode { |
63 | struct newnode |
|
|
64 | { |
61 | int newnode; |
65 | int newnode; |
62 | } *newnodes; |
66 | }*newnodes; |
63 | |
67 | |
64 | int newnode_count; |
68 | int newnode_count; |
65 | |
69 | |
66 | GHashTable *newnode_hash; |
70 | GHashTable *newnode_hash; |
67 | |
71 | |
68 | struct edge_hash_item { |
72 | struct edge_hash_item |
|
|
73 | { |
69 | int first,last; |
74 | int first, last; |
70 | }; |
75 | }; |
71 | |
76 | |
72 | |
|
|
73 | GHashTable *edge_hash; |
77 | GHashTable *edge_hash; |
74 | |
78 | |
75 | struct file *sgr,*ddsg_node_index; |
79 | struct file *sgr, *ddsg_node_index; |
76 | |
80 | |
77 | struct coord *node_index; |
81 | struct coord *node_index; |
78 | |
82 | |
79 | GHashTable *sgr_nodes_hash; |
83 | GHashTable *sgr_nodes_hash; |
80 | |
84 | |
81 | static int ch_levels=14; |
85 | static int ch_levels = 14; |
82 | |
86 | |
83 | static int |
|
|
84 | road_speed(enum item_type type) |
87 | static int road_speed(enum item_type type) |
85 | { |
88 | { |
86 | switch (type) { |
89 | switch (type) |
|
|
90 | { |
87 | case type_street_0: |
91 | case type_street_0: |
88 | case type_street_1_city: |
92 | case type_street_1_city: |
89 | case type_living_street: |
93 | case type_living_street: |
90 | case type_street_service: |
94 | case type_street_service: |
91 | case type_track_gravelled: |
95 | case type_track_gravelled: |
92 | case type_track_unpaved: |
96 | case type_track_unpaved: |
93 | return 10; |
97 | return 10; |
94 | case type_street_2_city: |
98 | case type_street_2_city: |
95 | case type_track_paved: |
99 | case type_track_paved: |
96 | return 30; |
100 | return 30; |
97 | case type_street_3_city: |
101 | case type_street_3_city: |
98 | return 40; |
102 | return 40; |
99 | case type_street_4_city: |
103 | case type_street_4_city: |
100 | return 50; |
104 | return 50; |
101 | case type_highway_city: |
105 | case type_highway_city: |
102 | return 80; |
106 | return 80; |
103 | case type_street_1_land: |
107 | case type_street_1_land: |
104 | return 60; |
108 | return 60; |
105 | case type_street_2_land: |
109 | case type_street_2_land: |
106 | return 65; |
110 | return 65; |
107 | case type_street_3_land: |
111 | case type_street_3_land: |
108 | return 70; |
112 | return 70; |
109 | case type_street_4_land: |
113 | case type_street_4_land: |
110 | return 80; |
114 | return 80; |
111 | case type_street_n_lanes: |
115 | case type_street_n_lanes: |
112 | return 120; |
116 | return 120; |
113 | case type_highway_land: |
117 | case type_highway_land: |
114 | return 120; |
118 | return 120; |
115 | case type_ramp: |
119 | case type_ramp: |
116 | return 40; |
120 | return 40; |
117 | case type_roundabout: |
121 | case type_roundabout: |
118 | return 10; |
122 | return 10; |
119 | case type_ferry: |
123 | case type_ferry: |
120 | return 40; |
124 | return 40; |
121 | default: |
125 | default: |
122 | return 0; |
126 | return 0; |
123 | } |
127 | } |
124 | } |
128 | } |
125 | |
129 | |
126 | static void |
|
|
127 | coord_slice_free(void *data) |
130 | static void coord_slice_free(void *data) |
128 | { |
131 | { |
129 | g_slice_free(struct coord, data); |
132 | g_slice_free(struct coord, data); |
130 | } |
133 | } |
131 | |
|
|
132 | |
134 | |
133 | static GHashTable * |
135 | static GHashTable * |
134 | coord_hash_new(void) |
136 | coord_hash_new(void) |
135 | { |
137 | { |
136 | return g_hash_table_new_full(coord_hash, coord_equal, coord_slice_free, NULL); |
138 | return g_hash_table_new_full(coord_hash, coord_equal, coord_slice_free, NULL); |
137 | } |
139 | } |
138 | |
140 | |
139 | static void |
|
|
140 | item_id_slice_free(void *data) |
141 | static void item_id_slice_free(void *data) |
141 | { |
142 | { |
142 | g_slice_free(struct item_id, data); |
143 | g_slice_free(struct item_id, data); |
143 | } |
144 | } |
144 | |
145 | |
145 | #define sq(x) ((double)(x)*(x)) |
146 | #define sq(x) ((double)(x)*(x)) |
146 | |
147 | |
147 | static void |
|
|
148 | add_node_to_hash(FILE *idx, GHashTable *hash, struct coord *c, int *nodes) |
148 | static void add_node_to_hash(FILE *idx, GHashTable *hash, struct coord *c, int *nodes) |
149 | { |
149 | { |
150 | if (! g_hash_table_lookup(hash, c)) { |
150 | if (!g_hash_table_lookup(hash, c)) |
|
|
151 | { |
151 | struct coord *ct=g_slice_new(struct coord); |
152 | struct coord *ct=g_slice_new(struct coord); |
152 | *ct=*c; |
153 | *ct = *c; |
153 | fwrite(c, sizeof(*c), 1, idx); |
154 | fwrite(c, sizeof(*c), 1, idx); |
154 | (*nodes)++; |
155 | (*nodes)++; |
155 | g_hash_table_insert(hash, ct, (void *)(*nodes)); |
156 | g_hash_table_insert(hash, ct, (void *) (*nodes)); |
156 | } |
157 | } |
157 | |
158 | |
158 | } |
159 | } |
159 | |
160 | |
160 | static void |
|
|
161 | edge_hash_slice_free(void *data) |
161 | static void edge_hash_slice_free(void *data) |
162 | { |
162 | { |
163 | g_slice_free(struct edge_hash_item, data); |
163 | g_slice_free(struct edge_hash_item, data); |
164 | } |
164 | } |
165 | |
165 | |
166 | static guint |
|
|
167 | edge_hash_hash(gconstpointer key) |
166 | static guint edge_hash_hash(gconstpointer key) |
168 | { |
167 | { |
169 | const struct edge_hash_item *itm=key; |
168 | const struct edge_hash_item *itm = key; |
170 | return itm->first*2654435761UL+itm->last; |
169 | return itm->first * 2654435761UL + itm->last; |
171 | } |
170 | } |
172 | |
171 | |
173 | static gboolean |
|
|
174 | edge_hash_equal(gconstpointer a, gconstpointer b) |
172 | static gboolean edge_hash_equal(gconstpointer a, gconstpointer b) |
175 | { |
173 | { |
176 | const struct edge_hash_item *itm_a=a; |
174 | const struct edge_hash_item *itm_a = a; |
177 | const struct edge_hash_item *itm_b=b; |
175 | const struct edge_hash_item *itm_b = b; |
178 | return (itm_a->first == itm_b->first && itm_a->last == itm_b->last); |
176 | return (itm_a->first == itm_b->first && itm_a->last == itm_b->last); |
179 | } |
177 | } |
180 | |
178 | |
181 | |
|
|
182 | |
|
|
183 | static void |
|
|
184 | ch_generate_ddsg(FILE *in, FILE *ref, FILE *idx, FILE *ddsg) |
179 | static void ch_generate_ddsg(FILE *in, FILE *ref, FILE *idx, FILE *ddsg) |
185 | { |
180 | { |
186 | GHashTable *hash=coord_hash_new(); |
181 | GHashTable *hash = coord_hash_new(); |
187 | struct item_bin *ib; |
182 | struct item_bin *ib; |
188 | int nodes=0,edges=0; |
183 | int nodes = 0, edges = 0; |
189 | |
184 | |
190 | while ((ib=read_item(in))) { |
185 | while ((ib = read_item(in, 0))) |
|
|
186 | { |
191 | int ccount=ib->clen/2; |
187 | int ccount = ib->clen / 2; |
192 | struct coord *c=(struct coord *)(ib+1); |
188 | struct coord *c = (struct coord *) (ib + 1); |
193 | if (road_speed(ib->type)) { |
189 | if (road_speed(ib->type)) |
|
|
190 | { |
194 | add_node_to_hash(idx, hash, &c[0], &nodes); |
191 | add_node_to_hash(idx, hash, &c[0], &nodes); |
195 | add_node_to_hash(idx, hash, &c[ccount-1], &nodes); |
192 | add_node_to_hash(idx, hash, &c[ccount - 1], &nodes); |
196 | edges++; |
193 | edges++; |
197 | } |
194 | } |
198 | } |
195 | } |
199 | edge_hash=g_hash_table_new_full(edge_hash_hash, edge_hash_equal, edge_hash_slice_free, item_id_slice_free); |
196 | edge_hash = g_hash_table_new_full(edge_hash_hash, edge_hash_equal, edge_hash_slice_free, item_id_slice_free); |
200 | fseek(in, 0, SEEK_SET); |
197 | fseek(in, 0, SEEK_SET); |
201 | fprintf(ddsg,"d\n"); |
198 | fprintf(ddsg, "d\n"); |
202 | fprintf(ddsg,"%d %d\n", nodes, edges); |
199 | fprintf(ddsg, "%d %d\n", nodes, edges); |
203 | while ((ib=read_item(in))) { |
200 | while ((ib = read_item(in, 0))) |
|
|
201 | { |
204 | int i,ccount=ib->clen/2; |
202 | int i, ccount = ib->clen / 2; |
205 | struct coord *c=(struct coord *)(ib+1); |
203 | struct coord *c = (struct coord *) (ib + 1); |
206 | int n1,n2,speed=road_speed(ib->type); |
204 | int n1, n2, speed = road_speed(ib->type); |
207 | struct item_id road_id; |
205 | struct item_id road_id; |
208 | double l; |
206 | double l; |
209 | fread(&road_id, sizeof(road_id), 1, ref); |
207 | fread(&road_id, sizeof(road_id), 1, ref); |
210 | if (speed) { |
208 | if (speed) |
|
|
209 | { |
211 | struct edge_hash_item *hi=g_slice_new(struct edge_hash_item); |
210 | struct edge_hash_item *hi=g_slice_new(struct edge_hash_item); |
212 | struct item_id *id=g_slice_new(struct item_id); |
211 | struct item_id *id=g_slice_new(struct item_id); |
213 | *id=road_id; |
212 | *id = road_id; |
214 | dbg_assert((n1=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[0]))) != 0); |
213 | dbg_assert((n1 = GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[0]))) != 0); |
215 | dbg_assert((n2=GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[ccount-1]))) != 0); |
214 | dbg_assert((n2 = GPOINTER_TO_INT(g_hash_table_lookup(hash, &c[ccount - 1]))) != 0); |
216 | l=0; |
215 | l = 0; |
217 | for (i = 0 ; i < ccount-1 ; i++) { |
216 | for (i = 0; i < ccount - 1; i++) |
|
|
217 | { |
218 | l+=sqrt(sq(c[i+1].x-c[i].x)+sq(c[i+1].y-c[i].y)); |
218 | l += sqrt(sq(c[i+1].x-c[i].x) + sq(c[i+1].y-c[i].y)); |
219 | } |
219 | } |
220 | fprintf(ddsg,"%d %d %d 0\n", n1-1, n2-1, (int)(l*36/speed)); |
220 | fprintf(ddsg, "%d %d %d 0\n", n1 - 1, n2 - 1, (int) (l * 36 / speed)); |
221 | hi->first=n1-1; |
221 | hi->first = n1 - 1; |
222 | hi->last=n2-1; |
222 | hi->last = n2 - 1; |
223 | g_hash_table_insert(edge_hash, hi, id); |
223 | g_hash_table_insert(edge_hash, hi, id); |
224 | } |
224 | } |
225 | } |
225 | } |
226 | g_hash_table_destroy(hash); |
226 | g_hash_table_destroy(hash); |
227 | } |
227 | } |
228 | |
228 | |
229 | static void |
|
|
230 | ch_generate_sgr(char *suffix) |
229 | static void ch_generate_sgr(char *suffix) |
231 | { |
230 | { |
232 | #ifndef HAVE_API_WIN32_CE |
231 | #ifndef HAVE_API_WIN32_CE |
233 | char command[1024]; |
232 | char command[1024]; |
234 | 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); |
233 | 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); |
235 | printf("%s\n",command); |
234 | printf("%s\n", command); |
236 | system(command); |
235 | system(command); |
237 | 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); |
236 | 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); |
238 | printf("%s\n",command); |
237 | printf("%s\n", command); |
239 | system(command); |
238 | system(command); |
240 | #endif |
239 | #endif |
241 | } |
240 | } |
242 | |
241 | |
243 | static void |
|
|
244 | ch_process_node(FILE *out, int node, int resolve) |
242 | static void ch_process_node(FILE *out, int node, int resolve) |
245 | { |
243 | { |
246 | int first_edge_id=nodes[node].first_edge; |
244 | int first_edge_id = nodes[node].first_edge; |
247 | int last_edge_id=nodes[node+1].first_edge; |
245 | int last_edge_id = nodes[node + 1].first_edge; |
248 | int edge_id; |
246 | int edge_id; |
249 | struct ch_edge ch_edge; |
247 | struct ch_edge ch_edge; |
250 | struct item_bin *item_bin; |
248 | struct item_bin *item_bin; |
251 | struct edge_hash_item fwd,rev; |
249 | struct edge_hash_item fwd, rev; |
252 | int oldnode; |
250 | int oldnode; |
253 | memset(&ch_edge, 0, sizeof(ch_edge)); |
251 | memset(&ch_edge, 0, sizeof(ch_edge)); |
254 | item_bin=init_item(type_ch_node); |
252 | item_bin = init_item(type_ch_node, 0); |
255 | oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER(node))); |
253 | oldnode = GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER(node))); |
256 | #if 0 |
254 | #if 0 |
257 | dbg(0,"0x%x,0x%x\n",node_index[oldnode].x,node_index[oldnode].y); |
255 | dbg(0,"0x%x,0x%x\n",node_index[oldnode].x,node_index[oldnode].y); |
258 | #endif |
256 | #endif |
259 | item_bin_add_coord(item_bin, &node_index[oldnode], 1); |
257 | item_bin_add_coord(item_bin, &node_index[oldnode], 1); |
260 | fwd.first=oldnode; |
258 | fwd.first = oldnode; |
261 | rev.last=oldnode; |
259 | rev.last = oldnode; |
262 | for (edge_id = first_edge_id ; edge_id < last_edge_id ; edge_id++) { |
260 | for (edge_id = first_edge_id; edge_id < last_edge_id; edge_id++) |
|
|
261 | { |
263 | if (resolve) { |
262 | if (resolve) |
|
|
263 | { |
264 | struct edge *edge=&edges[edge_id]; |
264 | struct edge *edge = &edges[edge_id]; |
265 | int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER((int)edge->target))); |
265 | int oldnode = GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER((int) edge->target))); |
266 | struct item_id *id; |
266 | struct item_id *id; |
267 | ch_edge.weight=edge->weight; |
267 | ch_edge.weight = edge->weight; |
268 | fwd.last=oldnode; |
268 | fwd.last = oldnode; |
269 | rev.first=oldnode; |
269 | rev.first = oldnode; |
270 | ch_edge.flags=edge->flags & 3; |
270 | ch_edge.flags = edge->flags & 3; |
271 | if (edge->scmiddle == 67108863) { |
271 | if (edge->scmiddle == 67108863) |
|
|
272 | { |
272 | id=g_hash_table_lookup(edge_hash, &fwd); |
273 | id = g_hash_table_lookup(edge_hash, &fwd); |
273 | if (!id) { |
274 | if (!id) |
|
|
275 | { |
274 | ch_edge.flags|=8; |
276 | ch_edge.flags |= 8; |
275 | id=g_hash_table_lookup(edge_hash, &rev); |
277 | id = g_hash_table_lookup(edge_hash, &rev); |
276 | } |
278 | } |
277 | if (id == NULL) { |
279 | if (id == NULL) |
|
|
280 | { |
278 | fprintf(stderr,"Shortcut %d Weight %d\n",edge->scmiddle,edge->weight); |
281 | fprintf(stderr, "Shortcut %d Weight %d\n", edge->scmiddle, edge->weight); |
279 | fprintf(stderr,"Neither %d-%d nor %d-%d exists\n",fwd.first,fwd.last,rev.first,rev.last); |
282 | fprintf(stderr, "Neither %d-%d nor %d-%d exists\n", fwd.first, fwd.last, rev.first, rev.last); |
280 | exit(1); |
283 | exit(1); |
|
|
284 | } |
281 | } else { |
285 | else |
|
|
286 | { |
282 | ch_edge.middle=*id; |
287 | ch_edge.middle = *id; |
283 | #if 0 |
288 | #if 0 |
284 | dbg(0,"middle street id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); |
289 | dbg(0,"middle street id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); |
285 | #endif |
290 | #endif |
286 | } |
291 | } |
|
|
292 | } |
287 | } else { |
293 | else |
|
|
294 | { |
288 | ch_edge.flags|=4; |
295 | ch_edge.flags |= 4; |
289 | id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->scmiddle)); |
296 | id = g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int) edge->scmiddle)); |
290 | dbg_assert(id != NULL); |
297 | dbg_assert(id != NULL); |
291 | ch_edge.middle=*id; |
298 | ch_edge.middle = *id; |
292 | #if 0 |
299 | #if 0 |
293 | dbg(0,"middle node id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); |
300 | dbg(0,"middle node id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); |
294 | #endif |
301 | #endif |
295 | } |
302 | } |
296 | id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->target)); |
303 | id = g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int) edge->target)); |
297 | #if 0 |
304 | #if 0 |
298 | dbg(0,"id for %d is "ITEM_ID_FMT"\n",edge->target,ITEM_ID_ARGS(*id)); |
305 | dbg(0,"id for %d is "ITEM_ID_FMT"\n",edge->target,ITEM_ID_ARGS(*id)); |
299 | #endif |
306 | #endif |
300 | if (id == NULL) { |
307 | if (id == NULL) |
|
|
308 | { |
301 | fprintf(stderr,"Failed to look up target %d\n",edge->target); |
309 | fprintf(stderr, "Failed to look up target %d\n", edge->target); |
302 | } else { |
|
|
303 | ch_edge.target=*id; |
|
|
304 | } |
310 | } |
|
|
311 | else |
|
|
312 | { |
|
|
313 | ch_edge.target = *id; |
305 | } |
314 | } |
|
|
315 | } |
306 | item_bin_add_attr_data(item_bin,attr_ch_edge,&ch_edge,sizeof(ch_edge)); |
316 | item_bin_add_attr_data(item_bin, attr_ch_edge, &ch_edge, sizeof(ch_edge)); |
307 | } |
317 | } |
308 | item_bin_write(item_bin, out); |
318 | item_bin_write(item_bin, out); |
309 | } |
319 | } |
310 | |
320 | |
311 | static void |
|
|
312 | ch_process_nodes(FILE *out, int pos, int count, int resolve) |
321 | static void ch_process_nodes(FILE *out, int pos, int count, int resolve) |
313 | { |
322 | { |
314 | int i; |
323 | int i; |
315 | printf("count %d sum=%d newnode_count=%d\n",count,pos,newnode_count); |
324 | printf("count %d sum=%d newnode_count=%d\n", count, pos, newnode_count); |
316 | for (i = 0 ; i < count ; i++) |
325 | for (i = 0; i < count; i++) |
317 | ch_process_node(out, pos+i, resolve); |
326 | ch_process_node(out, pos + i, resolve); |
318 | } |
327 | } |
319 | |
328 | |
320 | |
|
|
321 | static void |
|
|
322 | ch_process(FILE **files, int depth, int resolve) |
329 | static void ch_process(FILE **files, int depth, int resolve) |
323 | { |
330 | { |
324 | int count=newnode_count; |
331 | int count = newnode_count; |
325 | int pos=0; |
332 | int pos = 0; |
326 | |
333 | |
327 | while (depth > 0 && pos < newnode_count) { |
334 | while (depth > 0 && pos < newnode_count) |
|
|
335 | { |
328 | count=(count+1)/2; |
336 | count = (count + 1) / 2; |
329 | ch_process_nodes(files[depth], pos, count, resolve); |
337 | ch_process_nodes(files[depth], pos, count, resolve); |
330 | pos+=count; |
338 | pos += count; |
331 | depth--; |
339 | depth--; |
332 | } |
340 | } |
333 | ch_process_nodes(files[depth], pos, newnode_count-pos, resolve); |
341 | ch_process_nodes(files[depth], pos, newnode_count - pos, resolve); |
334 | } |
342 | } |
335 | |
343 | |
336 | static void |
|
|
337 | ch_setup(char *suffix) |
344 | static void ch_setup(char *suffix) |
338 | { |
345 | { |
339 | int i; |
346 | int i; |
340 | if (!sgr) { |
347 | if (!sgr) |
|
|
348 | { |
341 | int *data,size,offset=0; |
349 | int *data, size, offset = 0; |
342 | char *filename=tempfile_name(suffix,"sgr"); |
350 | char *filename = tempfile_name(suffix, "sgr"); |
343 | printf("filename=%s\n",filename); |
351 | printf("filename=%s\n", filename); |
344 | sgr=file_create(filename,0); |
352 | sgr = file_create(filename, 0); |
345 | g_free(filename); |
353 | g_free(filename); |
346 | dbg_assert(sgr != NULL); |
354 | dbg_assert(sgr != NULL); |
347 | file_mmap(sgr); |
355 | file_mmap(sgr); |
348 | |
356 | |
349 | size=sizeof(int); |
357 | size = sizeof(int); |
350 | data=(int *)file_data_read(sgr, offset, size); |
358 | data = (int *) file_data_read(sgr, offset, size); |
351 | node_count=*data; |
359 | node_count = *data; |
352 | offset+=size; |
360 | offset += size; |
353 | |
361 | |
354 | size=node_count*sizeof(struct node); |
362 | size = node_count * sizeof(struct node); |
355 | nodes=(struct node *)file_data_read(sgr, offset, size); |
363 | nodes = (struct node *) file_data_read(sgr, offset, size); |
356 | offset+=size; |
364 | offset += size; |
357 | |
365 | |
358 | size=sizeof(int); |
366 | size = sizeof(int); |
359 | data=(int *)file_data_read(sgr, offset, size); |
367 | data = (int *) file_data_read(sgr, offset, size); |
360 | edge_count=*data; |
368 | edge_count = *data; |
361 | offset+=size; |
369 | offset += size; |
362 | |
370 | |
363 | size=edge_count*sizeof(struct edge); |
371 | size = edge_count * sizeof(struct edge); |
364 | edges=(struct edge *)file_data_read(sgr, offset, size); |
372 | edges = (struct edge *) file_data_read(sgr, offset, size); |
365 | offset+=size; |
373 | offset += size; |
366 | |
374 | |
367 | size=sizeof(int); |
375 | size = sizeof(int); |
368 | data=(int *)file_data_read(sgr, offset, size); |
376 | data = (int *) file_data_read(sgr, offset, size); |
369 | newnode_count=*data; |
377 | newnode_count = *data; |
370 | offset+=size; |
378 | offset += size; |
371 | |
379 | |
372 | size=edge_count*sizeof(struct newnode); |
380 | size = edge_count * sizeof(struct newnode); |
373 | newnodes=(struct newnode *)file_data_read(sgr, offset, size); |
381 | newnodes = (struct newnode *) file_data_read(sgr, offset, size); |
374 | offset+=size; |
382 | offset += size; |
375 | |
383 | |
376 | newnode_hash=g_hash_table_new(NULL, NULL); |
384 | newnode_hash = g_hash_table_new(NULL, NULL); |
377 | |
385 | |
378 | for (i = 0 ; i < newnode_count ; i++) { |
386 | for (i = 0; i < newnode_count; i++) |
|
|
387 | { |
379 | g_hash_table_insert(newnode_hash, GINT_TO_POINTER(newnodes[i].newnode), GINT_TO_POINTER(i)); |
388 | g_hash_table_insert(newnode_hash, GINT_TO_POINTER(newnodes[i].newnode), GINT_TO_POINTER(i)); |
380 | } |
|
|
381 | } |
389 | } |
|
|
390 | } |
382 | if (!ddsg_node_index) { |
391 | if (!ddsg_node_index) |
|
|
392 | { |
383 | char *filename=tempfile_name(suffix,"ddsg_coords"); |
393 | char *filename = tempfile_name(suffix, "ddsg_coords"); |
384 | ddsg_node_index=file_create(filename,0); |
394 | ddsg_node_index = file_create(filename, 0); |
385 | g_free(filename); |
395 | g_free(filename); |
386 | dbg_assert(ddsg_node_index != NULL); |
396 | dbg_assert(ddsg_node_index != NULL); |
387 | file_mmap(ddsg_node_index); |
397 | file_mmap(ddsg_node_index); |
388 | node_index=(struct coord *)file_data_read(ddsg_node_index, 0, file_size(ddsg_node_index)); |
398 | node_index = (struct coord *) file_data_read(ddsg_node_index, 0, file_size(ddsg_node_index)); |
389 | } |
399 | } |
390 | } |
400 | } |
391 | |
401 | |
392 | static void |
|
|
393 | ch_create_tempfiles(char *suffix, FILE **files, int count, int mode) |
402 | static void ch_create_tempfiles(char *suffix, FILE **files, int count, int mode) |
394 | { |
403 | { |
395 | char name[256]; |
404 | char name[256]; |
396 | int i; |
405 | int i; |
397 | |
406 | |
398 | for (i = 0 ; i <= count ; i++) { |
407 | for (i = 0; i <= count; i++) |
|
|
408 | { |
399 | sprintf(name,"graph_%d",i); |
409 | sprintf(name, "graph_%d", i); |
400 | files[i]=tempfile(suffix, name, mode); |
410 | files[i] = tempfile(suffix, name, mode); |
401 | } |
411 | } |
402 | } |
412 | } |
403 | |
413 | |
404 | static void |
|
|
405 | ch_close_tempfiles(FILE **files, int count) |
414 | static void ch_close_tempfiles(FILE **files, int count) |
406 | { |
415 | { |
407 | int i; |
416 | int i; |
408 | |
417 | |
409 | for (i = 0 ; i <= count ; i++) { |
418 | for (i = 0; i <= count; i++) |
|
|
419 | { |
410 | fclose(files[i]); |
420 | fclose(files[i]); |
411 | } |
421 | } |
412 | } |
422 | } |
413 | |
423 | |
414 | static void |
|
|
415 | ch_remove_tempfiles(char *suffix, int count) |
424 | static void ch_remove_tempfiles(char *suffix, int count) |
416 | { |
425 | { |
417 | char name[256]; |
426 | char name[256]; |
418 | int i; |
427 | int i; |
419 | |
428 | |
420 | for (i = 0 ; i <= count ; i++) { |
429 | for (i = 0; i <= count; i++) |
|
|
430 | { |
421 | sprintf(name,"graph_%d",i); |
431 | sprintf(name, "graph_%d", i); |
422 | tempfile_unlink(suffix, name); |
432 | tempfile_unlink(suffix, name); |
423 | } |
433 | } |
424 | } |
434 | } |
425 | |
435 | |
426 | static void |
|
|
427 | ch_copy_to_tiles(char *suffix, int count, struct tile_info *info, FILE *ref) |
436 | static void ch_copy_to_tiles(char *suffix, int count, struct tile_info *info, FILE *ref) |
428 | { |
437 | { |
429 | char name[256]; |
438 | char name[256]; |
430 | int i; |
439 | int i; |
431 | FILE *f; |
440 | FILE *f; |
432 | struct item_bin *item_bin; |
441 | struct item_bin *item_bin; |
433 | |
442 | |
434 | for (i = count ; i >= 0 ; i--) { |
443 | for (i = count; i >= 0; i--) |
|
|
444 | { |
435 | sprintf(name,"graph_%d",i); |
445 | sprintf(name, "graph_%d", i); |
436 | f=tempfile(suffix, name, 0); |
446 | f = tempfile(suffix, name, 0); |
437 | while ((item_bin = read_item(f))) { |
447 | while ((item_bin = read_item(f, 0))) |
|
|
448 | { |
438 | tile_write_item_minmax(info, item_bin, ref, i, i); |
449 | tile_write_item_minmax(info, item_bin, ref, i, i); |
439 | } |
450 | } |
440 | fclose(f); |
451 | fclose(f); |
441 | } |
452 | } |
442 | } |
453 | } |
443 | |
454 | |
444 | void |
|
|
445 | ch_generate_tiles(char *map_suffix, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info) |
455 | void ch_generate_tiles(char *map_suffix, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info) |
446 | { |
456 | { |
447 | struct tile_info info; |
457 | struct tile_info info; |
448 | FILE *in,*ref,*ddsg_coords,*ddsg; |
458 | FILE *in, *ref, *ddsg_coords, *ddsg; |
449 | FILE **graphfiles; |
459 | FILE **graphfiles; |
450 | info.write=0; |
460 | info.write = 0; |
451 | info.maxlen=0; |
461 | info.maxlen = 0; |
452 | info.suffix=suffix; |
462 | info.suffix = suffix; |
453 | info.tiles_list=NULL; |
463 | info.tiles_list = NULL; |
454 | info.tilesdir_out=tilesdir_out; |
464 | info.tilesdir_out = tilesdir_out; |
455 | graphfiles=g_alloca(sizeof(FILE*)*(ch_levels+1)); |
465 | graphfiles = g_alloca(sizeof(FILE*) * (ch_levels + 1)); |
456 | |
466 | |
457 | ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); |
467 | ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); |
458 | in=tempfile(map_suffix,"ways_split",0); |
468 | in = tempfile(map_suffix, "ways_split", 0); |
459 | ref=tempfile(map_suffix,"ways_split_ref",0); |
469 | ref = tempfile(map_suffix, "ways_split_ref", 0); |
460 | ddsg_coords=tempfile(suffix,"ddsg_coords",1); |
470 | ddsg_coords = tempfile(suffix, "ddsg_coords", 1); |
461 | ddsg=tempfile(suffix,"ddsg",1); |
471 | ddsg = tempfile(suffix, "ddsg", 1); |
462 | ch_generate_ddsg(in, ref, ddsg_coords, ddsg); |
472 | ch_generate_ddsg(in, ref, ddsg_coords, ddsg); |
463 | fclose(in); |
473 | fclose(in); |
464 | fclose(ref); |
474 | fclose(ref); |
465 | fclose(ddsg_coords); |
475 | fclose(ddsg_coords); |
466 | fclose(ddsg); |
476 | fclose(ddsg); |
467 | ch_generate_sgr(suffix); |
477 | ch_generate_sgr(suffix); |
468 | ch_setup(suffix); |
478 | ch_setup(suffix); |
469 | ch_process(graphfiles, ch_levels, 0); |
479 | ch_process(graphfiles, ch_levels, 0); |
470 | ch_close_tempfiles(graphfiles, ch_levels); |
480 | ch_close_tempfiles(graphfiles, ch_levels); |
471 | |
481 | |
472 | tile_hash=g_hash_table_new(g_str_hash, g_str_equal); |
482 | tile_hash = g_hash_table_new(g_str_hash, g_str_equal); |
473 | ch_copy_to_tiles(suffix, ch_levels, &info, NULL); |
483 | ch_copy_to_tiles(suffix, ch_levels, &info, NULL); |
474 | merge_tiles(&info); |
484 | merge_tiles(&info); |
475 | |
485 | |
476 | write_tilesdir(&info, zip_info, tilesdir_out); |
486 | write_tilesdir(&info, zip_info, tilesdir_out); |
477 | } |
487 | } |
478 | |
488 | |
479 | void |
|
|
480 | ch_assemble_map(char *map_suffix, char *suffix, struct zip_info *zip_info) |
489 | void ch_assemble_map(char *map_suffix, char *suffix, struct zip_info *zip_info) |
481 | { |
490 | { |
482 | struct tile_info info; |
491 | struct tile_info info; |
483 | struct tile_head *th; |
492 | struct tile_head *th; |
484 | FILE **graphfiles=g_alloca(sizeof(FILE*)*(ch_levels+1)); |
493 | FILE **graphfiles = g_alloca(sizeof(FILE*) * (ch_levels + 1)); |
485 | FILE *ref; |
494 | FILE *ref; |
486 | struct item_id id; |
495 | struct item_id id; |
487 | int nodeid=0; |
496 | int nodeid = 0; |
488 | |
497 | |
489 | info.write=1; |
498 | info.write = 1; |
490 | info.maxlen=zip_get_maxnamelen(zip_info); |
499 | info.maxlen = zip_get_maxnamelen(zip_info); |
491 | info.suffix=suffix; |
500 | info.suffix = suffix; |
492 | info.tiles_list=NULL; |
501 | info.tiles_list = NULL; |
493 | info.tilesdir_out=NULL; |
502 | info.tilesdir_out = NULL; |
494 | ref=tempfile(suffix,"sgr_ref",1); |
503 | ref = tempfile(suffix, "sgr_ref", 1); |
495 | |
504 | |
496 | create_tile_hash(); |
505 | create_tile_hash(); |
497 | |
506 | |
498 | th=tile_head_root; |
507 | th = tile_head_root; |
499 | while (th) { |
508 | while (th) |
|
|
509 | { |
500 | th->zip_data=NULL; |
510 | th->zip_data = NULL; |
501 | th->process=1; |
511 | th->process = 1; |
502 | th=th->next; |
512 | th = th->next; |
503 | } |
513 | } |
504 | |
514 | |
505 | ch_setup(suffix); |
515 | ch_setup(suffix); |
506 | ch_copy_to_tiles(suffix, ch_levels, &info, ref); |
516 | ch_copy_to_tiles(suffix, ch_levels, &info, ref); |
507 | fclose(ref); |
517 | fclose(ref); |
508 | ref=tempfile(suffix,"sgr_ref",0); |
518 | ref = tempfile(suffix, "sgr_ref", 0); |
509 | sgr_nodes_hash=g_hash_table_new_full(NULL, NULL, NULL, item_id_slice_free); |
519 | sgr_nodes_hash = g_hash_table_new_full(NULL, NULL, NULL, item_id_slice_free); |
510 | while (fread(&id, sizeof(id), 1, ref)) { |
520 | while (fread(&id, sizeof(id), 1, ref)) |
|
|
521 | { |
511 | struct item_id *id2=g_slice_new(struct item_id); |
522 | struct item_id *id2=g_slice_new(struct item_id); |
512 | *id2=id; |
523 | *id2 = id; |
513 | #if 0 |
524 | #if 0 |
514 | dbg(0,"%d is "ITEM_ID_FMT"\n",nodeid,ITEM_ID_ARGS(*id2)); |
525 | dbg(0,"%d is "ITEM_ID_FMT"\n",nodeid,ITEM_ID_ARGS(*id2)); |
515 | #endif |
526 | #endif |
516 | g_hash_table_insert(sgr_nodes_hash, GINT_TO_POINTER(nodeid), id2); |
527 | g_hash_table_insert(sgr_nodes_hash, GINT_TO_POINTER(nodeid), id2); |
517 | nodeid++; |
528 | nodeid++; |
518 | } |
529 | } |
519 | th=tile_head_root; |
530 | th = tile_head_root; |
520 | while (th) { |
531 | while (th) |
|
|
532 | { |
521 | th->zip_data=malloc(th->total_size); |
533 | th->zip_data = malloc(th->total_size); |
522 | th->total_size_used=0; |
534 | th->total_size_used = 0; |
523 | th=th->next; |
535 | th = th->next; |
524 | } |
536 | } |
525 | ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); |
537 | ch_create_tempfiles(suffix, graphfiles, ch_levels, 1); |
526 | ch_process(graphfiles, ch_levels, 1); |
538 | ch_process(graphfiles, ch_levels, 1); |
527 | ch_close_tempfiles(graphfiles, ch_levels); |
539 | ch_close_tempfiles(graphfiles, ch_levels); |
528 | |
540 | |
529 | g_hash_table_destroy(newnode_hash); |
541 | g_hash_table_destroy(newnode_hash); |
… | |
… | |
531 | g_hash_table_destroy(sgr_nodes_hash); |
543 | g_hash_table_destroy(sgr_nodes_hash); |
532 | |
544 | |
533 | ch_copy_to_tiles(suffix, ch_levels, &info, NULL); |
545 | ch_copy_to_tiles(suffix, ch_levels, &info, NULL); |
534 | write_tilesdir(&info, zip_info, NULL); |
546 | write_tilesdir(&info, zip_info, NULL); |
535 | |
547 | |
536 | th=tile_head_root; |
548 | th = tile_head_root; |
537 | while (th) { |
549 | while (th) |
|
|
550 | { |
538 | if (th->name[0]) { |
551 | if (th->name[0]) |
|
|
552 | { |
539 | if (th->total_size != th->total_size_used) { |
553 | if (th->total_size != th->total_size_used) |
|
|
554 | { |
540 | fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used); |
555 | fprintf(stderr, "Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used); |
541 | exit(1); |
556 | exit(1); |
542 | } |
557 | } |
543 | write_zipmember(zip_info, th->name, zip_get_maxnamelen(zip_info), th->zip_data, th->total_size); |
558 | write_zipmember(zip_info, th->name, zip_get_maxnamelen(zip_info), th->zip_data, th->total_size); |
|
|
559 | } |
544 | } else { |
560 | else |
|
|
561 | { |
545 | fwrite(th->zip_data, th->total_size, 1, zip_get_index(zip_info)); |
562 | fwrite(th->zip_data, th->total_size, 1, zip_get_index(zip_info)); |
546 | } |
563 | } |
547 | g_free(th->zip_data); |
564 | g_free(th->zip_data); |
548 | th=th->next; |
565 | th = th->next; |
549 | } |
566 | } |
550 | } |
567 | } |