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 788 - (show annotations) (download) (as text)
Sat Jun 18 10:54:17 2011 UTC (13 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20584 byte(s)
Fix some more warnings from -Wextra and/or -pedantic options.

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

Properties

Name Value
cvs:description Extended segments functions.