Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/nodesx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 556 - (hide annotations) (download) (as text)
Mon Dec 20 19:05:59 2010 UTC (14 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 19552 byte(s)
Don't map the file into memory for writing out the Nodes file.

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

Properties

Name Value
cvs:description Extended nodes functions.