Merge branch 'master' into guido/notification
This commit is contained in:
		
						commit
						a824e64682
					
				@ -7,6 +7,8 @@
 | 
				
			|||||||
      - Notifications are now exposed more prominently, announcing turns onto a ferry/pushing your bike more prominently
 | 
					      - Notifications are now exposed more prominently, announcing turns onto a ferry/pushing your bike more prominently
 | 
				
			||||||
    - Trip Plugin
 | 
					    - Trip Plugin
 | 
				
			||||||
      - changed internal behaviour to prefer the smallest lexicographic result over the largest one
 | 
					      - changed internal behaviour to prefer the smallest lexicographic result over the largest one
 | 
				
			||||||
 | 
					    - Bugfixes
 | 
				
			||||||
 | 
					      - fixed a bug where polyline decoding on a defective polyline could end up in out-of-bound access on a vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 5.4.0
 | 
					# 5.4.0
 | 
				
			||||||
  - Changes from 5.3.0
 | 
					  - Changes from 5.3.0
 | 
				
			||||||
 | 
				
			|||||||
@ -249,7 +249,7 @@ http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397634,52
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Returns a asymmetric 3x2 matrix with from the polyline encoded locations `qikdcB}~dpXkkHz`:
 | 
					Returns a asymmetric 3x2 matrix with from the polyline encoded locations `qikdcB}~dpXkkHz`:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
http://router.project-osrm.org/table/v1/driving/qikdcB}~dpXkkHz?sources=0;1;3&destinations=2;4
 | 
					http://router.project-osrm.org/table/v1/driving/polyline(egs_Iq_aqAppHzbHulFzeMe`EuvKpnCglA)?sources=0;1;3&destinations=2;4
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Service `match`
 | 
					## Service `match`
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -100,7 +100,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
 | 
				
			|||||||
            b = geometry_string.at(index++) - 63;
 | 
					            b = geometry_string.at(index++) - 63;
 | 
				
			||||||
            result |= (b & 0x1f) << shift;
 | 
					            result |= (b & 0x1f) << shift;
 | 
				
			||||||
            shift += 5;
 | 
					            shift += 5;
 | 
				
			||||||
        } while (b >= 0x20);
 | 
					        } while (b >= 0x20 && index < len);
 | 
				
			||||||
        int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
 | 
					        int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
 | 
				
			||||||
        lat += dlat;
 | 
					        lat += dlat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +111,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
 | 
				
			|||||||
            b = geometry_string.at(index++) - 63;
 | 
					            b = geometry_string.at(index++) - 63;
 | 
				
			||||||
            result |= (b & 0x1f) << shift;
 | 
					            result |= (b & 0x1f) << shift;
 | 
				
			||||||
            shift += 5;
 | 
					            shift += 5;
 | 
				
			||||||
        } while (b >= 0x20);
 | 
					        } while (b >= 0x20 && index < len);
 | 
				
			||||||
        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
 | 
					        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
 | 
				
			||||||
        lng += dlng;
 | 
					        lng += dlng;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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