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 552 - (hide annotations) (download) (as text)
Mon Dec 20 17:38:29 2010 UTC (14 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 19279 byte(s)
Don't maintain a copy of the whole set of Nodes along with the NodeXs but
generate the Node from the NodeX when written to disk.  Create a lookup table
between the original index and the geographically sorted index.

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

Properties

Name Value
cvs:description Extended nodes functions.