Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/optimiser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 166 - (show annotations) (download) (as text)
Thu Apr 30 17:29:03 2009 UTC (15 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 25158 byte(s)
First attempt at preferences for highways - uses integer arithmetic and doesn't
work well.

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

Properties

Name Value
cvs:description Route optimiser.