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 228 - (hide annotations) (download) (as text)
Sun Jul 12 09:01:48 2009 UTC (15 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 17849 byte(s)
Tidy up and fix comments and include files.

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

Properties

Name Value
cvs:description Extended segments functions.