static void output_turnrestriction(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); index_t turnrelation=NO_RELATION; if(!IsTurnRestrictedNode(nodep)) return; turnrelation=FindFirstTurnRelation1(OSMRelations,node); do { TurnRelation *relation; Segment *from_segment,*to_segment; index_t from_node,to_node; double from_lat,from_lon,to_lat,to_lon; relation=LookupTurnRelation(OSMRelations,turnrelation,1); from_segment=LookupSegment(OSMSegments,relation->from,1); to_segment =LookupSegment(OSMSegments,relation->to ,2); from_node=OtherNode(from_segment,node); to_node=OtherNode(to_segment,node); GetLatLong(OSMNodes,from_node,&from_lat,&from_lon); GetLatLong(OSMNodes,to_node,&to_lat,&to_lon); printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",radians_to_degrees(from_lat),radians_to_degrees(from_lon), radians_to_degrees(latitude),radians_to_degrees(longitude), radians_to_degrees(to_lat),radians_to_degrees(to_lon)); turnrelation=FindNextTurnRelation1(OSMRelations,turnrelation); } while(turnrelation!=NO_RELATION); }
Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node) { Results *results,*results2; Queue *queue; Result *result1,*result2,*result3; /* Create the results and insert the finish node */ results=NewResultsList(64); results->finish_node=finish_node; result1=InsertResult(results,finish_node,NO_SEGMENT); /* Insert the first node into the queue */ queue=NewQueueList(); InsertInQueue(queue,result1); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { index_t node1,seg1,seg1r; Segment *segment; index_t turnrelation=NO_RELATION; node1=result1->node; seg1=result1->segment; if(IsFakeSegment(seg1)) seg1r=IndexRealSegment(seg1); else seg1r=seg1; /* lookup if a turn restriction applies */ if(profile->turns && !IsFakeNode(node1) && IsTurnRestrictedNode(LookupNode(nodes,node1,1))) turnrelation=FindFirstTurnRelation1(relations,node1); /* working backwards => turn relation sort order doesn't help */ /* Loop across all segments */ if(IsFakeNode(node1)) segment=FirstFakeSegment(node1); else segment=FirstSegment(segments,nodes,node1,1); while(segment) { Way *way; index_t node2,seg2,seg2r; score_t segment_pref,segment_score,cumulative_score; int i; /* must be a normal segment */ if((IsFakeNode(node1) || !IsSuperNode(LookupNode(nodes,node1,1))) && !IsNormalSegment(segment)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayFrom(segment,node1)) /* Disallow oneway from node2 *to* node1 */ goto endloop; node2=OtherNode(segment,node1); if(IsFakeNode(node1) || IsFakeNode(node2)) { seg2 =IndexFakeSegment(segment); seg2r=IndexRealSegment(seg2); } else { seg2 =IndexSegment(segments,segment); seg2r=seg2; } /* must not perform U-turn (unless profile allows) */ if(profile->turns && (seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2)))) goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION) { index_t turnrelation2=FindFirstTurnRelation2(relations,node1,seg2r); /* node2 -> node1 -> result1->next->node */ if(turnrelation2!=NO_RELATION && !IsTurnAllowed(relations,turnrelation2,node1,seg2r,seg1r,profile->allow)) goto endloop; } way=LookupWay(ways,segment->way,1); /* mode of transport must be allowed on the highway */ if(!(way->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(way->weight && way->weight<profile->weight) goto endloop; /* must obey height/width/length restriction (if exists) */ if((way->height && way->height<profile->height) || (way->width && way->width <profile->width ) || (way->length && way->length<profile->length)) goto endloop; segment_pref=profile->highway[HIGHWAY(way->type)]; for(i=1;i<Property_Count;i++) if(ways->file.props & PROPERTIES(i)) { if(way->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; /* mode of transport must be allowed through node2 */ if(!IsFakeNode(node2)) { Node *node=LookupNode(nodes,node2,2); if(!(node->allow&profile->allow)) goto endloop; } if(option_quickest==0) segment_score=(score_t)DISTANCE(segment->distance)/segment_pref; else segment_score=(score_t)Duration(segment,way,profile)/segment_pref; cumulative_score=result1->score+segment_score; result2=FindResult(results,node2,seg2); if(!result2) /* New end node */ { result2=InsertResult(results,node2,seg2); result2->next=result1; /* working backwards */ result2->score=cumulative_score; if(IsFakeNode(node1) || (!IsFakeNode(node1) && !IsSuperNode(LookupNode(nodes,node1,1)))) /* Overshoot by one segment */ { result2->sortby=result2->score; InsertInQueue(queue,result2); } } else if(cumulative_score<result2->score) /* New end node is better */ { result2->next=result1; /* working backwards */ result2->score=cumulative_score; if(IsFakeNode(node1) || (!IsFakeNode(node1) && !IsSuperNode(LookupNode(nodes,node1,1)))) /* Overshoot by one segment */ { result2->sortby=result2->score; InsertInQueue(queue,result2); } } endloop: if(IsFakeNode(node1)) segment=NextFakeSegment(segment,node1); else segment=NextSegment(segments,segment,node1); } } FreeQueueList(queue); /* Check it worked */ if(results->number==1) { FreeResultsList(results); return(NULL); } /* Create a results structure with the node at the end of the segment opposite the start */ results2=NewResultsList(64); results2->finish_node=results->finish_node; result3=FirstResult(results); while(result3) { if(result3->next) { result2=InsertResult(results2,result3->next->node,result3->segment); result2->score=result3->next->score; } result3=NextResult(results,result3); } /* Fix up the result->next pointers */ result3=FirstResult(results); while(result3) { if(result3->next && result3->next->next) { result1=FindResult(results2,result3->next->node,result3->segment); result2=FindResult(results2,result3->next->next->node,result3->next->segment); result1->next=result2; } result3=NextResult(results,result3); } FreeResultsList(results); return(results2); }