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 1405 - (show annotations) (download) (as text)
Thu Jun 20 18:36:47 2013 UTC (11 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 20398 byte(s)
Use the new functions for buffering while reading when looping through files
that use the FILESORT_VARINT method of storing data.

1 /***************************************
2 Extented Node data type functions.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2013 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "types.h"
27 #include "nodes.h"
28
29 #include "typesx.h"
30 #include "nodesx.h"
31 #include "segmentsx.h"
32 #include "waysx.h"
33
34 #include "files.h"
35 #include "logging.h"
36 #include "sorting.h"
37
38
39 /* Global variables */
40
41 /*+ The command line '--tmpdir' option or its default value. +*/
42 extern char *option_tmpdirname;
43
44 /* Local variables */
45
46 /*+ Temporary file-local variables for use by the sort functions. +*/
47 static NodesX *sortnodesx;
48 static latlong_t lat_min,lat_max,lon_min,lon_max;
49
50 /* Local functions */
51
52 static int sort_by_id(NodeX *a,NodeX *b);
53 static int deduplicate_and_index_by_id(NodeX *nodex,index_t index);
54
55 static int update_id(NodeX *nodex,index_t index);
56 static int sort_by_lat_long(NodeX *a,NodeX *b);
57 static int index_by_lat_long(NodeX *nodex,index_t index);
58
59
60 /*++++++++++++++++++++++++++++++++++++++
61 Allocate a new node list (create a new file or open an existing one).
62
63 NodesX *NewNodeList Returns a pointer to the node list.
64
65 int append Set to 1 if the file is to be opened for appending.
66
67 int readonly Set to 1 if the file is to be opened for reading.
68 ++++++++++++++++++++++++++++++++++++++*/
69
70 NodesX *NewNodeList(int append,int readonly)
71 {
72 NodesX *nodesx;
73
74 nodesx=(NodesX*)calloc(1,sizeof(NodesX));
75
76 logassert(nodesx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
77
78 nodesx->filename =(char*)malloc(strlen(option_tmpdirname)+32);
79 nodesx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
80
81 sprintf(nodesx->filename ,"%s/nodesx.parsed.mem",option_tmpdirname);
82 sprintf(nodesx->filename_tmp,"%s/nodesx.%p.tmp" ,option_tmpdirname,(void*)nodesx);
83
84 if(append || readonly)
85 if(ExistsFile(nodesx->filename))
86 {
87 off_t size;
88
89 size=SizeFile(nodesx->filename);
90
91 nodesx->number=size/sizeof(NodeX);
92
93 RenameFile(nodesx->filename,nodesx->filename_tmp);
94 }
95
96 if(append)
97 nodesx->fd=OpenFileBufferedAppend(nodesx->filename_tmp);
98 else if(!readonly)
99 nodesx->fd=OpenFileBufferedNew(nodesx->filename_tmp);
100 else
101 nodesx->fd=-1;
102
103 #if SLIM
104 nodesx->cache=NewNodeXCache();
105 #endif
106
107 return(nodesx);
108 }
109
110
111 /*++++++++++++++++++++++++++++++++++++++
112 Free a node list.
113
114 NodesX *nodesx The set of nodes to be freed.
115
116 int keep If set then the results file is to be kept.
117 ++++++++++++++++++++++++++++++++++++++*/
118
119 void FreeNodeList(NodesX *nodesx,int keep)
120 {
121 if(keep)
122 RenameFile(nodesx->filename_tmp,nodesx->filename);
123 else
124 DeleteFile(nodesx->filename_tmp);
125
126 free(nodesx->filename);
127 free(nodesx->filename_tmp);
128
129 if(nodesx->idata)
130 free(nodesx->idata);
131
132 if(nodesx->gdata)
133 free(nodesx->gdata);
134
135 if(nodesx->pdata)
136 free(nodesx->pdata);
137
138 if(nodesx->super)
139 free(nodesx->super);
140
141 #if SLIM
142 DeleteNodeXCache(nodesx->cache);
143 #endif
144
145 free(nodesx);
146 }
147
148
149 /*++++++++++++++++++++++++++++++++++++++
150 Append a single node to an unsorted node list.
151
152 NodesX *nodesx The set of nodes to modify.
153
154 node_t id The node identifier from the original OSM data.
155
156 double latitude The latitude of the node.
157
158 double longitude The longitude of the node.
159
160 transports_t allow The allowed traffic types through the node.
161
162 nodeflags_t flags The flags to set for this node.
163 ++++++++++++++++++++++++++++++++++++++*/
164
165 void AppendNodeList(NodesX *nodesx,node_t id,double latitude,double longitude,transports_t allow,nodeflags_t flags)
166 {
167 NodeX nodex;
168
169 nodex.id=id;
170 nodex.latitude =radians_to_latlong(latitude);
171 nodex.longitude=radians_to_latlong(longitude);
172 nodex.allow=allow;
173 nodex.flags=flags;
174
175 WriteFileBuffered(nodesx->fd,&nodex,sizeof(NodeX));
176
177 nodesx->number++;
178
179 logassert(nodesx->number<NODE_FAKE,"Too many nodes (change index_t to 64-bits?)"); /* NODE_FAKE marks the high-water mark for real nodes. */
180 }
181
182
183 /*++++++++++++++++++++++++++++++++++++++
184 Finish appending nodes and change the filename over.
185
186 NodesX *nodesx The nodes that have been appended.
187 ++++++++++++++++++++++++++++++++++++++*/
188
189 void FinishNodeList(NodesX *nodesx)
190 {
191 if(nodesx->fd!=-1)
192 nodesx->fd=CloseFileBuffered(nodesx->fd);
193 }
194
195
196 /*++++++++++++++++++++++++++++++++++++++
197 Find a particular node index.
198
199 index_t IndexNodeX Returns the index of the extended node with the specified id.
200
201 NodesX *nodesx The set of nodes to use.
202
203 node_t id The node id to look for.
204 ++++++++++++++++++++++++++++++++++++++*/
205
206 index_t IndexNodeX(NodesX *nodesx,node_t id)
207 {
208 index_t start=0;
209 index_t end=nodesx->number-1;
210 index_t mid;
211
212 if(nodesx->number==0) /* No nodes */
213 return(NO_NODE);
214
215 if(id<nodesx->idata[start]) /* Key is before start */
216 return(NO_NODE);
217
218 if(id>nodesx->idata[end]) /* Key is after end */
219 return(NO_NODE);
220
221 /* Binary search - search key exact match only is required.
222 *
223 * # <- start | Check mid and move start or end if it doesn't match
224 * # |
225 * # | Since an exact match is wanted we can set end=mid-1
226 * # <- mid | or start=mid+1 because we know that mid doesn't match.
227 * # |
228 * # | Eventually either end=start or end=start+1 and one of
229 * # <- end | start or end is the wanted one.
230 */
231
232 do
233 {
234 mid=(start+end)/2; /* Choose mid point */
235
236 if(nodesx->idata[mid]<id) /* Mid point is too low */
237 start=mid+1;
238 else if(nodesx->idata[mid]>id) /* Mid point is too high */
239 end=mid?(mid-1):mid;
240 else /* Mid point is correct */
241 return(mid);
242 }
243 while((end-start)>1);
244
245 if(nodesx->idata[start]==id) /* Start is correct */
246 return(start);
247
248 if(nodesx->idata[end]==id) /* End is correct */
249 return(end);
250
251 return(NO_NODE);
252 }
253
254
255 /*++++++++++++++++++++++++++++++++++++++
256 Sort the node list.
257
258 NodesX *nodesx The set of nodes to modify.
259 ++++++++++++++++++++++++++++++++++++++*/
260
261 void SortNodeList(NodesX *nodesx)
262 {
263 int fd;
264 index_t xnumber;
265
266 /* Print the start message */
267
268 printf_first("Sorting Nodes");
269
270 /* Re-open the file read-only and a new file writeable */
271
272 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
273
274 DeleteFile(nodesx->filename_tmp);
275
276 fd=OpenFileNew(nodesx->filename_tmp);
277
278 /* Allocate the array of indexes */
279
280 nodesx->idata=(node_t*)malloc(nodesx->number*sizeof(node_t));
281
282 logassert(nodesx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
283
284 /* Sort the nodes by ID and index them */
285
286 xnumber=nodesx->number;
287
288 sortnodesx=nodesx;
289
290 nodesx->number=filesort_fixed(nodesx->fd,fd,sizeof(NodeX),NULL,
291 (int (*)(const void*,const void*))sort_by_id,
292 (int (*)(void*,index_t))deduplicate_and_index_by_id);
293
294 nodesx->knumber=nodesx->number;
295
296 /* Close the files */
297
298 nodesx->fd=CloseFile(nodesx->fd);
299 CloseFile(fd);
300
301 /* Print the final message */
302
303 printf_last("Sorted Nodes: Nodes=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-nodesx->number);
304 }
305
306
307 /*++++++++++++++++++++++++++++++++++++++
308 Sort the nodes into id order.
309
310 int sort_by_id Returns the comparison of the id fields.
311
312 NodeX *a The first extended node.
313
314 NodeX *b The second extended node.
315 ++++++++++++++++++++++++++++++++++++++*/
316
317 static int sort_by_id(NodeX *a,NodeX *b)
318 {
319 node_t a_id=a->id;
320 node_t b_id=b->id;
321
322 if(a_id<b_id)
323 return(-1);
324 else if(a_id>b_id)
325 return(1);
326 else
327 return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
328 }
329
330
331 /*++++++++++++++++++++++++++++++++++++++
332 Create the index of identifiers and discard duplicate nodes.
333
334 int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise 0.
335
336 NodeX *nodex The extended node.
337
338 index_t index The number of sorted nodes that have already been written to the output file.
339 ++++++++++++++++++++++++++++++++++++++*/
340
341 static int deduplicate_and_index_by_id(NodeX *nodex,index_t index)
342 {
343 static node_t previd=NO_NODE_ID;
344
345 if(nodex->id!=previd)
346 {
347 previd=nodex->id;
348
349 if(nodex->flags&NODE_DELETED)
350 return(0);
351 else
352 {
353 sortnodesx->idata[index]=nodex->id;
354
355 return(1);
356 }
357 }
358 else
359 return(0);
360 }
361
362
363 /*++++++++++++++++++++++++++++++++++++++
364 Remove any nodes that are not part of a highway.
365
366 NodesX *nodesx The set of nodes to modify.
367
368 WaysX *waysx The set of ways to use.
369
370 int keep If set to 1 then keep the old data file otherwise delete it.
371 ++++++++++++++++++++++++++++++++++++++*/
372
373 void RemoveNonHighwayNodes(NodesX *nodesx,WaysX *waysx,int keep)
374 {
375 BitMask *usednode;
376 NodeX nodex;
377 index_t i,total=0,highway=0,nothighway=0;
378 int fd;
379
380
381 /* Print the start message */
382
383 printf_first("Checking Ways for unused Nodes: Ways=0");
384
385 /* Allocate the node usage bitmask */
386
387 usednode=AllocBitMask(nodesx->number);
388
389 logassert(usednode,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */
390
391 /* Re-open the file read-only */
392
393 waysx->fd=ReOpenFileBuffered(waysx->filename_tmp);
394
395 /* Loop through the ways and mark the used nodes */
396
397 for(i=0;i<waysx->number;i++)
398 {
399 WayX wayx;
400 FILESORT_VARINT waysize;
401 node_t node;
402
403 ReadFileBuffered(waysx->fd,&waysize,FILESORT_VARSIZE);
404
405 ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX));
406
407 while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID)
408 {
409 index_t index=IndexNodeX(nodesx,node);
410
411 waysize-=sizeof(node_t);
412
413 if(index!=NO_NODE)
414 SetBit(usednode,index);
415 }
416
417 waysize-=sizeof(node_t)+sizeof(WayX);
418
419 SeekFileBuffered(waysx->fd,waysize);
420
421 if(!((i+1)%1000))
422 printf_middle("Checking Ways for unused Nodes: Ways=%"Pindex_t,i+1);
423 }
424
425 /* Close the file */
426
427 waysx->fd=CloseFileBuffered(waysx->fd);
428
429 /* Print the final message */
430
431 printf_last("Checked Ways for unused Nodes: Ways=%"Pindex_t,waysx->number);
432
433
434 /* Print the start message */
435
436 printf_first("Removing unused Nodes: Nodes=0");
437
438 /* Re-open the file read-only and a new file writeable */
439
440 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
441
442 if(keep)
443 RenameFile(nodesx->filename_tmp,nodesx->filename);
444 else
445 DeleteFile(nodesx->filename_tmp);
446
447 fd=OpenFileNew(nodesx->filename_tmp);
448
449 /* Modify the on-disk image */
450
451 while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
452 {
453 if(!IsBitSet(usednode,total))
454 nothighway++;
455 else
456 {
457 nodesx->idata[highway]=nodex.id;
458
459 WriteFile(fd,&nodex,sizeof(NodeX));
460
461 highway++;
462 }
463
464 total++;
465
466 if(!(total%10000))
467 printf_middle("Removing unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
468 }
469
470 nodesx->number=highway;
471
472 /* Close the files */
473
474 nodesx->fd=CloseFile(nodesx->fd);
475 CloseFile(fd);
476
477 /* Free the now-unneeded index */
478
479 free(usednode);
480
481 /* Print the final message */
482
483 printf_last("Removed unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
484 }
485
486
487 /*++++++++++++++++++++++++++++++++++++++
488 Remove any nodes that have been pruned.
489
490 NodesX *nodesx The set of nodes to prune.
491
492 SegmentsX *segmentsx The set of segments to use.
493 ++++++++++++++++++++++++++++++++++++++*/
494
495 void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx)
496 {
497 NodeX nodex;
498 index_t total=0,pruned=0,notpruned=0;
499 int fd;
500
501 if(nodesx->number==0)
502 return;
503
504 /* Print the start message */
505
506 printf_first("Deleting Pruned Nodes: Nodes=0 Pruned=0");
507
508 /* Allocate the array of indexes */
509
510 nodesx->pdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
511
512 logassert(nodesx->pdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
513
514 /* Re-open the file read-only and a new file writeable */
515
516 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
517
518 DeleteFile(nodesx->filename_tmp);
519
520 fd=OpenFileNew(nodesx->filename_tmp);
521
522 /* Modify the on-disk image */
523
524 while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
525 {
526 if(segmentsx->firstnode[total]==NO_SEGMENT)
527 {
528 pruned++;
529
530 nodesx->pdata[total]=NO_NODE;
531 }
532 else
533 {
534 nodesx->pdata[total]=notpruned;
535
536 WriteFile(fd,&nodex,sizeof(NodeX));
537
538 notpruned++;
539 }
540
541 total++;
542
543 if(!(total%10000))
544 printf_middle("Deleting Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
545 }
546
547 nodesx->number=notpruned;
548
549 /* Close the files */
550
551 nodesx->fd=CloseFile(nodesx->fd);
552 CloseFile(fd);
553
554 /* Print the final message */
555
556 printf_last("Deleted Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
557 }
558
559
560 /*++++++++++++++++++++++++++++++++++++++
561 Sort the node list geographically.
562
563 NodesX *nodesx The set of nodes to modify.
564 ++++++++++++++++++++++++++++++++++++++*/
565
566 void SortNodeListGeographically(NodesX *nodesx)
567 {
568 int fd;
569 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
570
571 if(nodesx->number==0)
572 return;
573
574 /* Print the start message */
575
576 printf_first("Sorting Nodes Geographically");
577
578 /* Work out the range of data */
579
580 lat_min=radians_to_latlong( 2);
581 lat_max=radians_to_latlong(-2);
582 lon_min=radians_to_latlong( 4);
583 lon_max=radians_to_latlong(-4);
584
585 /* Allocate the memory for the geographical index array */
586
587 nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
588
589 logassert(nodesx->gdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
590
591 /* Re-open the file read-only and a new file writeable */
592
593 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
594
595 DeleteFile(nodesx->filename_tmp);
596
597 fd=OpenFileNew(nodesx->filename_tmp);
598
599 /* Sort nodes geographically and index them */
600
601 sortnodesx=nodesx;
602
603 filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(void*,index_t))update_id,
604 (int (*)(const void*,const void*))sort_by_lat_long,
605 (int (*)(void*,index_t))index_by_lat_long);
606
607 /* Close the files */
608
609 nodesx->fd=CloseFile(nodesx->fd);
610 CloseFile(fd);
611
612 /* Free the memory */
613
614 free(nodesx->super);
615 nodesx->super=NULL;
616
617 /* Work out the number of bins */
618
619 lat_min_bin=latlong_to_bin(lat_min);
620 lon_min_bin=latlong_to_bin(lon_min);
621 lat_max_bin=latlong_to_bin(lat_max);
622 lon_max_bin=latlong_to_bin(lon_max);
623
624 nodesx->latzero=lat_min_bin;
625 nodesx->lonzero=lon_min_bin;
626
627 nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
628 nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
629
630 /* Print the final message */
631
632 printf_last("Sorted Nodes Geographically: Nodes=%"Pindex_t,nodesx->number);
633 }
634
635
636 /*++++++++++++++++++++++++++++++++++++++
637 Update the node ids.
638
639 int update_id Return 1 if the value is to be kept, otherwise 0.
640
641 NodeX *nodex The extended node.
642
643 index_t index The number of unsorted nodes that have been read from the input file.
644 ++++++++++++++++++++++++++++++++++++++*/
645
646 static int update_id(NodeX *nodex,index_t index)
647 {
648 nodex->id=index;
649
650 return(1);
651 }
652
653
654 /*++++++++++++++++++++++++++++++++++++++
655 Sort the nodes into latitude and longitude order (first by longitude bin
656 number, then by latitude bin number and then by exact longitude and then by
657 exact latitude).
658
659 int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
660
661 NodeX *a The first extended node.
662
663 NodeX *b The second extended node.
664 ++++++++++++++++++++++++++++++++++++++*/
665
666 static int sort_by_lat_long(NodeX *a,NodeX *b)
667 {
668 ll_bin_t a_lon=latlong_to_bin(a->longitude);
669 ll_bin_t b_lon=latlong_to_bin(b->longitude);
670
671 if(a_lon<b_lon)
672 return(-1);
673 else if(a_lon>b_lon)
674 return(1);
675 else
676 {
677 ll_bin_t a_lat=latlong_to_bin(a->latitude);
678 ll_bin_t b_lat=latlong_to_bin(b->latitude);
679
680 if(a_lat<b_lat)
681 return(-1);
682 else if(a_lat>b_lat)
683 return(1);
684 else
685 {
686 if(a->longitude<b->longitude)
687 return(-1);
688 else if(a->longitude>b->longitude)
689 return(1);
690 else
691 {
692 if(a->latitude<b->latitude)
693 return(-1);
694 else if(a->latitude>b->latitude)
695 return(1);
696 }
697
698 return(FILESORT_PRESERVE_ORDER(a,b));
699 }
700 }
701 }
702
703
704 /*++++++++++++++++++++++++++++++++++++++
705 Create the index between the sorted and unsorted nodes.
706
707 int index_by_lat_long Return 1 if the value is to be kept, otherwise 0.
708
709 NodeX *nodex The extended node.
710
711 index_t index The number of sorted nodes that have already been written to the output file.
712 ++++++++++++++++++++++++++++++++++++++*/
713
714 static int index_by_lat_long(NodeX *nodex,index_t index)
715 {
716 sortnodesx->gdata[nodex->id]=index;
717
718 if(IsBitSet(sortnodesx->super,nodex->id))
719 nodex->flags|=NODE_SUPER;
720
721 if(nodex->latitude<lat_min)
722 lat_min=nodex->latitude;
723 if(nodex->latitude>lat_max)
724 lat_max=nodex->latitude;
725 if(nodex->longitude<lon_min)
726 lon_min=nodex->longitude;
727 if(nodex->longitude>lon_max)
728 lon_max=nodex->longitude;
729
730 return(1);
731 }
732
733
734 /*++++++++++++++++++++++++++++++++++++++
735 Save the final node list database to a file.
736
737 NodesX *nodesx The set of nodes to save.
738
739 const char *filename The name of the file to save.
740
741 SegmentsX *segmentsx The set of segments to use.
742 ++++++++++++++++++++++++++++++++++++++*/
743
744 void SaveNodeList(NodesX *nodesx,const char *filename,SegmentsX *segmentsx)
745 {
746 index_t i;
747 int fd;
748 NodesFile nodesfile={0};
749 index_t super_number=0;
750 ll_bin2_t latlonbin=0,maxlatlonbins;
751 index_t *offsets;
752
753 /* Print the start message */
754
755 printf_first("Writing Nodes: Nodes=0");
756
757 /* Allocate the memory for the geographical offsets array */
758
759 offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
760
761 logassert(offsets,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
762
763 latlonbin=0;
764
765 /* Re-open the file */
766
767 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
768
769 /* Write out the nodes data */
770
771 fd=OpenFileNew(filename);
772
773 SeekFile(fd,sizeof(NodesFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
774
775 for(i=0;i<nodesx->number;i++)
776 {
777 NodeX nodex;
778 Node node={0};
779 ll_bin_t latbin,lonbin;
780 ll_bin2_t llbin;
781
782 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
783
784 /* Create the Node */
785
786 node.latoffset=latlong_to_off(nodex.latitude);
787 node.lonoffset=latlong_to_off(nodex.longitude);
788 node.firstseg=segmentsx->firstnode[nodesx->gdata[nodex.id]];
789 node.allow=nodex.allow;
790 node.flags=nodex.flags;
791
792 if(node.flags&NODE_SUPER)
793 super_number++;
794
795 /* Work out the offsets */
796
797 latbin=latlong_to_bin(nodex.latitude )-nodesx->latzero;
798 lonbin=latlong_to_bin(nodex.longitude)-nodesx->lonzero;
799 llbin=lonbin*nodesx->latbins+latbin;
800
801 for(;latlonbin<=llbin;latlonbin++)
802 offsets[latlonbin]=i;
803
804 /* Write the data */
805
806 WriteFile(fd,&node,sizeof(Node));
807
808 if(!((i+1)%10000))
809 printf_middle("Writing Nodes: Nodes=%"Pindex_t,i+1);
810 }
811
812 /* Close the file */
813
814 nodesx->fd=CloseFile(nodesx->fd);
815
816 /* Finish off the offset indexing and write them out */
817
818 maxlatlonbins=nodesx->latbins*nodesx->lonbins;
819
820 for(;latlonbin<=maxlatlonbins;latlonbin++)
821 offsets[latlonbin]=nodesx->number;
822
823 SeekFile(fd,sizeof(NodesFile));
824 WriteFile(fd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
825
826 free(offsets);
827
828 /* Write out the header structure */
829
830 nodesfile.number=nodesx->number;
831 nodesfile.snumber=super_number;
832
833 nodesfile.latbins=nodesx->latbins;
834 nodesfile.lonbins=nodesx->lonbins;
835
836 nodesfile.latzero=nodesx->latzero;
837 nodesfile.lonzero=nodesx->lonzero;
838
839 SeekFile(fd,0);
840 WriteFile(fd,&nodesfile,sizeof(NodesFile));
841
842 CloseFile(fd);
843
844 /* Print the final message */
845
846 printf_last("Wrote Nodes: Nodes=%"Pindex_t,nodesx->number);
847 }

Properties

Name Value
cvs:description Extended nodes functions.