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/segmentsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 649 - (show annotations) (download) (as text)
Sun Feb 27 15:22:04 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 20286 byte(s)
Remove a now unused array of segment indexes.

1 /***************************************
2 Extended Segment data type functions.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2011 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 <assert.h>
24 #include <math.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/stat.h>
29
30 #include "types.h"
31 #include "nodes.h"
32 #include "segments.h"
33 #include "ways.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 "logging.h"
43 #include "sorting.h"
44
45
46 /* Variables */
47
48 /*+ The command line '--tmpdir' option or its default value. +*/
49 extern char *option_tmpdirname;
50
51 /* Local Functions */
52
53 static int sort_by_id(SegmentX *a,SegmentX *b);
54
55 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2);
56
57
58 /*++++++++++++++++++++++++++++++++++++++
59 Allocate a new segment list (create a new file or open an existing one).
60
61 SegmentsX *NewSegmentList Returns the segment list.
62
63 int append Set to 1 if the file is to be opened for appending (now or later).
64 ++++++++++++++++++++++++++++++++++++++*/
65
66 SegmentsX *NewSegmentList(int append)
67 {
68 SegmentsX *segmentsx;
69
70 segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX));
71
72 assert(segmentsx); /* Check calloc() worked */
73
74 segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
75
76 if(append)
77 sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
78 else
79 sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
80
81 if(append)
82 {
83 off_t size;
84
85 segmentsx->fd=OpenFileAppend(segmentsx->filename);
86
87 size=SizeFile(segmentsx->filename);
88
89 segmentsx->xnumber=size/sizeof(SegmentX);
90 }
91 else
92 segmentsx->fd=OpenFileNew(segmentsx->filename);
93
94 return(segmentsx);
95 }
96
97
98 /*++++++++++++++++++++++++++++++++++++++
99 Free a segment list.
100
101 SegmentsX *segmentsx The list to be freed.
102
103 int keep Set to 1 if the file is to be kept.
104 ++++++++++++++++++++++++++++++++++++++*/
105
106 void FreeSegmentList(SegmentsX *segmentsx,int keep)
107 {
108 if(!keep)
109 DeleteFile(segmentsx->filename);
110
111 free(segmentsx->filename);
112
113 if(segmentsx->usednode)
114 free(segmentsx->usednode);
115
116 if(segmentsx->firstnode)
117 free(segmentsx->firstnode);
118
119 free(segmentsx);
120 }
121
122
123 /*++++++++++++++++++++++++++++++++++++++
124 Append a single segment to an unsorted segment list.
125
126 SegmentsX* segmentsx The set of segments to process.
127
128 way_t way The way that the segment belongs to.
129
130 node_t node1 The first node in the segment.
131
132 node_t node2 The second node in the segment.
133
134 distance_t distance The distance between the nodes (or just the flags).
135 ++++++++++++++++++++++++++++++++++++++*/
136
137 void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,distance_t distance)
138 {
139 SegmentX segmentx;
140
141 if(node1>node2)
142 {
143 node_t temp;
144
145 temp=node1;
146 node1=node2;
147 node2=temp;
148
149 if(distance&(ONEWAY_2TO1|ONEWAY_1TO2))
150 distance^=ONEWAY_2TO1|ONEWAY_1TO2;
151 }
152
153 segmentx.node1=node1;
154 segmentx.node2=node2;
155 segmentx.next2=NO_SEGMENT;
156 segmentx.way=way;
157 segmentx.distance=distance;
158
159 WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
160
161 segmentsx->xnumber++;
162
163 assert(segmentsx->xnumber<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
164 }
165
166
167 /*++++++++++++++++++++++++++++++++++++++
168 Sort the segment list.
169
170 SegmentsX* segmentsx The set of segments to process.
171 ++++++++++++++++++++++++++++++++++++++*/
172
173 void SortSegmentList(SegmentsX* segmentsx)
174 {
175 int fd;
176
177 /* Print the start message */
178
179 printf_first("Sorting Segments");
180
181 /* Close the file (finished appending) */
182
183 segmentsx->fd=CloseFile(segmentsx->fd);
184
185 /* Re-open the file read-only and a new file writeable */
186
187 segmentsx->fd=ReOpenFile(segmentsx->filename);
188
189 DeleteFile(segmentsx->filename);
190
191 fd=OpenFileNew(segmentsx->filename);
192
193 /* Sort by node indexes */
194
195 filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(const void*,const void*))sort_by_id,NULL);
196
197 segmentsx->number=segmentsx->xnumber;
198
199 /* Close the files */
200
201 segmentsx->fd=CloseFile(segmentsx->fd);
202 CloseFile(fd);
203
204 /* Print the final message */
205
206 printf_last("Sorted Segments: Segments=%d",segmentsx->xnumber);
207 }
208
209
210 /*++++++++++++++++++++++++++++++++++++++
211 Sort the segments into id order (node1 then node2).
212
213 int sort_by_id Returns the comparison of the node fields.
214
215 SegmentX *a The first segment.
216
217 SegmentX *b The second segment.
218 ++++++++++++++++++++++++++++++++++++++*/
219
220 static int sort_by_id(SegmentX *a,SegmentX *b)
221 {
222 node_t a_id1=a->node1;
223 node_t b_id1=b->node1;
224
225 if(a_id1<b_id1)
226 return(-1);
227 else if(a_id1>b_id1)
228 return(1);
229 else /* if(a_id1==b_id1) */
230 {
231 node_t a_id2=a->node2;
232 node_t b_id2=b->node2;
233
234 if(a_id2<b_id2)
235 return(-1);
236 else if(a_id2>b_id2)
237 return(1);
238 else
239 {
240 distance_t a_distance=a->distance;
241 distance_t b_distance=b->distance;
242
243 if(a_distance<b_distance)
244 return(-1);
245 else if(a_distance>b_distance)
246 return(1);
247 else
248 return(0);
249 }
250 }
251 }
252
253
254 /*++++++++++++++++++++++++++++++++++++++
255 Find the first extended segment with a particular starting node index.
256
257 SegmentX *FirstSegmentX Returns a pointer to the first extended segment with the specified id.
258
259 SegmentsX* segmentsx The set of extended segments to process.
260
261 index_t nodeindex The node index to look for.
262
263 int position A flag to pass through.
264 ++++++++++++++++++++++++++++++++++++++*/
265
266 SegmentX *FirstSegmentX(SegmentsX* segmentsx,index_t nodeindex,int position)
267 {
268 index_t index=segmentsx->firstnode[nodeindex];
269 SegmentX *segmentx;
270
271 segmentx=LookupSegmentX(segmentsx,index,position);
272
273 if(segmentx->node1!=nodeindex && segmentx->node2!=nodeindex)
274 return(NULL);
275
276 return(segmentx);
277 }
278
279
280 /*++++++++++++++++++++++++++++++++++++++
281 Find the next segment with a particular starting node index.
282
283 SegmentX *NextSegmentX Returns a pointer to the next segment with the same id.
284
285 SegmentsX* segmentsx The set of segments to process.
286
287 SegmentX *segmentx The current segment.
288
289 index_t node The node index.
290
291 int position A flag to pass through.
292 ++++++++++++++++++++++++++++++++++++++*/
293
294 SegmentX *NextSegmentX(SegmentsX* segmentsx,SegmentX *segmentx,index_t node,int position)
295 {
296 if(segmentx->node1==node)
297 {
298 #if SLIM
299 index_t index=IndexSegmentX(segmentsx,segmentx);
300 index++;
301
302 if(index>=segmentsx->number)
303 return(NULL);
304 segmentx=LookupSegmentX(segmentsx,index,position);
305 if(segmentx->node1!=node)
306 return(NULL);
307 else
308 return(segmentx);
309 #else
310 segmentx++;
311 if(IndexSegmentX(segmentsx,segmentx)>=segmentsx->number || segmentx->node1!=node)
312 return(NULL);
313 else
314 return(segmentx);
315 #endif
316 }
317 else
318 {
319 if(segmentx->next2==NO_SEGMENT)
320 return(NULL);
321 else
322 return(LookupSegmentX(segmentsx,segmentx->next2,position));
323 }
324 }
325
326
327 /*++++++++++++++++++++++++++++++++++++++
328 Remove bad segments (duplicated, zero length or missing nodes).
329
330 NodesX *nodesx The nodes to check.
331
332 SegmentsX *segmentsx The segments to modify.
333 ++++++++++++++++++++++++++++++++++++++*/
334
335 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
336 {
337 int duplicate=0,loop=0,missing=0,good=0,total=0;
338 SegmentX segmentx;
339 int fd;
340 node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
341
342 /* Print the start message */
343
344 printf_first("Checking Segments: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
345
346 /* Allocate the array of node flags */
347
348 segmentsx->usednode=(char*)calloc(nodesx->xnumber,sizeof(char));
349
350 assert(segmentsx->usednode); /* Check malloc() worked */
351
352 /* Re-open the file read-only and a new file writeable */
353
354 segmentsx->fd=ReOpenFile(segmentsx->filename);
355
356 DeleteFile(segmentsx->filename);
357
358 fd=OpenFileNew(segmentsx->filename);
359
360 /* Modify the on-disk image */
361
362 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
363 {
364 index_t index1=IndexNodeX(nodesx,segmentx.node1);
365 index_t index2=IndexNodeX(nodesx,segmentx.node2);
366
367 if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2)
368 duplicate++;
369 else if(segmentx.node1==segmentx.node2)
370 loop++;
371 else if(index1==NO_NODE || index2==NO_NODE)
372 missing++;
373 else
374 {
375 WriteFile(fd,&segmentx,sizeof(SegmentX));
376
377 segmentsx->usednode[index1]=1;
378 segmentsx->usednode[index2]=1;
379
380 good++;
381
382 prevnode1=segmentx.node1;
383 prevnode2=segmentx.node2;
384 }
385
386 total++;
387
388 if(!(total%10000))
389 printf_middle("Checking Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
390 }
391
392 segmentsx->number=good;
393
394 /* Close the files */
395
396 segmentsx->fd=CloseFile(segmentsx->fd);
397 CloseFile(fd);
398
399 /* Print the final message */
400
401 printf_last("Checked Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
402 }
403
404
405 /*++++++++++++++++++++++++++++++++++++++
406 Measure the segments and replace node/way ids with indexes.
407
408 SegmentsX* segmentsx The set of segments to process.
409
410 NodesX *nodesx The list of nodes to use.
411
412 WaysX *waysx The list of ways to use.
413 ++++++++++++++++++++++++++++++++++++++*/
414
415 void MeasureSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
416 {
417 index_t index=0;
418 int fd;
419 SegmentX segmentx;
420
421 /* Print the start message */
422
423 printf_first("Measuring Segments: Segments=0");
424
425 /* Map into memory / open the file */
426
427 #if !SLIM
428 nodesx->xdata=MapFile(nodesx->filename);
429 #else
430 nodesx->fd=ReOpenFile(nodesx->filename);
431 #endif
432
433 /* Re-open the file read-only and a new file writeable */
434
435 segmentsx->fd=ReOpenFile(segmentsx->filename);
436
437 DeleteFile(segmentsx->filename);
438
439 fd=OpenFileNew(segmentsx->filename);
440
441 /* Modify the on-disk image */
442
443 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
444 {
445 index_t node1=IndexNodeX(nodesx,segmentx.node1);
446 index_t node2=IndexNodeX(nodesx,segmentx.node2);
447 index_t way =IndexWayX (waysx ,segmentx.way);
448
449 NodeX *nodex1=LookupNodeX(nodesx,node1,1);
450 NodeX *nodex2=LookupNodeX(nodesx,node2,2);
451
452 /* Replace the node and way ids with their indexes */
453
454 segmentx.node1=node1;
455 segmentx.node2=node2;
456 segmentx.way =way;
457
458 /* Set the distance but preserve the ONEWAY_* flags */
459
460 segmentx.distance|=DISTANCE(DistanceX(nodex1,nodex2));
461
462 /* Write the modified segment */
463
464 WriteFile(fd,&segmentx,sizeof(SegmentX));
465
466 index++;
467
468 if(!(index%10000))
469 printf_middle("Measuring Segments: Segments=%d",index);
470 }
471
472 /* Close the files */
473
474 segmentsx->fd=CloseFile(segmentsx->fd);
475 CloseFile(fd);
476
477 /* Free the other now-unneeded indexes */
478
479 free(nodesx->idata);
480 nodesx->idata=NULL;
481
482 free(waysx->idata);
483 waysx->idata=NULL;
484
485 /* Unmap from memory / close the file */
486
487 #if !SLIM
488 nodesx->xdata=UnmapFile(nodesx->filename);
489 #else
490 nodesx->fd=CloseFile(nodesx->fd);
491 #endif
492
493 /* Print the final message */
494
495 printf_last("Measured Segments: Segments=%d",segmentsx->number);
496 }
497
498
499 /*++++++++++++++++++++++++++++++++++++++
500 Remove the duplicate segments.
501
502 SegmentsX* segmentsx The set of segments to process.
503
504 NodesX *nodesx The list of nodes to use.
505
506 WaysX *waysx The list of ways to use.
507 ++++++++++++++++++++++++++++++++++++++*/
508
509 void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
510 {
511 int duplicate=0,good=0;
512 index_t firstindex=0,index=0;
513 int fd;
514 SegmentX prevsegmentx[16],segmentx;
515
516 /* Print the start message */
517
518 printf_first("Deduplicating Segments: Segments=0 Duplicate=0");
519
520 /* Map into memory / open the file */
521
522 #if !SLIM
523 waysx->xdata=MapFile(waysx->filename);
524 #else
525 waysx->fd=ReOpenFile(waysx->filename);
526 #endif
527
528 /* Re-open the file read-only and a new file writeable */
529
530 segmentsx->fd=ReOpenFile(segmentsx->filename);
531
532 DeleteFile(segmentsx->filename);
533
534 fd=OpenFileNew(segmentsx->filename);
535
536 /* Modify the on-disk image */
537
538 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
539 {
540 int isduplicate=0;
541
542 if(index && segmentx.node1==prevsegmentx[0].node1 &&
543 segmentx.node2==prevsegmentx[0].node2)
544 {
545 index_t previndex=firstindex;
546
547 while(previndex<index)
548 {
549 int offset=previndex-firstindex;
550
551 if(DISTFLAG(segmentx.distance)==DISTFLAG(prevsegmentx[offset].distance))
552 {
553 WayX *wayx1=LookupWayX(waysx,prevsegmentx[offset].way,1);
554 WayX *wayx2=LookupWayX(waysx, segmentx .way,2);
555
556 if(!WaysCompare(&wayx1->way,&wayx2->way))
557 {
558 isduplicate=1;
559 break;
560 }
561 }
562
563 previndex++;
564 }
565
566 assert((index-firstindex)<(sizeof(prevsegmentx)/sizeof(prevsegmentx[0])));
567
568 prevsegmentx[index-firstindex]=segmentx;
569 }
570 else
571 {
572 firstindex=index;
573 prevsegmentx[0]=segmentx;
574 }
575
576 if(isduplicate)
577 duplicate++;
578 else
579 {
580 WriteFile(fd,&segmentx,sizeof(SegmentX));
581
582 good++;
583 }
584
585 index++;
586
587 if(!(index%10000))
588 printf_middle("Deduplicating Segments: Segments=%d Duplicate=%d",index,duplicate);
589 }
590
591 segmentsx->number=good;
592
593 /* Close the files */
594
595 segmentsx->fd=CloseFile(segmentsx->fd);
596 CloseFile(fd);
597
598 /* Unmap from memory / close the file */
599
600 #if !SLIM
601 waysx->xdata=UnmapFile(waysx->filename);
602 #else
603 waysx->fd=CloseFile(waysx->fd);
604 #endif
605
606 /* Print the final message */
607
608 printf_last("Deduplicated Segments: Segments=%d Duplicate=%d Unique=%d",index,duplicate,good);
609 }
610
611
612 /*++++++++++++++++++++++++++++++++++++++
613 Index the segments by creating the firstnode index and the segment next2 indexes.
614
615 SegmentsX* segmentsx The set of segments to process.
616
617 NodesX *nodesx The list of nodes to use.
618 ++++++++++++++++++++++++++++++++++++++*/
619
620 void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
621 {
622 index_t index;
623 int i;
624
625 /* Print the start message */
626
627 printf_first("Indexing Segments: Segments=0");
628
629 /* Allocate the array of indexes */
630
631 if(!segmentsx->firstnode)
632 {
633 segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
634
635 assert(segmentsx->firstnode); /* Check malloc() worked */
636 }
637
638 for(i=0;i<nodesx->number;i++)
639 segmentsx->firstnode[i]=NO_SEGMENT;
640
641 /* Map into memory / open the files */
642
643 #if !SLIM
644 segmentsx->xdata=MapFileWriteable(segmentsx->filename);
645 #else
646 segmentsx->fd=ReOpenFileWriteable(segmentsx->filename);
647 #endif
648
649 /* Read through the segments in reverse order */
650
651 for(index=segmentsx->number-1;index!=NO_SEGMENT;index--)
652 {
653 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
654
655 if(segmentsx->firstnode[segmentx->node2]!=NO_SEGMENT)
656 {
657 segmentx->next2=segmentsx->firstnode[segmentx->node2];
658
659 PutBackSegmentX(segmentsx,index,1);
660 }
661
662 segmentsx->firstnode[segmentx->node1]=index;
663 segmentsx->firstnode[segmentx->node2]=index;
664
665 if(!(index%10000))
666 printf_middle("Indexing Segments: Segments=%d",segmentsx->number-index);
667 }
668
669 /* Unmap from memory / close the files */
670
671 #if !SLIM
672 segmentsx->xdata=UnmapFile(segmentsx->filename);
673 #else
674 segmentsx->fd=CloseFile(segmentsx->fd);
675 #endif
676
677 /* Fix-up the firstnode index for the missing nodes */
678
679 segmentsx->firstnode[nodesx->number]=segmentsx->number;
680
681 for(i=nodesx->number-1;i>=0;i--)
682 if(segmentsx->firstnode[i]==NO_SEGMENT)
683 segmentsx->firstnode[i]=segmentsx->firstnode[i+1];
684
685 /* Print the final message */
686
687 printf_last("Indexed Segments: Segments=%d",segmentsx->number);
688 }
689
690
691 /*++++++++++++++++++++++++++++++++++++++
692 Update the segment indexes after geographical sorting.
693
694 SegmentsX *segmentsx The list of segments to update.
695
696 NodesX *nodesx The set of nodes to use.
697
698 WaysX* waysx The set of ways to use.
699 ++++++++++++++++++++++++++++++++++++++*/
700
701 void UpdateSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx)
702 {
703 index_t i;
704 int fd;
705
706 /* Print the start message */
707
708 printf_first("Updating Super Segments: Segments=0");
709
710 /* Map into memory / open the files */
711
712 #if !SLIM
713 waysx->xdata=MapFile(waysx->filename);
714 #else
715 waysx->fd=ReOpenFile(waysx->filename);
716 #endif
717
718 /* Re-open the file read-only and a new file writeable */
719
720 segmentsx->fd=ReOpenFile(segmentsx->filename);
721
722 DeleteFile(segmentsx->filename);
723
724 fd=OpenFileNew(segmentsx->filename);
725
726 /* Modify the on-disk image */
727
728 for(i=0;i<segmentsx->number;i++)
729 {
730 SegmentX segmentx;
731 WayX *wayx;
732
733 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
734
735 segmentx.node1=nodesx->gdata[segmentx.node1];
736 segmentx.node2=nodesx->gdata[segmentx.node2];
737
738 wayx=LookupWayX(waysx,segmentx.way,1);
739
740 segmentx.way=wayx->prop;
741
742 WriteFile(fd,&segmentx,sizeof(SegmentX));
743
744 if(!((i+1)%10000))
745 printf_middle("Updating Super Segments: Segments=%d",i+1);
746 }
747
748 /* Close the files */
749
750 segmentsx->fd=CloseFile(segmentsx->fd);
751 CloseFile(fd);
752
753 /* Unmap from memory / close the files */
754
755 #if !SLIM
756 waysx->xdata=UnmapFile(waysx->filename);
757 #else
758 waysx->fd=CloseFile(waysx->fd);
759 #endif
760
761 /* Print the final message */
762
763 printf_last("Updated Super Segments: Segments=%d",segmentsx->number);
764 }
765
766
767 /*++++++++++++++++++++++++++++++++++++++
768 Save the segment list to a file.
769
770 SegmentsX* segmentsx The set of segments to save.
771
772 const char *filename The name of the file to save.
773 ++++++++++++++++++++++++++++++++++++++*/
774
775 void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
776 {
777 index_t i;
778 int fd;
779 SegmentsFile segmentsfile={0};
780 int super_number=0,normal_number=0;
781
782 /* Print the start message */
783
784 printf_first("Writing Segments: Segments=0");
785
786 /* Re-open the file */
787
788 segmentsx->fd=ReOpenFile(segmentsx->filename);
789
790 /* Write out the segments data */
791
792 fd=OpenFileNew(filename);
793
794 SeekFile(fd,sizeof(SegmentsFile));
795
796 for(i=0;i<segmentsx->number;i++)
797 {
798 SegmentX segmentx;
799 Segment segment;
800
801 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
802
803 segment.node1 =segmentx.node1;
804 segment.node2 =segmentx.node2;
805 segment.next2 =segmentx.next2;
806 segment.way =segmentx.way;
807 segment.distance=segmentx.distance;
808
809 if(IsSuperSegment(&segment))
810 super_number++;
811 if(IsNormalSegment(&segment))
812 normal_number++;
813
814 WriteFile(fd,&segment,sizeof(Segment));
815
816 if(!((i+1)%10000))
817 printf_middle("Writing Segments: Segments=%d",i+1);
818 }
819
820 /* Write out the header structure */
821
822 segmentsfile.number=segmentsx->number;
823 segmentsfile.snumber=super_number;
824 segmentsfile.nnumber=normal_number;
825
826 SeekFile(fd,0);
827 WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
828
829 CloseFile(fd);
830
831 /* Close the file */
832
833 segmentsx->fd=CloseFile(segmentsx->fd);
834
835 /* Print the final message */
836
837 printf_last("Wrote Segments: Segments=%d",segmentsx->number);
838 }
839
840
841 /*++++++++++++++++++++++++++++++++++++++
842 Calculate the distance between two nodes.
843
844 distance_t DistanceX Returns the distance between the extended nodes.
845
846 NodeX *nodex1 The starting node.
847
848 NodeX *nodex2 The end node.
849 ++++++++++++++++++++++++++++++++++++++*/
850
851 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
852 {
853 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
854 double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
855 double lat1 = latlong_to_radians(nodex1->latitude);
856 double lat2 = latlong_to_radians(nodex2->latitude);
857
858 double a1,a2,a,sa,c,d;
859
860 if(dlon==0 && dlat==0)
861 return 0;
862
863 a1 = sin (dlat / 2);
864 a2 = sin (dlon / 2);
865 a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
866 sa = sqrt (a);
867 if (sa <= 1.0)
868 {c = 2 * asin (sa);}
869 else
870 {c = 2 * asin (1.0);}
871 d = 6378.137 * c;
872
873 return km_to_distance(d);
874 }

Properties

Name Value
cvs:description Extended segments functions.