calculate roundabout radius from circumference, fix #2716
This commit is contained in:
		
							parent
							
								
									3d5a53566c
								
							
						
					
					
						commit
						7e2663f2ad
					
				| @ -243,9 +243,29 @@ Feature: Basic Roundabout | |||||||
|             | df    |            | |             | df    |            | | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | waypoints | route    | turns                           | |             | waypoints | route    | turns                                         | | ||||||
|             | a,e       | ab,ce,ce | depart,roundabout-exit-1,arrive | |             | a,e       | ab,ce,ce | depart,roundabout turn right exit-1,arrive    | | ||||||
|             | a,f       | ab,df,df | depart,roundabout-exit-2,arrive | |             | a,f       | ab,df,df | depart,roundabout turn straight exit-2,arrive | | ||||||
|  | 
 | ||||||
|  |        Scenario: Collinear in Y | ||||||
|  |         Given the node map | ||||||
|  |             |   | a | | ||||||
|  |             |   | b | | ||||||
|  |             | e | c | | ||||||
|  |             |   | d | | ||||||
|  |             |   | f | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | junction   | | ||||||
|  |             | ab    |            | | ||||||
|  |             | bcdb  | roundabout | | ||||||
|  |             | ce    |            | | ||||||
|  |             | df    |            | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route    | turns                                         | | ||||||
|  |             | a,e       | ab,ce,ce | depart,roundabout turn right exit-1,arrive    | | ||||||
|  |             | a,f       | ab,df,df | depart,roundabout turn straight exit-2,arrive | | ||||||
| 
 | 
 | ||||||
|        Scenario: Collinear in X,Y |        Scenario: Collinear in X,Y | ||||||
|         Given the node map |         Given the node map | ||||||
|  | |||||||
| @ -231,43 +231,6 @@ Feature: Basic Roundabout | |||||||
|            | j,f       | jk,ef,ef | depart,roundabout-exit-2,arrive | |            | j,f       | jk,ef,ef | depart,roundabout-exit-2,arrive | | ||||||
|            | j,c       | jk,bc,bc | depart,roundabout-exit-3,arrive | |            | j,c       | jk,bc,bc | depart,roundabout-exit-3,arrive | | ||||||
| 
 | 
 | ||||||
|        Scenario: Collinear in X |  | ||||||
|         Given the node map |  | ||||||
|             | a | b | c | d | f | |  | ||||||
|             |   |   | e |   |   | |  | ||||||
| 
 |  | ||||||
|         And the ways |  | ||||||
|             | nodes | junction   | |  | ||||||
|             | ab    |            | |  | ||||||
|             | bcdb  | roundabout | |  | ||||||
|             | ce    |            | |  | ||||||
|             | df    |            | |  | ||||||
| 
 |  | ||||||
|         When I route I should get |  | ||||||
|             | waypoints | route    | turns                           | |  | ||||||
|             | a,e       | ab,ce,ce | depart,roundabout-exit-1,arrive | |  | ||||||
|             | a,f       | ab,df,df | depart,roundabout-exit-2,arrive | |  | ||||||
| 
 |  | ||||||
|     Scenario: Collinear in Y |  | ||||||
|         Given the node map |  | ||||||
|             |   | a | |  | ||||||
|             |   | b | |  | ||||||
|             | e | c | |  | ||||||
|             |   | d | |  | ||||||
|             |   | f | |  | ||||||
| 
 |  | ||||||
|         And the ways |  | ||||||
|             | nodes | junction   | |  | ||||||
|             | ab    |            | |  | ||||||
|             | bcdb  | roundabout | |  | ||||||
|             | ce    |            | |  | ||||||
|             | df    |            | |  | ||||||
| 
 |  | ||||||
|         When I route I should get |  | ||||||
|             | waypoints | route    | turns                           | |  | ||||||
|             | a,e       | ab,ce,ce | depart,roundabout-exit-1,arrive | |  | ||||||
|             | a,f       | ab,df,df | depart,roundabout-exit-2,arrive | |  | ||||||
| 
 |  | ||||||
|     Scenario: Motorway Roundabout |     Scenario: Motorway Roundabout | ||||||
|     #See 39.933742 -75.082345 |     #See 39.933742 -75.082345 | ||||||
|         Given the node map |         Given the node map | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
| #include "util/node_based_graph.hpp" | #include "util/node_based_graph.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| 
 | 
 | ||||||
| #include <set> | #include <unordered_set> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| @ -82,7 +82,8 @@ class RoundaboutHandler : public IntersectionHandler | |||||||
|                                    const bool can_exit_roundabout, |                                    const bool can_exit_roundabout, | ||||||
|                                    Intersection intersection) const; |                                    Intersection intersection) const; | ||||||
| 
 | 
 | ||||||
|     bool qualifiesAsRoundaboutIntersection(const std::set<NodeID> &roundabout_nodes) const; |     bool | ||||||
|  |     qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const; | ||||||
| 
 | 
 | ||||||
|     const CompressedEdgeContainer &compressed_edge_container; |     const CompressedEdgeContainer &compressed_edge_container; | ||||||
|     const ProfileProperties &profile_properties; |     const ProfileProperties &profile_properties; | ||||||
|  | |||||||
| @ -8,7 +8,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <cmath> | #include <cmath> | ||||||
| #include <unordered_set> |  | ||||||
| 
 | 
 | ||||||
| #include <boost/assert.hpp> | #include <boost/assert.hpp> | ||||||
| 
 | 
 | ||||||
