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 558 - (hide annotations) (download) (as text)
Mon Dec 20 19:25:03 2010 UTC (14 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 19668 byte(s)
Handle the SegmentX Segment in the same way as the other data structures (map
into memory when used, open/close the file if slim).  Create the real nodes
without mapping the segments into memory.

1 amb 110 /***************************************
2 amb 558 $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.88 2010-12-20 19:25:03 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 552 PutBackNodeX(nodesx,nodesx->gdata[i],1);
570 amb 448
571 amb 110 if(!((i+1)%10000))
572 amb 519 printf_middle("Creating Real Nodes: Nodes=%d",i+1);
573 amb 110 }
574    
575 amb 280 /* Free the unneeded memory */
576    
577     free(nodesx->super);
578     nodesx->super=NULL;
579    
580 amb 555 /* Unmap from memory / close the file */
581 amb 275
582 amb 452 #if !SLIM
583     nodesx->xdata=UnmapFile(nodesx->filename);
584 amb 555 #else
585     CloseFile(nodesx->fd);
586 amb 452 #endif
587 amb 275
588     /* Print the final message */
589    
590 amb 519 printf_last("Creating Real Nodes: Nodes=%d",nodesx->number);
591 amb 110 }
592    
593    
594     /*++++++++++++++++++++++++++++++++++++++
595     Assign the segment indexes to the nodes.
596    
597     NodesX *nodesx The list of nodes to process.
598    
599     SegmentsX* segmentsx The set of segments to use.
600     ++++++++++++++++++++++++++++++++++++++*/
601    
602 amb 209 void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx)
603 amb 110 {
604 amb 214 index_t i;
605 amb 110
606 amb 510 if(nodesx->number==0 || segmentsx->number==0)
607 amb 508 return;
608    
609 amb 275 /* Print the start message */
610    
611 amb 519 printf_first("Indexing Segments: Segments=0");
612 amb 227
613 amb 555 /* Map into memory / open the files */
614 amb 275
615 amb 452 #if !SLIM
616 amb 552 nodesx->xdata=MapFileWriteable(nodesx->filename);
617 amb 452 segmentsx->xdata=MapFile(segmentsx->filename);
618 amb 558 segmentsx->sdata=MapFileWriteable(segmentsx->sfilename);
619 amb 555 #else
620     nodesx->fd=ReOpenFileWriteable(nodesx->filename);
621     segmentsx->fd=ReOpenFile(segmentsx->filename);
622 amb 558 segmentsx->sfd=ReOpenFileWriteable(segmentsx->sfilename);
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 552 PutBackNodeX(nodesx,nodesx->gdata[id1],1);
642 amb 110 }
643     else
644     {
645 amb 552 index_t index=nodex1->id;
646 amb 110
647     do
648     {
649 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
650 amb 256
651 amb 257 if(segmentx->node1==id1)
652 amb 110 {
653 amb 209 index++;
654 amb 128
655 amb 256 if(index>=segmentsx->number)
656 amb 209 break;
657 amb 256
658 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
659 amb 256
660 amb 257 if(segmentx->node1!=id1)
661 amb 256 break;
662 amb 110 }
663     else
664     {
665 amb 448 Segment *segment=LookupSegmentXSegment(segmentsx,index,1);
666    
667     if(segment->next2==NO_NODE)
668 amb 110 {
669 amb 448 segment->next2=i;
670    
671     PutBackSegmentXSegment(segmentsx,index,1);
672    
673 amb 209 break;
674 amb 110 }
675     else
676 amb 448 index=segment->next2;
677 amb 110 }
678     }
679 amb 209 while(1);
680 amb 110 }
681    
682     /* Check node2 */
683    
684 amb 552 if(nodex2->id==NO_SEGMENT)
685 amb 110 {
686 amb 552 nodex2->id=i;
687 amb 448
688 amb 552 PutBackNodeX(nodesx,nodesx->gdata[id2],2);
689 amb 110 }
690     else
691     {
692 amb 552 index_t index=nodex2->id;
693 amb 110
694     do
695     {
696 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
697 amb 256
698 amb 257 if(segmentx->node1==id2)
699 amb 110 {
700 amb 209 index++;
701 amb 128
702 amb 256 if(index>=segmentsx->number)
703 amb 209 break;
704 amb 256
705 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
706 amb 256
707 amb 257 if(segmentx->node1!=id2)
708 amb 256 break;
709 amb 110 }
710     else
711     {
712 amb 448 Segment *segment=LookupSegmentXSegment(segmentsx,index,1);
713    
714     if(segment->next2==NO_NODE)
715 amb 110 {
716 amb 448 segment->next2=i;
717    
718     PutBackSegmentXSegment(segmentsx,index,1);
719    
720 amb 209 break;
721 amb 110 }
722     else
723 amb 448 index=segment->next2;
724 amb 110 }
725     }
726 amb 209 while(1);
727 amb 110 }
728    
729     if(!((i+1)%10000))
730 amb 519 printf_middle("Indexing Segments: Segments=%d",i+1);
731 amb 110 }
732    
733 amb 555 /* Unmap from memory / close the files */
734 amb 275
735 amb 452 #if !SLIM
736     nodesx->xdata=UnmapFile(nodesx->filename);
737     segmentsx->xdata=UnmapFile(segmentsx->filename);
738 amb 558 segmentsx->sdata=UnmapFile(segmentsx->sfilename);
739 amb 555 #else
740     CloseFile(nodesx->fd);
741     CloseFile(segmentsx->fd);
742 amb 558 CloseFile(segmentsx->sfd);
743 amb 452 #endif
744 amb 275
745     /* Print the final message */
746    
747 amb 519 printf_last("Indexed Segments: Segments=%d ",segmentsx->number);
748 amb 110 }
749 amb 285
750    
751     /*++++++++++++++++++++++++++++++++++++++
752     Save the node list to a file.
753    
754     NodesX* nodesx The set of nodes to save.
755    
756     const char *filename The name of the file to save.
757     ++++++++++++++++++++++++++++++++++++++*/
758    
759     void SaveNodeList(NodesX* nodesx,const char *filename)
760     {
761     index_t i;
762     int fd;
763 amb 500 NodesFile nodesfile={0};
764 amb 285 int super_number=0;
765 amb 553 index_t latlonbin=0,*offsets;
766 amb 285
767     /* Print the start message */
768    
769 amb 519 printf_first("Writing Nodes: Nodes=0");
770 amb 285
771 amb 553 /* Allocate the memory for the geographical offsets array */
772    
773     offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
774    
775     assert(offsets); /* Check malloc() worked */
776    
777     latlonbin=0;
778    
779 amb 556 /* Re-open the file */
780 amb 285
781 amb 555 nodesx->fd=ReOpenFile(nodesx->filename);
782 amb 285
783 amb 461 /* Write out the nodes data */
784 amb 285
785 amb 502 fd=OpenFileNew(filename);
786 amb 285
787 amb 553 SeekFile(fd,sizeof(NodesFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
788 amb 285
789 amb 461 for(i=0;i<nodesx->number;i++)
790 amb 285 {
791 amb 556 NodeX nodex;
792 amb 552 Node node;
793 amb 553 ll_bin_t latbin,lonbin;
794     int llbin;
795 amb 285
796 amb 556 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
797    
798 amb 553 /* Create the Node */
799    
800 amb 556 node.latoffset=latlong_to_off(nodex.latitude);
801     node.lonoffset=latlong_to_off(nodex.longitude);
802     node.firstseg=nodex.id;
803     node.allow=nodex.allow;
804     node.flags=nodex.flags;
805 amb 552
806     if(node.flags&NODE_SUPER)
807 amb 461 super_number++;
808    
809 amb 553 /* Work out the offsets */
810    
811 amb 556 latbin=latlong_to_bin(nodex.latitude )-nodesx->latzero;
812     lonbin=latlong_to_bin(nodex.longitude)-nodesx->lonzero;
813 amb 553 llbin=lonbin*nodesx->latbins+latbin;
814    
815     for(;latlonbin<=llbin;latlonbin++)
816     offsets[latlonbin]=i;
817    
818     /* Write the data */
819    
820 amb 552 WriteFile(fd,&node,sizeof(Node));
821 amb 285
822     if(!((i+1)%10000))
823 amb 519 printf_middle("Writing Nodes: Nodes=%d",i+1);
824 amb 285 }
825    
826 amb 556 /* Close the file */
827    
828     CloseFile(nodesx->fd);
829    
830 amb 553 /* Finish off the offset indexing and write them out */
831    
832     for(;latlonbin<=(nodesx->latbins*nodesx->lonbins);latlonbin++)
833     offsets[latlonbin]=nodesx->number;
834    
835     SeekFile(fd,sizeof(NodesFile));
836     WriteFile(fd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
837    
838 amb 461 /* Write out the header structure */
839    
840     nodesfile.number=nodesx->number;
841     nodesfile.snumber=super_number;
842    
843     nodesfile.latbins=nodesx->latbins;
844     nodesfile.lonbins=nodesx->lonbins;
845    
846     nodesfile.latzero=nodesx->latzero;
847     nodesfile.lonzero=nodesx->lonzero;
848    
849     SeekFile(fd,0);
850     WriteFile(fd,&nodesfile,sizeof(NodesFile));
851    
852 amb 285 CloseFile(fd);
853    
854     /* Print the final message */
855    
856 amb 519 printf_last("Wrote Nodes: Nodes=%d",nodesx->number);
857 amb 285 }

Properties

Name Value
cvs:description Extended nodes functions.