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 305 - (hide annotations) (download) (as text)
Thu Nov 19 18:53:23 2009 UTC (15 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 23185 byte(s)
Made the verbose output consistent between different places.

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

Properties

Name Value
cvs:description Route optimiser.