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 470 - (show annotations) (download) (as text)
Tue Aug 3 18:28:30 2010 UTC (14 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 24414 byte(s)
Rename the variables that hold the node allowed transports and flags.

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

Properties

Name Value
cvs:description Route optimiser.