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/optimiser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 142 - (hide annotations) (download) (as text)
Sat Mar 7 14:26:55 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 31035 byte(s)
Renamed the *.txt output to *-all.txt and added a new shorted *.txt output.

1 amb 2 /***************************************
2 amb 142 $Header: /home/amb/CVS/routino/src/optimiser.c,v 1.56 2009-03-07 14:26:55 amb Exp $
3 amb 2
4     Routing optimiser.
5     ******************/ /******************
6     Written by Andrew M. Bishop
7    
8 amb 3 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     #include <string.h>
16 amb 109 #include <stdio.h>
17 amb 2
18 amb 96 #include "types.h"
19 amb 109 #include "functions.h"
20     #include "nodes.h"
21     #include "segments.h"
22     #include "ways.h"
23 amb 28 #include "results.h"
24 amb 2
25 amb 26
26 amb 113 /*+ The option not to print any progress information. +*/
27 amb 107 extern int option_quiet;
28 amb 2
29 amb 113 /*+ The option to calculate the quickest route insted of the shortest. +*/
30     extern int option_quickest;
31 amb 31
32 amb 113
33 amb 2 /*++++++++++++++++++++++++++++++++++++++
34     Find the optimum route between two nodes.
35    
36 amb 26 Results *FindRoute Returns a set of results.
37    
38     Nodes *nodes The set of nodes to use.
39    
40     Segments *segments The set of segments to use.
41    
42 amb 54 Ways *ways The set of ways to use.
43    
44 amb 96 index_t start The start node.
45 amb 2
46 amb 96 index_t finish The finish node.
47 amb 54
48 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
49 amb 71
50     int all A flag to indicate that a big results structure is required.
51 amb 2 ++++++++++++++++++++++++++++++++++++++*/
52    
53 amb 96 Results *FindRoute(Nodes *nodes,Segments *segments,Ways *ways,index_t start,index_t finish,Profile *profile,int all)
54 amb 2 {
55 amb 31 Results *results;
56 amb 96 index_t node1,node2;
57 amb 113 distance_t finish_distance;
58     duration_t finish_duration;
59 amb 119 float finish_lat,finish_lon;
60     speed_t max_speed=0;
61 amb 2 Result *result1,*result2;
62     Segment *segment;
63 amb 54 Way *way;
64 amb 119 int i;
65 amb 2
66 amb 10 /* Set up the finish conditions */
67    
68 amb 113 finish_distance=~0;
69     finish_duration=~0;
70 amb 10
71 amb 119 GetLatLong(nodes,LookupNode(nodes,finish),&finish_lat,&finish_lon);
72    
73     for(i=0;i<sizeof(profile->speed)/sizeof(profile->speed[0]);i++)
74     if(profile->speed[i]>max_speed)
75     max_speed=profile->speed[i];
76    
77 amb 2 /* Insert the first node into the queue */
78    
79 amb 71 if(all)
80     results=NewResultsList(65536);
81     else
82     results=NewResultsList(8);
83 amb 2
84 amb 31 result1=InsertResult(results,start);
85 amb 28
86 amb 2 result1->node=start;
87 amb 113 result1->prev=0;
88     result1->next=0;
89     result1->distance=0;
90     result1->duration=0;
91 amb 119 result1->sortby=0;
92 amb 2
93 amb 79 insert_in_queue(result1);
94 amb 2
95     /* Loop across all nodes in the queue */
96    
97 amb 79 while((result1=pop_from_queue()))
98 amb 2 {
99 amb 119 if((option_quickest==0 && result1->sortby>finish_distance) ||
100     (option_quickest==1 && result1->sortby>finish_duration))
101     continue;
102    
103 amb 43 node1=result1->node;
104 amb 2
105 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
106 amb 2
107     while(segment)
108     {
109 amb 113 distance_t cumulative_distance;
110     duration_t cumulative_duration;
111 amb 59
112 amb 95 if(!IsNormalSegment(segment))
113 amb 90 goto endloop;
114    
115 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
116 amb 64 goto endloop;
117    
118 amb 105 node2=OtherNode(segment,node1);
119 amb 2
120 amb 113 if(result1->prev==node2)
121 amb 64 goto endloop;
122    
123 amb 96 way=LookupWay(ways,segment->way);
124 amb 54
125 amb 82 if(!(way->allow&profile->allow))
126 amb 54 goto endloop;
127    
128 amb 82 if(!profile->highways[HIGHWAY(way->type)])
129 amb 75 goto endloop;
130    
131 amb 135 if(way->weight<profile->weight)
132     goto endloop;
133    
134     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
135     goto endloop;
136    
137 amb 113 cumulative_distance=result1->distance+DISTANCE(segment->distance);
138     cumulative_duration=result1->duration+Duration(segment,way,profile);
139 amb 59
140 amb 113 if((option_quickest==0 && cumulative_distance>finish_distance) ||
141     (option_quickest==1 && cumulative_duration>finish_duration))
142 amb 2 goto endloop;
143    
144 amb 42 result2=FindResult(results,node2);
145    
146 amb 2 if(!result2) /* New end node */
147     {
148 amb 31 result2=InsertResult(results,node2);
149 amb 2 result2->node=node2;
150 amb 113 result2->prev=node1;
151     result2->next=0;
152     result2->distance=cumulative_distance;
153     result2->duration=cumulative_duration;
154 amb 2
155     if(node2==finish)
156     {
157 amb 113 finish_distance=cumulative_distance;
158     finish_duration=cumulative_duration;
159 amb 2 }
160 amb 119 else if(!all)
161     {
162     result2->sortby=result2->distance;
163     insert_in_queue(result2);
164     }
165 amb 2 else
166 amb 119 {
167     float lat,lon;
168     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
169    
170     if(option_quickest==0)
171     result2->sortby=result2->distance+Distance(lat,lon,finish_lat,finish_lon);
172     else
173     result2->sortby=result2->duration+distance_speed_to_duration(Distance(lat,lon,finish_lat,finish_lon),max_speed);
174    
175 amb 79 insert_in_queue(result2);
176 amb 119 }
177 amb 2 }
178 amb 113 else if(option_quickest==0) /* shortest */
179 amb 2 {
180 amb 113 if(cumulative_distance<result2->distance ||
181     (cumulative_distance==result2->distance &&
182     cumulative_duration<result2->duration)) /* New end node is shorter */
183 amb 2 {
184 amb 113 result2->prev=node1;
185     result2->distance=cumulative_distance;
186     result2->duration=cumulative_duration;
187 amb 2
188     if(node2==finish)
189     {
190 amb 113 finish_distance=cumulative_distance;
191     finish_duration=cumulative_duration;
192 amb 2 }
193 amb 119 else if(!all)
194     {
195     result2->sortby=result2->distance;
196     insert_in_queue(result2);
197     }
198 amb 2 else
199 amb 119 {
200     float lat,lon;
201     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
202    
203     result2->sortby=result2->distance+Distance(lat,lon,finish_lat,finish_lon);
204 amb 79 insert_in_queue(result2);
205 amb 119 }
206 amb 2 }
207 amb 113 }
208     else if(option_quickest==1) /* quickest */
209     {
210     if(cumulative_duration<result2->duration ||
211     (cumulative_duration==result2->duration &&
212     cumulative_distance<result2->distance)) /* New end node is quicker */
213 amb 2 {
214 amb 113 result2->prev=node1;
215     result2->distance=cumulative_distance;
216     result2->duration=cumulative_duration;
217 amb 2
218     if(node2==finish)
219     {
220 amb 113 finish_distance=cumulative_distance;
221     finish_duration=cumulative_duration;
222 amb 2 }
223 amb 119 else if(!all)
224     {
225     result2->sortby=result2->distance;
226     insert_in_queue(result2);
227     }
228 amb 2 else
229 amb 119 {
230     float lat,lon;
231     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
232    
233     result2->sortby=result2->duration+distance_speed_to_duration(Distance(lat,lon,finish_lat,finish_lon),max_speed);
234 amb 79 insert_in_queue(result2);
235 amb 119 }
236 amb 2 }
237     }
238    
239     endloop:
240    
241 amb 107 if(!option_quiet && !(results->number%10000))
242 amb 95 {
243 amb 113 printf("\rRouting: End Nodes=%d %.1fkm %.0fmin ",results->number,
244 amb 119 distance_to_km(result1->distance),duration_to_minutes(result1->duration));
245 amb 95 fflush(stdout);
246     }
247    
248 amb 104 segment=NextSegment(segments,segment,node1);
249 amb 2 }
250     }
251    
252 amb 107 if(!option_quiet)
253 amb 31 {
254 amb 113 printf("\rRouted: End Nodes=%d %.1fkm %.0fmin \n",results->number,
255     distance_to_km(finish_distance),duration_to_minutes(finish_duration));
256 amb 31 fflush(stdout);
257     }
258    
259 amb 77 /* Check it worked */
260    
261     result2=FindResult(results,finish);
262    
263 amb 88 if(!result2)
264 amb 77 {
265     FreeResultsList(results);
266     return(NULL);
267     }
268    
269 amb 31 /* Reverse the results */
270    
271     result2=FindResult(results,finish);
272    
273     do
274     {
275 amb 113 if(result2->prev)
276 amb 31 {
277 amb 113 index_t node1=result2->prev;
278 amb 31
279     result1=FindResult(results,node1);
280    
281 amb 113 result1->next=result2->node;
282 amb 31
283     result2=result1;
284     }
285     else
286     result2=NULL;
287     }
288     while(result2);
289    
290     return(results);
291 amb 2 }
292    
293    
294     /*++++++++++++++++++++++++++++++++++++++
295 amb 34 Find the optimum route between two nodes.
296    
297     Results *FindRoute3 Returns a set of results.
298    
299 amb 95 Nodes *nodes The set of nodes to use.
300 amb 34
301 amb 95 Segments *segments The set of segments to use.
302 amb 34
303 amb 95 Ways *ways The set of ways to use.
304 amb 54
305 amb 96 index_t start The start node.
306 amb 34
307 amb 96 index_t finish The finish node.
308 amb 34
309     Results *begin The initial portion of the route.
310    
311     Results *end The final portion of the route.
312 amb 54
313 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
314 amb 34 ++++++++++++++++++++++++++++++++++++++*/
315    
316 amb 96 Results *FindRoute3(Nodes *nodes,Segments *segments,Ways *ways,index_t start,index_t finish,Results *begin,Results *end,Profile *profile)
317 amb 34 {
318     Results *results;
319 amb 96 index_t node1,node2;
320 amb 113 distance_t finish_distance;
321     duration_t finish_duration;
322 amb 119 float finish_lat,finish_lon;
323     speed_t max_speed=0;
324 amb 34 Result *result1,*result2,*result3;
325     Segment *segment;
326 amb 54 Way *way;
327 amb 119 int i;
328 amb 34
329     /* Set up the finish conditions */
330    
331 amb 113 finish_distance=~0;
332     finish_duration=~0;
333 amb 34
334 amb 119 GetLatLong(nodes,LookupNode(nodes,finish),&finish_lat,&finish_lon);
335    
336     for(i=0;i<sizeof(profile->speed)/sizeof(profile->speed[0]);i++)
337     if(profile->speed[i]>max_speed)
338     max_speed=profile->speed[i];
339    
340 amb 58 /* Insert the start node */
341 amb 34
342 amb 71 results=NewResultsList(65536);
343 amb 34
344     result1=InsertResult(results,start);
345 amb 81 result3=FindResult(begin,start);
346 amb 34
347 amb 81 *result1=*result3;
348 amb 34
349     /* Insert the finish points of the beginning part of the path into the queue */
350    
351 amb 79 result3=FirstResult(begin);
352    
353     while(result3)
354     {
355 amb 95 if(IsSuperNode(LookupNode(nodes,result3->node)))
356 amb 45 {
357 amb 81 if(!(result2=FindResult(results,result3->node)))
358 amb 34 {
359 amb 81 result2=InsertResult(results,result3->node);
360 amb 34
361 amb 81 *result2=*result3;
362 amb 34
363 amb 113 result2->prev=start;
364 amb 119
365     result2->sortby=result2->distance;
366 amb 47 }
367 amb 34
368 amb 81 insert_in_queue(result2);
369 amb 45 }
370 amb 34
371 amb 79 result3=NextResult(begin,result3);
372     }
373    
374 amb 95 /* Loop across all nodes in the queue */
375 amb 34
376 amb 79 while((result1=pop_from_queue()))
377 amb 34 {
378 amb 119 if((option_quickest==0 && result1->sortby>finish_distance) ||
379     (option_quickest==1 && result1->sortby>finish_duration))
380     continue;
381    
382 amb 43 node1=result1->node;
383 amb 34
384 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
385 amb 34
386     while(segment)
387     {
388 amb 113 distance_t cumulative_distance;
389     duration_t cumulative_duration;
390 amb 59
391 amb 95 if(!IsSuperSegment(segment))
392     goto endloop;
393    
394 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
395 amb 64 goto endloop;
396    
397 amb 105 node2=OtherNode(segment,node1);
398 amb 34
399 amb 113 if(result1->prev==node2)
400 amb 64 goto endloop;
401    
402 amb 96 way=LookupWay(ways,segment->way);
403 amb 54
404 amb 82 if(!(way->allow&profile->allow))
405 amb 54 goto endloop;
406    
407 amb 82 if(!profile->highways[HIGHWAY(way->type)])
408 amb 75 goto endloop;
409    
410 amb 135 if(way->weight<profile->weight)
411     goto endloop;
412    
413     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
414     goto endloop;
415    
416 amb 113 cumulative_distance=result1->distance+DISTANCE(segment->distance);
417     cumulative_duration=result1->duration+Duration(segment,way,profile);
418 amb 34
419 amb 113 if((option_quickest==0 && cumulative_distance>finish_distance) ||
420     (option_quickest==1 && cumulative_duration>finish_duration))
421 amb 34 goto endloop;
422    
423 amb 42 result2=FindResult(results,node2);
424    
425 amb 34 if(!result2) /* New end node */
426     {
427     result2=InsertResult(results,node2);
428     result2->node=node2;
429 amb 113 result2->prev=node1;
430     result2->next=0;
431     result2->distance=cumulative_distance;
432     result2->duration=cumulative_duration;
433 amb 34
434 amb 113 if((result3=FindResult(end,node2)))
435     {
436     finish_distance=cumulative_distance+result3->distance;
437     finish_duration=cumulative_duration+result3->duration;
438     }
439     else
440 amb 119 {
441     float lat,lon;
442     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
443    
444     if(option_quickest==0)
445     result2->sortby=result2->distance+Distance(lat,lon,finish_lat,finish_lon);
446     else
447     result2->sortby=result2->duration+distance_speed_to_duration(Distance(lat,lon,finish_lat,finish_lon),max_speed);
448    
449 amb 79 insert_in_queue(result2);
450 amb 119 }
451 amb 34 }
452 amb 113 else if(option_quickest==0) /* shortest */
453 amb 34 {
454 amb 113 if(cumulative_distance<result2->distance ||
455     (cumulative_distance==result2->distance &&
456     cumulative_duration<result2->duration)) /* New end node is shorter */
457 amb 34 {
458 amb 113 result2->prev=node1;
459     result2->distance=cumulative_distance;
460     result2->duration=cumulative_duration;
461 amb 34
462 amb 113 if((result3=FindResult(end,node2)))
463     {
464     if((cumulative_distance+result3->distance)<finish_distance ||
465     ((cumulative_distance+result3->distance)==finish_distance &&
466     (cumulative_duration+result3->duration)<finish_duration))
467     {
468     finish_distance=cumulative_distance+result3->distance;
469     finish_duration=cumulative_duration+result3->duration;
470     }
471     }
472     else
473 amb 119 {
474     float lat,lon;
475     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
476    
477     result2->sortby=result2->distance+Distance(lat,lon,finish_lat,finish_lon);
478 amb 79 insert_in_queue(result2);
479 amb 119 }
480 amb 34 }
481 amb 113 }
482     else if(option_quickest==1) /* quickest */
483     {
484     if(cumulative_duration<result2->duration ||
485     (cumulative_duration==result2->duration &&
486     cumulative_distance<result2->distance)) /* New end node is quicker */
487 amb 34 {
488 amb 113 result2->prev=node1;
489     result2->distance=cumulative_distance;
490     result2->duration=cumulative_duration;
491 amb 34
492 amb 113 if((result3=FindResult(end,node2)))
493     {
494     if((cumulative_duration+result3->duration)<finish_duration ||
495     ((cumulative_duration+result3->duration)==finish_duration &&
496     (cumulative_distance+result3->distance)<finish_distance))
497     {
498     finish_distance=cumulative_distance+result3->distance;
499     finish_duration=cumulative_duration+result3->duration;
500     }
501     }
502     else
503 amb 119 {
504     float lat,lon;
505     GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
506    
507     result2->sortby=result2->duration+distance_speed_to_duration(Distance(lat,lon,finish_lat,finish_lon),max_speed);
508 amb 79 insert_in_queue(result2);
509 amb 119 }
510 amb 34 }
511     }
512    
513     endloop:
514    
515 amb 107 if(!option_quiet && !(results->number%10000))
516 amb 95 {
517 amb 113 printf("\rRouting: End Nodes=%d %.1fkm %.0fmin ",results->number,
518 amb 119 distance_to_km(result1->distance),duration_to_minutes(result1->duration));
519 amb 95 fflush(stdout);
520     }
521 amb 34
522 amb 104 segment=NextSegment(segments,segment,node1);
523 amb 34 }
524     }
525    
526 amb 107 if(!option_quiet)
527 amb 34 {
528 amb 113 printf("\rRouted: End Super-Nodes=%d %.1fkm %.0fmin \n",results->number,
529     distance_to_km(finish_distance),duration_to_minutes(finish_duration));
530 amb 34 fflush(stdout);
531     }
532    
533     /* Finish off the end part of the route. */
534    
535 amb 54 if(!FindResult(results,finish))
536 amb 47 {
537 amb 54 result2=InsertResult(results,finish);
538 amb 81 result3=FindResult(end,finish);
539 amb 34
540 amb 81 *result2=*result3;
541 amb 47
542 amb 113 result2->distance=~0;
543     result2->duration=~0;
544 amb 54
545 amb 79 result3=FirstResult(end);
546    
547     while(result3)
548     {
549 amb 95 if(IsSuperNode(LookupNode(nodes,result3->node)))
550 amb 79 if((result1=FindResult(results,result3->node)))
551 amb 34 {
552 amb 113 if(option_quickest==0) /* shortest */
553 amb 47 {
554 amb 113 if((result1->distance+result3->distance)<result2->distance ||
555     ((result1->distance+result3->distance)==result2->distance &&
556     (result1->duration+result3->duration)<result2->duration))
557     {
558     result2->distance=result1->distance+result3->distance;
559     result2->duration=result1->duration+result3->duration;
560     result2->prev=result1->node;
561     }
562 amb 47 }
563 amb 113 else
564 amb 47 {
565 amb 113 if((result1->duration+result3->duration)<result2->duration ||
566     ((result1->duration+result3->duration)==result2->duration &&
567     (result1->distance+result3->distance)<result2->distance))
568     {
569     result2->distance=result1->distance+result3->distance;
570     result2->duration=result1->duration+result3->duration;
571     result2->prev=result1->node;
572     }
573 amb 47 }
574 amb 34 }
575 amb 79
576     result3=NextResult(end,result3);
577     }
578 amb 47 }
579 amb 34
580 amb 77 /* Check it worked */
581    
582 amb 123 if(finish_distance == ~0)
583 amb 77 {
584     FreeResultsList(results);
585     return(NULL);
586     }
587    
588 amb 34 /* Reverse the results */
589    
590     result2=FindResult(results,finish);
591    
592     do
593     {
594 amb 113 if(result2->prev)
595 amb 34 {
596 amb 113 index_t node1=result2->prev;
597 amb 34
598     result1=FindResult(results,node1);
599    
600 amb 113 result1->next=result2->node;
601 amb 34
602     result2=result1;
603     }
604     else
605     result2=NULL;
606     }
607     while(result2);
608    
609     return(results);
610     }
611    
612    
613     /*++++++++++++++++++++++++++++++++++++++
614 amb 2 Print the optimum route between two nodes.
615    
616 amb 31 Results *Results The set of results to print.
617    
618     Nodes *nodes The list of nodes.
619    
620 amb 26 Segments *segments The set of segments to use.
621    
622     Ways *ways The list of ways.
623    
624 amb 96 index_t start The start node.
625 amb 2
626 amb 96 index_t finish The finish node.
627 amb 63
628 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
629 amb 2 ++++++++++++++++++++++++++++++++++++++*/
630    
631 amb 96 void PrintRoute(Results *results,Nodes *nodes,Segments *segments,Ways *ways,index_t start,index_t finish,Profile *profile)
632 amb 2 {
633 amb 142 FILE *textfile,*gpxfile,*allfile;
634     distance_t distance=0;
635     duration_t duration=0;
636     char *prev_way_name=NULL;
637 amb 2 Result *result;
638    
639 amb 113 if(option_quickest==0)
640     {
641     /* Print the result for the shortest route */
642 amb 2
643 amb 113 textfile=fopen("shortest.txt","w");
644     gpxfile=fopen("shortest.gpx","w");
645 amb 142 allfile=fopen("shortest-all.txt","w");
646 amb 113 }
647     else
648 amb 2 {
649 amb 113 /* Print the result for the quickest route */
650 amb 43
651 amb 113 textfile=fopen("quickest.txt","w");
652     gpxfile=fopen("quickest.gpx","w");
653 amb 142 allfile=fopen("quickest-all.txt","w");
654 amb 2 }
655    
656 amb 55 fprintf(gpxfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
657     fprintf(gpxfile,"<gpx version=\"1.0\" creator=\"Router\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
658     fprintf(gpxfile,"<trk>\n");
659     fprintf(gpxfile,"<trkseg>\n");
660    
661 amb 31 result=FindResult(results,start);
662 amb 2
663     do
664     {
665 amb 99 float latitude,longitude;
666 amb 88 Node *node=LookupNode(nodes,result->node);
667 amb 43
668 amb 99 GetLatLong(nodes,node,&latitude,&longitude);
669 amb 55
670 amb 121 fprintf(gpxfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"></trkpt>\n",
671     (180/M_PI)*latitude,(180/M_PI)*longitude);
672 amb 99
673 amb 113 if(result->prev)
674 amb 2 {
675 amb 6 Segment *segment;
676     Way *way;
677 amb 142 char *way_name;
678 amb 2
679 amb 113 segment=FirstSegment(segments,LookupNode(nodes,result->prev));
680 amb 119 while(OtherNode(segment,result->prev)!=result->node)
681 amb 113 segment=NextSegment(segments,segment,result->prev);
682 amb 2
683 amb 96 way=LookupWay(ways,segment->way);
684 amb 6
685 amb 142 distance+=distance_to_km(distance);
686     duration+=Duration(segment,way,profile);
687     way_name=WayName(ways,way);
688    
689     if(!result->next || (IsSuperNode(node) && way_name!=prev_way_name))
690     {
691     fprintf(textfile,"%8.4f\t%9.4f\t%5.3f km\t%5.1f min\t%5.1f km\t%3.0f min\t%s\n",
692     (180/M_PI)*latitude,(180/M_PI)*longitude,
693     distance_to_km(distance),duration_to_minutes(duration),
694     distance_to_km(result->distance),duration_to_minutes(result->duration),
695     way_name);
696    
697     prev_way_name=way_name;
698     }
699    
700     fprintf(allfile,"%8.4f %9.4f %8d%c %5.3f %5.2f %7.2f %5.1f %3d %s\n",
701 amb 121 (180/M_PI)*latitude,(180/M_PI)*longitude,
702 amb 90 result->node,IsSuperNode(node)?'*':' ',
703 amb 105 distance_to_km(DISTANCE(segment->distance)),duration_to_minutes(Duration(segment,way,profile)),
704 amb 113 distance_to_km(result->distance),duration_to_minutes(result->duration),
705 amb 142 profile->speed[HIGHWAY(way->type)],way_name);
706 amb 34 }
707     else
708 amb 142 {
709     fprintf(textfile,"%8.4f\t%9.4f\t%5.3f km\t%5.1f min\t%5.1f km\t%3.0f min\t\n",
710 amb 121 (180/M_PI)*latitude,(180/M_PI)*longitude,
711 amb 142 0.0,0.0,0.0,0.0);
712    
713     fprintf(allfile,"%8.4f %9.4f %8d%c %5.3f %5.2f %7.2f %5.1f\n",
714     (180/M_PI)*latitude,(180/M_PI)*longitude,
715 amb 90 result->node,IsSuperNode(node)?'*':' ',
716 amb 34 0.0,0.0,0.0,0.0);
717 amb 142 }
718 amb 2
719 amb 113 if(result->next)
720     result=FindResult(results,result->next);
721 amb 2 else
722     result=NULL;
723     }
724 amb 113 while(result);
725 amb 2
726 amb 55 fprintf(gpxfile,"</trkseg>\n");
727     fprintf(gpxfile,"</trk>\n");
728     fprintf(gpxfile,"</gpx>\n");
729    
730     fclose(textfile);
731     fclose(gpxfile);
732 amb 142 fclose(allfile);
733 amb 31 }
734 amb 3
735    
736 amb 31 /*++++++++++++++++++++++++++++++++++++++
737 amb 95 Find all routes from a specified node to any super-node.
738 amb 3
739 amb 126 Results *FindStartRoutes Returns a set of results.
740 amb 31
741     Nodes *nodes The set of nodes to use.
742    
743     Segments *segments The set of segments to use.
744    
745 amb 54 Ways *ways The set of ways to use.
746    
747 amb 96 index_t start The start node.
748 amb 31
749 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
750 amb 31 ++++++++++++++++++++++++++++++++++++++*/
751    
752 amb 126 Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t start,Profile *profile)
753 amb 31 {
754     Results *results;
755 amb 96 index_t node1,node2;
756 amb 31 Result *result1,*result2;
757     Segment *segment;
758 amb 54 Way *way;
759 amb 31
760     /* Insert the first node into the queue */
761    
762 amb 71 results=NewResultsList(8);
763 amb 31
764     result1=InsertResult(results,start);
765    
766     result1->node=start;
767 amb 113 result1->prev=0;
768     result1->next=0;
769     result1->distance=0;
770     result1->duration=0;
771 amb 119 result1->sortby=0;
772 amb 31
773 amb 79 insert_in_queue(result1);
774 amb 31
775     /* Loop across all nodes in the queue */
776    
777 amb 79 while((result1=pop_from_queue()))
778 amb 31 {
779 amb 43 node1=result1->node;
780 amb 31
781 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
782 amb 31
783     while(segment)
784     {
785 amb 113 distance_t cumulative_distance;
786     duration_t cumulative_duration;
787 amb 59
788 amb 95 if(!IsNormalSegment(segment))
789     goto endloop;
790    
791 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
792 amb 64 goto endloop;
793    
794 amb 105 node2=OtherNode(segment,node1);
795 amb 31
796 amb 113 if(result1->prev==node2)
797 amb 64 goto endloop;
798    
799 amb 96 way=LookupWay(ways,segment->way);
800 amb 54
801 amb 82 if(!(way->allow&profile->allow))
802 amb 54 goto endloop;
803    
804 amb 82 if(!profile->highways[HIGHWAY(way->type)])
805 amb 75 goto endloop;
806    
807 amb 135 if(way->weight<profile->weight)
808     goto endloop;
809    
810     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
811     goto endloop;
812    
813 amb 113 cumulative_distance=result1->distance+DISTANCE(segment->distance);
814     cumulative_duration=result1->duration+Duration(segment,way,profile);
815 amb 59
816 amb 31 result2=FindResult(results,node2);
817    
818     if(!result2) /* New end node */
819     {
820     result2=InsertResult(results,node2);
821     result2->node=node2;
822 amb 113 result2->prev=node1;
823     result2->next=0;
824     result2->distance=cumulative_distance;
825     result2->duration=cumulative_duration;
826 amb 31
827 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
828 amb 119 {
829     result2->sortby=result2->distance;
830 amb 79 insert_in_queue(result2);
831 amb 119 }
832 amb 31 }
833 amb 113 else if(option_quickest==0) /* shortest */
834 amb 31 {
835 amb 113 if(cumulative_distance<result2->distance ||
836     (cumulative_distance==result2->distance &&
837     cumulative_duration<result2->duration)) /* New end node is shorter */
838 amb 31 {
839 amb 113 result2->prev=node1;
840     result2->distance=cumulative_distance;
841     result2->duration=cumulative_duration;
842 amb 31
843 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
844 amb 119 {
845     result2->sortby=result2->distance;
846 amb 79 insert_in_queue(result2);
847 amb 119 }
848 amb 31 }
849 amb 113 }
850     else if(option_quickest==1) /* quickest */
851     {
852     if(cumulative_duration<result2->duration ||
853     (cumulative_duration==result2->duration &&
854     cumulative_distance<result2->distance)) /* New end node is quicker */
855 amb 31 {
856 amb 113 result2->prev=node1;
857     result2->distance=cumulative_distance;
858     result2->duration=cumulative_duration;
859 amb 31
860 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
861 amb 119 {
862     result2->sortby=result2->duration;
863 amb 79 insert_in_queue(result2);
864 amb 119 }
865 amb 31 }
866     }
867    
868     endloop:
869    
870 amb 104 segment=NextSegment(segments,segment,node1);
871 amb 31 }
872     }
873    
874 amb 112 /* Check it worked */
875    
876     if(results->number==1)
877     {
878     FreeResultsList(results);
879     return(NULL);
880     }
881    
882 amb 31 return(results);
883 amb 2 }
884    
885    
886     /*++++++++++++++++++++++++++++++++++++++
887 amb 95 Find all routes from any super-node to a specific node.
888 amb 34
889 amb 126 Results *FindFinishRoutes Returns a set of results.
890 amb 34
891     Nodes *nodes The set of nodes to use.
892    
893     Segments *segments The set of segments to use.
894    
895 amb 54 Ways *ways The set of ways to use.
896    
897 amb 96 index_t finish The finishing node.
898 amb 54
899 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
900 amb 34 ++++++++++++++++++++++++++++++++++++++*/
901    
902 amb 126 Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t finish,Profile *profile)
903 amb 34 {
904     Results *results;
905 amb 96 index_t node1,node2;
906 amb 34 Result *result1,*result2;
907     Segment *segment;
908 amb 54 Way *way;
909 amb 34
910     /* Insert the first node into the queue */
911    
912 amb 71 results=NewResultsList(8);
913 amb 34
914     result1=InsertResult(results,finish);
915    
916     result1->node=finish;
917 amb 113 result1->prev=0;
918     result1->next=0;
919     result1->distance=0;
920     result1->duration=0;
921 amb 119 result1->sortby=0;
922 amb 34
923 amb 79 insert_in_queue(result1);
924 amb 34
925     /* Loop across all nodes in the queue */
926    
927 amb 79 while((result1=pop_from_queue()))
928 amb 34 {
929 amb 43 node1=result1->node;
930 amb 34
931 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
932 amb 34
933     while(segment)
934     {
935 amb 113 distance_t cumulative_distance;
936     duration_t cumulative_duration;
937 amb 59
938 amb 104 if(!IsNormalSegment(segment))
939 amb 34 goto endloop;
940    
941 amb 105 if(profile->oneway && IsOnewayFrom(segment,node1))
942 amb 95 goto endloop;
943    
944 amb 105 node2=OtherNode(segment,node1);
945 amb 64
946 amb 113 if(result1->next==node2)
947 amb 64 goto endloop;
948    
949 amb 104 way=LookupWay(ways,segment->way);
950 amb 54
951 amb 82 if(!(way->allow&profile->allow))
952 amb 54 goto endloop;
953    
954 amb 82 if(!profile->highways[HIGHWAY(way->type)])
955 amb 75 goto endloop;
956    
957 amb 135 if(way->weight<profile->weight)
958     goto endloop;
959    
960     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
961     goto endloop;
962    
963 amb 113 cumulative_distance=result1->distance+DISTANCE(segment->distance);
964     cumulative_duration=result1->duration+Duration(segment,way,profile);
965 amb 59
966 amb 34 result2=FindResult(results,node2);
967    
968     if(!result2) /* New end node */
969     {
970     result2=InsertResult(results,node2);
971     result2->node=node2;
972 amb 113 result2->prev=0;
973     result2->next=node1;
974     result2->distance=cumulative_distance;
975     result2->duration=cumulative_duration;
976 amb 34
977 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
978 amb 119 {
979     result2->sortby=result2->distance;
980 amb 79 insert_in_queue(result2);
981 amb 119 }
982 amb 34 }
983 amb 113 else if(option_quickest==0) /* shortest */
984 amb 34 {
985 amb 113 if(cumulative_distance<result2->distance ||
986     (cumulative_distance==result2->distance &&
987     cumulative_duration<result2->duration)) /* New end node is shorter */
988 amb 34 {
989 amb 113 result2->next=node1;
990     result2->distance=cumulative_distance;
991     result2->duration=cumulative_duration;
992 amb 34
993 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
994 amb 119 {
995     result2->sortby=result2->distance;
996 amb 79 insert_in_queue(result2);
997 amb 119 }
998 amb 34 }
999 amb 113 }
1000     else if(option_quickest==1) /* quickest */
1001     {
1002     if(cumulative_duration<result2->duration ||
1003     (cumulative_duration==result2->duration &&
1004     cumulative_distance<result2->distance)) /* New end node is quicker */
1005 amb 34 {
1006 amb 113 result2->next=node1;
1007     result2->distance=cumulative_distance;
1008     result2->duration=cumulative_duration;
1009 amb 34
1010 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
1011 amb 119 {
1012     result2->sortby=result2->duration;
1013 amb 79 insert_in_queue(result2);
1014 amb 119 }
1015 amb 34 }
1016     }
1017    
1018     endloop:
1019    
1020 amb 104 segment=NextSegment(segments,segment,node1);
1021 amb 34 }
1022     }
1023    
1024 amb 112 /* Check it worked */
1025    
1026     if(results->number==1)
1027     {
1028     FreeResultsList(results);
1029     return(NULL);
1030     }
1031    
1032 amb 34 return(results);
1033     }
1034    
1035    
1036     /*++++++++++++++++++++++++++++++++++++++
1037 amb 95 Create an optimum route given the set of super-nodes to follow.
1038 amb 31
1039 amb 58 Results *CombineRoutes Returns the results from joining the super-nodes.
1040 amb 55
1041 amb 58 Results *results The set of results from the super-nodes.
1042 amb 31
1043     Nodes *nodes The list of nodes.
1044    
1045     Segments *segments The set of segments to use.
1046    
1047     Ways *ways The list of ways.
1048    
1049 amb 96 index_t start The start node.
1050 amb 31
1051 amb 96 index_t finish The finish node.
1052 amb 54
1053 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
1054 amb 31 ++++++++++++++++++++++++++++++++++++++*/
1055    
1056 amb 96 Results *CombineRoutes(Results *results,Nodes *nodes,Segments *segments,Ways *ways,index_t start,index_t finish,Profile *profile)
1057 amb 31 {
1058     Result *result1,*result2,*result3,*result4;
1059     Results *combined;
1060 amb 107 int quiet=option_quiet;
1061 amb 31
1062 amb 71 combined=NewResultsList(64);
1063 amb 31
1064 amb 107 option_quiet=1;
1065 amb 31
1066 amb 113 /* Sort out the combined route */
1067 amb 31
1068     result1=FindResult(results,start);
1069    
1070 amb 58 result3=InsertResult(combined,start);
1071 amb 31
1072 amb 58 result3->node=result1->node;
1073 amb 36
1074 amb 113 result3->distance=0;
1075     result3->duration=0;
1076     result3->next=0;
1077     result3->prev=0;
1078 amb 31
1079 amb 58 do
1080     {
1081 amb 113 if(result1->next)
1082 amb 31 {
1083 amb 113 Results *results2=FindRoute(nodes,segments,ways,result1->node,result1->next,profile,0);
1084 amb 31
1085     result2=FindResult(results2,result1->node);
1086    
1087 amb 113 result3->next=result2->next;
1088 amb 36
1089 amb 113 result2=FindResult(results2,result2->next);
1090 amb 36
1091 amb 31 do
1092     {
1093 amb 58 result4=InsertResult(combined,result2->node);
1094 amb 31
1095 amb 58 result4->node=result2->node;
1096 amb 36
1097 amb 113 *result4=*result2;
1098     result4->distance+=result3->distance;
1099     result4->duration+=result3->duration;
1100 amb 31
1101 amb 113 if(result2->next)
1102     result2=FindResult(results2,result2->next);
1103 amb 31 else
1104     result2=NULL;
1105     }
1106     while(result2);
1107    
1108     FreeResultsList(results2);
1109    
1110 amb 113 result1=FindResult(results,result1->next);
1111 amb 58
1112     result3=result4;
1113 amb 31 }
1114     else
1115     result1=NULL;
1116     }
1117     while(result1);
1118    
1119     /* Now print out the result normally */
1120    
1121 amb 107 option_quiet=quiet;
1122 amb 31
1123 amb 55 return(combined);
1124 amb 31 }

Properties

Name Value
cvs:description Route optimiser.