Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/nodesx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 493 - (show annotations) (download) (as text)
Thu Sep 16 18:20:44 2010 UTC (14 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 19520 byte(s)
Fix the comment for the Append...() function.

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

Properties

Name Value
cvs:description Extended nodes functions.