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 666 - (show annotations) (download) (as text)
Mon Mar 21 19:07:47 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 20472 byte(s)
Fix bug with segment deduplication.

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->number=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->number++;
162
163 assert(segmentsx->number<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 /* Close the files */
198
199 segmentsx->fd=CloseFile(segmentsx->fd);
200 CloseFile(fd);
201
202 /* Print the final message */
203
204 printf_last("Sorted Segments: Segments=%d",segmentsx->number);
205 }
206
207
208 /*++++++++++++++++++++++++++++++++++++++
209 Sort the segments into id order (node1 then node2).
210
211 int sort_by_id Returns the comparison of the node fields.
212
213 SegmentX *a The first segment.
214
215 SegmentX *b The second segment.
216 ++++++++++++++++++++++++++++++++++++++*/
217
218 static int sort_by_id(SegmentX *a,SegmentX *b)
219 {
220 node_t a_id1=a->node1;
221 node_t b_id1=b->node1;
222
223 if(a_id1<b_id1)
224 return(-1);
225 else if(a_id1>b_id1)
226 return(1);
227 else /* if(a_id1==b_id1) */
228 {
229 node_t a_id2=a->node2;
230 node_t b_id2=b->node2;
231
232 if(a_id2<b_id2)
233 return(-1);
234 else if(a_id2>b_id2)
235 return(1);
236 else
237 {
238 distance_t a_distance=a->distance;
239 distance_t b_distance=b->distance;
240
241 if(a_distance<b_distance)
242 return(-1);
243 else if(a_distance>b_distance)
244 return(1);
245 else
246 return(0);
247 }
248 }
249 }
250
251
252 /*++++++++++++++++++++++++++++++++++++++
253 Find the first extended segment with a particular starting node index.
254
255 SegmentX *FirstSegmentX Returns a pointer to the first extended segment with the specified id.
256
257 SegmentsX* segmentsx The set of extended segments to process.
258
259 index_t nodeindex The node index to look for.
260
261 int position A flag to pass through.
262 ++++++++++++++++++++++++++++++++++++++*/
263
264 SegmentX *FirstSegmentX(SegmentsX* segmentsx,index_t nodeindex,int position)
265 {
266 index_t index=segmentsx->firstnode[nodeindex];
267 SegmentX *segmentx;
268
269 segmentx=LookupSegmentX(segmentsx,index,position);
270
271 if(segmentx->node1!=nodeindex && segmentx->node2!=nodeindex)
272 return(NULL);
273
274 return(segmentx);
275 }
276
277
278 /*++++++++++++++++++++++++++++++++++++++
279 Find the next segment with a particular starting node index.
280
281 SegmentX *NextSegmentX Returns a pointer to the next segment with the same id.
282
283 SegmentsX* segmentsx The set of segments to process.
284
285 SegmentX *segmentx The current segment.
286
287 index_t node The node index.
288
289 int position A flag to pass through.
290 ++++++++++++++++++++++++++++++++++++++*/
291
292 SegmentX *NextSegmentX(SegmentsX* segmentsx,SegmentX *segmentx,index_t node,int position)
293 {
294 if(segmentx->node1==node)
295 {
296 #if SLIM
297 index_t index=IndexSegmentX(segmentsx,segmentx);
298 index++;
299
300 if(index>=segmentsx->number)
301 return(NULL);
302 segmentx=LookupSegmentX(segmentsx,index,position);
303 if(segmentx->node1!=node)
304 return(NULL);
305 else
306 return(segmentx);
307 #else
308 segmentx++;
309 if(IndexSegmentX(segmentsx,segmentx)>=segmentsx->number || segmentx->node1!=node)
310 return(NULL);
311 else
312 return(segmentx);
313 #endif
314 }
315 else
316 {
317 if(segmentx->next2==NO_SEGMENT)
318 return(NULL);
319 else
320 return(LookupSegmentX(segmentsx,segmentx->next2,position));
321 }
322 }
323
324
325 /*++++++++++++++++++++++++++++++++++++++
326 Remove bad segments (duplicated, zero length or missing nodes).
327
328 NodesX *nodesx The nodes to check.
329
330 SegmentsX *segmentsx The segments to modify.
331 ++++++++++++++++++++++++++++++++++++++*/
332
333 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
334 {
335 int duplicate=0,loop=0,missing=0,good=0,total=0;
336 SegmentX segmentx;
337 int fd;
338 node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
339
340 /* Print the start message */
341
342 printf_first("Checking Segments: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
343
344 /* Allocate the array of node flags */
345
346 segmentsx->usednode=(char*)calloc((1+nodesx->number/8),sizeof(char));
347
348 assert(segmentsx->usednode); /* Check malloc() worked */
349
350 /* Re-open the file read-only and a new file writeable */
351
352 segmentsx->fd=ReOpenFile(segmentsx->filename);
353
354 DeleteFile(segmentsx->filename);
355
356 fd=OpenFileNew(segmentsx->filename);
357
358 /* Modify the on-disk image */
359
360 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
361 {
362 index_t index1=IndexNodeX(nodesx,segmentx.node1);
363 index_t index2=IndexNodeX(nodesx,segmentx.node2);
364
365 if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2)
366 duplicate++;
367 else if(segmentx.node1==segmentx.node2)
368 loop++;
369 else if(index1==NO_NODE || index2==NO_NODE)
370 missing++;
371 else
372 {
373 WriteFile(fd,&segmentx,sizeof(SegmentX));
374
375 SetBit(segmentsx->usednode,index1);
376 SetBit(segmentsx->usednode,index2);
377
378 good++;
379
380 prevnode1=segmentx.node1;
381 prevnode2=segmentx.node2;
382 }
383
384 total++;
385
386 if(!(total%10000))
387 printf_middle("Checking Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
388 }
389
390 segmentsx->number=good;
391
392 /* Close the files */
393
394 segmentsx->fd=CloseFile(segmentsx->fd);
395 CloseFile(fd);
396
397 /* Print the final message */
398
399 printf_last("Checked Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
400 }
401
402
403 /*++++++++++++++++++++++++++++++++++++++
404 Measure the segments and replace node/way ids with indexes.
405
406 SegmentsX* segmentsx The set of segments to process.
407
408 NodesX *nodesx The list of nodes to use.
409
410 WaysX *waysx The list of ways to use.
411 ++++++++++++++++++++++++++++++++++++++*/
412
413 void MeasureSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
414 {
415 index_t index=0;
416 int fd;
417 SegmentX segmentx;
418
419 /* Print the start message */
420
421 printf_first("Measuring Segments: Segments=0");
422
423 /* Map into memory / open the file */
424
425 #if !SLIM
426 nodesx->data=MapFile(nodesx->filename);
427 #else
428 nodesx->fd=ReOpenFile(nodesx->filename);
429 #endif
430
431 /* Re-open the file read-only and a new file writeable */
432
433 segmentsx->fd=ReOpenFile(segmentsx->filename);
434
435 DeleteFile(segmentsx->filename);
436
437 fd=OpenFileNew(segmentsx->filename);
438
439 /* Modify the on-disk image */
440
441 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
442 {
443 index_t node1=IndexNodeX(nodesx,segmentx.node1);
444 index_t node2=IndexNodeX(nodesx,segmentx.node2);
445 index_t way =IndexWayX (waysx ,segmentx.way);
446
447 NodeX *nodex1=LookupNodeX(nodesx,node1,1);
448 NodeX *nodex2=LookupNodeX(nodesx,node2,2);
449
450 /* Replace the node and way ids with their indexes */
451
452 segmentx.node1=node1;
453 segmentx.node2=node2;
454 segmentx.way =way;
455
456 /* Set the distance but preserve the ONEWAY_* flags */
457
458 segmentx.distance|=DISTANCE(DistanceX(nodex1,nodex2));
459
460 /* Write the modified segment */
461
462 WriteFile(fd,&segmentx,sizeof(SegmentX));
463
464 index++;
465
466 if(!(index%10000))
467 printf_middle("Measuring Segments: Segments=%d",index);
468 }
469
470 /* Close the files */
471
472 segmentsx->fd=CloseFile(segmentsx->fd);
473 CloseFile(fd);
474
475 /* Free the other now-unneeded indexes */
476
477 free(nodesx->idata);
478 nodesx->idata=NULL;
479
480 free(waysx->idata);
481 waysx->idata=NULL;
482
483 /* Unmap from memory / close the file */
484
485 #if !SLIM
486 nodesx->data=UnmapFile(nodesx->filename);
487 #else
488 nodesx->fd=CloseFile(nodesx->fd);
489 #endif
490
491 /* Print the final message */
492
493 printf_last("Measured Segments: Segments=%d",segmentsx->number);
494 }
495
496
497 /*++++++++++++++++++++++++++++++++++++++
498 Remove the duplicate segments.
499
500 SegmentsX* segmentsx The set of segments to process.
501
502 NodesX *nodesx The list of nodes to use.
503
504 WaysX *waysx The list of ways to use.
505 ++++++++++++++++++++++++++++++++++++++*/
506
507 void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
508 {
509 int duplicate=0,good=0;
510 index_t index=0;
511 int fd,nprev=0;
512 node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
513 SegmentX prevsegx[16],segmentx;
514 Way prevway[16];
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->data=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 WayX *wayx=LookupWayX(waysx,segmentx.way,1);
541 int isduplicate=0;
542
543 if(segmentx.node1==prevnode1 && segmentx.node2==prevnode2)
544 {
545 int offset;
546
547 for(offset=0;offset<nprev;offset++)
548 {
549 if(DISTFLAG(segmentx.distance)==DISTFLAG(prevsegx[offset].distance))
550 if(!WaysCompare(&prevway[offset],&wayx->way))
551 {
552 isduplicate=1;
553 break;
554 }
555 }
556
557 if(isduplicate)
558 {
559 nprev--;
560
561 for(;offset<nprev;offset++)
562 {
563 prevsegx[offset]=prevsegx[offset+1];
564 prevway[offset] =prevway[offset+1];
565 }
566 }
567 else
568 {
569 assert(nprev<(sizeof(prevsegx)/sizeof(prevsegx[0])));
570
571 prevsegx[nprev]=segmentx;
572 prevway[nprev] =wayx->way;
573
574 nprev++;
575 }
576 }
577 else
578 {
579 nprev=1;
580 prevnode1=segmentx.node1;
581 prevnode2=segmentx.node2;
582 prevsegx[0]=segmentx;
583 prevway[0] =wayx->way;
584 }
585
586 if(isduplicate)
587 duplicate++;
588 else
589 {
590 WriteFile(fd,&segmentx,sizeof(SegmentX));
591
592 good++;
593 }
594
595 index++;
596
597 if(!(index%10000))
598 printf_middle("Deduplicating Segments: Segments=%d Duplicate=%d",index,duplicate);
599 }
600
601 segmentsx->number=good;
602
603 /* Close the files */
604
605 segmentsx->fd=CloseFile(segmentsx->fd);
606 CloseFile(fd);
607
608 /* Unmap from memory / close the file */
609
610 #if !SLIM
611 waysx->data=UnmapFile(waysx->filename);
612 #else
613 waysx->fd=CloseFile(waysx->fd);
614 #endif
615
616 /* Print the final message */
617
618 printf_last("Deduplicated Segments: Segments=%d Duplicate=%d Unique=%d",index,duplicate,good);
619 }
620
621
622 /*++++++++++++++++++++++++++++++++++++++
623 Index the segments by creating the firstnode index and the segment next2 indexes.
624
625 SegmentsX* segmentsx The set of segments to process.
626
627 NodesX *nodesx The list of nodes to use.
628 ++++++++++++++++++++++++++++++++++++++*/
629
630 void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
631 {
632 index_t index;
633 int i;
634
635 if(segmentsx->number==0)
636 return;
637
638 /* Print the start message */
639
640 printf_first("Indexing Segments: Segments=0");
641
642 /* Allocate the array of indexes */
643
644 if(!segmentsx->firstnode)
645 {
646 segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
647
648 assert(segmentsx->firstnode); /* Check malloc() worked */
649 }
650
651 for(i=0;i<nodesx->number;i++)
652 segmentsx->firstnode[i]=NO_SEGMENT;
653
654 /* Map into memory / open the files */
655
656 #if !SLIM
657 segmentsx->data=MapFileWriteable(segmentsx->filename);
658 #else
659 segmentsx->fd=ReOpenFileWriteable(segmentsx->filename);
660 #endif
661
662 /* Read through the segments in reverse order */
663
664 for(index=segmentsx->number-1;index!=NO_SEGMENT;index--)
665 {
666 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
667
668 if(segmentsx->firstnode[segmentx->node2]!=NO_SEGMENT)
669 {
670 segmentx->next2=segmentsx->firstnode[segmentx->node2];
671
672 PutBackSegmentX(segmentsx,index,1);
673 }
674
675 segmentsx->firstnode[segmentx->node1]=index;
676 segmentsx->firstnode[segmentx->node2]=index;
677
678 if(!(index%10000))
679 printf_middle("Indexing Segments: Segments=%d",segmentsx->number-index);
680 }
681
682 /* Unmap from memory / close the files */
683
684 #if !SLIM
685 segmentsx->data=UnmapFile(segmentsx->filename);
686 #else
687 segmentsx->fd=CloseFile(segmentsx->fd);
688 #endif
689
690 /* Fix-up the firstnode index for the missing nodes */
691
692 segmentsx->firstnode[nodesx->number]=segmentsx->number;
693
694 for(i=nodesx->number-1;i>=0;i--)
695 if(segmentsx->firstnode[i]==NO_SEGMENT)
696 segmentsx->firstnode[i]=segmentsx->firstnode[i+1];
697
698 /* Print the final message */
699
700 printf_last("Indexed Segments: Segments=%d",segmentsx->number);
701 }
702
703
704 /*++++++++++++++++++++++++++++++++++++++
705 Update the segment indexes after geographical sorting.
706
707 SegmentsX *segmentsx The list of segments to update.
708
709 NodesX *nodesx The set of nodes to use.
710
711 WaysX* waysx The set of ways to use.
712 ++++++++++++++++++++++++++++++++++++++*/
713
714 void UpdateSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx)
715 {
716 index_t i;
717 int fd;
718
719 /* Print the start message */
720
721 printf_first("Updating Super Segments: Segments=0");
722
723 /* Map into memory / open the files */
724
725 #if !SLIM
726 waysx->data=MapFile(waysx->filename);
727 #else
728 waysx->fd=ReOpenFile(waysx->filename);
729 #endif
730
731 /* Re-open the file read-only and a new file writeable */
732
733 segmentsx->fd=ReOpenFile(segmentsx->filename);
734
735 DeleteFile(segmentsx->filename);
736
737 fd=OpenFileNew(segmentsx->filename);
738
739 /* Modify the on-disk image */
740
741 for(i=0;i<segmentsx->number;i++)
742 {
743 SegmentX segmentx;
744 WayX *wayx;
745
746 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
747
748 segmentx.node1=nodesx->gdata[segmentx.node1];
749 segmentx.node2=nodesx->gdata[segmentx.node2];
750
751 wayx=LookupWayX(waysx,segmentx.way,1);
752
753 segmentx.way=wayx->prop;
754
755 WriteFile(fd,&segmentx,sizeof(SegmentX));
756
757 if(!((i+1)%10000))
758 printf_middle("Updating Super Segments: Segments=%d",i+1);
759 }
760
761 /* Close the files */
762
763 segmentsx->fd=CloseFile(segmentsx->fd);
764 CloseFile(fd);
765
766 /* Unmap from memory / close the files */
767
768 #if !SLIM
769 waysx->data=UnmapFile(waysx->filename);
770 #else
771 waysx->fd=CloseFile(waysx->fd);
772 #endif
773
774 /* Print the final message */
775
776 printf_last("Updated Super Segments: Segments=%d",segmentsx->number);
777 }
778
779
780 /*++++++++++++++++++++++++++++++++++++++
781 Save the segment list to a file.
782
783 SegmentsX* segmentsx The set of segments to save.
784
785 const char *filename The name of the file to save.
786 ++++++++++++++++++++++++++++++++++++++*/
787
788 void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
789 {
790 index_t i;
791 int fd;
792 SegmentsFile segmentsfile={0};
793 int super_number=0,normal_number=0;
794
795 /* Print the start message */
796
797 printf_first("Writing Segments: Segments=0");
798
799 /* Re-open the file */
800
801 segmentsx->fd=ReOpenFile(segmentsx->filename);
802
803 /* Write out the segments data */
804
805 fd=OpenFileNew(filename);
806
807 SeekFile(fd,sizeof(SegmentsFile));
808
809 for(i=0;i<segmentsx->number;i++)
810 {
811 SegmentX segmentx;
812 Segment segment;
813
814 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
815
816 segment.node1 =segmentx.node1;
817 segment.node2 =segmentx.node2;
818 segment.next2 =segmentx.next2;
819 segment.way =segmentx.way;
820 segment.distance=segmentx.distance;
821
822 if(IsSuperSegment(&segment))
823 super_number++;
824 if(IsNormalSegment(&segment))
825 normal_number++;
826
827 WriteFile(fd,&segment,sizeof(Segment));
828
829 if(!((i+1)%10000))
830 printf_middle("Writing Segments: Segments=%d",i+1);
831 }
832
833 /* Write out the header structure */
834
835 segmentsfile.number=segmentsx->number;
836 segmentsfile.snumber=super_number;
837 segmentsfile.nnumber=normal_number;
838
839 SeekFile(fd,0);
840 WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
841
842 CloseFile(fd);
843
844 /* Close the file */
845
846 segmentsx->fd=CloseFile(segmentsx->fd);
847
848 /* Print the final message */
849
850 printf_last("Wrote Segments: Segments=%d",segmentsx->number);
851 }
852
853
854 /*++++++++++++++++++++++++++++++++++++++
855 Calculate the distance between two nodes.
856
857 distance_t DistanceX Returns the distance between the extended nodes.
858
859 NodeX *nodex1 The starting node.
860
861 NodeX *nodex2 The end node.
862 ++++++++++++++++++++++++++++++++++++++*/
863
864 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
865 {
866 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
867 double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
868 double lat1 = latlong_to_radians(nodex1->latitude);
869 double lat2 = latlong_to_radians(nodex2->latitude);
870
871 double a1,a2,a,sa,c,d;
872
873 if(dlon==0 && dlat==0)
874 return 0;
875
876 a1 = sin (dlat / 2);
877 a2 = sin (dlon / 2);
878 a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
879 sa = sqrt (a);
880 if (sa <= 1.0)
881 {c = 2 * asin (sa);}
882 else
883 {c = 2 * asin (1.0);}
884 d = 6378.137 * c;
885
886 return km_to_distance(d);
887 }

Properties

Name Value
cvs:description Extended segments functions.