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 467 - (show annotations) (download) (as text)
Sat Jul 31 18:13:38 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 19419 byte(s)
Add extra information to a node to store turn restrictions and properties.
(Move the super-node bit from the first segment to here.)

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

Properties

Name Value
cvs:description Extended nodes functions.