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 471 - (show annotations) (download) (as text)
Wed Aug 4 16:44:52 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 23340 byte(s)
Change the way that fake nodes and segments are recognised (allows nearly 4G
nodes to be stored instead of 2G nodes).

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/segmentsx.c,v 1.62 2010-08-04 16:44:52 amb Exp $
3
4 Extended Segment data type functions.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
23
24
25 #include <assert.h>
26 #include <math.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/stat.h>
31
32 #include "types.h"
33 #include "nodes.h"
34 #include "segments.h"
35 #include "ways.h"
36
37 #include "nodesx.h"
38 #include "segmentsx.h"
39 #include "waysx.h"
40
41 #include "types.h"
42
43 #include "files.h"
44 #include "functions.h"
45
46
47 /* Variables */
48
49 /*+ The command line '--tmpdir' option or its default value. +*/
50 extern char *option_tmpdirname;
51
52 /* Local Functions */
53
54 static int sort_by_id(SegmentX *a,SegmentX *b);
55
56 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2);
57
58
59 /*++++++++++++++++++++++++++++++++++++++
60 Allocate a new segment list (create a new file or open an existing one).
61
62 SegmentsX *NewSegmentList Returns the segment list.
63
64 int append Set to 1 if the file is to be opened for appending (now or later).
65 ++++++++++++++++++++++++++++++++++++++*/
66
67 SegmentsX *NewSegmentList(int append)
68 {
69 SegmentsX *segmentsx;
70
71 segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX));
72
73 assert(segmentsx); /* Check calloc() worked */
74
75 segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
76
77 if(append)
78 sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
79 else
80 sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
81
82 #if SLIM
83 segmentsx->sfilename=(char*)malloc(strlen(option_tmpdirname)+32);
84
85 sprintf(segmentsx->sfilename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
86 #endif
87
88 if(append)
89 {
90 off_t size;
91
92 segmentsx->fd=AppendFile(segmentsx->filename);
93
94 size=SizeFile(segmentsx->filename);
95
96 segmentsx->xnumber=size/sizeof(SegmentX);
97 }
98 else
99 segmentsx->fd=OpenFile(segmentsx->filename);
100
101 return(segmentsx);
102 }
103
104
105 /*++++++++++++++++++++++++++++++++++++++
106 Free a segment list.
107
108 SegmentsX *segmentsx The list to be freed.
109
110 int keep Set to 1 if the file is to be kept.
111 ++++++++++++++++++++++++++++++++++++++*/
112
113 void FreeSegmentList(SegmentsX *segmentsx,int keep)
114 {
115 if(!keep)
116 DeleteFile(segmentsx->filename);
117
118 free(segmentsx->filename);
119
120 if(segmentsx->idata)
121 free(segmentsx->idata);
122
123 if(segmentsx->firstnode)
124 free(segmentsx->firstnode);
125
126 #if !SLIM
127 if(segmentsx->sdata)
128 free(segmentsx->sdata);
129 #endif
130
131 #if SLIM
132 DeleteFile(segmentsx->sfilename);
133
134 free(segmentsx->sfilename);
135 #endif
136
137 free(segmentsx);
138 }
139
140
141 /*++++++++++++++++++++++++++++++++++++++
142 Append a single segment to a segment list.
143
144 SegmentsX* segmentsx The set of segments to process.
145
146 way_t way The way that the segment belongs to.
147
148 node_t node1 The first node in the segment.
149
150 node_t node2 The second node in the segment.
151
152 distance_t distance The distance between the nodes (or just the flags).
153 ++++++++++++++++++++++++++++++++++++++*/
154
155 void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,distance_t distance)
156 {
157 SegmentX segmentx;
158
159 segmentx.node1=node1;
160 segmentx.node2=node2;
161 segmentx.way=way;
162 segmentx.distance=distance;
163
164 WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
165
166 segmentsx->xnumber++;
167
168 assert(segmentsx->xnumber<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
169 }
170
171
172 /*++++++++++++++++++++++++++++++++++++++
173 Sort the segment list.
174
175 SegmentsX* segmentsx The set of segments to process.
176 ++++++++++++++++++++++++++++++++++++++*/
177
178 void SortSegmentList(SegmentsX* segmentsx)
179 {
180 int fd;
181
182 /* Print the start message */
183
184 printf("Sorting Segments");
185 fflush(stdout);
186
187 /* Close the files and re-open them (finished appending) */
188
189 CloseFile(segmentsx->fd);
190 segmentsx->fd=ReOpenFile(segmentsx->filename);
191
192 DeleteFile(segmentsx->filename);
193
194 fd=OpenFile(segmentsx->filename);
195
196 /* Sort by node indexes */
197
198 filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(const void*,const void*))sort_by_id,NULL);
199
200 segmentsx->number=segmentsx->xnumber;
201
202 /* Close the files and re-open them */
203
204 CloseFile(segmentsx->fd);
205 CloseFile(fd);
206
207 segmentsx->fd=ReOpenFile(segmentsx->filename);
208
209 /* Print the final message */
210
211 printf("\rSorted Segments: Segments=%d\n",segmentsx->xnumber);
212 fflush(stdout);
213 }
214
215
216 /*++++++++++++++++++++++++++++++++++++++
217 Sort the segments into id order (node1 then node2).
218
219 int sort_by_id Returns the comparison of the node fields.
220
221 SegmentX *a The first segment.
222
223 SegmentX *b The second segment.
224 ++++++++++++++++++++++++++++++++++++++*/
225
226 static int sort_by_id(SegmentX *a,SegmentX *b)
227 {
228 node_t a_id1=a->node1;
229 node_t b_id1=b->node1;
230
231 if(a_id1<b_id1)
232 return(-1);
233 else if(a_id1>b_id1)
234 return(1);
235 else /* if(a_id1==b_id1) */
236 {
237 node_t a_id2=a->node2;
238 node_t b_id2=b->node2;
239
240 if(a_id2<b_id2)
241 return(-1);
242 else if(a_id2>b_id2)
243 return(1);
244 else
245 {
246 distance_t a_distance=a->distance;
247 distance_t b_distance=b->distance;
248
249 if(a_distance<b_distance)
250 return(-1);
251 else if(a_distance>b_distance)
252 return(1);
253 else
254 return(0);
255 }
256 }
257 }
258
259
260 /*++++++++++++++++++++++++++++++++++++++
261 Find the first segment index with a particular starting node.
262
263 index_t IndexFirstSegmentX Returns a pointer to the index of the first extended segment with the specified id.
264
265 SegmentsX* segmentsx The set of segments to process.
266
267 node_t node The node to look for.
268 ++++++++++++++++++++++++++++++++++++++*/
269
270 index_t IndexFirstSegmentX(SegmentsX* segmentsx,node_t node)
271 {
272 int start=0;
273 int end=segmentsx->number-1;
274 int mid;
275 int found;
276
277 /* Check if the first node index exists */
278
279 if(segmentsx->firstnode)
280 {
281 index_t index=segmentsx->firstnode[node];
282
283 if(segmentsx->firstnode[node+1]==index)
284 return(NO_SEGMENT);
285
286 return(index);
287 }
288
289 /* Binary search - search key exact match only is required.
290 *
291 * # <- start | Check mid and move start or end if it doesn't match
292 * # |
293 * # | Since an exact match is wanted we can set end=mid-1
294 * # <- mid | or start=mid+1 because we know that mid doesn't match.
295 * # |
296 * # | Eventually either end=start or end=start+1 and one of
297 * # <- end | start or end is the wanted one.
298 */
299
300 if(end<start) /* There are no nodes */
301 return(NO_SEGMENT);
302 else if(node<segmentsx->idata[start]) /* Check key is not before start */
303 return(NO_SEGMENT);
304 else if(node>segmentsx->idata[end]) /* Check key is not after end */
305 return(NO_SEGMENT);
306 else
307 {
308 do
309 {
310 mid=(start+end)/2; /* Choose mid point */
311
312 if(segmentsx->idata[mid]<node) /* Mid point is too low */
313 start=mid;
314 else if(segmentsx->idata[mid]>node) /* Mid point is too high */
315 end=mid;
316 else /* Mid point is correct */
317 {found=mid; goto found;}
318 }
319 while((end-start)>1);
320
321 if(segmentsx->idata[start]==node) /* Start is correct */
322 {found=start; goto found;}
323
324 if(segmentsx->idata[end]==node) /* End is correct */
325 {found=end; goto found;}
326 }
327
328 return(NO_SEGMENT);
329
330 found:
331
332 while(found>0 && segmentsx->idata[found-1]==node)
333 found--;
334
335 return(found);
336 }
337
338
339 /*++++++++++++++++++++++++++++++++++++++
340 Find the next segment index with a particular starting node.
341
342 index_t IndexNextSegmentX Returns the index of the next segment with the same id.
343
344 SegmentsX* segmentsx The set of segments to process.
345
346 index_t segindex The current segment index.
347
348 index_t nodeindex The node index.
349 ++++++++++++++++++++++++++++++++++++++*/
350
351 index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeindex)
352 {
353 if(++segindex==segmentsx->firstnode[nodeindex+1])
354 return(NO_SEGMENT);
355 else
356 return(segindex);
357 }
358
359
360 /*++++++++++++++++++++++++++++++++++++++
361 Remove bad segments (duplicated, zero length or missing nodes).
362
363 NodesX *nodesx The nodes to check.
364
365 SegmentsX *segmentsx The segments to modify.
366 ++++++++++++++++++++++++++++++++++++++*/
367
368 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
369 {
370 int duplicate=0,loop=0,missing=0,good=0,total=0;
371 SegmentX segmentx;
372 int fd;
373 node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
374
375 /* Print the start message */
376
377 printf("Checking: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
378 fflush(stdout);
379
380 /* Allocate the array of indexes */
381
382 segmentsx->idata=(node_t*)malloc(segmentsx->xnumber*sizeof(node_t));
383
384 assert(segmentsx->idata); /* Check malloc() worked */
385
386 /* Modify the on-disk image */
387
388 DeleteFile(segmentsx->filename);
389
390 fd=OpenFile(segmentsx->filename);
391 SeekFile(segmentsx->fd,0);
392
393 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
394 {
395 if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2)
396 duplicate++;
397 else if(segmentx.node1==segmentx.node2)
398 loop++;
399 else if(IndexNodeX(nodesx,segmentx.node1)==NO_NODE ||
400 IndexNodeX(nodesx,segmentx.node2)==NO_NODE)
401 missing++;
402 else
403 {
404 WriteFile(fd,&segmentx,sizeof(SegmentX));
405
406 segmentsx->idata[good]=segmentx.node1;
407 good++;
408
409 prevnode1=segmentx.node1;
410 prevnode2=segmentx.node2;
411 }
412
413 total++;
414
415 if(!(total%10000))
416 {
417 printf("\rChecking: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
418 fflush(stdout);
419 }
420 }
421
422 /* Close the files and re-open them */
423
424 CloseFile(segmentsx->fd);
425 CloseFile(fd);
426
427 segmentsx->fd=ReOpenFile(segmentsx->filename);
428
429 segmentsx->number=good;
430
431 /* Print the final message */
432
433 printf("\rChecked: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d \n",total,duplicate,loop,missing);
434 fflush(stdout);
435 }
436
437
438 /*++++++++++++++++++++++++++++++++++++++
439 Measure the segments and replace node/way ids with indexes.
440
441 SegmentsX* segmentsx The set of segments to process.
442
443 NodesX *nodesx The list of nodes to use.
444
445 WaysX *waysx The list of ways to use.
446 ++++++++++++++++++++++++++++++++++++++*/
447
448 void UpdateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
449 {
450 index_t index=0;
451 int i,fd;
452 SegmentX segmentx;
453
454 /* Print the start message */
455
456 printf("Measuring Segments: Segments=0");
457 fflush(stdout);
458
459 /* Map into memory */
460
461 #if !SLIM
462 nodesx->xdata=MapFile(nodesx->filename);
463 #endif
464
465 /* Free the now-unneeded index */
466
467 free(segmentsx->idata);
468 segmentsx->idata=NULL;
469
470 /* Allocate the array of indexes */
471
472 segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
473
474 assert(segmentsx->firstnode); /* Check malloc() worked */
475
476 for(i=0;i<nodesx->number;i++)
477 segmentsx->firstnode[i]=NO_SEGMENT;
478
479 segmentsx->firstnode[nodesx->number]=segmentsx->number;
480
481 /* Modify the on-disk image */
482
483 DeleteFile(segmentsx->filename);
484
485 fd=OpenFile(segmentsx->filename);
486 SeekFile(segmentsx->fd,0);
487
488 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
489 {
490 index_t node1=IndexNodeX(nodesx,segmentx.node1);
491 index_t node2=IndexNodeX(nodesx,segmentx.node2);
492 index_t way =IndexWayX (waysx ,segmentx.way);
493
494 NodeX *nodex1=LookupNodeX(nodesx,node1,1);
495 NodeX *nodex2=LookupNodeX(nodesx,node2,2);
496
497 /* Replace the node and way ids with their indexes */
498
499 segmentx.node1=node1;
500 segmentx.node2=node2;
501 segmentx.way =way;
502
503 /* Set the distance but preserve the ONEWAY_* flags */
504
505 segmentx.distance|=DISTANCE(DistanceX(nodex1,nodex2));
506
507 /* Set the first segment index in the nodes */
508
509 if(index<segmentsx->firstnode[node1])
510 segmentsx->firstnode[node1]=index;
511
512 /* Write the modified segment */
513
514 WriteFile(fd,&segmentx,sizeof(SegmentX));
515
516 index++;
517
518 if(!(index%10000))
519 {
520 printf("\rMeasuring Segments: Segments=%d",index);
521 fflush(stdout);
522 }
523 }
524
525 /* Close the files and re-open them */
526
527 CloseFile(segmentsx->fd);
528 CloseFile(fd);
529
530 segmentsx->fd=ReOpenFile(segmentsx->filename);
531
532 /* Free the other now-unneeded indexes */
533
534 free(nodesx->idata);
535 nodesx->idata=NULL;
536
537 free(waysx->idata);
538 waysx->idata=NULL;
539
540 /* Unmap from memory */
541
542 #if !SLIM
543 nodesx->xdata=UnmapFile(nodesx->filename);
544 #endif
545
546 /* Print the final message */
547
548 printf("\rMeasured Segments: Segments=%d \n",segmentsx->number);
549 fflush(stdout);
550 }
551
552
553 /*++++++++++++++++++++++++++++++++++++++
554 Make the segments all point the same way (node1<node2).
555
556 SegmentsX* segmentsx The set of segments to process.
557 ++++++++++++++++++++++++++++++++++++++*/
558
559 void RotateSegments(SegmentsX* segmentsx)
560 {
561 int index=0,rotated=0;
562 int fd;
563 SegmentX segmentx;
564
565 /* Print the start message */
566
567 printf("Rotating Segments: Segments=0 Rotated=0");
568 fflush(stdout);
569
570 /* Close the files and re-open them (finished appending) */
571
572 CloseFile(segmentsx->fd);
573 segmentsx->fd=ReOpenFile(segmentsx->filename);
574
575 DeleteFile(segmentsx->filename);
576
577 fd=OpenFile(segmentsx->filename);
578
579 /* Modify the file contents */
580
581 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
582 {
583 if(segmentx.node1>segmentx.node2)
584 {
585 node_t temp;
586
587 temp=segmentx.node1;
588 segmentx.node1=segmentx.node2;
589 segmentx.node2=temp;
590
591 if(segmentx.distance&(ONEWAY_2TO1|ONEWAY_1TO2))
592 segmentx.distance^=ONEWAY_2TO1|ONEWAY_1TO2;
593
594 rotated++;
595 }
596
597 WriteFile(fd,&segmentx,sizeof(SegmentX));
598
599 index++;
600
601 if(!(index%10000))
602 {
603 printf("\rRotating Segments: Segments=%d Rotated=%d",index,rotated);
604 fflush(stdout);
605 }
606 }
607
608 /* Close the files and re-open them */
609
610 CloseFile(segmentsx->fd);
611 CloseFile(fd);
612
613 segmentsx->fd=ReOpenFile(segmentsx->filename);
614
615 /* Print the final message */
616
617 printf("\rRotated Segments: Segments=%d Rotated=%d \n",index,rotated);
618 fflush(stdout);
619 }
620
621
622 /*++++++++++++++++++++++++++++++++++++++
623 Remove the duplicate segments.
624
625 SegmentsX* segmentsx The set of segments to process.
626
627 NodesX *nodesx The list of nodes to use.
628
629 WaysX *waysx The list of ways to use.
630 ++++++++++++++++++++++++++++++++++++++*/
631
632 void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
633 {
634 int duplicate=0,good=0;
635 index_t firstindex=0,index=0;
636 int i,fd;
637 SegmentX prevsegmentx[16],segmentx;
638
639 /* Print the start message */
640
641 printf("Deduplicating Segments: Segments=0 Duplicate=0");
642 fflush(stdout);
643
644 /* Map into memory */
645
646 #if !SLIM
647 waysx->xdata=MapFile(waysx->filename);
648 #endif
649
650 /* Allocate the array of indexes */
651
652 segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
653
654 assert(segmentsx->firstnode); /* Check malloc() worked */
655
656 for(i=0;i<nodesx->number;i++)
657 segmentsx->firstnode[i]=NO_SEGMENT;
658
659 segmentsx->firstnode[nodesx->number]=segmentsx->number;
660
661 /* Modify the on-disk image */
662
663 DeleteFile(segmentsx->filename);
664
665 fd=OpenFile(segmentsx->filename);
666 SeekFile(segmentsx->fd,0);
667
668 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
669 {
670 int isduplicate=0;
671
672 if(index && segmentx.node1==prevsegmentx[0].node1 &&
673 segmentx.node2==prevsegmentx[0].node2)
674 {
675 index_t previndex=firstindex;
676
677 while(previndex<index)
678 {
679 int offset=previndex-firstindex;
680
681 if(DISTFLAG(segmentx.distance)==DISTFLAG(prevsegmentx[offset].distance))
682 {
683 WayX *wayx1=LookupWayX(waysx,prevsegmentx[offset].way,1);
684 WayX *wayx2=LookupWayX(waysx, segmentx .way,2);
685
686 if(!WaysCompare(&wayx1->way,&wayx2->way))
687 {
688 isduplicate=1;
689 duplicate++;
690 break;
691 }
692 }
693
694 previndex++;
695 }
696
697 assert((index-firstindex)<(sizeof(prevsegmentx)/sizeof(prevsegmentx[0])));
698
699 prevsegmentx[index-firstindex]=segmentx;
700 }
701 else
702 {
703 firstindex=index;
704 prevsegmentx[0]=segmentx;
705 }
706
707 if(!isduplicate)
708 {
709 WriteFile(fd,&segmentx,sizeof(SegmentX));
710
711 if(good<segmentsx->firstnode[segmentx.node1])
712 segmentsx->firstnode[segmentx.node1]=good;
713
714 good++;
715 }
716
717 index++;
718
719 if(!(index%10000))
720 {
721 printf("\rDeduplicating Segments: Segments=%d Duplicate=%d",index,duplicate);
722 fflush(stdout);
723 }
724 }
725
726 /* Close the files and re-open them */
727
728 CloseFile(segmentsx->fd);
729 CloseFile(fd);
730
731 segmentsx->fd=ReOpenFile(segmentsx->filename);
732
733 segmentsx->number=good;
734
735 /* Fix-up the firstnode index for the missing nodes */
736
737 for(i=nodesx->number-1;i>=0;i--)
738 if(segmentsx->firstnode[i]==NO_SEGMENT)
739 segmentsx->firstnode[i]=segmentsx->firstnode[i+1];
740
741 /* Unmap from memory */
742
743 #if !SLIM
744 waysx->xdata=UnmapFile(waysx->filename);
745 #endif
746
747 /* Print the final message */
748
749 printf("\rDeduplicated Segments: Segments=%d Duplicate=%d Unique=%d\n",index,duplicate,index-duplicate);
750 fflush(stdout);
751 }
752
753
754 /*++++++++++++++++++++++++++++++++++++++
755 Create the real segments data.
756
757 SegmentsX* segmentsx The set of segments to use.
758
759 WaysX* waysx The set of ways to use.
760 ++++++++++++++++++++++++++++++++++++++*/
761
762 void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
763 {
764 index_t i;
765
766 /* Print the start message */
767
768 printf("Creating Real Segments: Segments=0");
769 fflush(stdout);
770
771 /* Map into memory */
772
773 #if !SLIM
774 segmentsx->xdata=MapFile(segmentsx->filename);
775 waysx->xdata=MapFile(waysx->filename);
776 #endif
777
778 /* Free the unneeded memory */
779
780 free(segmentsx->firstnode);
781 segmentsx->firstnode=NULL;
782
783 /* Allocate the memory (or open the file) */
784
785 #if !SLIM
786 segmentsx->sdata=(Segment*)malloc(segmentsx->number*sizeof(Segment));
787
788 assert(segmentsx->sdata); /* Check malloc() worked */
789 #else
790 segmentsx->sfd=OpenFile(segmentsx->sfilename);
791 #endif
792
793 /* Loop through and fill */
794
795 for(i=0;i<segmentsx->number;i++)
796 {
797 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
798 Segment *segment =LookupSegmentXSegment(segmentsx,i,1);
799 WayX *wayx=LookupWayX(waysx,segmentx->way,1);
800
801 segment->node1=0;
802 segment->node2=0;
803 segment->next2=NO_NODE;
804 segment->way=wayx->prop;
805 segment->distance=segmentx->distance;
806
807 #if SLIM
808 PutBackSegmentXSegment(segmentsx,i,1);
809 #endif
810
811 if(!((i+1)%10000))
812 {
813 printf("\rCreating Real Segments: Segments=%d",i+1);
814 fflush(stdout);
815 }
816 }
817
818 /* Unmap from memory */
819
820 #if !SLIM
821 segmentsx->xdata=UnmapFile(segmentsx->filename);
822 waysx->xdata=UnmapFile(waysx->filename);
823 #endif
824
825 /* Print the final message */
826
827 printf("\rCreating Real Segments: Segments=%d \n",segmentsx->number);
828 fflush(stdout);
829 }
830
831
832 /*++++++++++++++++++++++++++++++++++++++
833 Assign the nodes indexes to the segments.
834
835 SegmentsX* segmentsx The set of segments to process.
836
837 NodesX *nodesx The list of nodes to use.
838 ++++++++++++++++++++++++++++++++++++++*/
839
840 void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
841 {
842 index_t i;
843
844 /* Print the start message */
845
846 printf("Indexing Nodes: Nodes=0");
847 fflush(stdout);
848
849 /* Map into memory */
850
851 #if !SLIM
852 nodesx->xdata=MapFile(nodesx->filename);
853 segmentsx->xdata=MapFile(segmentsx->filename);
854 #endif
855
856 /* Index the segments */
857
858 for(i=0;i<nodesx->number;i++)
859 {
860 NodeX *nodex=LookupNodeX(nodesx,i,1);
861 Node *node =LookupNodeXNode(nodesx,nodex->id,1);
862 index_t index=node->firstseg;
863
864 do
865 {
866 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
867 Segment *segment =LookupSegmentXSegment(segmentsx,index,1);
868
869 if(segmentx->node1==nodex->id)
870 {
871 segment->node1=i;
872
873 #if SLIM
874 PutBackSegmentXSegment(segmentsx,index,1);
875 #endif
876
877 index++;
878
879 if(index>=segmentsx->number)
880 break;
881
882 segmentx=LookupSegmentX(segmentsx,index,1);
883
884 if(segmentx->node1!=nodex->id)
885 break;
886 }
887 else
888 {
889 segment->node2=i;
890
891 #if SLIM
892 PutBackSegmentXSegment(segmentsx,index,1);
893 #endif
894
895 if(segment->next2==NO_NODE)
896 break;
897 else
898 index=segment->next2;
899 }
900 }
901 while(1);
902
903 if(!((i+1)%10000))
904 {
905 printf("\rIndexing Nodes: Nodes=%d",i+1);
906 fflush(stdout);
907 }
908 }
909
910 /* Unmap from memory */
911
912 #if !SLIM
913 nodesx->xdata=UnmapFile(nodesx->filename);
914 segmentsx->xdata=UnmapFile(segmentsx->filename);
915 #endif
916
917 /* Print the final message */
918
919 printf("\rIndexed Nodes: Nodes=%d \n",nodesx->number);
920 fflush(stdout);
921 }
922
923
924 /*++++++++++++++++++++++++++++++++++++++
925 Save the segment list to a file.
926
927 SegmentsX* segmentsx The set of segments to save.
928
929 const char *filename The name of the file to save.
930 ++++++++++++++++++++++++++++++++++++++*/
931
932 void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
933 {
934 index_t i;
935 int fd;
936 SegmentsFile segmentsfile;
937 int super_number=0,normal_number=0;
938
939 /* Print the start message */
940
941 printf("Writing Segments: Segments=0");
942 fflush(stdout);
943
944 /* Write out the segments data */
945
946 fd=OpenFile(filename);
947
948 SeekFile(fd,sizeof(SegmentsFile));
949
950 for(i=0;i<segmentsx->number;i++)
951 {
952 Segment *segment=LookupSegmentXSegment(segmentsx,i,1);
953
954 if(IsSuperSegment(segment))
955 super_number++;
956 if(IsNormalSegment(segment))
957 normal_number++;
958
959 WriteFile(fd,segment,sizeof(Segment));
960
961 if(!((i+1)%10000))
962 {
963 printf("\rWriting Segments: Segments=%d",i+1);
964 fflush(stdout);
965 }
966 }
967
968 /* Write out the header structure */
969
970 segmentsfile.number=segmentsx->number;
971 segmentsfile.snumber=super_number;
972 segmentsfile.nnumber=normal_number;
973
974 SeekFile(fd,0);
975 WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
976
977 CloseFile(fd);
978
979 /* Print the final message */
980
981 printf("\rWrote Segments: Segments=%d \n",segmentsx->number);
982 fflush(stdout);
983 }
984
985
986 /*++++++++++++++++++++++++++++++++++++++
987 Calculate the distance between two nodes.
988
989 distance_t DistanceX Returns the distance between the extended nodes.
990
991 NodeX *nodex1 The starting node.
992
993 NodeX *nodex2 The end node.
994 ++++++++++++++++++++++++++++++++++++++*/
995
996 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
997 {
998 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
999 double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
1000 double lat1 = latlong_to_radians(nodex1->latitude);
1001 double lat2 = latlong_to_radians(nodex2->latitude);
1002
1003 double a1,a2,a,sa,c,d;
1004
1005 if(dlon==0 && dlat==0)
1006 return 0;
1007
1008 a1 = sin (dlat / 2);
1009 a2 = sin (dlon / 2);
1010 a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
1011 sa = sqrt (a);
1012 if (sa <= 1.0)
1013 {c = 2 * asin (sa);}
1014 else
1015 {c = 2 * asin (1.0);}
1016 d = 6378.137 * c;
1017
1018 return km_to_distance(d);
1019 }

Properties

Name Value
cvs:description Extended segments functions.