Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/segmentsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 229 - (hide annotations) (download) (as text)
Sun Jul 19 12:54:07 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 21886 byte(s)
Store only one copy of each segment but index once for each direction.

1 amb 110 /***************************************
2 amb 229 $Header: /home/amb/CVS/routino/src/segmentsx.c,v 1.28 2009-07-19 12:54:07 amb Exp $
3 amb 110
4     Extended Segment data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 151 This file Copyright 2008,2009 Andrew M. Bishop
9 amb 110
10 amb 151 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 amb 110 ***************************************/
23    
24    
25     #include <assert.h>
26     #include <math.h>
27     #include <stdlib.h>
28     #include <stdio.h>
29    
30     #include "types.h"
31     #include "functions.h"
32     #include "nodesx.h"
33     #include "segmentsx.h"
34     #include "waysx.h"
35 amb 228 #include "nodes.h"
36     #include "segments.h"
37     #include "ways.h"
38 amb 110
39    
40     /* Constants */
41    
42 amb 229 /*+ The array size increment for SegmentsX (UK is ~7.1M raw segments, this is ~53 increments). +*/
43     #define INCREMENT_SEGMENTSX (128*1024)
44 amb 110
45    
46 amb 228 /* Local Functions */
47 amb 110
48 amb 229 static int sort_by_id1_and_distance(SegmentX **a,SegmentX **b);
49     static int sort_by_id2_and_distance(SegmentX **a,SegmentX **b);
50     static SegmentX **find_first1_segmentx(SegmentsX* segmentsx,node_t node);
51     static SegmentX **find_first2_segmentx(SegmentsX* segmentsx,node_t node);
52 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2);
53 amb 110
54    
55     /*++++++++++++++++++++++++++++++++++++++
56     Allocate a new segment list.
57    
58     SegmentsX *NewSegmentList Returns the segment list.
59     ++++++++++++++++++++++++++++++++++++++*/
60    
61     SegmentsX *NewSegmentList(void)
62     {
63     SegmentsX *segmentsx;
64    
65 amb 213 segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX));
66 amb 110
67 amb 216 segmentsx->row=-1;
68    
69 amb 110 return(segmentsx);
70     }
71    
72    
73     /*++++++++++++++++++++++++++++++++++++++
74 amb 226 Free a segment list.
75 amb 110
76     SegmentsX *segmentsx The list to be freed.
77     ++++++++++++++++++++++++++++++++++++++*/
78    
79     void FreeSegmentList(SegmentsX *segmentsx)
80     {
81 amb 213 if(segmentsx->xdata)
82 amb 222 {
83     int i;
84 amb 225 for(i=0;i<=segmentsx->row;i++)
85 amb 222 free(segmentsx->xdata[i]);
86 amb 213 free(segmentsx->xdata);
87 amb 222 }
88 amb 226
89 amb 229 if(segmentsx->n1data)
90     free(segmentsx->n1data);
91 amb 226
92 amb 229 if(segmentsx->n2data)
93     free(segmentsx->n2data);
94    
95 amb 226 if(segmentsx->sdata)
96     free(segmentsx->sdata);
97    
98 amb 110 free(segmentsx);
99     }
100    
101    
102     /*++++++++++++++++++++++++++++++++++++++
103     Save the segment list to a file.
104    
105     SegmentsX* segmentsx The set of segments to save.
106    
107     const char *filename The name of the file to save.
108     ++++++++++++++++++++++++++++++++++++++*/
109    
110     void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
111     {
112 amb 214 index_t i;
113 amb 110 int fd;
114     Segments *segments=calloc(1,sizeof(Segments));
115    
116     assert(segmentsx->sorted); /* Must be sorted */
117 amb 213 assert(segmentsx->sdata); /* Must have sdata filled in */
118 amb 110
119 amb 227 printf("Writing Segments: Segments=0");
120     fflush(stdout);
121    
122 amb 110 /* Fill in a Segments structure with the offset of the real data in the file after
123     the Segment structure itself. */
124    
125     segments->number=segmentsx->number;
126     segments->data=NULL;
127     segments->segments=(void*)sizeof(Segments);
128    
129     /* Write out the Segments structure and then the real data. */
130    
131     fd=OpenFile(filename);
132    
133     WriteFile(fd,segments,sizeof(Segments));
134    
135 amb 203 for(i=0;i<segments->number;i++)
136 amb 132 {
137 amb 209 WriteFile(fd,&segmentsx->sdata[i],sizeof(Segment));
138 amb 110
139 amb 132 if(!((i+1)%10000))
140     {
141     printf("\rWriting Segments: Segments=%d",i+1);
142     fflush(stdout);
143     }
144     }
145    
146 amb 203 printf("\rWrote Segments: Segments=%d \n",segments->number);
147 amb 132 fflush(stdout);
148    
149 amb 110 CloseFile(fd);
150    
151     /* Free the fake Segments */
152    
153     free(segments);
154     }
155    
156    
157     /*++++++++++++++++++++++++++++++++++++++
158     Find the first segment with a particular starting node.
159    
160     SegmentX **FindFirstSegmentX Returns a pointer to the first extended segment with the specified id.
161    
162     SegmentsX* segmentsx The set of segments to process.
163    
164     node_t node The node to look for.
165     ++++++++++++++++++++++++++++++++++++++*/
166    
167     SegmentX **FindFirstSegmentX(SegmentsX* segmentsx,node_t node)
168     {
169 amb 229 SegmentX **first=find_first1_segmentx(segmentsx,node);
170    
171     if(first)
172     return(first);
173    
174     return(find_first2_segmentx(segmentsx,node));
175     }
176    
177    
178     /*++++++++++++++++++++++++++++++++++++++
179     Find the first segment with a particular starting node in either n1data or n2data.
180    
181     SegmentX **find_first1_segmentx Returns a pointer to the first extended segment with the specified id.
182    
183     SegmentsX* segmentsx The set of segments to process.
184    
185     node_t node The node to look for.
186     ++++++++++++++++++++++++++++++++++++++*/
187    
188     static SegmentX **find_first1_segmentx(SegmentsX* segmentsx,node_t node)
189     {
190 amb 110 int start=0;
191     int end=segmentsx->number-1;
192     int mid;
193     int found;
194    
195     assert(segmentsx->sorted); /* Must be sorted */
196 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
197 amb 110
198     /* Binary search - search key exact match only is required.
199     *
200     * # <- start | Check mid and move start or end if it doesn't match
201     * # |
202     * # | Since an exact match is wanted we can set end=mid-1
203     * # <- mid | or start=mid+1 because we know that mid doesn't match.
204     * # |
205     * # | Eventually either end=start or end=start+1 and one of
206     * # <- end | start or end is the wanted one.
207     */
208    
209 amb 229 if(end<start) /* There are no nodes */
210 amb 110 return(NULL);
211 amb 229 else if(node<segmentsx->n1data[start]->node1) /* Check key is not before start */
212 amb 110 return(NULL);
213 amb 229 else if(node>segmentsx->n1data[end]->node1) /* Check key is not after end */
214 amb 110 return(NULL);
215     else
216     {
217     do
218     {
219 amb 229 mid=(start+end)/2; /* Choose mid point */
220 amb 110
221 amb 229 if(segmentsx->n1data[mid]->node1<node) /* Mid point is too low */
222 amb 110 start=mid;
223 amb 229 else if(segmentsx->n1data[mid]->node1>node) /* Mid point is too high */
224 amb 110 end=mid;
225 amb 229 else /* Mid point is correct */
226 amb 110 {found=mid; goto found;}
227     }
228     while((end-start)>1);
229    
230 amb 229 if(segmentsx->n1data[start]->node1==node) /* Start is correct */
231 amb 110 {found=start; goto found;}
232    
233 amb 229 if(segmentsx->n1data[end]->node1==node) /* End is correct */
234 amb 110 {found=end; goto found;}
235     }
236    
237     return(NULL);
238    
239     found:
240    
241 amb 229 while(found>0 && segmentsx->n1data[found-1]->node1==node)
242 amb 110 found--;
243    
244 amb 229 return(&segmentsx->n1data[found]);
245 amb 110 }
246    
247    
248     /*++++++++++++++++++++++++++++++++++++++
249 amb 229 Find the first segment with a particular starting node in node2.
250    
251     SegmentX **find_first2_segmentx Returns a pointer to the first extended segment with the specified id.
252    
253     SegmentsX* segmentsx The set of segments to process.
254    
255     node_t node The node to look for.
256     ++++++++++++++++++++++++++++++++++++++*/
257    
258     static SegmentX **find_first2_segmentx(SegmentsX* segmentsx,node_t node)
259     {
260     int start=0;
261     int end=segmentsx->number-1;
262     int mid;
263     int found;
264    
265     assert(segmentsx->sorted); /* Must be sorted */
266     assert(segmentsx->n2data); /* Must have n2data filled in */
267    
268     /* Binary search - search key exact match only is required.
269     *
270     * # <- start | Check mid and move start or end if it doesn't match
271     * # |
272     * # | Since an exact match is wanted we can set end=mid-1
273     * # <- mid | or start=mid+1 because we know that mid doesn't match.
274     * # |
275     * # | Eventually either end=start or end=start+1 and one of
276     * # <- end | start or end is the wanted one.
277     */
278    
279     if(end<start) /* There are no nodes */
280     return(NULL);
281     else if(node<segmentsx->n2data[start]->node2) /* Check key is not before start */
282     return(NULL);
283     else if(node>segmentsx->n2data[end]->node2) /* Check key is not after end */
284     return(NULL);
285     else
286     {
287     do
288     {
289     mid=(start+end)/2; /* Choose mid point */
290    
291     if(segmentsx->n2data[mid]->node2<node) /* Mid point is too low */
292     start=mid;
293     else if(segmentsx->n2data[mid]->node2>node) /* Mid point is too high */
294     end=mid;
295     else /* Mid point is correct */
296     {found=mid; goto found;}
297     }
298     while((end-start)>1);
299    
300     if(segmentsx->n2data[start]->node2==node) /* Start is correct */
301     {found=start; goto found;}
302    
303     if(segmentsx->n2data[end]->node2==node) /* End is correct */
304     {found=end; goto found;}
305     }
306    
307     return(NULL);
308    
309     found:
310    
311     while(found>0 && segmentsx->n2data[found-1]->node2==node)
312     found--;
313    
314     return(&segmentsx->n2data[found]);
315     }
316    
317    
318     /*++++++++++++++++++++++++++++++++++++++
319 amb 110 Find the next segment with a particular starting node.
320    
321     SegmentX **FindNextSegmentX Returns a pointer to the next segment with the same id.
322    
323     SegmentsX* segmentsx The set of segments to process.
324    
325     SegmentX **segmentx The current segment.
326     ++++++++++++++++++++++++++++++++++++++*/
327    
328     SegmentX **FindNextSegmentX(SegmentsX* segmentsx,SegmentX **segmentx)
329     {
330 amb 229 if((segmentsx->n1data<segmentsx->n2data && segmentx<segmentsx->n2data) ||
331     (segmentsx->n1data>segmentsx->n2data && segmentx>segmentsx->n1data))
332     {
333     SegmentX **next=segmentx+1;
334 amb 110
335 amb 229 if((next-segmentsx->n1data)==segmentsx->number)
336     return(find_first2_segmentx(segmentsx,(*segmentx)->node1));
337 amb 110
338 amb 229 if((*next)->node1==(*segmentx)->node1)
339     return(next);
340 amb 110
341 amb 229 return(find_first2_segmentx(segmentsx,(*segmentx)->node1));
342     }
343     else
344     {
345     SegmentX **next=segmentx+1;
346    
347     if((next-segmentsx->n2data)==segmentsx->number)
348     return(NULL);
349    
350     if((*next)->node2==(*segmentx)->node2)
351     return(next);
352    
353     return(NULL);
354     }
355 amb 110 }
356    
357    
358     /*++++++++++++++++++++++++++++++++++++++
359     Append a segment to a segment list.
360    
361     SegmentsX* segmentsx The set of segments to process.
362    
363 amb 203 way_t way The way that the segment belongs to.
364    
365 amb 110 node_t node1 The first node in the segment.
366    
367     node_t node2 The second node in the segment.
368 amb 228
369     distance_t distance The distance between the nodes (or just the flags).
370 amb 110 ++++++++++++++++++++++++++++++++++++++*/
371    
372 amb 209 void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,distance_t distance)
373 amb 110 {
374     /* Check that the array has enough space. */
375    
376 amb 216 if(segmentsx->row==-1 || segmentsx->col==INCREMENT_SEGMENTSX)
377 amb 110 {
378 amb 216 segmentsx->row++;
379     segmentsx->col=0;
380 amb 110
381 amb 216 if((segmentsx->row%16)==0)
382     segmentsx->xdata=(SegmentX**)realloc((void*)segmentsx->xdata,(segmentsx->row+16)*sizeof(SegmentX*));
383    
384     segmentsx->xdata[segmentsx->row]=(SegmentX*)malloc(INCREMENT_SEGMENTSX*sizeof(SegmentX));
385 amb 110 }
386    
387     /* Insert the segment */
388    
389 amb 216 segmentsx->xdata[segmentsx->row][segmentsx->col].way=way;
390     segmentsx->xdata[segmentsx->row][segmentsx->col].distance=distance;
391 amb 110
392 amb 229 if(node1>node2)
393     {
394     segmentsx->xdata[segmentsx->row][segmentsx->col].node1=node2;
395     segmentsx->xdata[segmentsx->row][segmentsx->col].node2=node1;
396     if(distance&(ONEWAY_2TO1|ONEWAY_1TO2))
397     segmentsx->xdata[segmentsx->row][segmentsx->col].distance^=(ONEWAY_2TO1|ONEWAY_1TO2);
398     }
399     else
400     {
401     segmentsx->xdata[segmentsx->row][segmentsx->col].node1=node1;
402     segmentsx->xdata[segmentsx->row][segmentsx->col].node2=node2;
403     }
404    
405 amb 216 segmentsx->col++;
406 amb 110
407     segmentsx->sorted=0;
408     }
409    
410    
411     /*++++++++++++++++++++++++++++++++++++++
412     Sort the segment list.
413    
414     SegmentsX* segmentsx The set of segments to process.
415     ++++++++++++++++++++++++++++++++++++++*/
416    
417     void SortSegmentList(SegmentsX* segmentsx)
418     {
419 amb 214 index_t i;
420 amb 110
421 amb 213 assert(segmentsx->xdata); /* Must have xdata filled in */
422    
423 amb 227 printf("Sorting Segments");
424     fflush(stdout);
425 amb 132
426 amb 213 /* Allocate the array of pointers and sort them */
427 amb 110
428 amb 229 segmentsx->n1data=(SegmentX**)realloc(segmentsx->n1data,(segmentsx->row*INCREMENT_SEGMENTSX+segmentsx->col)*sizeof(SegmentX*));
429     segmentsx->n2data=(SegmentX**)realloc(segmentsx->n2data,(segmentsx->row*INCREMENT_SEGMENTSX+segmentsx->col)*sizeof(SegmentX*));
430 amb 110
431     segmentsx->number=0;
432    
433 amb 216 for(i=0;i<(segmentsx->row*INCREMENT_SEGMENTSX+segmentsx->col);i++)
434     if(segmentsx->xdata[i/INCREMENT_SEGMENTSX][i%INCREMENT_SEGMENTSX].node1!=NO_NODE)
435 amb 110 {
436 amb 229 segmentsx->n1data[segmentsx->number]=&segmentsx->xdata[i/INCREMENT_SEGMENTSX][i%INCREMENT_SEGMENTSX];
437     segmentsx->n2data[segmentsx->number]=&segmentsx->xdata[i/INCREMENT_SEGMENTSX][i%INCREMENT_SEGMENTSX];
438 amb 110 segmentsx->number++;
439     }
440    
441 amb 229 qsort(segmentsx->n1data,segmentsx->number,sizeof(SegmentX*),(int (*)(const void*,const void*))sort_by_id1_and_distance);
442     qsort(segmentsx->n2data,segmentsx->number,sizeof(SegmentX*),(int (*)(const void*,const void*))sort_by_id2_and_distance);
443 amb 110
444 amb 227 printf("\rSorted Segments \n");
445     fflush(stdout);
446 amb 213
447 amb 110 segmentsx->sorted=1;
448     }
449    
450    
451     /*++++++++++++++++++++++++++++++++++++++
452 amb 229 Sort the segments into id order (node1 then node2) and then distance order.
453 amb 110
454 amb 229 int sort_by_id1_and_distance Returns the comparison of the node fields.
455 amb 110
456     SegmentX **a The first Segment.
457    
458     SegmentX **b The second Segment.
459     ++++++++++++++++++++++++++++++++++++++*/
460    
461 amb 229 static int sort_by_id1_and_distance(SegmentX **a,SegmentX **b)
462 amb 110 {
463     node_t a_id1=(*a)->node1;
464     node_t b_id1=(*b)->node1;
465    
466     if(a_id1<b_id1)
467     return(-1);
468     else if(a_id1>b_id1)
469     return(1);
470     else /* if(a_id1==b_id1) */
471     {
472     node_t a_id2=(*a)->node2;
473     node_t b_id2=(*b)->node2;
474    
475     if(a_id2<b_id2)
476     return(-1);
477     else if(a_id2>b_id2)
478     return(1);
479     else
480     {
481 amb 229 distance_t a_distance=(*a)->distance;
482     distance_t b_distance=(*b)->distance;
483 amb 110
484     if(a_distance<b_distance)
485     return(-1);
486     else if(a_distance>b_distance)
487     return(1);
488     else
489     return(0);
490     }
491     }
492     }
493    
494    
495     /*++++++++++++++++++++++++++++++++++++++
496 amb 229 Sort the segments into id order (node2 then node1) and then distance order.
497    
498     int sort_by_id2_and_distance Returns the comparison of the node fields.
499    
500     SegmentX **a The first Segment.
501    
502     SegmentX **b The second Segment.
503     ++++++++++++++++++++++++++++++++++++++*/
504    
505     static int sort_by_id2_and_distance(SegmentX **a,SegmentX **b)
506     {
507     node_t a_id2=(*a)->node2;
508     node_t b_id2=(*b)->node2;
509    
510     if(a_id2<b_id2)
511     return(-1);
512     else if(a_id2>b_id2)
513     return(1);
514     else /* if(a_id2==b_id2) */
515     {
516     node_t a_id1=(*a)->node1;
517     node_t b_id1=(*b)->node1;
518    
519     if(a_id1<b_id1)
520     return(-1);
521     else if(a_id1>b_id1)
522     return(1);
523     else
524     {
525     distance_t a_distance=(*a)->distance;
526     distance_t b_distance=(*b)->distance;
527    
528     if(a_distance<b_distance)
529     return(-1);
530     else if(a_distance>b_distance)
531     return(1);
532     else
533     return(0);
534     }
535     }
536     }
537    
538    
539     /*++++++++++++++++++++++++++++++++++++++
540 amb 110 Remove bad segments (zero length or duplicated).
541    
542 amb 195 NodesX *nodesx The nodes to check.
543    
544 amb 110 SegmentsX *segmentsx The segments to modify.
545     ++++++++++++++++++++++++++++++++++++++*/
546    
547 amb 204 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
548 amb 110 {
549 amb 214 index_t i;
550 amb 195 int duplicate=0,loop=0,missing=0;
551 amb 110
552 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
553 amb 110
554 amb 227 printf("Checking: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
555     fflush(stdout);
556    
557 amb 110 for(i=0;i<segmentsx->number;i++)
558     {
559 amb 229 if(i && segmentsx->n1data[i]->node1==segmentsx->n1data[i-1]->node1 &&
560     segmentsx->n1data[i]->node2==segmentsx->n1data[i-1]->node2)
561 amb 110 {
562     duplicate++;
563 amb 229 segmentsx->n1data[i-1]->node1=NO_NODE;
564 amb 110 }
565 amb 229 else if(segmentsx->n1data[i]->node1==segmentsx->n1data[i]->node2)
566 amb 110 {
567     loop++;
568 amb 229 segmentsx->n1data[i]->node1=NO_NODE;
569 amb 110 }
570 amb 229 else if(!FindNodeX(nodesx,segmentsx->n1data[i]->node1) ||
571     !FindNodeX(nodesx,segmentsx->n1data[i]->node2))
572 amb 195 {
573     missing++;
574 amb 229 segmentsx->n1data[i]->node1=NO_NODE;
575 amb 195 }
576 amb 110
577     if(!((i+1)%10000))
578     {
579 amb 195 printf("\rChecking: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",i+1,duplicate,loop,missing);
580 amb 110 fflush(stdout);
581     }
582     }
583    
584 amb 195 printf("\rChecked: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d \n",segmentsx->number,duplicate,loop,missing);
585 amb 110 fflush(stdout);
586     }
587    
588    
589     /*++++++++++++++++++++++++++++++++++++++
590     Measure the segments.
591    
592     SegmentsX* segmentsx The set of segments to process.
593    
594     NodesX *nodesx The list of nodes to use.
595     ++++++++++++++++++++++++++++++++++++++*/
596    
597     void MeasureSegments(SegmentsX* segmentsx,NodesX *nodesx)
598     {
599 amb 214 index_t i;
600 amb 110
601 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
602 amb 110
603 amb 227 printf("Measuring Segments: Segments=0");
604     fflush(stdout);
605    
606 amb 110 for(i=0;i<segmentsx->number;i++)
607     {
608 amb 229 NodeX **nodex1=FindNodeX(nodesx,segmentsx->n1data[i]->node1);
609     NodeX **nodex2=FindNodeX(nodesx,segmentsx->n1data[i]->node2);
610 amb 110
611     /* Set the distance but preserve the ONEWAY_* flags */
612    
613 amb 229 segmentsx->n1data[i]->distance|=DISTANCE(DistanceX(*nodex1,*nodex2));
614 amb 110
615     if(!((i+1)%10000))
616     {
617     printf("\rMeasuring Segments: Segments=%d",i+1);
618     fflush(stdout);
619     }
620     }
621    
622     printf("\rMeasured Segments: Segments=%d \n",segmentsx->number);
623     fflush(stdout);
624     }
625    
626    
627     /*++++++++++++++++++++++++++++++++++++++
628     Mark the duplicate segments.
629    
630     SegmentsX* segmentsx The set of segments to process.
631    
632     WaysX *waysx The list of ways to use.
633     ++++++++++++++++++++++++++++++++++++++*/
634    
635 amb 212 void DeduplicateSegments(SegmentsX* segmentsx,WaysX *waysx)
636 amb 110 {
637 amb 214 index_t i;
638     int duplicate=0;
639 amb 110
640 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
641 amb 110
642 amb 227 printf("Deduplicating Segments: Segments=0 Duplicate=0");
643     fflush(stdout);
644    
645 amb 110 for(i=1;i<segmentsx->number;i++)
646     {
647 amb 229 if(segmentsx->n1data[i]->node1==segmentsx->n1data[i-1]->node1 &&
648     segmentsx->n1data[i]->node2==segmentsx->n1data[i-1]->node2 &&
649     DISTFLAG(segmentsx->n1data[i]->distance)==DISTFLAG(segmentsx->n1data[i-1]->distance))
650 amb 110 {
651 amb 229 WayX *wayx1=FindWayX(waysx,segmentsx->n1data[i-1]->way);
652     WayX *wayx2=FindWayX(waysx,segmentsx->n1data[i ]->way);
653 amb 110
654 amb 204 if(!WaysCompare(wayx1->way,wayx2->way))
655 amb 110 {
656 amb 229 segmentsx->n1data[i-1]->node1=NO_NODE;
657 amb 110
658     duplicate++;
659     }
660     }
661    
662     if(!((i+1)%10000))
663     {
664     printf("\rDeduplicating Segments: Segments=%d Duplicate=%d",i+1,duplicate);
665     fflush(stdout);
666     }
667     }
668    
669 amb 229 printf("\rDeduplicated Segments: Segments=%d Duplicate=%d Unique=%d\n",segmentsx->number,duplicate,segmentsx->number-duplicate);
670 amb 110 fflush(stdout);
671     }
672    
673    
674     /*++++++++++++++++++++++++++++++++++++++
675 amb 209 Create the real segments data.
676    
677     SegmentsX* segmentsx The set of segments to use.
678    
679     WaysX* waysx The set of ways to use.
680     ++++++++++++++++++++++++++++++++++++++*/
681    
682     void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
683     {
684 amb 214 index_t i;
685 amb 209
686 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
687 amb 213
688 amb 227 printf("Creating Real Segments: Segments=0");
689     fflush(stdout);
690    
691 amb 209 /* Allocate the memory */
692    
693     segmentsx->sdata=(Segment*)malloc(segmentsx->number*sizeof(Segment));
694    
695     /* Loop through and allocate. */
696    
697     for(i=0;i<segmentsx->number;i++)
698     {
699 amb 229 WayX *wayx=FindWayX(waysx,segmentsx->n1data[i]->way);
700 amb 209
701     segmentsx->sdata[i].node1=0;
702     segmentsx->sdata[i].node2=0;
703     segmentsx->sdata[i].next2=NO_NODE;
704 amb 216 segmentsx->sdata[i].way=IndexWayInWaysX(waysx,wayx);
705 amb 229 segmentsx->sdata[i].distance=segmentsx->n1data[i]->distance;
706 amb 209
707     if(!((i+1)%10000))
708     {
709     printf("\rCreating Real Segments: Segments=%d",i+1);
710     fflush(stdout);
711     }
712     }
713    
714     printf("\rCreating Real Segments: Segments=%d \n",segmentsx->number);
715     fflush(stdout);
716     }
717    
718    
719     /*++++++++++++++++++++++++++++++++++++++
720 amb 110 Assign the nodes indexes to the segments.
721    
722     SegmentsX* segmentsx The set of segments to process.
723    
724     NodesX *nodesx The list of nodes to use.
725     ++++++++++++++++++++++++++++++++++++++*/
726    
727     void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
728     {
729 amb 214 index_t i;
730 amb 110
731     assert(segmentsx->sorted); /* Must be sorted */
732 amb 229 assert(segmentsx->n1data); /* Must have n1data filled in */
733 amb 213 assert(segmentsx->sdata); /* Must have sdata filled in */
734 amb 110 assert(nodesx->sorted); /* Must be sorted */
735 amb 213 assert(nodesx->gdata); /* Must have gdata filled in */
736 amb 110
737 amb 227 printf("Indexing Nodes: Nodes=0");
738     fflush(stdout);
739    
740 amb 110 /* Index the segments */
741    
742     for(i=0;i<nodesx->number;i++)
743     {
744 amb 212 NodeX **nodex=FindNodeX(nodesx,nodesx->gdata[i]->id);
745     Node *node =&nodesx->ndata[nodex-nodesx->idata];
746     index_t index=SEGMENT(node->firstseg);
747 amb 110
748     do
749     {
750 amb 229 if(segmentsx->n1data[index]->node1==nodesx->gdata[i]->id)
751 amb 110 {
752 amb 209 segmentsx->sdata[index].node1=i;
753 amb 110
754 amb 209 index++;
755 amb 128
756 amb 229 if(index>=segmentsx->number || segmentsx->n1data[index]->node1!=nodesx->gdata[i]->id)
757 amb 209 break;
758 amb 110 }
759     else
760     {
761 amb 209 segmentsx->sdata[index].node2=i;
762 amb 110
763 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
764     break;
765 amb 110 else
766 amb 209 index=segmentsx->sdata[index].next2;
767 amb 110 }
768     }
769 amb 209 while(1);
770 amb 110
771     if(!((i+1)%10000))
772     {
773     printf("\rIndexing Nodes: Nodes=%d",i+1);
774     fflush(stdout);
775     }
776     }
777    
778     printf("\rIndexed Nodes: Nodes=%d \n",nodesx->number);
779     fflush(stdout);
780     }
781    
782    
783     /*++++++++++++++++++++++++++++++++++++++
784     Calculate the distance between two nodes.
785    
786     distance_t DistanceX Returns the distance between the extended nodes.
787    
788     NodeX *nodex1 The starting node.
789    
790     NodeX *nodex2 The end node.
791     ++++++++++++++++++++++++++++++++++++++*/
792    
793 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
794 amb 110 {
795 amb 223 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
796     double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
797     double lat1 = latlong_to_radians(nodex1->latitude);
798     double lat2 = latlong_to_radians(nodex2->latitude);
799 amb 110
800 amb 219 double a1,a2,a,sa,c,d;
801 amb 110
802     if(dlon==0 && dlat==0)
803     return 0;
804    
805 amb 219 a1 = sin (dlat / 2);
806     a2 = sin (dlon / 2);
807     a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
808     sa = sqrt (a);
809 amb 110 if (sa <= 1.0)
810 amb 219 {c = 2 * asin (sa);}
811 amb 110 else
812 amb 219 {c = 2 * asin (1.0);}
813 amb 110 d = 6378.137 * c;
814    
815     return km_to_distance(d);
816     }

Properties

Name Value
cvs:description Extended segments functions.