Compare commits
16 Commits
master
...
v5.6.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
|
cfee0f1109 | ||
|
c7ce758e1c | ||
|
3ac4fb5933 | ||
|
2afe5e971b | ||
|
519b744502 | ||
|
d3c2ac671f | ||
|
07a1a907f8 | ||
|
062cae82a0 | ||
|
316c7781a3 | ||
|
e11bcfece5 | ||
|
cb8dee3e60 | ||
|
a1abe71d9f | ||
|
d54c837e51 | ||
|
106d17541d | ||
|
ad29b237e3 | ||
|
febefb4684 |
@ -13,6 +13,7 @@ notifications:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
- "5.6"
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
ccache: true
|
ccache: true
|
||||||
|
10
docs/http.md
10
docs/http.md
@ -172,7 +172,7 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|------------|---------------------------------------------|-------------------------------------------------------------------------------|
|
|------------|---------------------------------------------|-------------------------------------------------------------------------------|
|
||||||
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|
||||||
|steps |`true`, `false` (default) |Return route steps for each route leg |
|
|steps |`true`, `false` (default) |Return route steps for each route leg |
|
||||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||||
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|
||||||
@ -275,7 +275,7 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|
||||||
|steps |`true`, `false` (default) |Return route steps for each route |
|
|steps |`true`, `false` (default) |Return route steps for each route |
|
||||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||||
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. |
|
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. |
|
||||||
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|
||||||
@ -327,7 +327,7 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate |
|
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate |
|
||||||
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate |
|
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate |
|
||||||
|steps |`true`, `false` (default) |Return route instructions for each trip |
|
|steps |`true`, `false` (default) |Return route instructions for each trip |
|
||||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||||
|
|
||||||
@ -518,7 +518,8 @@ With `steps=false` and `annotations=true`:
|
|||||||
"distance": [5,5,10,5,5],
|
"distance": [5,5,10,5,5],
|
||||||
"duration": [15,15,40,15,15],
|
"duration": [15,15,40,15,15],
|
||||||
"datasources": [1,0,0,0,1],
|
"datasources": [1,0,0,0,1],
|
||||||
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
|
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
|
||||||
|
"speed": [0.3, 0.3, 0.3, 0.3, 0.3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -534,6 +535,7 @@ Annotation of the whole route leg with fine-grained information about each segme
|
|||||||
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
|
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
|
||||||
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
|
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
|
||||||
- `weight`: The weights between each pair of coordinates
|
- `weight`: The weights between each pair of coordinates
|
||||||
|
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -28,6 +28,29 @@ This dataset is a small extract and may not even contain all tags or edge cases.
|
|||||||
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
|
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
|
||||||
See the library tests for how to add new dataset dependent tests.
|
See the library tests for how to add new dataset dependent tests.
|
||||||
|
|
||||||
|
To prepare the test data simply `cd test/data/` and then run `make`.
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
To build the unit tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make tests
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see the compiled binaries in `build/unit_tests`, you can then run each suite individually:
|
||||||
|
|
||||||
|
```
|
||||||
|
./engine-tests
|
||||||
|
```
|
||||||
|
|
||||||
|
For `library-tests` you will need to provide a path to the test data:
|
||||||
|
|
||||||
|
```
|
||||||
|
./library-tests ../../test/data/monaco.osrm
|
||||||
|
```
|
||||||
|
|
||||||
## Cucumber
|
## Cucumber
|
||||||
|
|
||||||
|
@ -45,3 +45,9 @@ Feature: Car - speeds
|
|||||||
| primary | 60 | 47 km/h | 47 km/h |
|
| primary | 60 | 47 km/h | 47 km/h |
|
||||||
| primary | 60 | 47 km/h | 47 km/h |
|
| primary | 60 | 47 km/h | 47 km/h |
|
||||||
| primary | 60 | 47 km/h | 47 km/h |
|
| primary | 60 | 47 km/h | 47 km/h |
|
||||||
|
|
||||||
|
Scenario: Car - Side road penalties
|
||||||
|
Then routability should be
|
||||||
|
|
||||||
|
| highway | side_road | forw | backw | forw_rate | backw_rate |
|
||||||
|
| primary | yes | 64 km/h | 64 km/h | 14 | 14 |
|
||||||
|
@ -1158,3 +1158,45 @@ Feature: Turn Lane Guidance
|
|||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | bearings | route | turns |
|
| waypoints | bearings | route | turns |
|
||||||
| 1,a | 90,2 180,180 | | |
|
| 1,a | 90,2 180,180 | | |
|
||||||
|
|
||||||
|
@3379
|
||||||
|
Scenario: Don't Turn through potential through lanes
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
d
|
||||||
|
|
|
||||||
|
a - - - - b - - - - - c
|
||||||
|
|
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes | name | oneway | turn:lanes:forward |
|
||||||
|
| ab | road | yes | left\|none\|none |
|
||||||
|
| bc | road | yes | |
|
||||||
|
| ebd | cross | no | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns | lanes |
|
||||||
|
| a,e | road,cross,cross | depart,turn right,arrive | ,left:false none:false none:true, |
|
||||||
|
| a,c | road,road | depart,arrive | , |
|
||||||
|
|
||||||
|
@3379
|
||||||
|
Scenario: Don't Turn through potential through lanes
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
d
|
||||||
|
|
|
||||||
|
a - - - - b - - - - - c
|
||||||
|
|
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes | name | oneway | turn:lanes:forward |
|
||||||
|
| ab | road | yes | none\|none\|right |
|
||||||
|
| bc | road | yes | |
|
||||||
|
| ebd | cross | no | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns | lanes |
|
||||||
|
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
|
||||||
|
| a,c | road,road | depart,arrive | , |
|
||||||
|
@ -28,3 +28,11 @@ Feature: osrm-contract command line options: datasources
|
|||||||
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
|
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
|
||||||
Then datasource names should contain "lua profile,27_osrmcontract_passing_base_file_speeds"
|
Then datasource names should contain "lua profile,27_osrmcontract_passing_base_file_speeds"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
|
Scenario: osrm-contract - Passing base file
|
||||||
|
Given the speed file
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
And the data has been extracted
|
||||||
|
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
|
||||||
|
Then it should exit successfully
|
||||||
|
@ -147,7 +147,7 @@ module.exports = function () {
|
|||||||
// if header matches 'a:*', parse out the values for *
|
// if header matches 'a:*', parse out the values for *
|
||||||
// and return in that header
|
// and return in that header
|
||||||
headers.forEach((k) => {
|
headers.forEach((k) => {
|
||||||
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight'];
|
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed'];
|
||||||
if (k.match(/^a:/)) {
|
if (k.match(/^a:/)) {
|
||||||
let a_type = k.slice(2);
|
let a_type = k.slice(2);
|
||||||
if (whitelist.indexOf(a_type) == -1)
|
if (whitelist.indexOf(a_type) == -1)
|
||||||
|
@ -39,7 +39,7 @@ Feature: Weight tests
|
|||||||
# FIXME include/engine/guidance/assemble_geometry.hpp:95
|
# FIXME include/engine/guidance/assemble_geometry.hpp:95
|
||||||
Scenario: Start and target on the same and adjacent edge
|
Scenario: Start and target on the same and adjacent edge
|
||||||
Given the query options
|
Given the query options
|
||||||
| annotations | distance,duration,weight,nodes |
|
| annotations | distance,duration,weight,nodes,speed |
|
||||||
|
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@ -53,11 +53,11 @@ Feature: Weight tests
|
|||||||
| abc |
|
| abc |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight |
|
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
||||||
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 |
|
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 | 6.7 |
|
||||||
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 |
|
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 | 6.5 |
|
||||||
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 |
|
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
|
||||||
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 |
|
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
|
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
|
||||||
|
@ -228,42 +228,59 @@ class RouteAPI : public BaseAPI
|
|||||||
|
|
||||||
std::vector<util::json::Object> annotations;
|
std::vector<util::json::Object> annotations;
|
||||||
|
|
||||||
if (parameters.annotations_type != RouteParameters::AnnotationsType::None)
|
// To maintain support for uses of the old default constructors, we check
|
||||||
|
// if annotations property was set manually after default construction
|
||||||
|
auto requested_annotations = parameters.annotations_type;
|
||||||
|
if ((parameters.annotations == true) &&
|
||||||
|
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
|
||||||
|
{
|
||||||
|
requested_annotations = RouteParameters::AnnotationsType::All;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requested_annotations != RouteParameters::AnnotationsType::None)
|
||||||
{
|
{
|
||||||
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
|
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
|
||||||
{
|
{
|
||||||
auto &leg_geometry = leg_geometries[idx];
|
auto &leg_geometry = leg_geometries[idx];
|
||||||
util::json::Object annotation;
|
util::json::Object annotation;
|
||||||
|
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Duration)
|
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||||
|
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
||||||
|
{
|
||||||
|
annotation.values["speed"] = GetAnnotations(
|
||||||
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||||
|
return std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||||
{
|
{
|
||||||
annotation.values["duration"] = GetAnnotations(
|
annotation.values["duration"] = GetAnnotations(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||||
return anno.duration;
|
return anno.duration;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Distance)
|
|
||||||
{
|
{
|
||||||
annotation.values["distance"] = GetAnnotations(
|
annotation.values["distance"] = GetAnnotations(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||||
return anno.distance;
|
return anno.distance;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Weight)
|
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||||
{
|
{
|
||||||
annotation.values["weight"] = GetAnnotations(
|
annotation.values["weight"] = GetAnnotations(
|
||||||
leg_geometry,
|
leg_geometry,
|
||||||
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
|
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
|
||||||
}
|
}
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Datasources)
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||||
{
|
{
|
||||||
annotation.values["datasources"] = GetAnnotations(
|
annotation.values["datasources"] = GetAnnotations(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||||
return anno.datasource;
|
return anno.datasource;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Nodes)
|
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||||
{
|
{
|
||||||
util::json::Array nodes;
|
util::json::Array nodes;
|
||||||
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
||||||
|
@ -75,7 +75,8 @@ struct RouteParameters : public BaseParameters
|
|||||||
Distance = 0x04,
|
Distance = 0x04,
|
||||||
Weight = 0x08,
|
Weight = 0x08,
|
||||||
Datasources = 0x10,
|
Datasources = 0x10,
|
||||||
All = Duration | Nodes | Distance | Weight | Datasources
|
Speed = 0x20,
|
||||||
|
All = Duration | Nodes | Distance | Weight | Datasources | Speed
|
||||||
};
|
};
|
||||||
|
|
||||||
RouteParameters() = default;
|
RouteParameters() = default;
|
||||||
|
@ -42,11 +42,13 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
|
|
||||||
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||||
{
|
{
|
||||||
|
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
|
||||||
|
|
||||||
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
||||||
engine::api::RouteParameters::AnnotationsType &route_param) {
|
AnnotationsType route_param) {
|
||||||
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
|
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
|
||||||
route_parameters.annotations = route_parameters.annotations_type !=
|
route_parameters.annotations =
|
||||||
engine::api::RouteParameters::AnnotationsType::None;
|
route_parameters.annotations_type != AnnotationsType::None;
|
||||||
};
|
};
|
||||||
|
|
||||||
geometries_type.add("geojson", engine::api::RouteParameters::GeometriesType::GeoJSON)(
|
geometries_type.add("geojson", engine::api::RouteParameters::GeometriesType::GeoJSON)(
|
||||||
@ -57,13 +59,10 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
"full", engine::api::RouteParameters::OverviewType::Full)(
|
"full", engine::api::RouteParameters::OverviewType::Full)(
|
||||||
"false", engine::api::RouteParameters::OverviewType::False);
|
"false", engine::api::RouteParameters::OverviewType::False);
|
||||||
|
|
||||||
annotations_type.add("true", engine::api::RouteParameters::AnnotationsType::All)(
|
annotations_type.add("duration", AnnotationsType::Duration)("nodes",
|
||||||
"false", engine::api::RouteParameters::AnnotationsType::None)(
|
AnnotationsType::Nodes)(
|
||||||
"duration", engine::api::RouteParameters::AnnotationsType::Duration)(
|
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
|
||||||
"nodes", engine::api::RouteParameters::AnnotationsType::Nodes)(
|
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
|
||||||
"distance", engine::api::RouteParameters::AnnotationsType::Distance)(
|
|
||||||
"weight", engine::api::RouteParameters::AnnotationsType::Weight)(
|
|
||||||
"datasources", engine::api::RouteParameters::AnnotationsType::Datasources);
|
|
||||||
|
|
||||||
base_rule =
|
base_rule =
|
||||||
BaseGrammar::base_rule(qi::_r1) |
|
BaseGrammar::base_rule(qi::_r1) |
|
||||||
@ -75,7 +74,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
(qi::lit("overview=") >
|
(qi::lit("overview=") >
|
||||||
overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1]) |
|
overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1]) |
|
||||||
(qi::lit("annotations=") >
|
(qi::lit("annotations=") >
|
||||||
annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',');
|
(qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] |
|
||||||
|
qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] |
|
||||||
|
(annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',')));
|
||||||
|
|
||||||
query_rule = BaseGrammar::query_rule(qi::_r1);
|
query_rule = BaseGrammar::query_rule(qi::_r1);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "osrm-backend-test-suite",
|
"name": "osrm-backend-test-suite",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.",
|
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"cucumber": "^1.2.1",
|
"cucumber": "^1.2.1",
|
||||||
|
@ -327,7 +327,7 @@ function Handlers.handle_penalties(way,result,data,profile)
|
|||||||
local sideroad_penalty = 1.0
|
local sideroad_penalty = 1.0
|
||||||
data.sideroad = way:get_value_by_key("side_road")
|
data.sideroad = way:get_value_by_key("side_road")
|
||||||
if "yes" == data.sideroad or "rotary" == data.sideroad then
|
if "yes" == data.sideroad or "rotary" == data.sideroad then
|
||||||
sideroad_penalty = side_road_multiplier;
|
sideroad_penalty = profile.side_road_multiplier
|
||||||
end
|
end
|
||||||
|
|
||||||
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, forward_hov_penalty)
|
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, forward_hov_penalty)
|
||||||
|
@ -268,7 +268,7 @@ template <typename Key, typename Value> struct CSVFilesParser
|
|||||||
qi::rule<Iterator, std::pair<Key, Value>()> csv_line =
|
qi::rule<Iterator, std::pair<Key, Value>()> csv_line =
|
||||||
(key_rule >> ',' >> value_source) >> -(',' >> *(qi::char_ - qi::eol));
|
(key_rule >> ',' >> value_source) >> -(',' >> *(qi::char_ - qi::eol));
|
||||||
std::vector<std::pair<Key, Value>> result;
|
std::vector<std::pair<Key, Value>> result;
|
||||||
const auto ok = qi::parse(first, last, (csv_line % qi::eol) >> *qi::eol, result);
|
const auto ok = qi::parse(first, last, -(csv_line % qi::eol) >> *qi::eol, result);
|
||||||
|
|
||||||
if (!ok || first != last)
|
if (!ok || first != last)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,6 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
|
|||||||
LaneDataVector lane_data,
|
LaneDataVector lane_data,
|
||||||
const Intersection &intersection)
|
const Intersection &intersection)
|
||||||
{
|
{
|
||||||
|
|
||||||
// a none-turn is allowing multiple turns. we have to add a lane-data entry for
|
// a none-turn is allowing multiple turns. we have to add a lane-data entry for
|
||||||
// every possible turn. This should, hopefully, only be the case for single lane
|
// every possible turn. This should, hopefully, only be the case for single lane
|
||||||
// entries?
|
// entries?
|
||||||
@ -107,20 +106,64 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
|
|||||||
util::Log(logWARNING) << "Failed lane assignment. Reached bad situation.";
|
util::Log(logWARNING) << "Failed lane assignment. Reached bad situation.";
|
||||||
return std::make_pair(std::size_t{0}, std::size_t{0});
|
return std::make_pair(std::size_t{0}, std::size_t{0});
|
||||||
}();
|
}();
|
||||||
for (auto intersection_index = range.first; intersection_index < range.second;
|
|
||||||
++intersection_index)
|
const auto intersection_range_first = intersection.begin() + range.first;
|
||||||
|
const auto intersection_range_end = intersection.begin() + range.second;
|
||||||
|
const auto allowed_in_range =
|
||||||
|
std::count_if(intersection_range_first, intersection_range_end, [](const auto &road) {
|
||||||
|
return road.entry_allowed;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (allowed_in_range > 1 && lane_data[none_index].to - lane_data[none_index].from >= 1)
|
||||||
{
|
{
|
||||||
if (intersection[intersection_index].entry_allowed)
|
// check if there is a straight turn
|
||||||
|
auto straight_itr =
|
||||||
|
std::find_if(intersection_range_first, intersection_range_end, [](const auto &road) {
|
||||||
|
return road.instruction.direction_modifier == DirectionModifier::Straight;
|
||||||
|
});
|
||||||
|
|
||||||
|
// we have a straight turn?
|
||||||
|
if (straight_itr != intersection_range_end)
|
||||||
{
|
{
|
||||||
// FIXME this probably can be only a subset of these turns here?
|
for (auto itr = intersection_range_first; itr != straight_itr; ++itr)
|
||||||
lane_data.push_back(
|
{
|
||||||
{tag_by_modifier[intersection[intersection_index].instruction.direction_modifier],
|
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
|
||||||
lane_data[none_index].from,
|
lane_data[none_index].from,
|
||||||
lane_data[none_index].to,
|
lane_data[none_index].from,
|
||||||
false});
|
false});
|
||||||
|
}
|
||||||
|
lane_data.push_back({tag_by_modifier[straight_itr->instruction.direction_modifier],
|
||||||
|
lane_data[none_index].from,
|
||||||
|
lane_data[none_index].to,
|
||||||
|
false});
|
||||||
|
for (auto itr = straight_itr + 1; itr != intersection_range_end; ++itr)
|
||||||
|
{
|
||||||
|
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
|
||||||
|
lane_data[none_index].to,
|
||||||
|
lane_data[none_index].to,
|
||||||
|
false});
|
||||||
|
}
|
||||||
|
|
||||||
|
lane_data.erase(lane_data.begin() + none_index);
|
||||||
}
|
}
|
||||||
|
return lane_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto intersection_index = range.first; intersection_index < range.second;
|
||||||
|
++intersection_index)
|
||||||
|
{
|
||||||
|
if (intersection[intersection_index].entry_allowed)
|
||||||
|
{
|
||||||
|
lane_data.push_back({tag_by_modifier[intersection[intersection_index]
|
||||||
|
.instruction.direction_modifier],
|
||||||
|
lane_data[none_index].from,
|
||||||
|
lane_data[none_index].to,
|
||||||
|
false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lane_data.erase(lane_data.begin() + none_index);
|
||||||
}
|
}
|
||||||
lane_data.erase(lane_data.begin() + none_index);
|
|
||||||
return lane_data;
|
return lane_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
#ifndef OSRM_UNIT_TEST_ARGS
|
#ifndef OSRM_UNIT_TEST_ARGS
|
||||||
#define OSRM_UNIT_TEST_ARGS
|
#define OSRM_UNIT_TEST_ARGS
|
||||||
|
|
||||||
|
#include "util/log.hpp"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
inline std::vector<std::string> get_args()
|
inline std::vector<std::string> get_args()
|
||||||
{
|
{
|
||||||
|
osrm::util::LogPolicy::GetInstance().Unmute();
|
||||||
|
if ((boost::unit_test::framework::master_test_suite().argc != 2) ||
|
||||||
|
(!boost::filesystem::is_regular_file(
|
||||||
|
boost::unit_test::framework::master_test_suite().argv[1])))
|
||||||
|
{
|
||||||
|
osrm::util::Log(logERROR) << "Please provide valid input osrm file";
|
||||||
|
osrm::util::Log(logERROR) << "Usage: "
|
||||||
|
<< boost::unit_test::framework::master_test_suite().argv[0]
|
||||||
|
<< " /path/to/input_osrm_file" << std::endl;
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Split off argv[0], store actual positional arguments in args
|
// Split off argv[0], store actual positional arguments in args
|
||||||
const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
|
const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
|
||||||
const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;
|
const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;
|
||||||
|
@ -387,4 +387,72 @@ BOOST_AUTO_TEST_CASE(test_route_user_disables_generating_hints)
|
|||||||
BOOST_CHECK_EQUAL(waypoint.get<json::Object>().values.count("hint"), 0);
|
BOOST_CHECK_EQUAL(waypoint.get<json::Object>().values.count("hint"), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
RouteParameters params;
|
||||||
|
params.annotations_type = RouteParameters::AnnotationsType::Duration |
|
||||||
|
RouteParameters::AnnotationsType::Distance |
|
||||||
|
RouteParameters::AnnotationsType::Speed;
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Route(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto &routes = result.values["routes"].get<json::Array>().values;
|
||||||
|
const auto &legs = routes[0].get<json::Object>().values.at("legs").get<json::Array>().values;
|
||||||
|
const auto &annotation =
|
||||||
|
legs[0].get<json::Object>().values.at("annotation").get<json::Object>();
|
||||||
|
const auto &speeds = annotation.values.at("speed").get<json::Array>().values;
|
||||||
|
const auto &durations = annotation.values.at("duration").get<json::Array>().values;
|
||||||
|
const auto &distances = annotation.values.at("distance").get<json::Array>().values;
|
||||||
|
int length = speeds.size();
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
auto speed = speeds[i].get<json::Number>().value;
|
||||||
|
auto duration = durations[i].get<json::Number>().value;
|
||||||
|
auto distance = distances[i].get<json::Number>().value;
|
||||||
|
BOOST_CHECK_EQUAL(speed, std::round(distance / duration * 10.) / 10.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
RouteParameters params{};
|
||||||
|
params.annotations = true;
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Route(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
auto annotations = result.values["routes"]
|
||||||
|
.get<json::Array>()
|
||||||
|
.values[0]
|
||||||
|
.get<json::Object>()
|
||||||
|
.values["legs"]
|
||||||
|
.get<json::Array>()
|
||||||
|
.values[0]
|
||||||
|
.get<json::Object>()
|
||||||
|
.values["annotation"]
|
||||||
|
.get<json::Object>()
|
||||||
|
.values;
|
||||||
|
BOOST_CHECK_EQUAL(annotations.size(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -67,6 +67,7 @@ BOOST_AUTO_TEST_CASE(invalid_route_urls)
|
|||||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=distances"), 28UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=distances"), 28UL);
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations="), 20UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations="), 20UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=true,false"), 24UL);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
testInvalidOptions<RouteParameters>("1,2;3,4?annotations=&overview=simplified"), 20UL);
|
testInvalidOptions<RouteParameters>("1,2;3,4?annotations=&overview=simplified"), 20UL);
|
||||||
|
|
||||||
@ -349,6 +350,22 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
true);
|
true);
|
||||||
BOOST_CHECK_EQUAL(result_15->annotations, true);
|
BOOST_CHECK_EQUAL(result_15->annotations, true);
|
||||||
|
|
||||||
|
RouteParameters reference_speed{};
|
||||||
|
reference_speed.annotations_type = RouteParameters::AnnotationsType::Duration;
|
||||||
|
reference_speed.coordinates = coords_1;
|
||||||
|
auto result_speed =
|
||||||
|
parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
|
||||||
|
"overview=simplified&annotations=duration,distance,speed");
|
||||||
|
BOOST_CHECK(result_speed);
|
||||||
|
BOOST_CHECK_EQUAL(reference_speed.geometries, result_speed->geometries);
|
||||||
|
BOOST_CHECK_EQUAL(reference_speed.overview, result_speed->overview);
|
||||||
|
BOOST_CHECK_EQUAL(result_speed->annotations_type ==
|
||||||
|
(RouteParameters::AnnotationsType::Duration |
|
||||||
|
RouteParameters::AnnotationsType::Distance |
|
||||||
|
RouteParameters::AnnotationsType::Speed),
|
||||||
|
true);
|
||||||
|
BOOST_CHECK_EQUAL(result_speed->annotations, true);
|
||||||
|
|
||||||
// parse multiple annotations correctly
|
// parse multiple annotations correctly
|
||||||
RouteParameters reference_16{};
|
RouteParameters reference_16{};
|
||||||
reference_16.annotations_type = RouteParameters::AnnotationsType::Duration |
|
reference_16.annotations_type = RouteParameters::AnnotationsType::Duration |
|
||||||
|
Loading…
Reference in New Issue
Block a user