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 173 - (hide annotations) (download) (as text)
Wed May 13 18:06:53 2009 UTC (15 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 21065 byte(s)
Move some common code into the profile.

1 amb 2 /***************************************
2 amb 173 $Header: /home/amb/CVS/routino/src/optimiser.c,v 1.68 2009-05-13 18:06:53 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 166 score_t finish_score;
69 amb 119 float finish_lat,finish_lon;
70 amb 2 Result *result1,*result2;
71     Segment *segment;
72 amb 54 Way *way;
73 amb 2
74 amb 10 /* Set up the finish conditions */
75    
76 amb 113 finish_distance=~0;
77     finish_duration=~0;
78 amb 168 finish_score =~(distance_t)0;
79 amb 10
80 amb 119 GetLatLong(nodes,LookupNode(nodes,finish),&finish_lat,&finish_lon);
81    
82 amb 165 /* Create the list of results and insert the first node into the queue */
83 amb 2
84 amb 71 if(all)
85     results=NewResultsList(65536);
86     else
87     results=NewResultsList(8);
88 amb 2
89 amb 165 results->start=start;
90     results->finish=finish;
91    
92 amb 31 result1=InsertResult(results,start);
93 amb 28
94 amb 166 ZeroResult(result1);
95 amb 2
96 amb 79 insert_in_queue(result1);
97 amb 2
98     /* Loop across all nodes in the queue */
99    
100 amb 79 while((result1=pop_from_queue()))
101 amb 2 {
102 amb 168 if(result1->sortby>finish_score)
103 amb 119 continue;
104    
105 amb 43 node1=result1->node;
106 amb 2
107 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
108 amb 2
109     while(segment)
110     {
111 amb 170 score_t segment_score,cumulative_score;
112 amb 59
113 amb 95 if(!IsNormalSegment(segment))
114 amb 90 goto endloop;
115    
116 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
117 amb 64 goto endloop;
118    
119 amb 105 node2=OtherNode(segment,node1);
120 amb 2
121 amb 113 if(result1->prev==node2)
122 amb 64 goto endloop;
123    
124 amb 96 way=LookupWay(ways,segment->way);
125 amb 54
126 amb 82 if(!(way->allow&profile->allow))
127 amb 54 goto endloop;
128    
129 amb 168 if(!profile->highway[HIGHWAY(way->type)])
130 amb 75 goto endloop;
131    
132 amb 135 if(way->weight<profile->weight)
133     goto endloop;
134    
135     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
136     goto endloop;
137    
138 amb 166 if(option_quickest==0)
139 amb 170 segment_score=(score_t)DISTANCE(segment->distance)/profile->highway[HIGHWAY(way->type)];
140 amb 166 else
141 amb 170 segment_score=(score_t)Duration(segment,way,profile)/profile->highway[HIGHWAY(way->type)];
142 amb 59
143 amb 170 cumulative_score=result1->score+segment_score;
144 amb 166
145     if(cumulative_score>finish_score)
146 amb 2 goto endloop;
147    
148 amb 42 result2=FindResult(results,node2);
149    
150 amb 2 if(!result2) /* New end node */
151     {
152 amb 31 result2=InsertResult(results,node2);
153 amb 113 result2->prev=node1;
154     result2->next=0;
155 amb 170 result2->score=cumulative_score;
156     result2->segment=segment;
157 amb 2
158     if(node2==finish)
159     {
160 amb 170 finish_score=cumulative_score;
161 amb 2 }
162     else
163 amb 119 {
164     float lat,lon;
165 amb 166 distance_t direct;
166    
167 amb 119 GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
168 amb 166 direct=Distance(lat,lon,finish_lat,finish_lon);
169 amb 119
170     if(option_quickest==0)
171 amb 173 result2->sortby=result2->score+(score_t)direct/profile->max_pref;
172 amb 119 else
173 amb 173 result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref;
174 amb 119
175 amb 79 insert_in_queue(result2);
176 amb 119 }
177 amb 2 }
178 amb 166 else if(cumulative_score<result2->score) /* New end node is better */
179 amb 2 {
180 amb 166 result2->prev=node1;
181 amb 170 result2->score=cumulative_score;
182     result2->segment=segment;
183 amb 166
184     if(node2==finish)
185 amb 2 {
186 amb 166 finish_score=cumulative_score;
187 amb 2 }
188 amb 166 else if(!all)
189 amb 2 {
190 amb 166 insert_in_queue(result2);
191     }
192     else
193     {
194     float lat,lon;
195     distance_t direct;
196 amb 2
197 amb 166 GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
198     direct=Distance(lat,lon,finish_lat,finish_lon);
199    
200     if(option_quickest==0)
201 amb 173 result2->sortby=result2->score+(score_t)direct/profile->max_pref;
202 amb 2 else
203 amb 173 result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref;
204 amb 119
205 amb 166 insert_in_queue(result2);
206 amb 2 }
207     }
208    
209     endloop:
210    
211 amb 107 if(!option_quiet && !(results->number%10000))
212 amb 95 {
213 amb 170 printf("\rRouting: End Nodes=%d",results->number);
214 amb 95 fflush(stdout);
215     }
216    
217 amb 104 segment=NextSegment(segments,segment,node1);
218 amb 2 }
219     }
220    
221 amb 107 if(!option_quiet)
222 amb 31 {
223 amb 170 printf("\rRouted: End Nodes=%d\n",results->number);
224 amb 31 fflush(stdout);
225     }
226    
227 amb 77 /* Check it worked */
228    
229     result2=FindResult(results,finish);
230    
231 amb 88 if(!result2)
232 amb 77 {
233     FreeResultsList(results);
234     return(NULL);
235     }
236    
237 amb 170 /* Create the forward links for the optimum path */
238 amb 31
239     result2=FindResult(results,finish);
240    
241     do
242     {
243 amb 113 if(result2->prev)
244 amb 31 {
245 amb 113 index_t node1=result2->prev;
246 amb 31
247     result1=FindResult(results,node1);
248    
249 amb 113 result1->next=result2->node;
250 amb 31
251     result2=result1;
252     }
253     else
254     result2=NULL;
255     }
256     while(result2);
257    
258     return(results);
259 amb 2 }
260    
261    
262     /*++++++++++++++++++++++++++++++++++++++
263 amb 34 Find the optimum route between two nodes.
264    
265     Results *FindRoute3 Returns a set of results.
266    
267 amb 95 Nodes *nodes The set of nodes to use.
268 amb 34
269 amb 95 Segments *segments The set of segments to use.
270 amb 34
271 amb 95 Ways *ways The set of ways to use.
272 amb 54
273 amb 34 Results *begin The initial portion of the route.
274    
275     Results *end The final portion of the route.
276 amb 54
277 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
278 amb 34 ++++++++++++++++++++++++++++++++++++++*/
279    
280 amb 165 Results *FindRoute3(Nodes *nodes,Segments *segments,Ways *ways,Results *begin,Results *end,Profile *profile)
281 amb 34 {
282     Results *results;
283 amb 96 index_t node1,node2;
284 amb 166 score_t finish_score;
285 amb 119 float finish_lat,finish_lon;
286 amb 34 Result *result1,*result2,*result3;
287     Segment *segment;
288 amb 54 Way *way;
289 amb 34
290     /* Set up the finish conditions */
291    
292 amb 170 finish_score=~(distance_t)0;
293 amb 34
294 amb 165 GetLatLong(nodes,LookupNode(nodes,end->finish),&finish_lat,&finish_lon);
295 amb 119
296 amb 165 /* Create the list of results and insert the first node into the queue */
297 amb 34
298 amb 71 results=NewResultsList(65536);
299 amb 34
300 amb 165 results->start=begin->start;
301     results->finish=end->finish;
302 amb 34
303 amb 165 result1=InsertResult(results,begin->start);
304     result3=FindResult(begin,begin->start);
305    
306 amb 81 *result1=*result3;
307 amb 34
308     /* Insert the finish points of the beginning part of the path into the queue */
309    
310 amb 79 result3=FirstResult(begin);
311    
312     while(result3)
313     {
314 amb 95 if(IsSuperNode(LookupNode(nodes,result3->node)))
315 amb 45 {
316 amb 81 if(!(result2=FindResult(results,result3->node)))
317 amb 34 {
318 amb 81 result2=InsertResult(results,result3->node);
319 amb 34
320 amb 81 *result2=*result3;
321 amb 34
322 amb 165 result2->prev=begin->start;
323 amb 119
324 amb 166 result2->sortby=result2->score;
325 amb 47 }
326 amb 34
327 amb 81 insert_in_queue(result2);
328 amb 45 }
329 amb 34
330 amb 79 result3=NextResult(begin,result3);
331     }
332    
333 amb 95 /* Loop across all nodes in the queue */
334 amb 34
335 amb 79 while((result1=pop_from_queue()))
336 amb 34 {
337 amb 168 if(result1->sortby>finish_score)
338 amb 119 continue;
339    
340 amb 43 node1=result1->node;
341 amb 34
342 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
343 amb 34
344     while(segment)
345     {
346 amb 170 score_t segment_score,cumulative_score;
347 amb 59
348 amb 95 if(!IsSuperSegment(segment))
349     goto endloop;
350    
351 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
352 amb 64 goto endloop;
353    
354 amb 105 node2=OtherNode(segment,node1);
355 amb 34
356 amb 113 if(result1->prev==node2)
357 amb 64 goto endloop;
358    
359 amb 96 way=LookupWay(ways,segment->way);
360 amb 54
361 amb 82 if(!(way->allow&profile->allow))
362 amb 54 goto endloop;
363    
364 amb 168 if(!profile->highway[HIGHWAY(way->type)])
365 amb 75 goto endloop;
366    
367 amb 135 if(way->weight<profile->weight)
368     goto endloop;
369    
370     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
371     goto endloop;
372    
373 amb 166 if(option_quickest==0)
374 amb 170 segment_score=(score_t)DISTANCE(segment->distance)/profile->highway[HIGHWAY(way->type)];
375 amb 166 else
376 amb 170 segment_score=(score_t)Duration(segment,way,profile)/profile->highway[HIGHWAY(way->type)];
377 amb 34
378 amb 170 cumulative_score=result1->score+segment_score;
379 amb 166
380     if(cumulative_score>finish_score)
381 amb 34 goto endloop;
382    
383 amb 42 result2=FindResult(results,node2);
384    
385 amb 34 if(!result2) /* New end node */
386     {
387     result2=InsertResult(results,node2);
388 amb 113 result2->prev=node1;
389     result2->next=0;
390 amb 170 result2->score=cumulative_score;
391     result2->segment=segment;
392 amb 34
393 amb 113 if((result3=FindResult(end,node2)))
394     {
395 amb 170 finish_score=result2->score+result3->score;
396 amb 113 }
397     else
398 amb 119 {
399     float lat,lon;
400 amb 166 distance_t direct;
401    
402 amb 119 GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
403 amb 166 direct=Distance(lat,lon,finish_lat,finish_lon);
404 amb 119
405     if(option_quickest==0)
406 amb 173 result2->sortby=result2->score+(score_t)direct/profile->max_pref;
407 amb 119 else
408 amb 173 result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref;
409 amb 119
410 amb 79 insert_in_queue(result2);
411 amb 119 }
412 amb 34 }
413 amb 166 else if(cumulative_score<result2->score) /* New end node is better */
414 amb 34 {
415 amb 166 result2->prev=node1;
416 amb 170 result2->score=cumulative_score;
417     result2->segment=segment;
418 amb 166
419     if((result3=FindResult(end,node2)))
420 amb 34 {
421 amb 166 if((result2->score+result3->score)<finish_score)
422 amb 113 {
423 amb 166 finish_score=result2->score+result3->score;
424 amb 113 }
425 amb 34 }
426 amb 166 else
427 amb 34 {
428 amb 166 float lat,lon;
429     distance_t direct;
430 amb 34
431 amb 166 GetLatLong(nodes,LookupNode(nodes,node2),&lat,&lon);
432     direct=Distance(lat,lon,finish_lat,finish_lon);
433    
434     if(option_quickest==0)
435 amb 173 result2->sortby=result2->score+(score_t)direct/profile->max_pref;
436 amb 113 else
437 amb 173 result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref;
438 amb 119
439 amb 166 insert_in_queue(result2);
440 amb 34 }
441     }
442    
443     endloop:
444    
445 amb 107 if(!option_quiet && !(results->number%10000))
446 amb 95 {
447 amb 170 printf("\rRouting: End Nodes=%d",results->number);
448 amb 95 fflush(stdout);
449     }
450 amb 34
451 amb 104 segment=NextSegment(segments,segment,node1);
452 amb 34 }
453     }
454    
455 amb 107 if(!option_quiet)
456 amb 34 {
457 amb 170 printf("\rRouted: End Super-Nodes=%d\n",results->number);
458 amb 34 fflush(stdout);
459     }
460    
461     /* Finish off the end part of the route. */
462    
463 amb 165 if(!FindResult(results,end->finish))
464 amb 47 {
465 amb 165 result2=InsertResult(results,end->finish);
466     result3=FindResult(end,end->finish);
467 amb 34
468 amb 81 *result2=*result3;
469 amb 47
470 amb 170 result2->score=~(distance_t)0;
471 amb 54
472 amb 79 result3=FirstResult(end);
473    
474     while(result3)
475     {
476 amb 95 if(IsSuperNode(LookupNode(nodes,result3->node)))
477 amb 79 if((result1=FindResult(results,result3->node)))
478 amb 170 if((result1->score+result3->score)<result2->score)
479 amb 47 {
480 amb 170 result2->score=result1->score+result3->score;
481     result2->prev=result1->node;
482 amb 47 }
483 amb 79
484     result3=NextResult(end,result3);
485     }
486 amb 47 }
487 amb 34
488 amb 77 /* Check it worked */
489    
490 amb 170 if(finish_score==~0)
491 amb 77 {
492     FreeResultsList(results);
493     return(NULL);
494     }
495    
496 amb 170 /* Create the forward links for the optimum path */
497 amb 34
498 amb 165 result2=FindResult(results,end->finish);
499 amb 34
500     do
501     {
502 amb 113 if(result2->prev)
503 amb 34 {
504 amb 113 index_t node1=result2->prev;
505 amb 34
506     result1=FindResult(results,node1);
507    
508 amb 113 result1->next=result2->node;
509 amb 34
510     result2=result1;
511     }
512     else
513     result2=NULL;
514     }
515     while(result2);
516    
517     return(results);
518     }
519    
520    
521     /*++++++++++++++++++++++++++++++++++++++
522 amb 95 Find all routes from a specified node to any super-node.
523 amb 3
524 amb 126 Results *FindStartRoutes Returns a set of results.
525 amb 31
526     Nodes *nodes The set of nodes to use.
527    
528     Segments *segments The set of segments to use.
529    
530 amb 54 Ways *ways The set of ways to use.
531    
532 amb 96 index_t start The start node.
533 amb 31
534 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
535 amb 31 ++++++++++++++++++++++++++++++++++++++*/
536    
537 amb 126 Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t start,Profile *profile)
538 amb 31 {
539     Results *results;
540 amb 96 index_t node1,node2;
541 amb 31 Result *result1,*result2;
542     Segment *segment;
543 amb 54 Way *way;
544 amb 31
545     /* Insert the first node into the queue */
546    
547 amb 71 results=NewResultsList(8);
548 amb 31
549 amb 165 results->start=start;
550    
551 amb 31 result1=InsertResult(results,start);
552    
553 amb 166 ZeroResult(result1);
554 amb 31
555 amb 79 insert_in_queue(result1);
556 amb 31
557     /* Loop across all nodes in the queue */
558    
559 amb 79 while((result1=pop_from_queue()))
560 amb 31 {
561 amb 43 node1=result1->node;
562 amb 31
563 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
564 amb 31
565     while(segment)
566     {
567 amb 170 score_t segment_score,cumulative_score;
568 amb 59
569 amb 95 if(!IsNormalSegment(segment))
570     goto endloop;
571    
572 amb 105 if(profile->oneway && IsOnewayTo(segment,node1))
573 amb 64 goto endloop;
574    
575 amb 105 node2=OtherNode(segment,node1);
576 amb 31
577 amb 113 if(result1->prev==node2)
578 amb 64 goto endloop;
579    
580 amb 96 way=LookupWay(ways,segment->way);
581 amb 54
582 amb 82 if(!(way->allow&profile->allow))
583 amb 54 goto endloop;
584    
585 amb 168 if(!profile->highway[HIGHWAY(way->type)])
586 amb 75 goto endloop;
587    
588 amb 135 if(way->weight<profile->weight)
589     goto endloop;
590    
591     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
592     goto endloop;
593    
594 amb 166 if(option_quickest==0)
595 amb 170 segment_score=(score_t)DISTANCE(segment->distance)/profile->highway[HIGHWAY(way->type)];
596 amb 166 else
597 amb 170 segment_score=(score_t)Duration(segment,way,profile)/profile->highway[HIGHWAY(way->type)];
598 amb 59
599 amb 170 cumulative_score=result1->score+segment_score;
600 amb 166
601 amb 31 result2=FindResult(results,node2);
602    
603     if(!result2) /* New end node */
604     {
605     result2=InsertResult(results,node2);
606 amb 113 result2->prev=node1;
607     result2->next=0;
608 amb 170 result2->score=cumulative_score;
609     result2->segment=segment;
610 amb 31
611 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
612 amb 119 {
613 amb 166 result2->sortby=result2->score;
614 amb 79 insert_in_queue(result2);
615 amb 119 }
616 amb 31 }
617 amb 166 else if(cumulative_score<result2->score) /* New end node is better */
618 amb 31 {
619 amb 166 result2->prev=node1;
620 amb 170 result2->score=cumulative_score;
621     result2->segment=segment;
622 amb 31
623 amb 166 if(!IsSuperNode(LookupNode(nodes,node2)))
624 amb 31 {
625 amb 166 result2->sortby=result2->score;
626     insert_in_queue(result2);
627 amb 31 }
628     }
629    
630     endloop:
631    
632 amb 104 segment=NextSegment(segments,segment,node1);
633 amb 31 }
634     }
635    
636 amb 112 /* Check it worked */
637    
638     if(results->number==1)
639     {
640     FreeResultsList(results);
641     return(NULL);
642     }
643    
644 amb 31 return(results);
645 amb 2 }
646    
647    
648     /*++++++++++++++++++++++++++++++++++++++
649 amb 95 Find all routes from any super-node to a specific node.
650 amb 34
651 amb 126 Results *FindFinishRoutes Returns a set of results.
652 amb 34
653     Nodes *nodes The set of nodes to use.
654    
655     Segments *segments The set of segments to use.
656    
657 amb 54 Ways *ways The set of ways to use.
658    
659 amb 96 index_t finish The finishing node.
660 amb 54
661 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
662 amb 34 ++++++++++++++++++++++++++++++++++++++*/
663    
664 amb 126 Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t finish,Profile *profile)
665 amb 34 {
666     Results *results;
667 amb 96 index_t node1,node2;
668 amb 34 Result *result1,*result2;
669     Segment *segment;
670 amb 54 Way *way;
671 amb 34
672     /* Insert the first node into the queue */
673    
674 amb 71 results=NewResultsList(8);
675 amb 34
676 amb 165 results->finish=finish;
677    
678 amb 34 result1=InsertResult(results,finish);
679    
680 amb 166 ZeroResult(result1);
681 amb 34
682 amb 79 insert_in_queue(result1);
683 amb 34
684     /* Loop across all nodes in the queue */
685    
686 amb 79 while((result1=pop_from_queue()))
687 amb 34 {
688 amb 43 node1=result1->node;
689 amb 34
690 amb 95 segment=FirstSegment(segments,LookupNode(nodes,node1));
691 amb 34
692     while(segment)
693     {
694 amb 170 score_t segment_score,cumulative_score;
695 amb 59
696 amb 104 if(!IsNormalSegment(segment))
697 amb 34 goto endloop;
698    
699 amb 105 if(profile->oneway && IsOnewayFrom(segment,node1))
700 amb 95 goto endloop;
701    
702 amb 105 node2=OtherNode(segment,node1);
703 amb 64
704 amb 113 if(result1->next==node2)
705 amb 64 goto endloop;
706    
707 amb 104 way=LookupWay(ways,segment->way);
708 amb 54
709 amb 82 if(!(way->allow&profile->allow))
710 amb 54 goto endloop;
711    
712 amb 168 if(!profile->highway[HIGHWAY(way->type)])
713 amb 75 goto endloop;
714    
715 amb 135 if(way->weight<profile->weight)
716     goto endloop;
717    
718     if(way->height<profile->height || way->width<profile->width || way->length<profile->length)
719     goto endloop;
720    
721 amb 166 if(option_quickest==0)
722 amb 170 segment_score=(score_t)DISTANCE(segment->distance)/profile->highway[HIGHWAY(way->type)];
723 amb 166 else
724 amb 170 segment_score=(score_t)Duration(segment,way,profile)/profile->highway[HIGHWAY(way->type)];
725 amb 59
726 amb 170 cumulative_score=result1->score+segment_score;
727 amb 166
728 amb 34 result2=FindResult(results,node2);
729    
730     if(!result2) /* New end node */
731     {
732     result2=InsertResult(results,node2);
733 amb 113 result2->prev=0;
734     result2->next=node1;
735 amb 170 result2->score=cumulative_score;
736     result2->segment=segment;
737 amb 34
738 amb 95 if(!IsSuperNode(LookupNode(nodes,node2)))
739 amb 119 {
740 amb 166 result2->sortby=result2->score;
741 amb 79 insert_in_queue(result2);
742 amb 119 }
743 amb 34 }
744 amb 166 else if(cumulative_score<result2->score) /* New end node is better */
745 amb 34 {
746 amb 166 result2->next=node1;
747 amb 170 result2->score=cumulative_score;
748     result2->segment=segment;
749 amb 34
750 amb 166 if(!IsSuperNode(LookupNode(nodes,node2)))
751 amb 34 {
752 amb 166 result2->sortby=result2->score;
753     insert_in_queue(result2);
754 amb 34 }
755     }
756    
757     endloop:
758    
759 amb 104 segment=NextSegment(segments,segment,node1);
760 amb 34 }
761     }
762    
763 amb 112 /* Check it worked */
764    
765     if(results->number==1)
766     {
767     FreeResultsList(results);
768     return(NULL);
769     }
770    
771 amb 34 return(results);
772     }
773    
774    
775     /*++++++++++++++++++++++++++++++++++++++
776 amb 95 Create an optimum route given the set of super-nodes to follow.
777 amb 31
778 amb 58 Results *CombineRoutes Returns the results from joining the super-nodes.
779 amb 55
780 amb 58 Results *results The set of results from the super-nodes.
781 amb 31
782     Nodes *nodes The list of nodes.
783    
784     Segments *segments The set of segments to use.
785    
786     Ways *ways The list of ways.
787    
788 amb 82 Profile *profile The profile containing the transport type, speeds and allowed highways.
789 amb 31 ++++++++++++++++++++++++++++++++++++++*/
790    
791 amb 165 Results *CombineRoutes(Results *results,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
792 amb 31 {
793     Result *result1,*result2,*result3,*result4;
794     Results *combined;
795 amb 107 int quiet=option_quiet;
796 amb 31
797 amb 71 combined=NewResultsList(64);
798 amb 31
799 amb 165 combined->start=results->start;
800     combined->finish=results->finish;
801    
802 amb 170 /* Don't print any output for this part */
803    
804 amb 107 option_quiet=1;
805 amb 31
806 amb 113 /* Sort out the combined route */
807 amb 31
808 amb 165 result1=FindResult(results,results->start);
809 amb 31
810 amb 165 result3=InsertResult(combined,results->start);
811 amb 31
812 amb 166 ZeroResult(result3);
813 amb 36
814 amb 58 do
815     {
816 amb 113 if(result1->next)
817 amb 31 {
818 amb 113 Results *results2=FindRoute(nodes,segments,ways,result1->node,result1->next,profile,0);
819 amb 31
820     result2=FindResult(results2,result1->node);
821    
822 amb 113 result3->next=result2->next;
823 amb 36
824 amb 113 result2=FindResult(results2,result2->next);
825 amb 36
826 amb 31 do
827     {
828 amb 58 result4=InsertResult(combined,result2->node);
829 amb 31
830 amb 113 *result4=*result2;
831 amb 170 result4->score+=result3->score;
832 amb 31
833 amb 113 if(result2->next)
834     result2=FindResult(results2,result2->next);
835 amb 31 else
836     result2=NULL;
837     }
838     while(result2);
839    
840     FreeResultsList(results2);
841    
842 amb 113 result1=FindResult(results,result1->next);
843 amb 58
844     result3=result4;
845 amb 31 }
846     else
847     result1=NULL;
848     }
849     while(result1);
850    
851     /* Now print out the result normally */
852    
853 amb 107 option_quiet=quiet;
854 amb 31
855 amb 55 return(combined);
856 amb 31 }

Properties

Name Value
cvs:description Route optimiser.