| @ -145,7 +144,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid, | |||||||
| // Processing segregated roads would technically require an angle of the turn to be available
 | // Processing segregated roads would technically require an angle of the turn to be available
 | ||||||
| // in postprocessing since we correct the turn-angle in turn-generaion.
 | // in postprocessing since we correct the turn-angle in turn-generaion.
 | ||||||
| bool RoundaboutHandler::qualifiesAsRoundaboutIntersection( | bool RoundaboutHandler::qualifiesAsRoundaboutIntersection( | ||||||
|     const std::set<NodeID> &roundabout_nodes) const |     const std::unordered_set<NodeID> &roundabout_nodes) const | ||||||
| { | { | ||||||
|     // translate a node ID into its respective coordinate stored in the node_info_list
 |     // translate a node ID into its respective coordinate stored in the node_info_list
 | ||||||
|     const auto getCoordinate = [this](const NodeID node) { |     const auto getCoordinate = [this](const NodeID node) { | ||||||
| @ -262,10 +261,6 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const | |||||||
|         } |         } | ||||||
|         return continue_edge; |         return continue_edge; | ||||||
|     }; |     }; | ||||||
|     // the roundabout radius has to be the same for all locations we look at it from
 |  | ||||||
|     // to guarantee this, we search the full roundabout for its vertices
 |  | ||||||
|     // and select the three smallest ids
 |  | ||||||
|     std::set<NodeID> roundabout_nodes; // needs to be sorted
 |  | ||||||
| 
 | 
 | ||||||
|     // this value is a hard abort to deal with potential self-loops
 |     // this value is a hard abort to deal with potential self-loops
 | ||||||
|     const auto countRoundaboutFlags = [&](const NodeID at_node) { |     const auto countRoundaboutFlags = [&](const NodeID at_node) { | ||||||
| @ -281,6 +276,25 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const | |||||||
|         return count; |         return count; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) { | ||||||
|  |         double length = 0.; | ||||||
|  |         auto last_coord = getCoordinate(source_node); | ||||||
|  |         const auto &edge_bucket = compressed_edge_container.GetBucketReference(eid); | ||||||
|  |         for (const auto &compressed_edge : edge_bucket) | ||||||
|  |         { | ||||||
|  |             const auto next_coord = getCoordinate(compressed_edge.node_id); | ||||||
|  |             length += util::coordinate_calculation::haversineDistance(last_coord, next_coord); | ||||||
|  |             last_coord = next_coord; | ||||||
|  |         } | ||||||
|  |         return length; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // the roundabout radius has to be the same for all locations we look at it from
 | ||||||
|  |     // to guarantee this, we search the full roundabout for its vertices
 | ||||||
|  |     // and select the three smallest ids
 | ||||||
|  |     std::unordered_set<NodeID> roundabout_nodes; | ||||||
|  |     double roundabout_length = 0.; | ||||||
|  | 
 | ||||||
|     NodeID last_node = nid; |     NodeID last_node = nid; | ||||||
|     while (0 == roundabout_nodes.count(last_node)) |     while (0 == roundabout_nodes.count(last_node)) | ||||||
|     { |     { | ||||||
| @ -299,6 +313,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const | |||||||
|             return RoundaboutType::None; |             return RoundaboutType::None; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         roundabout_length += getEdgeLength(last_node, eid); | ||||||
|  | 
 | ||||||
|         last_node = node_based_graph.GetTarget(eid); |         last_node = node_based_graph.GetTarget(eid); | ||||||
| 
 | 
 | ||||||
|         if (last_node == nid) |         if (last_node == nid) | ||||||
| @ -315,31 +331,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const | |||||||
|         return RoundaboutType::RoundaboutIntersection; |         return RoundaboutType::RoundaboutIntersection; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // calculate the radius of the roundabout/rotary. For two coordinates, we assume a minimal
 |     const double radius = roundabout_length / (2 * M_PI); | ||||||
|     // circle
 |  | ||||||
|     // with both vertices right at the other side (so half their distance in meters).
 |  | ||||||
|     // Otherwise, we construct a circle through the first tree vertices.
 |  | ||||||
|     const auto getRadius = [&roundabout_nodes, &getCoordinate]() { |  | ||||||
|         auto node_itr = roundabout_nodes.begin(); |  | ||||||
|         if (roundabout_nodes.size() == 2) |  | ||||||
|         { |  | ||||||
|             const auto first = getCoordinate(*node_itr++), second = getCoordinate(*node_itr++); |  | ||||||
|             return 0.5 * util::coordinate_calculation::haversineDistance(first, second); |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             const auto first = getCoordinate(*node_itr++), second = getCoordinate(*node_itr++), |  | ||||||
|                        third = getCoordinate(*node_itr++); |  | ||||||
|             return util::coordinate_calculation::circleRadius(first, second, third); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|     const double radius = getRadius(); |  | ||||||
| 
 |  | ||||||
|     // check whether the circle computation has gone wrong
 |  | ||||||
|     // The radius computation can result in infinity, if the three coordinates are non-distinct.
 |  | ||||||
|     // To stay on the safe side, we say its not a rotary
 |  | ||||||
|     if (std::isinf(radius)) |  | ||||||
|         return RoundaboutType::Roundabout; |  | ||||||
| 
 | 
 | ||||||
|     // Looks like a rotary: large roundabout with dedicated name
 |     // Looks like a rotary: large roundabout with dedicated name
 | ||||||
|     // do we have a dedicated name for the rotary, if not its a roundabout
 |     // do we have a dedicated name for the rotary, if not its a roundabout
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user