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 161 - (hide annotations) (download) (as text)
Wed Apr 22 18:52:35 2009 UTC (15 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 27597 byte(s)
Split the function to print the output into a new file.

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

Properties

Name Value
cvs:description Route optimiser.