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 285 - (show annotations) (download) (as text)
Mon Oct 12 17:54:18 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 24237 byte(s)
Re-order the functions in the file into a more logical order.
No functional changes.

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

Properties

Name Value
cvs:description Extended segments functions.