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 1383 - (show annotations) (download) (as text)
Wed Jun 5 19:14:31 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20294 byte(s)
Update the node id just before sorting geographically rather than relying on the
pruning process to do it.

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=OpenFileAppend(nodesx->filename_tmp);
98 else if(!readonly)
99 nodesx->fd=OpenFileNew(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 WriteFile(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=CloseFile(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 off_t position=0;
379 int fd;
380
381
382 /* Print the start message */
383
384 printf_first("Checking Ways for unused Nodes: Ways=0");
385
386 /* Allocate the node usage bitmask */
387
388 usednode=AllocBitMask(nodesx->number);
389
390 logassert(usednode,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */
391
392 /* Re-open the file read-only */
393
394 waysx->fd=ReOpenFile(waysx->filename_tmp);
395
396 /* Loop through the ways and mark the used nodes */
397
398 for(i=0;i<waysx->number;i++)
399 {
400 WayX wayx;
401 FILESORT_VARINT size;
402 node_t node;
403
404 SeekFile(waysx->fd,position);
405
406 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
407
408 position+=size+FILESORT_VARSIZE;
409
410 ReadFile(waysx->fd,&wayx,sizeof(WayX));
411
412 while(!ReadFile(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID)
413 {
414 index_t index=IndexNodeX(nodesx,node);
415
416 if(index!=NO_NODE)
417 SetBit(usednode,index);
418 }
419
420 if(!((i+1)%1000))
421 printf_middle("Checking Ways for unused Nodes: Ways=%"Pindex_t,i+1);
422 }
423
424 /* Close the file */
425
426 waysx->fd=CloseFile(waysx->fd);
427
428 /* Print the final message */
429
430 printf_last("Checked Ways for unused Nodes: Ways=%"Pindex_t,waysx->number);
431
432
433 /* Print the start message */
434
435 printf_first("Removing unused Nodes: Nodes=0");
436
437 /* Re-open the file read-only and a new file writeable */
438
439 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
440
441 if(keep)
442 RenameFile(nodesx->filename_tmp,nodesx->filename);
443 else
444 DeleteFile(nodesx->filename_tmp);
445
446 fd=OpenFileNew(nodesx->filename_tmp);
447
448 /* Modify the on-disk image */
449
450 while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
451 {
452 if(!IsBitSet(usednode,total))
453 nothighway++;
454 else
455 {
456 nodesx->idata[highway]=nodex.id;
457
458 WriteFile(fd,&nodex,sizeof(NodeX));
459
460 highway++;
461 }
462
463 total++;
464
465 if(!(total%10000))
466 printf_middle("Removing unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
467 }
468
469 nodesx->number=highway;
470
471 /* Close the files */
472
473 nodesx->fd=CloseFile(nodesx->fd);
474 CloseFile(fd);
475
476 /* Free the now-unneeded index */
477
478 free(usednode);
479
480 /* Print the final message */
481
482 printf_last("Removed unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
483 }
484
485
486 /*++++++++++++++++++++++++++++++++++++++
487 Remove any nodes that have been pruned.
488
489 NodesX *nodesx The set of nodes to prune.
490
491 SegmentsX *segmentsx The set of segments to use.
492 ++++++++++++++++++++++++++++++++++++++*/
493
494 void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx)
495 {
496 NodeX nodex;
497 index_t total=0,pruned=0,notpruned=0;
498 int fd;
499
500 if(nodesx->number==0)
501 return;
502
503 /* Print the start message */
504
505 printf_first("Deleting Pruned Nodes: Nodes=0 Pruned=0");
506
507 /* Allocate the array of indexes */
508
509 nodesx->pdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
510
511 logassert(nodesx->pdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
512
513 /* Re-open the file read-only and a new file writeable */
514
515 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
516
517 DeleteFile(nodesx->filename_tmp);
518
519 fd=OpenFileNew(nodesx->filename_tmp);
520
521 /* Modify the on-disk image */
522
523 while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
524 {
525 if(segmentsx->firstnode[total]==NO_SEGMENT)
526 {
527 pruned++;
528
529 nodesx->pdata[total]=NO_NODE;
530 }
531 else
532 {
533 nodesx->pdata[total]=notpruned;
534
535 WriteFile(fd,&nodex,sizeof(NodeX));
536
537 notpruned++;
538 }
539
540 total++;
541
542 if(!(total%10000))
543 printf_middle("Deleting Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
544 }
545
546 nodesx->number=notpruned;
547
548 /* Close the files */
549
550 nodesx->fd=CloseFile(nodesx->fd);
551 CloseFile(fd);
552
553 /* Print the final message */
554
555 printf_last("Deleted Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
556 }
557
558
559 /*++++++++++++++++++++++++++++++++++++++
560 Sort the node list geographically.
561
562 NodesX *nodesx The set of nodes to modify.
563 ++++++++++++++++++++++++++++++++++++++*/
564
565 void SortNodeListGeographically(NodesX *nodesx)
566 {
567 int fd;
568 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
569
570 if(nodesx->number==0)
571 return;
572
573 /* Print the start message */
574
575 printf_first("Sorting Nodes Geographically");
576
577 /* Work out the range of data */
578
579 lat_min=radians_to_latlong( 2);
580 lat_max=radians_to_latlong(-2);
581 lon_min=radians_to_latlong( 4);
582 lon_max=radians_to_latlong(-4);
583
584 /* Allocate the memory for the geographical index array */
585
586 nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
587
588 logassert(nodesx->gdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
589
590 /* Re-open the file read-only and a new file writeable */
591
592 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
593
594 DeleteFile(nodesx->filename_tmp);
595
596 fd=OpenFileNew(nodesx->filename_tmp);
597
598 /* Sort nodes geographically and index them */
599
600 sortnodesx=nodesx;
601
602 filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(void*,index_t))update_id,
603 (int (*)(const void*,const void*))sort_by_lat_long,
604 (int (*)(void*,index_t))index_by_lat_long);
605
606 /* Close the files */
607
608 nodesx->fd=CloseFile(nodesx->fd);
609 CloseFile(fd);
610
611 /* Free the memory */
612
613 free(nodesx->super);
614 nodesx->super=NULL;
615
616 /* Work out the number of bins */
617
618 lat_min_bin=latlong_to_bin(lat_min);
619 lon_min_bin=latlong_to_bin(lon_min);
620 lat_max_bin=latlong_to_bin(lat_max);
621 lon_max_bin=latlong_to_bin(lon_max);
622
623 nodesx->latzero=lat_min_bin;
624 nodesx->lonzero=lon_min_bin;
625
626 nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
627 nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
628
629 /* Print the final message */
630
631 printf_last("Sorted Nodes Geographically: Nodes=%"Pindex_t,nodesx->number);
632 }
633
634
635 /*++++++++++++++++++++++++++++++++++++++
636 Update the node ids.
637
638 int update_id Return 1 if the value is to be kept, otherwise 0.
639
640 NodeX *nodex The extended node.
641
642 index_t index The number of unsorted nodes that have been read from the input file.
643 ++++++++++++++++++++++++++++++++++++++*/
644
645 static int update_id(NodeX *nodex,index_t index)
646 {
647 nodex->id=index;
648
649 return(1);
650 }
651
652
653 /*++++++++++++++++++++++++++++++++++++++
654 Sort the nodes into latitude and longitude order (first by longitude bin
655 number, then by latitude bin number and then by exact longitude and then by
656 exact latitude).
657
658 int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
659
660 NodeX *a The first extended node.
661
662 NodeX *b The second extended node.
663 ++++++++++++++++++++++++++++++++++++++*/
664
665 static int sort_by_lat_long(NodeX *a,NodeX *b)
666 {
667 ll_bin_t a_lon=latlong_to_bin(a->longitude);
668 ll_bin_t b_lon=latlong_to_bin(b->longitude);
669
670 if(a_lon<b_lon)
671 return(-1);
672 else if(a_lon>b_lon)
673 return(1);
674 else
675 {
676 ll_bin_t a_lat=latlong_to_bin(a->latitude);
677 ll_bin_t b_lat=latlong_to_bin(b->latitude);
678
679 if(a_lat<b_lat)
680 return(-1);
681 else if(a_lat>b_lat)
682 return(1);
683 else
684 {
685 if(a->longitude<b->longitude)
686 return(-1);
687 else if(a->longitude>b->longitude)
688 return(1);
689 else
690 {
691 if(a->latitude<b->latitude)
692 return(-1);
693 else if(a->latitude>b->latitude)
694 return(1);
695 }
696
697 return(FILESORT_PRESERVE_ORDER(a,b));
698 }
699 }
700 }
701
702
703 /*++++++++++++++++++++++++++++++++++++++
704 Create the index between the sorted and unsorted nodes.
705
706 int index_by_lat_long Return 1 if the value is to be kept, otherwise 0.
707
708 NodeX *nodex The extended node.
709
710 index_t index The number of sorted nodes that have already been written to the output file.
711 ++++++++++++++++++++++++++++++++++++++*/
712
713 static int index_by_lat_long(NodeX *nodex,index_t index)
714 {
715 sortnodesx->gdata[nodex->id]=index;
716
717 if(IsBitSet(sortnodesx->super,nodex->id))
718 nodex->flags|=NODE_SUPER;
719
720 if(nodex->latitude<lat_min)
721 lat_min=nodex->latitude;
722 if(nodex->latitude>lat_max)
723 lat_max=nodex->latitude;
724 if(nodex->longitude<lon_min)
725 lon_min=nodex->longitude;
726 if(nodex->longitude>lon_max)
727 lon_max=nodex->longitude;
728
729 return(1);
730 }
731
732
733 /*++++++++++++++++++++++++++++++++++++++
734 Save the final node list database to a file.
735
736 NodesX *nodesx The set of nodes to save.
737
738 const char *filename The name of the file to save.
739
740 SegmentsX *segmentsx The set of segments to use.
741 ++++++++++++++++++++++++++++++++++++++*/
742
743 void SaveNodeList(NodesX *nodesx,const char *filename,SegmentsX *segmentsx)
744 {
745 index_t i;
746 int fd;
747 NodesFile nodesfile={0};
748 index_t super_number=0;
749 ll_bin2_t latlonbin=0,maxlatlonbins;
750 index_t *offsets;
751
752 /* Print the start message */
753
754 printf_first("Writing Nodes: Nodes=0");
755
756 /* Allocate the memory for the geographical offsets array */
757
758 offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
759
760 logassert(offsets,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
761
762 latlonbin=0;
763
764 /* Re-open the file */
765
766 nodesx->fd=ReOpenFile(nodesx->filename_tmp);
767
768 /* Write out the nodes data */
769
770 fd=OpenFileNew(filename);
771
772 SeekFile(fd,sizeof(NodesFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
773
774 for(i=0;i<nodesx->number;i++)
775 {
776 NodeX nodex;
777 Node node={0};
778 ll_bin_t latbin,lonbin;
779 ll_bin2_t llbin;
780
781 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
782
783 /* Create the Node */
784
785 node.latoffset=latlong_to_off(nodex.latitude);
786 node.lonoffset=latlong_to_off(nodex.longitude);
787 node.firstseg=segmentsx->firstnode[nodesx->gdata[nodex.id]];
788 node.allow=nodex.allow;
789 node.flags=nodex.flags;
790
791 if(node.flags&NODE_SUPER)
792 super_number++;
793
794 /* Work out the offsets */
795
796 latbin=latlong_to_bin(nodex.latitude )-nodesx->latzero;
797 lonbin=latlong_to_bin(nodex.longitude)-nodesx->lonzero;
798 llbin=lonbin*nodesx->latbins+latbin;
799
800 for(;latlonbin<=llbin;latlonbin++)
801 offsets[latlonbin]=i;
802
803 /* Write the data */
804
805 WriteFile(fd,&node,sizeof(Node));
806
807 if(!((i+1)%10000))
808 printf_middle("Writing Nodes: Nodes=%"Pindex_t,i+1);
809 }
810
811 /* Close the file */
812
813 nodesx->fd=CloseFile(nodesx->fd);
814
815 /* Finish off the offset indexing and write them out */
816
817 maxlatlonbins=nodesx->latbins*nodesx->lonbins;
818
819 for(;latlonbin<=maxlatlonbins;latlonbin++)
820 offsets[latlonbin]=nodesx->number;
821
822 SeekFile(fd,sizeof(NodesFile));
823 WriteFile(fd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
824
825 free(offsets);
826
827 /* Write out the header structure */
828
829 nodesfile.number=nodesx->number;
830 nodesfile.snumber=super_number;
831
832 nodesfile.latbins=nodesx->latbins;
833 nodesfile.lonbins=nodesx->lonbins;
834
835 nodesfile.latzero=nodesx->latzero;
836 nodesfile.lonzero=nodesx->lonzero;
837
838 SeekFile(fd,0);
839 WriteFile(fd,&nodesfile,sizeof(NodesFile));
840
841 CloseFile(fd);
842
843 /* Print the final message */
844
845 printf_last("Wrote Nodes: Nodes=%"Pindex_t,nodesx->number);
846 }

Properties

Name Value
cvs:description Extended nodes functions.