Compare commits

...

6 Commits

Author SHA1 Message Date
Daniel Patterson 9b414a17e8 Build tags with semver metadata. 2019-02-02 22:19:15 -08:00
Daniel Patterson 54a8a8c494 Update version for custom build. 2019-02-02 22:15:41 -08:00
Daniel Patterson 469c3331e4 Fix formatting. 2019-02-02 22:15:16 -08:00
Daniel Patterson 2aa9e2859a Prototype configurable snapping. 2019-02-02 22:12:05 -08:00
Lev Dragunov 8b45ff7a18 Store metadata about original OSM data, and return it in the API response, if available. 2019-01-30 15:31:56 -08:00
Daniel Patterson 4c665b24d9 Add optional builds for lts and node version aliases. This will give us a heads up when new Node (#5347)
versions break bindings, and might automagically get us support for new versions if it "just works".
2019-01-30 12:17:04 -08:00
27 changed files with 392 additions and 42 deletions
+136 -2
View File
@@ -14,7 +14,7 @@ branches:
only: only:
- master - master
# enable building tags # enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - /^v\d+\.\d+(\.\d+)?(\+[^-]+)?(-\S*)?$/
cache: cache:
npm: true npm: true
@@ -36,6 +36,10 @@ env:
- ENABLE_NODE_BINDINGS=On - ENABLE_NODE_BINDINGS=On
- NODE="10" - NODE="10"
stages:
- core
- optional
matrix: matrix:
fast_finish: true fast_finish: true
@@ -43,12 +47,14 @@ matrix:
include: include:
# Debug Builds # Debug Builds
- os: linux - stage: core
os: linux
compiler: "format-taginfo-docs" compiler: "format-taginfo-docs"
env: NODE=10 env: NODE=10
sudo: false sudo: false
before_install: before_install:
install: install:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
- source $NVM_DIR/nvm.sh - source $NVM_DIR/nvm.sh
- nvm install $NODE - nvm install $NODE
- nvm use $NODE - nvm use $NODE
@@ -275,7 +281,135 @@ matrix:
after_success: after_success:
- ./scripts/travis/publish.sh - ./scripts/travis/publish.sh
- os: osx
stage: optional
osx_image: xcode9.2
compiler: "mason-osx-release-node-latest"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-latest-mason-linux-release"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-latest-mason-linux-debug"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: osx
osx_image: xcode9.2
compiler: "mason-osx-release-node-lts"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-lts-mason-linux-release"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-lts-mason-linux-debug"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
allow_failures:
- compiler: "mason-osx-release-node-latest"
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
- compiler: "node-latest-mason-linux-release"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
- compiler: "node-latest-mason-linux-debug"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
- compiler: "mason-osx-release-node-lts"
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
- compiler: "node-lts-mason-linux-release"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
- compiler: "node-lts-mason-linux-debug"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
before_install: before_install:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
- source $NVM_DIR/nvm.sh - source $NVM_DIR/nvm.sh
- nvm install $NODE - nvm install $NODE
- nvm use $NODE - nvm use $NODE
+3
View File
@@ -1,7 +1,10 @@
# Unreleased # Unreleased
- Changes from 5.21.0 - Changes from 5.21.0
- Build:
- ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347)
- Features: - Features:
- ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345) - ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345)
- ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115)
# 5.21.0 # 5.21.0
- Changes from 5.20.0 - Changes from 5.20.0
+8 -1
View File
@@ -70,6 +70,8 @@ curl 'http://router.project-osrm.org/route/v1/driving/polyline(ofp_Ik_vpAilAyu@t
### Responses ### Responses
#### Code
Every response object has a `code` property containing one of the strings below or a service dependent code: Every response object has a `code` property containing one of the strings below or a service dependent code:
| Type | Description | | Type | Description |
@@ -87,12 +89,17 @@ Every response object has a `code` property containing one of the strings below
- `message` is a **optional** human-readable error message. All other status types are service dependent. - `message` is a **optional** human-readable error message. All other status types are service dependent.
- In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`. - In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
#### Data version
Every response object has a `data_version` propetry containing timestamp from the original OpenStreetMap file. This field is optional. It can be ommited if data_version parametr was not set on osrm-extract stage or OSM file has not `osmosis_replication_timestamp` section.
#### Example response #### Example response
```json ```json
{ {
"code": "Ok", "code": "Ok",
"message": "Everything worked" "message": "Everything worked",
"data_version": "2017-11-17T21:43:02Z"
} }
``` ```
+20
View File
@@ -35,3 +35,23 @@ Feature: Car - Allowed start/end modes
| from | to | route | modes | | from | to | route | modes |
| 1 | 2 | ab,ab | driving,driving | | 1 | 2 | ab,ab | driving,driving |
| 2 | 1 | ab,ab | driving,driving | | 2 | 1 | ab,ab | driving,driving |
Scenario: Car - URL override of non-startpoints
Given the node map
"""
a 1 b c 2 d
"""
Given the query options
| snapping | any |
And the ways
| nodes | highway | access |
| ab | service | private |
| bc | primary | |
| cd | service | private |
When I route I should get
| from | to | route |
| 1 | 2 | ab,bc,cd |
| 2 | 1 | cd,bc,ab |
+4
View File
@@ -75,6 +75,10 @@ module.exports = function () {
got.message = json.message || ''; got.message = json.message || '';
} }
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
if (headers.has('#')) { if (headers.has('#')) {
// comment column // comment column
got['#'] = row['#']; got['#'] = row['#'];
+20 -3
View File
@@ -17,9 +17,26 @@ Feature: Basic Routing
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | | from | to | route | data_version |
| a | b | ab,ab | | a | b | ab,ab | |
| b | a | ab,ab | | b | a | ab,ab | |
Scenario: Data_version test
Given the node map
"""
a b
"""
And the extract extra arguments "--data_version cucumber_data_version"
And the ways
| nodes |
| ab |
When I route I should get
| from | to | route | data_version |
| a | b | ab,ab | cucumber_data_version |
| b | a | ab,ab | cucumber_data_version |
Scenario: Routing in between two nodes of way Scenario: Routing in between two nodes of way
Given the node map Given the node map
+5
View File
@@ -68,6 +68,11 @@ class RouteAPI : public BaseAPI
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points); response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
response.values["routes"] = std::move(jsRoutes); response.values["routes"] = std::move(jsRoutes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
protected: protected:
+10 -2
View File
@@ -78,6 +78,11 @@ struct RouteParameters : public BaseParameters
Speed = 0x20, Speed = 0x20,
All = Duration | Nodes | Distance | Weight | Datasources | Speed All = Duration | Nodes | Distance | Weight | Datasources | Speed
}; };
enum class SnappingType
{
Default,
Any
};
RouteParameters() = default; RouteParameters() = default;
@@ -147,12 +152,13 @@ struct RouteParameters : public BaseParameters
const OverviewType overview_, const OverviewType overview_,
const boost::optional<bool> continue_straight_, const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_, std::vector<std::size_t> waypoints_,
const SnappingType snapping_,
const Args... args_) const Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_}, number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None}, annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}, geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_},
waypoints{waypoints_} waypoints{waypoints_}, snapping{snapping_}
{ {
} }
@@ -165,12 +171,13 @@ struct RouteParameters : public BaseParameters
const OverviewType overview_, const OverviewType overview_,
const boost::optional<bool> continue_straight_, const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_, std::vector<std::size_t> waypoints_,
const SnappingType snapping_,
Args... args_) Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, number_of_alternatives{alternatives_ ? 1u : 0u},
annotations{annotations_ == AnnotationsType::None ? false : true}, annotations{annotations_ == AnnotationsType::None ? false : true},
annotations_type{annotations_}, geometries{geometries_}, overview{overview_}, annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}, waypoints{waypoints_} continue_straight{continue_straight_}, waypoints{waypoints_}, snapping{snapping_}
{ {
} }
@@ -184,6 +191,7 @@ struct RouteParameters : public BaseParameters
OverviewType overview = OverviewType::Simplified; OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight; boost::optional<bool> continue_straight;
std::vector<std::size_t> waypoints; std::vector<std::size_t> waypoints;
SnappingType snapping = SnappingType::Default;
bool IsValid() const bool IsValid() const
{ {
@@ -137,6 +137,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
extractor::Datasources *m_datasources; extractor::Datasources *m_datasources;
std::uint32_t m_check_sum; std::uint32_t m_check_sum;
StringView m_data_timestamp;
util::vector_view<util::Coordinate> m_coordinate_list; util::vector_view<util::Coordinate> m_coordinate_list;
extractor::PackedOSMIDsView m_osmnodeid_list; extractor::PackedOSMIDsView m_osmnodeid_list;
util::vector_view<std::uint32_t> m_lane_description_offsets; util::vector_view<std::uint32_t> m_lane_description_offsets;
@@ -183,6 +184,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum"); m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
std::tie(m_coordinate_list, m_osmnodeid_list) = std::tie(m_coordinate_list, m_osmnodeid_list) =
make_nbn_data_view(index, "/common/nbn_data"); make_nbn_data_view(index, "/common/nbn_data");
@@ -386,23 +389,25 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, approach); input_coordinate, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, approach); input_coordinate, max_distance, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
@@ -410,28 +415,35 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range, approach); input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range, approach); input_coordinate, bearing, bearing_range, approach, use_all_edges);
} }
std::uint32_t GetCheckSum() const override final { return m_check_sum; } std::uint32_t GetCheckSum() const override final { return m_check_sum; }
std::string GetTimestamp() const override final
{
return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
}
GeometryID GetGeometryIndex(const NodeID id) const override final GeometryID GetGeometryIndex(const NodeID id) const override final
{ {
return edge_based_node_data.GetGeometryID(id); return edge_based_node_data.GetGeometryID(id);
+10 -4
View File
@@ -74,6 +74,8 @@ class BaseDataFacade
virtual std::uint32_t GetCheckSum() const = 0; virtual std::uint32_t GetCheckSum() const = 0;
virtual std::string GetTimestamp() const = 0;
// node and edge information access // node and edge information access
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0; virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
@@ -159,22 +161,26 @@ class BaseDataFacade
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges = false) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
+28 -14
View File
@@ -205,18 +205,23 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
&input_coordinate,
&has_big_component,
&has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment, use_all_edges);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, admissible_segments); use_directions = boolPairAnd(use_directions, admissible_segments);
use_directions = boolPairAnd(use_directions, valid_edges); use_directions = boolPairAnd(use_directions, valid_edges);
@@ -251,19 +256,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
&input_coordinate,
&has_big_component,
&has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment, use_all_edges);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, admissible_segments); use_directions = boolPairAnd(use_directions, admissible_segments);
use_directions = boolPairAnd(use_directions, valid_edges); use_directions = boolPairAnd(use_directions, valid_edges);
@@ -298,7 +308,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
@@ -310,12 +321,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component](const CandidateSegment &segment) { &has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
if (use_segment) if (use_segment)
{ {
@@ -356,7 +368,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
@@ -368,12 +381,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component](const CandidateSegment &segment) { &has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
if (use_segment) if (use_segment)
{ {
+11 -5
View File
@@ -262,7 +262,8 @@ class BasePlugin
} }
std::vector<PhantomNodePair> GetPhantomNodes(const datafacade::BaseDataFacade &facade, std::vector<PhantomNodePair> GetPhantomNodes(const datafacade::BaseDataFacade &facade,
const api::BaseParameters &parameters) const const api::BaseParameters &parameters,
const bool use_all_edges = false) const
{ {
std::vector<PhantomNodePair> phantom_node_pairs(parameters.coordinates.size()); std::vector<PhantomNodePair> phantom_node_pairs(parameters.coordinates.size());
@@ -296,7 +297,8 @@ class BasePlugin
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range,
approach); approach,
use_all_edges);
} }
else else
{ {
@@ -305,7 +307,8 @@ class BasePlugin
parameters.coordinates[i], parameters.coordinates[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range,
approach); approach,
use_all_edges);
} }
} }
else else
@@ -314,13 +317,16 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], *parameters.radiuses[i], approach); parameters.coordinates[i],
*parameters.radiuses[i],
approach,
use_all_edges);
} }
else else
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], approach); parameters.coordinates[i], approach, use_all_edges);
} }
} }
+2
View File
@@ -55,6 +55,7 @@ struct ExtractorConfig final : storage::IOConfig
".osrm.geometry", ".osrm.geometry",
".osrm.nbg_nodes", ".osrm.nbg_nodes",
".osrm.ebg_nodes", ".osrm.ebg_nodes",
".osrm.timestamp",
".osrm.edges", ".osrm.edges",
".osrm.ebg", ".osrm.ebg",
".osrm.ramIndex", ".osrm.ramIndex",
@@ -82,6 +83,7 @@ struct ExtractorConfig final : storage::IOConfig
boost::filesystem::path input_path; boost::filesystem::path input_path;
boost::filesystem::path profile_path; boost::filesystem::path profile_path;
std::vector<boost::filesystem::path> location_dependent_data_paths; std::vector<boost::filesystem::path> location_dependent_data_paths;
std::string data_version;
unsigned requested_num_threads; unsigned requested_num_threads;
unsigned small_component_size; unsigned small_component_size;
+20
View File
@@ -308,6 +308,26 @@ inline void writeTurnLaneData(const boost::filesystem::path &path,
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data); storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
} }
// reads .osrm.timestamp
template <typename TimestampDataT>
inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT &timestamp)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/timestamp", timestamp);
}
// writes .osrm.timestamp
template <typename TimestampDataT>
inline void writeTimestamp(const boost::filesystem::path &path, const TimestampDataT &timestamp)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/common/timestamp", timestamp);
}
// reads .osrm.maneuver_overrides // reads .osrm.maneuver_overrides
template <typename StorageManeuverOverrideT, typename NodeSequencesT> template <typename StorageManeuverOverrideT, typename NodeSequencesT>
inline void readManeuverOverrides(const boost::filesystem::path &path, inline void readManeuverOverrides(const boost::filesystem::path &path,
+29
View File
@@ -1010,6 +1010,35 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("snapping").ToLocalChecked()))
{
v8::Local<v8::Value> snapping = obj->Get(Nan::New("snapping").ToLocalChecked());
if (snapping.IsEmpty())
return route_parameters_ptr();
if (!snapping->IsString())
{
Nan::ThrowError("Snapping must be a string: [default, any]");
return route_parameters_ptr();
}
const Nan::Utf8String snapping_utf8str(snapping);
std::string snapping_str{*snapping_utf8str, *snapping_utf8str + snapping_utf8str.length()};
if (snapping_str == "default")
{
params->snapping = osrm::RouteParameters::SnappingType::Default;
}
else if (snapping_str == "any")
{
params->snapping = osrm::RouteParameters::SnappingType::Any;
}
else
{
Nan::ThrowError("'snapping' param must be one of [default, any]");
return route_parameters_ptr();
}
}
bool parsedSuccessfully = parseCommonParameters(obj, params); bool parsedSuccessfully = parseCommonParameters(obj, params);
if (!parsedSuccessfully) if (!parsedSuccessfully)
{ {
@@ -82,6 +82,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
qi::lit("waypoints=") > qi::lit("waypoints=") >
(size_t_ % ';')[ph::bind(&engine::api::RouteParameters::waypoints, qi::_r1) = qi::_1]; (size_t_ % ';')[ph::bind(&engine::api::RouteParameters::waypoints, qi::_r1) = qi::_1];
snapping_type.add("default", engine::api::RouteParameters::SnappingType::Default)(
"any", engine::api::RouteParameters::SnappingType::Any);
base_rule = base_rule =
BaseGrammar::base_rule(qi::_r1) | waypoints_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | waypoints_rule(qi::_r1) |
(qi::lit("steps=") > (qi::lit("steps=") >
@@ -91,6 +94,8 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
qi::_1]) | qi::_1]) |
(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("snapping=") >
snapping_type[ph::bind(&engine::api::RouteParameters::snapping, qi::_r1) = qi::_1]) |
(qi::lit("annotations=") > (qi::lit("annotations=") >
(qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] | (qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] |
qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] | qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] |
@@ -112,6 +117,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type; qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type;
qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type; qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type;
qi::symbols<char, engine::api::RouteParameters::AnnotationsType> annotations_type; qi::symbols<char, engine::api::RouteParameters::AnnotationsType> annotations_type;
qi::symbols<char, engine::api::RouteParameters::SnappingType> snapping_type;
}; };
} }
} }
+1
View File
@@ -58,6 +58,7 @@ struct StorageConfig final : IOConfig
".osrm.turn_duration_penalties", ".osrm.turn_duration_penalties",
".osrm.datasource_names", ".osrm.datasource_names",
".osrm.names", ".osrm.names",
".osrm.timestamp",
".osrm.properties", ".osrm.properties",
".osrm.icd", ".osrm.icd",
".osrm.maneuver_overrides"}, ".osrm.maneuver_overrides"},
+5
View File
@@ -272,6 +272,11 @@ inline auto make_partition_view(const SharedDataIndex &index, const std::string
level_data_ptr, std::move(partition), std::move(cell_to_children)}; level_data_ptr, std::move(partition), std::move(cell_to_children)};
} }
inline auto make_timestamp_view(const SharedDataIndex &index, const std::string &name)
{
return util::StringView(index.GetBlockPtr<char>(name), index.GetBlockEntries(name));
}
inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name) inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name)
{ {
auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary"); auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary");
+1
View File
@@ -79,6 +79,7 @@ using EdgeDistance = float;
using SegmentWeight = std::uint32_t; using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t; using SegmentDuration = std::uint32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units using TurnPenalty = std::int16_t; // turn penalty in 100ms units
using DataTimestamp = std::string;
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max(); static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.22.0-latest.1", "version": "5.22.0+customsnapping.2"
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 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": {
+4 -1
View File
@@ -87,7 +87,10 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Status::Error; return Status::Error;
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
auto phantom_node_pairs = GetPhantomNodes(facade, route_parameters); auto phantom_node_pairs =
GetPhantomNodes(facade,
route_parameters,
(route_parameters.snapping == api::RouteParameters::SnappingType::Any));
if (phantom_node_pairs.size() != route_parameters.coordinates.size()) if (phantom_node_pairs.size() != route_parameters.coordinates.size())
{ {
return Error("NoSegment", return Error("NoSegment",
+9
View File
@@ -51,6 +51,7 @@
#include <osmium/handler/node_locations_for_ways.hpp> #include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/index/map/flex_mem.hpp> #include <osmium/index/map/flex_mem.hpp>
#include <osmium/io/any_input.hpp> #include <osmium/io/any_input.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/thread/pool.hpp> #include <osmium/thread/pool.hpp>
#include <osmium/visitor.hpp> #include <osmium/visitor.hpp>
@@ -425,6 +426,14 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
// write .timestamp data file // write .timestamp data file
std::string timestamp = header.get("osmosis_replication_timestamp"); std::string timestamp = header.get("osmosis_replication_timestamp");
if (config.data_version == "osmosis")
{
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), timestamp);
}
else
{
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), config.data_version);
}
if (timestamp.empty()) if (timestamp.empty())
{ {
timestamp = "n/a"; timestamp = "n/a";
+12
View File
@@ -302,6 +302,7 @@ std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
{REQUIRED, config.GetPath(".osrm.ebg_nodes")}, {REQUIRED, config.GetPath(".osrm.ebg_nodes")},
{REQUIRED, config.GetPath(".osrm.tls")}, {REQUIRED, config.GetPath(".osrm.tls")},
{REQUIRED, config.GetPath(".osrm.tld")}, {REQUIRED, config.GetPath(".osrm.tld")},
{REQUIRED, config.GetPath(".osrm.timestamp")},
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")}, {REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
{REQUIRED, config.GetPath(".osrm.edges")}, {REQUIRED, config.GetPath(".osrm.edges")},
{REQUIRED, config.GetPath(".osrm.names")}, {REQUIRED, config.GetPath(".osrm.names")},
@@ -401,6 +402,17 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
extractor::files::readNames(config.GetPath(".osrm.names"), name_table); extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
} }
// Timestamp mark
{
auto timestamp_ref = make_timestamp_view(index, "/common/timestamp");
std::string ts;
extractor::files::readTimestamp(config.GetPath(".osrm.timestamp"), ts);
if (!ts.empty())
{
memcpy(const_cast<char *>(timestamp_ref.data()), ts.data(), ts.size());
}
}
// Turn lane data // Turn lane data
{ {
auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes"); auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes");
+4
View File
@@ -43,6 +43,10 @@ return_code parseArguments(int argc,
boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path) boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path)
->default_value("profiles/car.lua"), ->default_value("profiles/car.lua"),
"Path to LUA routing profile")( "Path to LUA routing profile")(
"data_version,d",
boost::program_options::value<std::string>(&extractor_config.data_version)
->default_value(""),
"Data version. Leave blank to avoid. osmosis - to get timestamp from file")(
"threads,t", "threads,t",
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads) boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()), ->default_value(tbb::task_scheduler_init::default_num_threads()),
+21
View File
@@ -689,4 +689,25 @@ test('route: throws on invalid waypoints values, waypoints must be an array of i
}; };
assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); }, assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); },
/Waypoints must be supplied in increasing order/); /Waypoints must be supplied in increasing order/);
});
test('route: throws on invalid snapping values', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates.concat(three_test_coordinates),
snapping: "zing"
};
assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); },
/'snapping' param must be one of \[default, any\]/);
});
test('route: snapping parameter passed through OK', function(assert) {
assert.plan(2);
var osrm = new OSRM(monaco_path);
osrm.route({snapping: "any", coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]]}, function(err, route) {
assert.ifError(err);
assert.equal(Math.round(route.routes[0].distance * 10), 1314); // Round it to nearest 0.1m to eliminate floating point comparison error
});
}); });
+1
View File
@@ -341,6 +341,7 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
StringView GetDestinationsForID(const NameID /*id*/) const override { return StringView{}; } StringView GetDestinationsForID(const NameID /*id*/) const override { return StringView{}; }
StringView GetExitsForID(const NameID /*id*/) const override { return StringView{}; } StringView GetExitsForID(const NameID /*id*/) const override { return StringView{}; }
bool GetContinueStraightDefault() const override { return false; } bool GetContinueStraightDefault() const override { return false; }
std::string GetTimestamp() const override { return ""; }
double GetMapMatchingMaxSpeed() const override { return 0; } double GetMapMatchingMaxSpeed() const override { return 0; }
const char *GetWeightName() const override { return ""; } const char *GetWeightName() const override { return ""; }
unsigned GetWeightPrecision() const override { return 0; } unsigned GetWeightPrecision() const override { return 0; }
+1 -1
View File
@@ -10,7 +10,6 @@
#include "extractor/turn_lane_types.hpp" #include "extractor/turn_lane_types.hpp"
#include "guidance/turn_bearing.hpp" #include "guidance/turn_bearing.hpp"
#include "guidance/turn_instruction.hpp" #include "guidance/turn_instruction.hpp"
#include "guidance/turn_instruction.hpp"
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "engine/datafacade/algorithm_datafacade.hpp" #include "engine/datafacade/algorithm_datafacade.hpp"
@@ -54,6 +53,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
{ {
return 0; return 0;
} }
std::string GetTimestamp() const override { return ""; }
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID /* id */) const override NodeForwardRange GetUncompressedForwardGeometry(const EdgeID /* id */) const override
{ {
static NodeID data[] = {0, 1, 2, 3}; static NodeID data[] = {0, 1, 2, 3};