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 236 - (hide annotations) (download) (as text)
Sat Aug 15 14:18:23 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 21727 byte(s)
Optimise the priority queue used for routing.

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

Properties

Name Value
cvs:description Route optimiser.