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 279 - (show annotations) (download) (as text)
Thu Oct 8 19:20:29 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 23773 byte(s)
Replace node, segment and way indexes with a single index for a set of segments
containing the location of the first segment for each node.

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

Properties

Name Value
cvs:description Extended segments functions.