Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/nodesx.c
Parent Directory
|
Revision Log
Revision 466 -
(hide annotations)
(download)
(as text)
Sat Jul 31 14:56:17 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 19549 byte(s)
Sat Jul 31 14:56:17 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 19549 byte(s)
Assert if the number of nodes, segments or ways exceeds the legal range of the index counters.
1 | amb | 110 | /*************************************** |
2 | amb | 466 | $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.65 2010-07-31 14:56:17 amb Exp $ |
3 | amb | 110 | |
4 | Extented Node data type functions. | ||
5 | amb | 151 | |
6 | Part of the Routino routing software. | ||
7 | amb | 110 | ******************/ /****************** |
8 | amb | 326 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | amb | 110 | |
10 | amb | 151 | This program is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU Affero General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU Affero General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Affero General Public License | ||
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | amb | 110 | ***************************************/ |
23 | |||
24 | |||
25 | #include <assert.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <stdio.h> | ||
28 | amb | 249 | #include <string.h> |
29 | amb | 326 | #include <sys/stat.h> |
30 | amb | 110 | |
31 | #include "types.h" | ||
32 | amb | 449 | #include "nodes.h" |
33 | #include "segments.h" | ||
34 | |||
35 | amb | 110 | #include "nodesx.h" |
36 | #include "segmentsx.h" | ||
37 | amb | 204 | #include "waysx.h" |
38 | amb | 110 | |
39 | amb | 466 | #include "types.h" |
40 | |||
41 | amb | 449 | #include "files.h" |
42 | #include "functions.h" | ||
43 | amb | 110 | |
44 | amb | 449 | |
45 | amb | 252 | /* Variables */ |
46 | amb | 110 | |
47 | amb | 289 | /*+ The command line '--tmpdir' option or its default value. +*/ |
48 | amb | 284 | extern char *option_tmpdirname; |
49 | amb | 110 | |
50 | amb | 284 | /*+ A temporary file-local variable for use by the sort functions. +*/ |
51 | static NodesX *sortnodesx; | ||
52 | |||
53 | amb | 110 | /* Functions */ |
54 | |||
55 | amb | 271 | static int sort_by_id(NodeX *a,NodeX *b); |
56 | amb | 273 | static int index_by_id(NodeX *nodex,index_t index); |
57 | amb | 271 | |
58 | amb | 281 | static int sort_by_lat_long(NodeX *a,NodeX *b); |
59 | static int index_by_lat_long(NodeX *nodex,index_t index); | ||
60 | amb | 110 | |
61 | |||
62 | /*++++++++++++++++++++++++++++++++++++++ | ||
63 | amb | 326 | Allocate a new node list (create a new file or open an existing one). |
64 | amb | 110 | |
65 | NodesX *NewNodeList Returns the node list. | ||
66 | amb | 326 | |
67 | int append Set to 1 if the file is to be opened for appending (now or later). | ||
68 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
69 | |||
70 | amb | 326 | NodesX *NewNodeList(int append) |
71 | amb | 110 | { |
72 | NodesX *nodesx; | ||
73 | |||
74 | amb | 213 | nodesx=(NodesX*)calloc(1,sizeof(NodesX)); |
75 | amb | 110 | |
76 | amb | 243 | assert(nodesx); /* Check calloc() worked */ |
77 | |||
78 | amb | 284 | nodesx->filename=(char*)malloc(strlen(option_tmpdirname)+32); |
79 | amb | 216 | |
80 | amb | 326 | if(append) |
81 | amb | 447 | sprintf(nodesx->filename,"%s/nodesx.input.tmp",option_tmpdirname); |
82 | amb | 326 | else |
83 | amb | 447 | sprintf(nodesx->filename,"%s/nodesx.%p.tmp",option_tmpdirname,nodesx); |
84 | amb | 249 | |
85 | amb | 452 | #if SLIM |
86 | amb | 448 | nodesx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32); |
87 | |||
88 | sprintf(nodesx->nfilename,"%s/nodes.%p.tmp",option_tmpdirname,nodesx); | ||
89 | amb | 452 | #endif |
90 | amb | 448 | |
91 | amb | 326 | if(append) |
92 | { | ||
93 | amb | 331 | off_t size; |
94 | amb | 326 | |
95 | nodesx->fd=AppendFile(nodesx->filename); | ||
96 | |||
97 | amb | 331 | size=SizeFile(nodesx->filename); |
98 | amb | 326 | |
99 | amb | 331 | nodesx->xnumber=size/sizeof(NodeX); |
100 | amb | 326 | } |
101 | else | ||
102 | nodesx->fd=OpenFile(nodesx->filename); | ||
103 | |||
104 | amb | 110 | return(nodesx); |
105 | } | ||
106 | |||
107 | |||
108 | /*++++++++++++++++++++++++++++++++++++++ | ||
109 | amb | 226 | Free a node list. |
110 | |||
111 | NodesX *nodesx The list to be freed. | ||
112 | amb | 326 | |
113 | int keep Set to 1 if the file is to be kept. | ||
114 | amb | 226 | ++++++++++++++++++++++++++++++++++++++*/ |
115 | |||
116 | amb | 326 | void FreeNodeList(NodesX *nodesx,int keep) |
117 | amb | 226 | { |
118 | amb | 326 | if(!keep) |
119 | DeleteFile(nodesx->filename); | ||
120 | |||
121 | amb | 283 | free(nodesx->filename); |
122 | amb | 226 | |
123 | if(nodesx->idata) | ||
124 | free(nodesx->idata); | ||
125 | |||
126 | amb | 452 | #if !SLIM |
127 | amb | 226 | if(nodesx->ndata) |
128 | free(nodesx->ndata); | ||
129 | amb | 452 | #endif |
130 | amb | 226 | |
131 | amb | 452 | #if SLIM |
132 | amb | 448 | DeleteFile(nodesx->nfilename); |
133 | |||
134 | free(nodesx->nfilename); | ||
135 | amb | 452 | #endif |
136 | amb | 448 | |
137 | amb | 283 | if(nodesx->super) |
138 | free(nodesx->super); | ||
139 | |||
140 | amb | 257 | if(nodesx->offsets) |
141 | free(nodesx->offsets); | ||
142 | |||
143 | amb | 226 | free(nodesx); |
144 | } | ||
145 | |||
146 | |||
147 | /*++++++++++++++++++++++++++++++++++++++ | ||
148 | amb | 252 | Append a node to a newly created node list (unsorted). |
149 | amb | 243 | |
150 | amb | 252 | NodesX* nodesx The set of nodes to process. |
151 | amb | 243 | |
152 | amb | 252 | node_t id The node identification. |
153 | amb | 110 | |
154 | amb | 252 | double latitude The latitude of the node. |
155 | amb | 110 | |
156 | amb | 252 | double longitude The longitude of the node. |
157 | ++++++++++++++++++++++++++++++++++++++*/ | ||
158 | amb | 110 | |
159 | amb | 252 | void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude) |
160 | { | ||
161 | NodeX nodex; | ||
162 | amb | 249 | |
163 | amb | 252 | nodex.id=id; |
164 | nodex.latitude =radians_to_latlong(latitude); | ||
165 | nodex.longitude=radians_to_latlong(longitude); | ||
166 | |||
167 | WriteFile(nodesx->fd,&nodex,sizeof(NodeX)); | ||
168 | |||
169 | nodesx->xnumber++; | ||
170 | amb | 466 | |
171 | assert(!(nodesx->xnumber==NODE_FAKE)); /* NODE_FAKE marks the high-water mark for real nodes. */ | ||
172 | amb | 110 | } |
173 | |||
174 | |||
175 | /*++++++++++++++++++++++++++++++++++++++ | ||
176 | amb | 263 | Sort the node list (i.e. create the sortable indexes). |
177 | amb | 110 | |
178 | NodesX* nodesx The set of nodes to process. | ||
179 | ++++++++++++++++++++++++++++++++++++++*/ | ||
180 | |||
181 | amb | 263 | void SortNodeList(NodesX* nodesx) |
182 | amb | 110 | { |
183 | amb | 263 | int fd; |
184 | amb | 110 | |
185 | amb | 263 | /* Print the start message */ |
186 | |||
187 | printf("Sorting Nodes"); | ||
188 | amb | 227 | fflush(stdout); |
189 | amb | 132 | |
190 | amb | 263 | /* Close the files and re-open them (finished appending) */ |
191 | amb | 260 | |
192 | CloseFile(nodesx->fd); | ||
193 | nodesx->fd=ReOpenFile(nodesx->filename); | ||
194 | |||
195 | amb | 271 | DeleteFile(nodesx->filename); |
196 | |||
197 | fd=OpenFile(nodesx->filename); | ||
198 | |||
199 | amb | 252 | /* Allocate the array of indexes */ |
200 | amb | 249 | |
201 | amb | 252 | nodesx->idata=(node_t*)malloc(nodesx->xnumber*sizeof(node_t)); |
202 | amb | 249 | |
203 | amb | 252 | assert(nodesx->idata); /* Check malloc() worked */ |
204 | amb | 249 | |
205 | amb | 271 | /* Sort by node indexes */ |
206 | amb | 249 | |
207 | amb | 271 | sortnodesx=nodesx; |
208 | amb | 110 | |
209 | amb | 311 | filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))index_by_id); |
210 | amb | 252 | |
211 | amb | 260 | /* Close the files and re-open them */ |
212 | |||
213 | amb | 257 | CloseFile(nodesx->fd); |
214 | CloseFile(fd); | ||
215 | amb | 252 | |
216 | amb | 257 | nodesx->fd=ReOpenFile(nodesx->filename); |
217 | amb | 252 | |
218 | amb | 263 | /* Print the final message */ |
219 | |||
220 | amb | 273 | printf("\rSorted Nodes: Nodes=%d Duplicates=%d\n",nodesx->xnumber,nodesx->xnumber-nodesx->number); |
221 | amb | 263 | fflush(stdout); |
222 | amb | 110 | } |
223 | |||
224 | |||
225 | /*++++++++++++++++++++++++++++++++++++++ | ||
226 | Sort the nodes into id order. | ||
227 | |||
228 | int sort_by_id Returns the comparison of the id fields. | ||
229 | |||
230 | amb | 271 | NodeX *a The first extended node. |
231 | amb | 110 | |
232 | amb | 271 | NodeX *b The second extended node. |
233 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
234 | |||
235 | amb | 271 | static int sort_by_id(NodeX *a,NodeX *b) |
236 | amb | 110 | { |
237 | amb | 271 | node_t a_id=a->id; |
238 | node_t b_id=b->id; | ||
239 | amb | 252 | |
240 | if(a_id<b_id) | ||
241 | return(-1); | ||
242 | else if(a_id>b_id) | ||
243 | amb | 249 | return(1); |
244 | amb | 110 | else |
245 | amb | 252 | return(0); |
246 | amb | 110 | } |
247 | |||
248 | |||
249 | amb | 271 | /*++++++++++++++++++++++++++++++++++++++ |
250 | Index the nodes after sorting. | ||
251 | amb | 252 | |
252 | amb | 289 | int index_by_id Return 1 if the value is to be kept, otherwise zero. |
253 | amb | 273 | |
254 | amb | 271 | NodeX *nodex The extended node. |
255 | amb | 252 | |
256 | amb | 271 | index_t index The index of this node in the total. |
257 | ++++++++++++++++++++++++++++++++++++++*/ | ||
258 | |||
259 | amb | 273 | static int index_by_id(NodeX *nodex,index_t index) |
260 | amb | 271 | { |
261 | amb | 273 | if(index==0 || sortnodesx->idata[index-1]!=nodex->id) |
262 | { | ||
263 | sortnodesx->idata[index]=nodex->id; | ||
264 | amb | 271 | |
265 | amb | 273 | sortnodesx->number++; |
266 | |||
267 | return(1); | ||
268 | } | ||
269 | |||
270 | return(0); | ||
271 | amb | 271 | } |
272 | |||
273 | |||
274 | amb | 110 | /*++++++++++++++++++++++++++++++++++++++ |
275 | amb | 212 | Sort the node list geographically. |
276 | |||
277 | NodesX* nodesx The set of nodes to process. | ||
278 | ++++++++++++++++++++++++++++++++++++++*/ | ||
279 | |||
280 | void SortNodeListGeographically(NodesX* nodesx) | ||
281 | { | ||
282 | amb | 281 | int fd; |
283 | amb | 212 | |
284 | amb | 263 | /* Print the start message */ |
285 | |||
286 | amb | 227 | printf("Sorting Nodes Geographically"); |
287 | fflush(stdout); | ||
288 | amb | 212 | |
289 | amb | 281 | /* Allocate the memory for the geographical offsets array */ |
290 | amb | 275 | |
291 | amb | 281 | nodesx->offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); |
292 | amb | 275 | |
293 | amb | 281 | nodesx->latlonbin=0; |
294 | amb | 212 | |
295 | amb | 281 | /* Close the files and re-open them */ |
296 | amb | 212 | |
297 | amb | 281 | CloseFile(nodesx->fd); |
298 | nodesx->fd=ReOpenFile(nodesx->filename); | ||
299 | amb | 243 | |
300 | amb | 281 | DeleteFile(nodesx->filename); |
301 | amb | 212 | |
302 | amb | 281 | fd=OpenFile(nodesx->filename); |
303 | amb | 212 | |
304 | amb | 281 | /* Sort geographically */ |
305 | amb | 252 | |
306 | amb | 281 | sortnodesx=nodesx; |
307 | amb | 257 | |
308 | amb | 311 | filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_lat_long,(int (*)(void*,index_t))index_by_lat_long); |
309 | amb | 257 | |
310 | amb | 281 | /* Close the files and re-open them */ |
311 | amb | 257 | |
312 | amb | 281 | CloseFile(nodesx->fd); |
313 | CloseFile(fd); | ||
314 | amb | 257 | |
315 | amb | 281 | nodesx->fd=ReOpenFile(nodesx->filename); |
316 | amb | 257 | |
317 | amb | 281 | /* Finish off the indexing */ |
318 | amb | 257 | |
319 | amb | 281 | for(;nodesx->latlonbin<=(nodesx->latbins*nodesx->lonbins);nodesx->latlonbin++) |
320 | nodesx->offsets[nodesx->latlonbin]=nodesx->number; | ||
321 | amb | 257 | |
322 | amb | 263 | /* Print the final message */ |
323 | amb | 257 | |
324 | amb | 227 | printf("\rSorted Nodes Geographically \n"); |
325 | fflush(stdout); | ||
326 | amb | 212 | } |
327 | |||
328 | |||
329 | /*++++++++++++++++++++++++++++++++++++++ | ||
330 | amb | 110 | Sort the nodes into latitude and longitude order. |
331 | |||
332 | int sort_by_lat_long Returns the comparison of the latitude and longitude fields. | ||
333 | |||
334 | amb | 281 | NodeX *a The first extended node. |
335 | amb | 110 | |
336 | amb | 281 | NodeX *b The second extended node. |
337 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
338 | |||
339 | amb | 281 | static int sort_by_lat_long(NodeX *a,NodeX *b) |
340 | amb | 110 | { |
341 | amb | 281 | ll_bin_t a_lon=latlong_to_bin(a->longitude); |
342 | ll_bin_t b_lon=latlong_to_bin(b->longitude); | ||
343 | amb | 110 | |
344 | if(a_lon<b_lon) | ||
345 | return(-1); | ||
346 | else if(a_lon>b_lon) | ||
347 | return(1); | ||
348 | else | ||
349 | { | ||
350 | amb | 281 | ll_bin_t a_lat=latlong_to_bin(a->latitude); |
351 | ll_bin_t b_lat=latlong_to_bin(b->latitude); | ||
352 | amb | 110 | |
353 | if(a_lat<b_lat) | ||
354 | return(-1); | ||
355 | else if(a_lat>b_lat) | ||
356 | return(1); | ||
357 | else | ||
358 | amb | 281 | { |
359 | #ifdef REGRESSION_TESTING | ||
360 | // Need this for regression testing because heapsort() is not order | ||
361 | // preserving like qsort() is (or was when tested). | ||
362 | |||
363 | index_t a_id=a->id; | ||
364 | index_t b_id=b->id; | ||
365 | |||
366 | if(a_id<b_id) | ||
367 | return(-1); | ||
368 | else if(a_id>b_id) | ||
369 | return(1); | ||
370 | else | ||
371 | #endif | ||
372 | return(0); | ||
373 | } | ||
374 | amb | 110 | } |
375 | } | ||
376 | |||
377 | |||
378 | /*++++++++++++++++++++++++++++++++++++++ | ||
379 | amb | 281 | Index the nodes after sorting. |
380 | |||
381 | amb | 289 | int index_by_lat_long Return 1 if the value is to be kept, otherwise zero. |
382 | amb | 281 | |
383 | NodeX *nodex The extended node. | ||
384 | |||
385 | index_t index The index of this node in the total. | ||
386 | ++++++++++++++++++++++++++++++++++++++*/ | ||
387 | |||
388 | static int index_by_lat_long(NodeX *nodex,index_t index) | ||
389 | { | ||
390 | /* Work out the offsets */ | ||
391 | |||
392 | ll_bin_t latbin=latlong_to_bin(nodex->latitude )-sortnodesx->latzero; | ||
393 | ll_bin_t lonbin=latlong_to_bin(nodex->longitude)-sortnodesx->lonzero; | ||
394 | int llbin=lonbin*sortnodesx->latbins+latbin; | ||
395 | |||
396 | for(;sortnodesx->latlonbin<=llbin;sortnodesx->latlonbin++) | ||
397 | sortnodesx->offsets[sortnodesx->latlonbin]=index; | ||
398 | |||
399 | return(1); | ||
400 | } | ||
401 | |||
402 | |||
403 | /*++++++++++++++++++++++++++++++++++++++ | ||
404 | amb | 285 | Find a particular node index. |
405 | |||
406 | index_t IndexNodeX Returns the index of the extended node with the specified id. | ||
407 | |||
408 | NodesX* nodesx The set of nodes to process. | ||
409 | |||
410 | node_t id The node id to look for. | ||
411 | ++++++++++++++++++++++++++++++++++++++*/ | ||
412 | |||
413 | index_t IndexNodeX(NodesX* nodesx,node_t id) | ||
414 | { | ||
415 | int start=0; | ||
416 | int end=nodesx->number-1; | ||
417 | int mid; | ||
418 | |||
419 | /* Binary search - search key exact match only is required. | ||
420 | * | ||
421 | * # <- start | Check mid and move start or end if it doesn't match | ||
422 | * # | | ||
423 | * # | Since an exact match is wanted we can set end=mid-1 | ||
424 | * # <- mid | or start=mid+1 because we know that mid doesn't match. | ||
425 | * # | | ||
426 | * # | Eventually either end=start or end=start+1 and one of | ||
427 | * # <- end | start or end is the wanted one. | ||
428 | */ | ||
429 | |||
430 | if(end<start) /* There are no nodes */ | ||
431 | return(NO_NODE); | ||
432 | else if(id<nodesx->idata[start]) /* Check key is not before start */ | ||
433 | return(NO_NODE); | ||
434 | else if(id>nodesx->idata[end]) /* Check key is not after end */ | ||
435 | return(NO_NODE); | ||
436 | else | ||
437 | { | ||
438 | do | ||
439 | { | ||
440 | mid=(start+end)/2; /* Choose mid point */ | ||
441 | |||
442 | if(nodesx->idata[mid]<id) /* Mid point is too low */ | ||
443 | start=mid+1; | ||
444 | else if(nodesx->idata[mid]>id) /* Mid point is too high */ | ||
445 | end=mid-1; | ||
446 | else /* Mid point is correct */ | ||
447 | return(mid); | ||
448 | } | ||
449 | while((end-start)>1); | ||
450 | |||
451 | if(nodesx->idata[start]==id) /* Start is correct */ | ||
452 | return(start); | ||
453 | |||
454 | if(nodesx->idata[end]==id) /* End is correct */ | ||
455 | return(end); | ||
456 | } | ||
457 | |||
458 | return(NO_NODE); | ||
459 | } | ||
460 | |||
461 | |||
462 | /*++++++++++++++++++++++++++++++++++++++ | ||
463 | amb | 110 | Remove any nodes that are not part of a highway. |
464 | |||
465 | NodesX *nodesx The complete node list. | ||
466 | |||
467 | SegmentsX *segmentsx The list of segments. | ||
468 | ++++++++++++++++++++++++++++++++++++++*/ | ||
469 | |||
470 | void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx) | ||
471 | { | ||
472 | amb | 263 | NodeX nodex; |
473 | amb | 273 | int total=0,highway=0,nothighway=0; |
474 | amb | 281 | ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin; |
475 | latlong_t lat_min,lat_max,lon_min,lon_max; | ||
476 | amb | 263 | int fd; |
477 | amb | 110 | |
478 | amb | 263 | /* Print the start message */ |
479 | |||
480 | amb | 227 | printf("Checking: Nodes=0"); |
481 | fflush(stdout); | ||
482 | |||
483 | amb | 281 | /* While we are here we can work out the range of data */ |
484 | |||
485 | lat_min=radians_to_latlong( 2); | ||
486 | lat_max=radians_to_latlong(-2); | ||
487 | lon_min=radians_to_latlong( 4); | ||
488 | lon_max=radians_to_latlong(-4); | ||
489 | |||
490 | amb | 263 | /* Modify the on-disk image */ |
491 | |||
492 | DeleteFile(nodesx->filename); | ||
493 | |||
494 | fd=OpenFile(nodesx->filename); | ||
495 | SeekFile(nodesx->fd,0); | ||
496 | |||
497 | while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX))) | ||
498 | amb | 110 | { |
499 | amb | 275 | if(IndexFirstSegmentX(segmentsx,nodex.id)==NO_SEGMENT) |
500 | amb | 271 | nothighway++; |
501 | else | ||
502 | amb | 263 | { |
503 | amb | 280 | nodex.id=highway; |
504 | |||
505 | amb | 263 | WriteFile(fd,&nodex,sizeof(NodeX)); |
506 | |||
507 | nodesx->idata[highway]=nodesx->idata[total]; | ||
508 | amb | 110 | highway++; |
509 | amb | 281 | |
510 | if(nodex.latitude<lat_min) | ||
511 | lat_min=nodex.latitude; | ||
512 | if(nodex.latitude>lat_max) | ||
513 | lat_max=nodex.latitude; | ||
514 | if(nodex.longitude<lon_min) | ||
515 | lon_min=nodex.longitude; | ||
516 | if(nodex.longitude>lon_max) | ||
517 | lon_max=nodex.longitude; | ||
518 | amb | 263 | } |
519 | amb | 110 | |
520 | amb | 263 | total++; |
521 | |||
522 | if(!(total%10000)) | ||
523 | amb | 110 | { |
524 | amb | 273 | printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",total,highway,nothighway); |
525 | amb | 110 | fflush(stdout); |
526 | } | ||
527 | } | ||
528 | |||
529 | amb | 263 | /* Close the files and re-open them */ |
530 | |||
531 | CloseFile(nodesx->fd); | ||
532 | CloseFile(fd); | ||
533 | |||
534 | nodesx->fd=ReOpenFile(nodesx->filename); | ||
535 | |||
536 | nodesx->number=highway; | ||
537 | |||
538 | amb | 281 | /* Work out the number of bins */ |
539 | |||
540 | lat_min_bin=latlong_to_bin(lat_min); | ||
541 | lon_min_bin=latlong_to_bin(lon_min); | ||
542 | lat_max_bin=latlong_to_bin(lat_max); | ||
543 | lon_max_bin=latlong_to_bin(lon_max); | ||
544 | |||
545 | nodesx->latzero=lat_min_bin; | ||
546 | nodesx->lonzero=lon_min_bin; | ||
547 | |||
548 | nodesx->latbins=(lat_max_bin-lat_min_bin)+1; | ||
549 | nodesx->lonbins=(lon_max_bin-lon_min_bin)+1; | ||
550 | |||
551 | amb | 263 | /* Allocate and clear the super-node markers */ |
552 | |||
553 | nodesx->super=(uint8_t*)calloc(nodesx->number,sizeof(uint8_t)); | ||
554 | |||
555 | assert(nodesx->super); /* Check calloc() worked */ | ||
556 | |||
557 | /* Print the final message */ | ||
558 | |||
559 | amb | 273 | printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",total,highway,nothighway); |
560 | amb | 110 | fflush(stdout); |
561 | } | ||
562 | |||
563 | |||
564 | /*++++++++++++++++++++++++++++++++++++++ | ||
565 | amb | 212 | Create the real node data. |
566 | amb | 110 | |
567 | amb | 212 | NodesX *nodesx The set of nodes to use. |
568 | amb | 110 | |
569 | amb | 212 | int iteration The final super-node iteration. |
570 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
571 | |||
572 | amb | 212 | void CreateRealNodes(NodesX *nodesx,int iteration) |
573 | amb | 110 | { |
574 | amb | 214 | index_t i; |
575 | amb | 110 | |
576 | amb | 275 | /* Print the start message */ |
577 | |||
578 | amb | 227 | printf("Creating Real Nodes: Nodes=0"); |
579 | fflush(stdout); | ||
580 | |||
581 | amb | 275 | /* Map into memory */ |
582 | |||
583 | amb | 452 | #if !SLIM |
584 | nodesx->xdata=MapFile(nodesx->filename); | ||
585 | #endif | ||
586 | amb | 275 | |
587 | amb | 448 | /* Allocate the memory (or open the file) */ |
588 | amb | 212 | |
589 | amb | 452 | #if !SLIM |
590 | nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node)); | ||
591 | amb | 212 | |
592 | amb | 452 | assert(nodesx->ndata); /* Check malloc() worked */ |
593 | #else | ||
594 | nodesx->nfd=OpenFile(nodesx->nfilename); | ||
595 | #endif | ||
596 | amb | 243 | |
597 | amb | 212 | /* Loop through and allocate. */ |
598 | |||
599 | amb | 110 | for(i=0;i<nodesx->number;i++) |
600 | { | ||
601 | amb | 275 | NodeX *nodex=LookupNodeX(nodesx,i,1); |
602 | amb | 448 | Node *node =LookupNodeXNode(nodesx,nodex->id,1); |
603 | amb | 208 | |
604 | amb | 448 | node->latoffset=latlong_to_off(nodex->latitude); |
605 | node->lonoffset=latlong_to_off(nodex->longitude); | ||
606 | node->firstseg=SEGMENT(NO_SEGMENT); | ||
607 | amb | 212 | |
608 | amb | 281 | if(nodesx->super[nodex->id]==iteration) |
609 | amb | 448 | node->firstseg|=NODE_SUPER; |
610 | amb | 212 | |
611 | amb | 452 | #if SLIM |
612 | PutBackNodeXNode(nodesx,nodex->id,1); | ||
613 | #endif | ||
614 | amb | 448 | |
615 | amb | 110 | if(!((i+1)%10000)) |
616 | { | ||
617 | amb | 212 | printf("\rCreating Real Nodes: Nodes=%d",i+1); |
618 | amb | 110 | fflush(stdout); |
619 | } | ||
620 | } | ||
621 | |||
622 | amb | 280 | /* Free the unneeded memory */ |
623 | |||
624 | free(nodesx->super); | ||
625 | nodesx->super=NULL; | ||
626 | |||
627 | amb | 275 | /* Unmap from memory */ |
628 | |||
629 | amb | 452 | #if !SLIM |
630 | nodesx->xdata=UnmapFile(nodesx->filename); | ||
631 | #endif | ||
632 | amb | 275 | |
633 | /* Print the final message */ | ||
634 | |||
635 | amb | 212 | printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number); |
636 | amb | 110 | fflush(stdout); |
637 | } | ||
638 | |||
639 | |||
640 | /*++++++++++++++++++++++++++++++++++++++ | ||
641 | Assign the segment indexes to the nodes. | ||
642 | |||
643 | NodesX *nodesx The list of nodes to process. | ||
644 | |||
645 | SegmentsX* segmentsx The set of segments to use. | ||
646 | ++++++++++++++++++++++++++++++++++++++*/ | ||
647 | |||
648 | amb | 209 | void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx) |
649 | amb | 110 | { |
650 | amb | 214 | index_t i; |
651 | amb | 110 | |
652 | amb | 275 | /* Print the start message */ |
653 | |||
654 | amb | 227 | printf("Indexing Segments: Segments=0"); |
655 | fflush(stdout); | ||
656 | |||
657 | amb | 275 | /* Map into memory */ |
658 | |||
659 | amb | 452 | #if !SLIM |
660 | nodesx->xdata=MapFile(nodesx->filename); | ||
661 | segmentsx->xdata=MapFile(segmentsx->filename); | ||
662 | #endif | ||
663 | amb | 275 | |
664 | amb | 110 | /* Index the nodes */ |
665 | |||
666 | for(i=0;i<segmentsx->number;i++) | ||
667 | { | ||
668 | amb | 275 | SegmentX *segmentx=LookupSegmentX(segmentsx,i,1); |
669 | amb | 257 | node_t id1=segmentx->node1; |
670 | node_t id2=segmentx->node2; | ||
671 | amb | 448 | Node *node1=LookupNodeXNode(nodesx,id1,1); |
672 | Node *node2=LookupNodeXNode(nodesx,id2,2); | ||
673 | amb | 110 | |
674 | /* Check node1 */ | ||
675 | |||
676 | amb | 212 | if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT)) |
677 | amb | 110 | { |
678 | amb | 212 | node1->firstseg^=SEGMENT(NO_SEGMENT); |
679 | node1->firstseg|=i; | ||
680 | amb | 448 | |
681 | amb | 452 | #if SLIM |
682 | PutBackNodeXNode(nodesx,id1,1); | ||
683 | #endif | ||
684 | amb | 110 | } |
685 | else | ||
686 | { | ||
687 | amb | 212 | index_t index=SEGMENT(node1->firstseg); |
688 | amb | 110 | |
689 | do | ||
690 | { | ||
691 | amb | 275 | segmentx=LookupSegmentX(segmentsx,index,1); |
692 | amb | 256 | |
693 | amb | 257 | if(segmentx->node1==id1) |
694 | amb | 110 | { |
695 | amb | 209 | index++; |
696 | amb | 128 | |
697 | amb | 256 | if(index>=segmentsx->number) |
698 | amb | 209 | break; |
699 | amb | 256 | |
700 | amb | 275 | segmentx=LookupSegmentX(segmentsx,index,1); |
701 | amb | 256 | |
702 | amb | 257 | if(segmentx->node1!=id1) |
703 | amb | 256 | break; |
704 | amb | 110 | } |
705 | else | ||
706 | { | ||
707 | amb | 448 | Segment *segment=LookupSegmentXSegment(segmentsx,index,1); |
708 | |||
709 | if(segment->next2==NO_NODE) | ||
710 | amb | 110 | { |
711 | amb | 448 | segment->next2=i; |
712 | |||
713 | amb | 452 | #if SLIM |
714 | amb | 448 | PutBackSegmentXSegment(segmentsx,index,1); |
715 | amb | 452 | #endif |
716 | amb | 448 | |
717 | amb | 209 | break; |
718 | amb | 110 | } |
719 | else | ||
720 | amb | 448 | index=segment->next2; |
721 | amb | 110 | } |
722 | } | ||
723 | amb | 209 | while(1); |
724 | amb | 110 | } |
725 | |||
726 | /* Check node2 */ | ||
727 | |||
728 | amb | 212 | if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT)) |
729 | amb | 110 | { |
730 | amb | 212 | node2->firstseg^=SEGMENT(NO_SEGMENT); |
731 | node2->firstseg|=i; | ||
732 | amb | 448 | |
733 | amb | 452 | #if SLIM |
734 | PutBackNodeXNode(nodesx,id2,2); | ||
735 | #endif | ||
736 | amb | 110 | } |
737 | else | ||
738 | { | ||
739 | amb | 212 | index_t index=SEGMENT(node2->firstseg); |
740 | amb | 110 | |
741 | do | ||
742 | { | ||
743 | amb | 275 | segmentx=LookupSegmentX(segmentsx,index,1); |
744 | amb | 256 | |
745 | amb | 257 | if(segmentx->node1==id2) |
746 | amb | 110 | { |
747 | amb | 209 | index++; |
748 | amb | 128 | |
749 | amb | 256 | if(index>=segmentsx->number) |
750 | amb | 209 | break; |
751 | amb | 256 | |
752 | amb | 275 | segmentx=LookupSegmentX(segmentsx,index,1); |
753 | amb | 256 | |
754 | amb | 257 | if(segmentx->node1!=id2) |
755 | amb | 256 | break; |
756 | amb | 110 | } |
757 | else | ||
758 | { | ||
759 | amb | 448 | Segment *segment=LookupSegmentXSegment(segmentsx,index,1); |
760 | |||
761 | if(segment->next2==NO_NODE) | ||
762 | amb | 110 | { |
763 | amb | 448 | segment->next2=i; |
764 | |||
765 | amb | 452 | #if SLIM |
766 | amb | 448 | PutBackSegmentXSegment(segmentsx,index,1); |
767 | amb | 452 | #endif |
768 | amb | 448 | |
769 | amb | 209 | break; |
770 | amb | 110 | } |
771 | else | ||
772 | amb | 448 | index=segment->next2; |
773 | amb | 110 | } |
774 | } | ||
775 | amb | 209 | while(1); |
776 | amb | 110 | } |
777 | |||
778 | if(!((i+1)%10000)) | ||
779 | { | ||
780 | printf("\rIndexing Segments: Segments=%d",i+1); | ||
781 | fflush(stdout); | ||
782 | } | ||
783 | } | ||
784 | |||
785 | amb | 275 | /* Unmap from memory */ |
786 | |||
787 | amb | 452 | #if !SLIM |
788 | nodesx->xdata=UnmapFile(nodesx->filename); | ||
789 | segmentsx->xdata=UnmapFile(segmentsx->filename); | ||
790 | #endif | ||
791 | amb | 275 | |
792 | /* Print the final message */ | ||
793 | |||
794 | amb | 110 | printf("\rIndexed Segments: Segments=%d \n",segmentsx->number); |
795 | fflush(stdout); | ||
796 | } | ||
797 | amb | 285 | |
798 | |||
799 | /*++++++++++++++++++++++++++++++++++++++ | ||
800 | Save the node list to a file. | ||
801 | |||
802 | NodesX* nodesx The set of nodes to save. | ||
803 | |||
804 | const char *filename The name of the file to save. | ||
805 | ++++++++++++++++++++++++++++++++++++++*/ | ||
806 | |||
807 | void SaveNodeList(NodesX* nodesx,const char *filename) | ||
808 | { | ||
809 | index_t i; | ||
810 | int fd; | ||
811 | amb | 461 | NodesFile nodesfile; |
812 | amb | 285 | int super_number=0; |
813 | |||
814 | /* Print the start message */ | ||
815 | |||
816 | printf("Writing Nodes: Nodes=0"); | ||
817 | fflush(stdout); | ||
818 | |||
819 | /* Map into memory */ | ||
820 | |||
821 | amb | 452 | #if !SLIM |
822 | nodesx->xdata=MapFile(nodesx->filename); | ||
823 | #endif | ||
824 | amb | 285 | |
825 | amb | 461 | /* Write out the nodes data */ |
826 | amb | 285 | |
827 | fd=OpenFile(filename); | ||
828 | |||
829 | amb | 461 | SeekFile(fd,sizeof(NodesFile)); |
830 | amb | 285 | WriteFile(fd,nodesx->offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); |
831 | |||
832 | amb | 461 | for(i=0;i<nodesx->number;i++) |
833 | amb | 285 | { |
834 | NodeX *nodex=LookupNodeX(nodesx,i,1); | ||
835 | amb | 448 | Node *node=LookupNodeXNode(nodesx,nodex->id,1); |
836 | amb | 285 | |
837 | amb | 461 | if(node->firstseg&NODE_SUPER) |
838 | super_number++; | ||
839 | |||
840 | amb | 285 | WriteFile(fd,node,sizeof(Node)); |
841 | |||
842 | if(!((i+1)%10000)) | ||
843 | { | ||
844 | printf("\rWriting Nodes: Nodes=%d",i+1); | ||
845 | fflush(stdout); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | amb | 461 | /* Write out the header structure */ |
850 | |||
851 | nodesfile.number=nodesx->number; | ||
852 | nodesfile.snumber=super_number; | ||
853 | |||
854 | nodesfile.latbins=nodesx->latbins; | ||
855 | nodesfile.lonbins=nodesx->lonbins; | ||
856 | |||
857 | nodesfile.latzero=nodesx->latzero; | ||
858 | nodesfile.lonzero=nodesx->lonzero; | ||
859 | |||
860 | SeekFile(fd,0); | ||
861 | WriteFile(fd,&nodesfile,sizeof(NodesFile)); | ||
862 | |||
863 | amb | 285 | CloseFile(fd); |
864 | |||
865 | /* Unmap from memory */ | ||
866 | |||
867 | amb | 452 | #if !SLIM |
868 | nodesx->xdata=UnmapFile(nodesx->filename); | ||
869 | #endif | ||
870 | amb | 285 | |
871 | /* Print the final message */ | ||
872 | |||
873 | amb | 461 | printf("\rWrote Nodes: Nodes=%d \n",nodesx->number); |
874 | amb | 285 | fflush(stdout); |
875 | } |
Properties
Name | Value |
---|---|
cvs:description | Extended nodes functions. |