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
|
||||
- Trip Plugin
|
||||
- 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
|
||||
- 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`:
|
||||
```
|
||||
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`
|
||||
|
@ -244,8 +244,28 @@ Feature: Basic Roundabout
|
||||
|
||||
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 |
|
||||
| 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 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
|
||||
Given the node map
|
||||
|
@ -231,43 +231,6 @@ Feature: Basic Roundabout
|
||||
| j,f | jk,ef,ef | depart,roundabout-exit-2,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
|
||||
#See 39.933742 -75.082345
|
||||
Given the node map
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -82,7 +82,8 @@ class RoundaboutHandler : public IntersectionHandler
|
||||
const bool can_exit_roundabout,
|
||||
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 ProfileProperties &profile_properties;
|
||||
|
@ -100,7 +100,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
|
||||
b = geometry_string.at(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
} while (b >= 0x20 && index < len);
|
||||
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lat += dlat;
|
||||
|
||||
@ -111,7 +111,7 @@ std::vector<util::Coordinate> decodePolyline(const std::string &geometry_string)
|
||||
b = geometry_string.at(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
} while (b >= 0x20 && index < len);
|
||||
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lng += dlng;
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <unordered_set>
|
||||
|
||||
#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
|
||||
// in postprocessing since we correct the turn-angle in turn-generaion.
|
||||
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
|
||||
const auto getCoordinate = [this](const NodeID node) {
|
||||
@ -262,10 +261,6 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
}
|
||||
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
|
||||
const auto countRoundaboutFlags = [&](const NodeID at_node) {
|
||||
@ -281,6 +276,25 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
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;
|
||||
while (0 == roundabout_nodes.count(last_node))
|
||||
{
|
||||
@ -299,6 +313,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
return RoundaboutType::None;
|
||||
}
|
||||
|
||||
roundabout_length += getEdgeLength(last_node, eid);
|
||||
|
||||
last_node = node_based_graph.GetTarget(eid);
|
||||
|
||||
if (last_node == nid)
|
||||
@ -315,31 +331,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
return RoundaboutType::RoundaboutIntersection;
|
||||
}
|
||||
|
||||
// calculate the radius of the roundabout/rotary. For two coordinates, we assume a minimal
|
||||
// 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;
|
||||
const double radius = roundabout_length / (2 * M_PI);
|
||||
|
||||
// Looks like a rotary: large roundabout with dedicated name
|
||||
// do we have a dedicated name for the rotary, if not its a roundabout
|
||||
|
Loading…
Reference in New Issue
Block a user