Merge branch 'master' into guido/notification

This commit is contained in:
Moritz Kobitzsch 2016-09-29 16:03:44 +02:00 committed by GitHub
commit a824e64682
7 changed files with 54 additions and 76 deletions

View File

@ -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

View File

@ -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`

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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