Compare commits
10 Commits
master
...
v5.15.0-rc
Author | SHA1 | Date | |
---|---|---|---|
|
f7613d77d5 | ||
|
c80edef46c | ||
|
cfae4a1923 | ||
|
fd9d5af7e0 | ||
|
c81942c167 | ||
|
c5c4a1b4fe | ||
|
eb13041784 | ||
|
fa1f121b02 | ||
|
c26642de6e | ||
|
ef1fc8a757 |
@ -12,7 +12,7 @@ notifications:
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- 5.15
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
# UNRELEASED
|
||||
# 5.15.0 RC2
|
||||
- Changes from 5.14.3:
|
||||
- Bugfixes:
|
||||
- FIXED #4704: Fixed regression in bearings reordering introduced in 5.13 [#4704](https://github.com/Project-OSRM/osrm-backend/issues/4704)
|
||||
- FIXED #4781: Fixed overflow exceptions in percent-encoding parsing
|
||||
- FIXED #4770: Fixed exclude flags for single toll road scenario
|
||||
- FIXED #4283: Fix overflow on zero duration segments
|
||||
- FIXED #4804: Ignore no_*_on_red turn restrictions
|
||||
- Guidance:
|
||||
- CHANGED #4706: Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation [#4706](https://github.com/Project-OSRM/osrm-backend/pull/4706)
|
||||
- Profile:
|
||||
- ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such
|
||||
|
||||
# 5.14.3
|
||||
- Changes from 5.14.2:
|
||||
|
@ -82,7 +82,7 @@ Feature: Car - Mode flag
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,cd | depart,arrive| [(restricted),(motorway,restricted),()],[()] |
|
||||
|
||||
Scenario: Car - We toll restricted with a class
|
||||
Scenario: Car - We tag toll with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
@ -99,6 +99,26 @@ Feature: Car - Mode flag
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,cd | depart,arrive | [(toll),(motorway,toll),()],[()] |
|
||||
|
||||
Scenario: Car - We tag tunnel with a class
|
||||
Background:
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | tunnel |
|
||||
| ab | no |
|
||||
| bc | yes |
|
||||
| cd | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,bc,cd,cd | depart,new name right,new name left,arrive | [()],[(tunnel)],[()],[()] |
|
||||
|
||||
Scenario: Car - From roundabout on toll road
|
||||
Given the node map
|
||||
"""
|
||||
|
@ -141,6 +141,33 @@ Feature: Car - Turn restrictions
|
||||
| c | a | cj,aj,aj |
|
||||
| c | b | cj,bj,bj |
|
||||
|
||||
@no_turning
|
||||
Scenario: Car - Ignore no_*_on_red relations
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
d j b
|
||||
c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| cj | yes |
|
||||
| aj | -1 |
|
||||
| dj | -1 |
|
||||
| bj | -1 |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | cj | dj | j | no_turn_on_red |
|
||||
| restriction | cj | bj | j | no_right_turn_on_red |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| c | d | cj,dj,dj |
|
||||
| c | a | cj,aj,aj |
|
||||
| c | b | cj,bj,bj |
|
||||
|
||||
@only_turning
|
||||
Scenario: Car - Only left turn
|
||||
Given the node map
|
||||
|
@ -59,3 +59,27 @@ Feature: Annotations
|
||||
| from | to | route | a:datasources | a:speed |
|
||||
| a | i | abcdefghi,abcdefghi | 1:0:1:0:1:0:0:0 | 50:10:50:10:50:10:10:10 |
|
||||
| i | a | abcdefghi,abcdefghi | 0:1:0:0:0:0:0:1 | 10:50:10:10:10:10:10:50 |
|
||||
|
||||
Scenario: Speed annotations should handle zero segments
|
||||
Given the profile "testbot"
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a -- b --- c
|
||||
|
|
||||
d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abc |
|
||||
| cd |
|
||||
|
||||
# This test relies on the snapping to the EBN cd to introduce a zero segment after the turn
|
||||
And the query options
|
||||
| annotations | speed,distance,duration,nodes |
|
||||
| bearings | 90,5;180,5 |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
||||
| a | c | abc,abc | 10:10:10 | 249.998641:299.931643:0 | 25:30:0 | 1:2:3 |
|
||||
|
@ -87,9 +87,9 @@ class MatchAPI final : public RouteAPI
|
||||
0u, static_cast<unsigned>(sub_matchings[sub_matching_index].indices.size())))
|
||||
{
|
||||
// tidied_to_original: index of the input coordinate that a tidied coordinate
|
||||
// corresponds to
|
||||
// corresponds to.
|
||||
// sub_matching indices: index of the coordinate passed to map matching plugin that
|
||||
// a matched node corresponds to
|
||||
// a matched node corresponds to.
|
||||
trace_idx_to_matching_idx[tidy_result
|
||||
.tidied_to_original[sub_matchings[sub_matching_index]
|
||||
.indices[point_index]]] =
|
||||
@ -97,6 +97,8 @@ class MatchAPI final : public RouteAPI
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1);
|
||||
|
||||
std::size_t was_waypoint_idx = 0;
|
||||
for (auto trace_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
|
||||
{
|
||||
@ -115,17 +117,23 @@ class MatchAPI final : public RouteAPI
|
||||
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
|
||||
auto waypoint = BaseAPI::MakeWaypoint(phantom);
|
||||
waypoint.values["matchings_index"] = matching_index.sub_matching_index;
|
||||
waypoint.values["waypoint_index"] = matching_index.point_index;
|
||||
waypoint.values["alternatives_count"] =
|
||||
sub_matchings[matching_index.sub_matching_index]
|
||||
.alternatives_count[matching_index.point_index];
|
||||
if (tidy_result.was_waypoint[trace_index])
|
||||
// waypoint indices need to be adjusted if route legs were collapsed
|
||||
// waypoint parameter assumes there is only one match object
|
||||
if (!parameters.waypoints.empty())
|
||||
{
|
||||
waypoint.values["waypoint_index"] = was_waypoint_idx;
|
||||
was_waypoint_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
waypoint.values["waypoint_index"] = util::json::Null();
|
||||
if (tidy_result.was_waypoint[trace_index])
|
||||
{
|
||||
waypoint.values["waypoint_index"] = was_waypoint_idx;
|
||||
was_waypoint_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
waypoint.values["waypoint_index"] = util::json::Null();
|
||||
}
|
||||
}
|
||||
waypoints.values.push_back(std::move(waypoint));
|
||||
}
|
||||
|
@ -88,11 +88,12 @@ class RouteAPI : public BaseAPI
|
||||
{
|
||||
util::json::Array annotations_store;
|
||||
annotations_store.values.reserve(leg.annotations.size());
|
||||
std::for_each(leg.annotations.begin(),
|
||||
leg.annotations.end(),
|
||||
[Get, &annotations_store](const auto &step) {
|
||||
annotations_store.values.push_back(Get(step));
|
||||
});
|
||||
|
||||
for (const auto &step : leg.annotations)
|
||||
{
|
||||
annotations_store.values.push_back(Get(step));
|
||||
}
|
||||
|
||||
return annotations_store;
|
||||
}
|
||||
|
||||
@ -255,10 +256,19 @@ class RouteAPI : public BaseAPI
|
||||
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
||||
{
|
||||
double prev_speed = 0;
|
||||
annotation.values["speed"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
auto val = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||
return util::json::clamp_float(val);
|
||||
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
||||
if (anno.duration < std::numeric_limits<double>::min())
|
||||
{
|
||||
return prev_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||
prev_speed = speed;
|
||||
return util::json::clamp_float(speed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -293,11 +303,10 @@ class RouteAPI : public BaseAPI
|
||||
{
|
||||
util::json::Array nodes;
|
||||
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
||||
std::for_each(leg_geometry.osm_node_ids.begin(),
|
||||
leg_geometry.osm_node_ids.end(),
|
||||
[this, &nodes](const OSMNodeID &node_id) {
|
||||
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
|
||||
});
|
||||
for (const auto node_id : leg_geometry.osm_node_ids)
|
||||
{
|
||||
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
|
||||
}
|
||||
annotation.values["nodes"] = std::move(nodes);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "osrm",
|
||||
"version": "5.15.0-latest.4",
|
||||
"version": "5.15.0-rc.2",
|
||||
"private": false,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
|
@ -104,7 +104,7 @@ function setup()
|
||||
},
|
||||
|
||||
classes = Sequence {
|
||||
'toll', 'motorway', 'ferry', 'restricted'
|
||||
'toll', 'motorway', 'ferry', 'restricted', 'tunnel'
|
||||
},
|
||||
|
||||
-- classes to support for exclude flags
|
||||
|
@ -23,8 +23,6 @@ function Measure.parse_value_meters(value)
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
print("Can't parse value: ", value)
|
||||
end
|
||||
|
||||
--- according to http://wiki.openstreetmap.org/wiki/Map_Features/Units#Explicit_specifications
|
||||
@ -55,10 +53,6 @@ function Measure.parse_value_kilograms(value)
|
||||
return tonumber(m) * 1000
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
print("Can't parse value: ", value)
|
||||
return
|
||||
end
|
||||
|
||||
--- Get maxheight of specified way in meters. If there are no
|
||||
|
@ -283,6 +283,12 @@ end
|
||||
function WayHandlers.classes(profile,way,result,data)
|
||||
local forward_toll, backward_toll = Tags.get_forward_backward_by_key(way, data, "toll")
|
||||
local forward_route, backward_route = Tags.get_forward_backward_by_key(way, data, "route")
|
||||
local tunnel = way:get_value_by_key("tunnel")
|
||||
|
||||
if tunnel and tunnel ~= "no" then
|
||||
result.forward_classes["tunnel"] = true
|
||||
result.backward_classes["tunnel"] = true
|
||||
end
|
||||
|
||||
if forward_toll == "yes" then
|
||||
result.forward_classes["toll"] = true
|
||||
|
@ -107,12 +107,12 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
const std::string value(fi_begin->value());
|
||||
|
||||
// documented OSM restriction tags start either with only_* or no_*;
|
||||
// check and return on these values, and ignore unrecognized values
|
||||
// check and return on these values, and ignore no_*_on_red or unrecognized values
|
||||
if (value.find("only_") == 0)
|
||||
{
|
||||
is_only_restriction = true;
|
||||
}
|
||||
else if (value.find("no_") == 0)
|
||||
else if (value.find("no_") == 0 && !boost::algorithm::ends_with(value, "_on_red"))
|
||||
{
|
||||
is_only_restriction = false;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ exports.three_test_coordinates = [[7.41337, 43.72956],
|
||||
|
||||
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
|
||||
|
||||
exports.test_tile = {'at': [17059, 11948, 15], 'size': 168606};
|
||||
exports.test_tile = {'at': [17059, 11948, 15], 'size': 169239};
|
||||
|
||||
|
||||
// Test files generated by the routing engine; check test/data
|
||||
|
@ -13,6 +13,14 @@ using Latitude = osrm::util::FloatLatitude;
|
||||
using Location = osrm::util::Coordinate;
|
||||
using Locations = std::vector<Location>;
|
||||
|
||||
inline Locations get_split_trace_locations()
|
||||
{
|
||||
return {{Longitude{7.420202}, Latitude{43.732274}},
|
||||
{Longitude{7.422369}, Latitude{43.732282}},
|
||||
{Longitude{7.421511}, Latitude{43.734181}},
|
||||
{Longitude{7.421489}, Latitude{43.736553}}};
|
||||
}
|
||||
|
||||
inline Location get_dummy_location()
|
||||
{
|
||||
return {osrm::util::FloatLongitude{7.437069}, osrm::util::FloatLatitude{43.749249}};
|
||||
|
@ -64,4 +64,61 @@ BOOST_AUTO_TEST_CASE(test_match)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_match_split)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm");
|
||||
|
||||
MatchParameters params;
|
||||
params.coordinates = get_split_trace_locations();
|
||||
params.timestamps = {1, 2, 1700, 1800};
|
||||
|
||||
json::Object result;
|
||||
|
||||
const auto rc = osrm.Match(params, result);
|
||||
|
||||
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
||||
const auto code = result.values.at("code").get<json::String>().value;
|
||||
BOOST_CHECK_EQUAL(code, "Ok");
|
||||
|
||||
const auto &tracepoints = result.values.at("tracepoints").get<json::Array>().values;
|
||||
BOOST_CHECK_EQUAL(tracepoints.size(), params.coordinates.size());
|
||||
|
||||
const auto &matchings = result.values.at("matchings").get<json::Array>().values;
|
||||
const auto &number_of_matchings = matchings.size();
|
||||
BOOST_CHECK_EQUAL(number_of_matchings, 2);
|
||||
std::size_t current_matchings_index = 0, expected_waypoint_index = 0;
|
||||
for (const auto &waypoint : tracepoints)
|
||||
{
|
||||
if (waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
|
||||
{
|
||||
BOOST_CHECK(waypoint_check(waypoint));
|
||||
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||
const auto matchings_index =
|
||||
waypoint_object.values.at("matchings_index").get<json::Number>().value;
|
||||
const auto waypoint_index =
|
||||
waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
||||
const auto &route_legs = matchings[matchings_index]
|
||||
.get<json::Object>()
|
||||
.values.at("legs")
|
||||
.get<json::Array>()
|
||||
.values;
|
||||
|
||||
BOOST_CHECK_LT(matchings_index, number_of_matchings);
|
||||
|
||||
expected_waypoint_index =
|
||||
(current_matchings_index != matchings_index) ? 0 : expected_waypoint_index;
|
||||
BOOST_CHECK_EQUAL(waypoint_index, expected_waypoint_index);
|
||||
|
||||
current_matchings_index = matchings_index;
|
||||
++expected_waypoint_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_CHECK(waypoint.is<json::Null>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user