Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/segments.c
Parent Directory
|
Revision Log
Revision 100 -
(hide annotations)
(download)
(as text)
Wed Feb 4 18:26:29 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 15197 byte(s)
Wed Feb 4 18:26:29 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 15197 byte(s)
Make sure that nodes, segments and ways could be loaded.
1 | amb | 2 | /*************************************** |
2 | amb | 100 | $Header: /home/amb/CVS/routino/src/segments.c,v 1.29 2009-02-04 18:26:29 amb Exp $ |
3 | amb | 2 | |
4 | Segment data type functions. | ||
5 | ******************/ /****************** | ||
6 | Written by Andrew M. Bishop | ||
7 | |||
8 | amb | 4 | This file Copyright 2008,2009 Andrew M. Bishop |
9 | amb | 2 | It may be distributed under the GNU Public License, version 2, or |
10 | any higher version. See section COPYING of the GNU Public license | ||
11 | for conditions under which this file may be redistributed. | ||
12 | ***************************************/ | ||
13 | |||
14 | |||
15 | amb | 8 | #include <assert.h> |
16 | amb | 2 | #include <math.h> |
17 | #include <stdlib.h> | ||
18 | |||
19 | amb | 39 | #include "nodes.h" |
20 | amb | 26 | #include "segments.h" |
21 | amb | 2 | #include "functions.h" |
22 | |||
23 | |||
24 | amb | 96 | /* Constants */ |
25 | |||
26 | /*+ The array size increment for segments - expect ~8,000,000 segments. +*/ | ||
27 | #define INCREMENT_SEGMENTS 1024*1024 | ||
28 | |||
29 | |||
30 | amb | 23 | /* Functions */ |
31 | amb | 2 | |
32 | amb | 97 | static int sort_by_id(SegmentX *a,SegmentX *b); |
33 | amb | 2 | |
34 | amb | 8 | |
35 | amb | 23 | /*++++++++++++++++++++++++++++++++++++++ |
36 | amb | 2 | Load in a segment list from a file. |
37 | |||
38 | amb | 23 | Segments* SaveSegmentList Returns the segment list that has just been loaded. |
39 | |||
40 | amb | 2 | const char *filename The name of the file to load. |
41 | ++++++++++++++++++++++++++++++++++++++*/ | ||
42 | |||
43 | amb | 23 | Segments *LoadSegmentList(const char *filename) |
44 | amb | 2 | { |
45 | amb | 88 | void *data; |
46 | Segments *segments; | ||
47 | |||
48 | segments=(Segments*)malloc(sizeof(Segments)); | ||
49 | |||
50 | data=MapFile(filename); | ||
51 | |||
52 | amb | 100 | if(!data) |
53 | return(NULL); | ||
54 | |||
55 | amb | 88 | /* Copy the Segments structure from the loaded data */ |
56 | |||
57 | *segments=*((Segments*)data); | ||
58 | |||
59 | /* Adjust the pointers in the Segments structure. */ | ||
60 | |||
61 | segments->data =data; | ||
62 | segments->segments=(Segment*)(data+(off_t)segments->segments); | ||
63 | |||
64 | return(segments); | ||
65 | amb | 2 | } |
66 | |||
67 | |||
68 | /*++++++++++++++++++++++++++++++++++++++ | ||
69 | amb | 97 | Allocate a new segment list. |
70 | |||
71 | SegmentsX *NewSegmentList Returns the segment list. | ||
72 | ++++++++++++++++++++++++++++++++++++++*/ | ||
73 | |||
74 | SegmentsX *NewSegmentList(void) | ||
75 | { | ||
76 | SegmentsX *segmentsx; | ||
77 | |||
78 | segmentsx=(SegmentsX*)malloc(sizeof(SegmentsX)); | ||
79 | |||
80 | segmentsx->sorted=0; | ||
81 | segmentsx->alloced=INCREMENT_SEGMENTS; | ||
82 | segmentsx->number=0; | ||
83 | |||
84 | segmentsx->xdata=(SegmentX*)malloc(segmentsx->alloced*sizeof(SegmentX)); | ||
85 | |||
86 | return(segmentsx); | ||
87 | } | ||
88 | |||
89 | |||
90 | /*++++++++++++++++++++++++++++++++++++++ | ||
91 | Free a segment list. | ||
92 | |||
93 | SegmentsX *segmentsx The list to be freed. | ||
94 | ++++++++++++++++++++++++++++++++++++++*/ | ||
95 | |||
96 | void FreeSegmentList(SegmentsX *segmentsx) | ||
97 | { | ||
98 | free(segmentsx->xdata); | ||
99 | free(segmentsx); | ||
100 | } | ||
101 | |||
102 | |||
103 | /*++++++++++++++++++++++++++++++++++++++ | ||
104 | amb | 2 | Save the segment list to a file. |
105 | |||
106 | amb | 97 | SegmentsX* segmentsx The set of segments to save. |
107 | amb | 23 | |
108 | amb | 2 | const char *filename The name of the file to save. |
109 | ++++++++++++++++++++++++++++++++++++++*/ | ||
110 | |||
111 | amb | 97 | void SaveSegmentList(SegmentsX* segmentsx,const char *filename) |
112 | amb | 2 | { |
113 | amb | 88 | int i; |
114 | int fd; | ||
115 | Segments *segments=calloc(1,sizeof(Segments)); | ||
116 | amb | 2 | |
117 | amb | 97 | assert(segmentsx->sorted); /* Must be sorted */ |
118 | amb | 23 | |
119 | amb | 88 | /* Fill in a Segments structure with the offset of the real data in the file after |
120 | the Segment structure itself. */ | ||
121 | |||
122 | amb | 97 | segments->number=segmentsx->number; |
123 | amb | 88 | segments->data=NULL; |
124 | segments->segments=(void*)sizeof(Segments); | ||
125 | |||
126 | /* Write out the Segments structure and then the real data. */ | ||
127 | |||
128 | fd=OpenFile(filename); | ||
129 | |||
130 | amb | 97 | WriteFile(fd,segments,sizeof(Segments)); |
131 | amb | 88 | |
132 | amb | 97 | for(i=0;i<segmentsx->number;i++) |
133 | WriteFile(fd,&segmentsx->xdata[i].segment,sizeof(Segment)); | ||
134 | amb | 88 | |
135 | amb | 97 | CloseFile(fd); |
136 | amb | 88 | |
137 | amb | 89 | /* Free the fake Segments */ |
138 | amb | 88 | |
139 | amb | 23 | free(segments); |
140 | amb | 2 | } |
141 | |||
142 | |||
143 | /*++++++++++++++++++++++++++++++++++++++ | ||
144 | Find the first segment with a particular starting node. | ||
145 | |||
146 | amb | 98 | SegmentX *FindFirstSegmentX Returns the first extended segment with the specified id. |
147 | amb | 2 | |
148 | amb | 97 | SegmentsX* segmentsx The set of segments to process. |
149 | amb | 23 | |
150 | amb | 2 | node_t node The node to look for. |
151 | ++++++++++++++++++++++++++++++++++++++*/ | ||
152 | |||
153 | amb | 98 | SegmentX *FindFirstSegmentX(SegmentsX* segmentsx,node_t node) |
154 | amb | 2 | { |
155 | amb | 88 | int start=0; |
156 | amb | 97 | int end=segmentsx->number-1; |
157 | amb | 2 | int mid; |
158 | int found; | ||
159 | |||
160 | /* Binary search - search key exact match only is required. | ||
161 | * | ||
162 | * # <- start | Check mid and move start or end if it doesn't match | ||
163 | * # | | ||
164 | * # | Since an exact match is wanted we can set end=mid-1 | ||
165 | * # <- mid | or start=mid+1 because we know that mid doesn't match. | ||
166 | * # | | ||
167 | * # | Eventually either end=start or end=start+1 and one of | ||
168 | * # <- end | start or end is the wanted one. | ||
169 | */ | ||
170 | |||
171 | amb | 23 | if(end<start) /* There are no nodes */ |
172 | amb | 89 | return(NULL); |
173 | amb | 97 | else if(node<segmentsx->xdata[start].node1) /* Check key is not before start */ |
174 | amb | 89 | return(NULL); |
175 | amb | 97 | else if(node>segmentsx->xdata[end].node1) /* Check key is not after end */ |
176 | amb | 89 | return(NULL); |
177 | amb | 2 | else |
178 | { | ||
179 | do | ||
180 | { | ||
181 | amb | 23 | mid=(start+end)/2; /* Choose mid point */ |
182 | amb | 2 | |
183 | amb | 97 | if(segmentsx->xdata[mid].node1<node) /* Mid point is too low */ |
184 | amb | 2 | start=mid; |
185 | amb | 97 | else if(segmentsx->xdata[mid].node1>node) /* Mid point is too high */ |
186 | amb | 2 | end=mid; |
187 | amb | 23 | else /* Mid point is correct */ |
188 | amb | 2 | {found=mid; goto found;} |
189 | } | ||
190 | while((end-start)>1); | ||
191 | |||
192 | amb | 97 | if(segmentsx->xdata[start].node1==node) /* Start is correct */ |
193 | amb | 2 | {found=start; goto found;} |
194 | |||
195 | amb | 97 | if(segmentsx->xdata[end].node1==node) /* End is correct */ |
196 | amb | 2 | {found=end; goto found;} |
197 | } | ||
198 | |||
199 | amb | 89 | return(NULL); |
200 | amb | 2 | |
201 | found: | ||
202 | |||
203 | amb | 97 | while(found>0 && segmentsx->xdata[found-1].node1==node) |
204 | amb | 2 | found--; |
205 | |||
206 | amb | 97 | return(&segmentsx->xdata[found]); |
207 | amb | 2 | } |
208 | |||
209 | |||
210 | /*++++++++++++++++++++++++++++++++++++++ | ||
211 | Find the next segment with a particular starting node. | ||
212 | |||
213 | amb | 98 | SegmentX *FindNextSegmentX Returns a pointer to the next segment with the same id. |
214 | amb | 89 | |
215 | amb | 98 | SegmentsX* segmentss The set of segments to process. |
216 | amb | 89 | |
217 | amb | 98 | SegmentX *segmentx The current segment. |
218 | amb | 89 | ++++++++++++++++++++++++++++++++++++++*/ |
219 | |||
220 | amb | 98 | SegmentX *FindNextSegmentX(SegmentsX* segmentsx,SegmentX *segmentx) |
221 | amb | 89 | { |
222 | amb | 98 | SegmentX *next=segmentx+1; |
223 | amb | 89 | |
224 | amb | 97 | if(IndexSegmentX(segmentsx,next)==segmentsx->number) |
225 | amb | 89 | return(NULL); |
226 | |||
227 | amb | 98 | if(next->node1==segmentx->node1) |
228 | amb | 89 | return(next); |
229 | |||
230 | return(NULL); | ||
231 | } | ||
232 | |||
233 | |||
234 | /*++++++++++++++++++++++++++++++++++++++ | ||
235 | Find the next segment with a particular starting node. | ||
236 | |||
237 | amb | 88 | Segment *NextSegment Returns a pointer to the next segment with the same id. |
238 | amb | 2 | |
239 | amb | 23 | Segments* segments The set of segments to process. |
240 | |||
241 | amb | 2 | Segment *segment The current segment. |
242 | ++++++++++++++++++++++++++++++++++++++*/ | ||
243 | |||
244 | amb | 88 | Segment *NextSegment(Segments* segments,Segment *segment) |
245 | amb | 2 | { |
246 | Segment *next=segment+1; | ||
247 | |||
248 | amb | 89 | if(IndexSegment(segments,next)==segments->number) |
249 | amb | 23 | return(NULL); |
250 | amb | 2 | |
251 | amb | 90 | if(NODE(next->node1)==NODE(segment->node1)) |
252 | amb | 2 | return(next); |
253 | |||
254 | return(NULL); | ||
255 | amb | 89 | } |
256 | amb | 88 | |
257 | |||
258 | amb | 2 | /*++++++++++++++++++++++++++++++++++++++ |
259 | amb | 98 | Append a segment to a segment list. |
260 | amb | 2 | |
261 | amb | 98 | Segment *AppendSegmentX Returns the appended segment. |
262 | amb | 31 | |
263 | amb | 97 | SegmentsX* segmentsx The set of segments to process. |
264 | amb | 23 | |
265 | amb | 2 | node_t node1 The first node in the segment. |
266 | |||
267 | node_t node2 The second node in the segment. | ||
268 | ++++++++++++++++++++++++++++++++++++++*/ | ||
269 | |||
270 | amb | 98 | Segment *AppendSegment(SegmentsX* segmentsx,node_t node1,node_t node2) |
271 | amb | 2 | { |
272 | amb | 23 | /* Check that the array has enough space. */ |
273 | amb | 8 | |
274 | amb | 97 | if(segmentsx->number==segmentsx->alloced) |
275 | amb | 4 | { |
276 | amb | 97 | segmentsx->alloced+=INCREMENT_SEGMENTS; |
277 | amb | 4 | |
278 | amb | 97 | segmentsx->xdata=(SegmentX*)realloc((void*)segmentsx->xdata,segmentsx->alloced*sizeof(SegmentX)); |
279 | amb | 4 | } |
280 | |||
281 | /* Insert the segment */ | ||
282 | |||
283 | amb | 97 | segmentsx->xdata[segmentsx->number].node1=node1; |
284 | segmentsx->xdata[segmentsx->number].node2=node2; | ||
285 | amb | 98 | |
286 | amb | 97 | segmentsx->xdata[segmentsx->number].segment.distance=0; |
287 | amb | 2 | |
288 | amb | 97 | segmentsx->number++; |
289 | amb | 2 | |
290 | amb | 97 | segmentsx->sorted=0; |
291 | amb | 31 | |
292 | amb | 98 | return(&segmentsx->xdata[segmentsx->number-1].segment); |
293 | amb | 2 | } |
294 | |||
295 | |||
296 | /*++++++++++++++++++++++++++++++++++++++ | ||
297 | Sort the segment list. | ||
298 | amb | 23 | |
299 | amb | 97 | SegmentsX* segmentsx The set of segments to process. |
300 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
301 | |||
302 | amb | 97 | void SortSegmentList(SegmentsX* segmentsx) |
303 | amb | 2 | { |
304 | amb | 97 | qsort(segmentsx->xdata,segmentsx->number,sizeof(SegmentX),(int (*)(const void*,const void*))sort_by_id); |
305 | amb | 39 | |
306 | amb | 97 | while(segmentsx->xdata[segmentsx->number-1].node1==~0) |
307 | segmentsx->number--; | ||
308 | amb | 8 | |
309 | amb | 97 | segmentsx->sorted=1; |
310 | amb | 2 | } |
311 | |||
312 | |||
313 | /*++++++++++++++++++++++++++++++++++++++ | ||
314 | Sort the segments into id order. | ||
315 | |||
316 | int sort_by_id Returns the comparison of the node fields. | ||
317 | |||
318 | amb | 97 | SegmentX *a The first Segment. |
319 | amb | 2 | |
320 | amb | 97 | SegmentX *b The second Segment. |
321 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
322 | |||
323 | amb | 97 | static int sort_by_id(SegmentX *a,SegmentX *b) |
324 | amb | 2 | { |
325 | node_t a_id1=a->node1,a_id2=a->node2; | ||
326 | node_t b_id1=b->node1,b_id2=b->node2; | ||
327 | |||
328 | amb | 39 | if(a_id1<b_id1) |
329 | return(-1); | ||
330 | else if(a_id1>b_id1) | ||
331 | return(1); | ||
332 | else /* if(a_id1==b_id1) */ | ||
333 | { | ||
334 | if(a_id2<b_id2) | ||
335 | return(-1); | ||
336 | amb | 88 | else |
337 | amb | 39 | return(1); |
338 | } | ||
339 | amb | 2 | } |
340 | |||
341 | |||
342 | /*++++++++++++++++++++++++++++++++++++++ | ||
343 | amb | 39 | Remove bad segments (zero length or duplicated). |
344 | |||
345 | amb | 97 | SegmentsX *segmentsx The segments to modify. |
346 | amb | 39 | ++++++++++++++++++++++++++++++++++++++*/ |
347 | |||
348 | amb | 97 | void RemoveBadSegments(SegmentsX *segmentsx) |
349 | amb | 39 | { |
350 | int i; | ||
351 | int duplicate=0,loop=0; | ||
352 | node_t node1=~0,node2=~0; | ||
353 | |||
354 | amb | 97 | for(i=0;i<segmentsx->number;i++) |
355 | amb | 39 | { |
356 | amb | 97 | if(segmentsx->xdata[i].node1==node1 && segmentsx->xdata[i].node2==node2) |
357 | amb | 39 | { |
358 | duplicate++; | ||
359 | amb | 97 | segmentsx->xdata[i].node1=~0; |
360 | amb | 39 | } |
361 | amb | 97 | else if(segmentsx->xdata[i].node1==segmentsx->xdata[i].node2) |
362 | amb | 39 | { |
363 | loop++; | ||
364 | amb | 97 | segmentsx->xdata[i].node1=~0; |
365 | amb | 39 | } |
366 | |||
367 | amb | 97 | node1=segmentsx->xdata[i].node1; |
368 | node2=segmentsx->xdata[i].node2; | ||
369 | amb | 39 | |
370 | if(!((i+1)%10000)) | ||
371 | { | ||
372 | printf("\rChecking: Segments=%d Duplicate=%d Loop=%d",i+1,duplicate,loop); | ||
373 | fflush(stdout); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | amb | 97 | printf("\rChecked: Segments=%d Duplicate=%d Loop=%d \n",segmentsx->number,duplicate,loop); |
378 | amb | 39 | fflush(stdout); |
379 | } | ||
380 | |||
381 | |||
382 | /*++++++++++++++++++++++++++++++++++++++ | ||
383 | amb | 89 | Measure the segments. |
384 | amb | 23 | |
385 | amb | 97 | SegmentsX* segmentsx The set of segments to process. |
386 | amb | 23 | |
387 | amb | 97 | NodesX *nodesx The list of nodes to use. |
388 | amb | 8 | ++++++++++++++++++++++++++++++++++++++*/ |
389 | amb | 2 | |
390 | amb | 97 | void MeasureSegments(SegmentsX* segmentsx,NodesX *nodesx) |
391 | amb | 8 | { |
392 | int i; | ||
393 | amb | 2 | |
394 | amb | 97 | assert(segmentsx->sorted); /* Must be sorted */ |
395 | amb | 8 | |
396 | amb | 97 | for(i=0;i<segmentsx->number;i++) |
397 | amb | 8 | { |
398 | amb | 98 | NodeX *node1=FindNodeX(nodesx,segmentsx->xdata[i].node1); |
399 | NodeX *node2=FindNodeX(nodesx,segmentsx->xdata[i].node2); | ||
400 | amb | 8 | |
401 | amb | 82 | /* Set the distance but preserve the ONEWAY_OPPOSITE flag */ |
402 | amb | 8 | |
403 | amb | 99 | segmentsx->xdata[i].segment.distance|=DistanceX(node1,node2); |
404 | amb | 69 | |
405 | amb | 54 | if(!((i+1)%10000)) |
406 | { | ||
407 | amb | 89 | printf("\rMeasuring Segments: Segments=%d",i+1); |
408 | fflush(stdout); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | amb | 97 | printf("\rMeasured Segments: Segments=%d \n",segmentsx->number); |
413 | amb | 89 | fflush(stdout); |
414 | } | ||
415 | |||
416 | |||
417 | /*++++++++++++++++++++++++++++++++++++++ | ||
418 | Fix the segment indexes to the nodes. | ||
419 | |||
420 | amb | 97 | SegmentsX* segmentsx The set of segments to process. |
421 | amb | 89 | |
422 | amb | 97 | NodesX *nodesx The list of nodes to use. |
423 | amb | 90 | |
424 | amb | 97 | SegmentsX* supersegmentsx The set of super-segments to append. |
425 | amb | 89 | ++++++++++++++++++++++++++++++++++++++*/ |
426 | |||
427 | amb | 97 | void FixupSegments(SegmentsX* segmentsx,NodesX *nodesx,SegmentsX* supersegmentsx) |
428 | amb | 89 | { |
429 | amb | 90 | int i,j,n; |
430 | amb | 89 | |
431 | amb | 97 | assert(segmentsx->sorted); /* Must be sorted */ |
432 | assert(supersegmentsx->sorted); /* Must be sorted */ | ||
433 | amb | 89 | |
434 | amb | 97 | for(i=0;i<segmentsx->number;i++) |
435 | amb | 89 | { |
436 | amb | 98 | NodeX *node1=FindNodeX(nodesx,segmentsx->xdata[i].node1); |
437 | NodeX *node2=FindNodeX(nodesx,segmentsx->xdata[i].node2); | ||
438 | amb | 89 | |
439 | amb | 97 | segmentsx->xdata[i].segment.node1=IndexNodeX(nodesx,node1)|SUPER_FLAG; |
440 | segmentsx->xdata[i].segment.node2=IndexNodeX(nodesx,node2); | ||
441 | amb | 89 | |
442 | if(!((i+1)%10000)) | ||
443 | { | ||
444 | amb | 88 | printf("\rFixing Segments: Segments=%d",i+1); |
445 | amb | 54 | fflush(stdout); |
446 | } | ||
447 | amb | 8 | } |
448 | amb | 54 | |
449 | amb | 97 | printf("\rFixed Segments: Segments=%d \n",segmentsx->number); |
450 | amb | 54 | fflush(stdout); |
451 | amb | 90 | |
452 | amb | 97 | for(i=0;i<supersegmentsx->number;i++) |
453 | amb | 90 | { |
454 | amb | 98 | NodeX *node1=FindNodeX(nodesx,supersegmentsx->xdata[i].node1); |
455 | NodeX *node2=FindNodeX(nodesx,supersegmentsx->xdata[i].node2); | ||
456 | amb | 90 | |
457 | amb | 97 | supersegmentsx->xdata[i].segment.node1=IndexNodeX(nodesx,node1); |
458 | supersegmentsx->xdata[i].segment.node2=IndexNodeX(nodesx,node2)|SUPER_FLAG; | ||
459 | amb | 90 | |
460 | if(!((i+1)%10000)) | ||
461 | { | ||
462 | printf("\rFixing Super-Segments: Super-Segments=%d",i+1); | ||
463 | fflush(stdout); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | amb | 97 | printf("\rFixed Super-Segments: Super-Segments=%d \n",supersegmentsx->number); |
468 | amb | 90 | fflush(stdout); |
469 | |||
470 | amb | 97 | n=segmentsx->number; |
471 | amb | 90 | |
472 | for(i=0,j=0;i<n;i++) | ||
473 | { | ||
474 | amb | 97 | while(j<supersegmentsx->number) |
475 | amb | 90 | { |
476 | amb | 97 | if(segmentsx->xdata[i].node1==supersegmentsx->xdata[j].node1 && |
477 | segmentsx->xdata[i].node2==supersegmentsx->xdata[j].node2) | ||
478 | amb | 90 | { |
479 | amb | 97 | segmentsx->xdata[i].segment.node2|=SUPER_FLAG; |
480 | amb | 90 | j++; |
481 | break; | ||
482 | } | ||
483 | amb | 97 | else if(segmentsx->xdata[i].node1==supersegmentsx->xdata[j].node1 && |
484 | segmentsx->xdata[i].node2>supersegmentsx->xdata[j].node2) | ||
485 | amb | 90 | { |
486 | amb | 98 | Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->xdata[j].node1,supersegmentsx->xdata[j].node2); |
487 | amb | 90 | |
488 | amb | 98 | *supersegment=supersegmentsx->xdata[j].segment; |
489 | amb | 90 | } |
490 | amb | 97 | else if(segmentsx->xdata[i].node1>supersegmentsx->xdata[j].node1) |
491 | amb | 90 | { |
492 | amb | 98 | Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->xdata[j].node1,supersegmentsx->xdata[j].node2); |
493 | amb | 90 | |
494 | amb | 98 | *supersegment=supersegmentsx->xdata[j].segment; |
495 | amb | 90 | } |
496 | else | ||
497 | break; | ||
498 | |||
499 | j++; | ||
500 | } | ||
501 | |||
502 | if(!((i+1)%10000)) | ||
503 | { | ||
504 | amb | 97 | printf("\rMerging Segments: Segments=%d Super-Segment=%d Total=%d",i+1,j+1,segmentsx->number); |
505 | amb | 90 | fflush(stdout); |
506 | } | ||
507 | } | ||
508 | |||
509 | amb | 97 | printf("\rMerged Segments: Segments=%d Super-Segment=%d Total=%d \n",n,supersegmentsx->number,segmentsx->number); |
510 | amb | 90 | fflush(stdout); |
511 | amb | 8 | } |
512 | |||
513 | |||
514 | /*++++++++++++++++++++++++++++++++++++++ | ||
515 | amb | 99 | Calculate the distance between two locations. |
516 | |||
517 | float Distance Returns the distance between the locations. | ||
518 | |||
519 | float lat1 The latitude of the first location. | ||
520 | |||
521 | float lon1 The longitude of the first location. | ||
522 | |||
523 | float lat2 The latitude of the second location. | ||
524 | |||
525 | float lon2 The longitude of the second location. | ||
526 | ++++++++++++++++++++++++++++++++++++++*/ | ||
527 | |||
528 | float Distance(float lat1,float lon1,float lat2,float lon2) | ||
529 | { | ||
530 | double radiant = M_PI / 180; | ||
531 | |||
532 | double dlon = radiant * (lon1 - lon2); | ||
533 | double dlat = radiant * (lat1 - lat2); | ||
534 | |||
535 | double a1,a2,a,sa,c,d; | ||
536 | |||
537 | if(dlon==0 && dlat==0) | ||
538 | return 0; | ||
539 | |||
540 | a1 = sin (dlat / 2); | ||
541 | a2 = sin (dlon / 2); | ||
542 | a = (a1 * a1) + cos (lat1 * radiant) * cos (lat2 * radiant) * a2 * a2; | ||
543 | sa = sqrt (a); | ||
544 | if (sa <= 1.0) | ||
545 | {c = 2 * asin (sa);} | ||
546 | else | ||
547 | {c = 2 * asin (1.0);} | ||
548 | d = 6378.137 * c; | ||
549 | |||
550 | return d; | ||
551 | } | ||
552 | |||
553 | |||
554 | /*++++++++++++++++++++++++++++++++++++++ | ||
555 | amb | 8 | Calculate the distance between two nodes. |
556 | |||
557 | amb | 99 | distance_t DistanceX Returns the distance between the extended nodes. |
558 | amb | 8 | |
559 | amb | 98 | NodeX *nodex1 The starting node. |
560 | amb | 2 | |
561 | amb | 98 | NodeX *nodex2 The end node. |
562 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
563 | |||
564 | amb | 99 | distance_t DistanceX(NodeX *nodex1,NodeX *nodex2) |
565 | amb | 2 | { |
566 | double radiant = M_PI / 180; | ||
567 | |||
568 | amb | 99 | double dlon = radiant * (nodex1->longitude - nodex2->longitude); |
569 | double dlat = radiant * (nodex1->latitude - nodex2->latitude); | ||
570 | amb | 2 | |
571 | double a1,a2,a,sa,c,d; | ||
572 | |||
573 | if(dlon==0 && dlat==0) | ||
574 | return 0; | ||
575 | |||
576 | a1 = sin (dlat / 2); | ||
577 | a2 = sin (dlon / 2); | ||
578 | amb | 99 | a = (a1 * a1) + cos (nodex1->latitude * radiant) * cos (nodex2->latitude * radiant) * a2 * a2; |
579 | amb | 2 | sa = sqrt (a); |
580 | if (sa <= 1.0) | ||
581 | {c = 2 * asin (sa);} | ||
582 | else | ||
583 | {c = 2 * asin (1.0);} | ||
584 | amb | 5 | d = 6378.137 * c; |
585 | amb | 2 | |
586 | amb | 5 | return km_to_distance(d); |
587 | amb | 2 | } |
588 | amb | 63 | |
589 | |||
590 | /*++++++++++++++++++++++++++++++++++++++ | ||
591 | Calculate the duration of segment. | ||
592 | |||
593 | duration_t Duration Returns the duration of travel between the nodes. | ||
594 | |||
595 | Segment *segment The segment to traverse. | ||
596 | |||
597 | Way *way The way that the segment belongs to. | ||
598 | |||
599 | amb | 82 | Profile *profile The profile of the transport being used. |
600 | amb | 63 | ++++++++++++++++++++++++++++++++++++++*/ |
601 | |||
602 | amb | 82 | duration_t Duration(Segment *segment,Way *way,Profile *profile) |
603 | amb | 63 | { |
604 | amb | 82 | speed_t speed=profile->speed[HIGHWAY(way->type)]; |
605 | amb | 90 | distance_t distance=DISTANCE(segment->distance); |
606 | amb | 63 | |
607 | amb | 86 | return distance_speed_to_duration(distance,speed); |
608 | amb | 63 | } |
Properties
Name | Value |
---|---|
cvs:description | Segment data type. |