Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 607fbce1ef | |||
| 06330a694e | |||
| cbecdf8a4f | |||
| dc26f7d8b9 | |||
| 791f6d02e1 | |||
| 7b7871d5aa |
+9
-1
@@ -1,4 +1,11 @@
|
|||||||
# 5.15.0 RC2
|
# 5.15.1
|
||||||
|
- Changes from 5.15.0:
|
||||||
|
- Bugfixes:
|
||||||
|
- FIXED: Segfault in map matching when RouteLeg collapsing code is run on a match with multiple submatches
|
||||||
|
- Guidance:
|
||||||
|
- Set type of trivial intersections where classes change to Suppressed instead of NoTurn
|
||||||
|
|
||||||
|
# 5.15.0
|
||||||
- Changes from 5.14.3:
|
- Changes from 5.14.3:
|
||||||
- Bugfixes:
|
- Bugfixes:
|
||||||
- FIXED #4704: Fixed regression in bearings reordering introduced in 5.13 [#4704](https://github.com/Project-OSRM/osrm-backend/issues/4704)
|
- FIXED #4704: Fixed regression in bearings reordering introduced in 5.13 [#4704](https://github.com/Project-OSRM/osrm-backend/issues/4704)
|
||||||
@@ -8,6 +15,7 @@
|
|||||||
- FIXED #4804: Ignore no_*_on_red turn restrictions
|
- FIXED #4804: Ignore no_*_on_red turn restrictions
|
||||||
- Guidance:
|
- 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)
|
- CHANGED #4706: Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation [#4706](https://github.com/Project-OSRM/osrm-backend/pull/4706)
|
||||||
|
- CHANGED #3491: Refactor `isThroughStreet`/Intersection options
|
||||||
- Profile:
|
- Profile:
|
||||||
- ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such
|
- ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ endif()
|
|||||||
project(OSRM C CXX)
|
project(OSRM C CXX)
|
||||||
set(OSRM_VERSION_MAJOR 5)
|
set(OSRM_VERSION_MAJOR 5)
|
||||||
set(OSRM_VERSION_MINOR 15)
|
set(OSRM_VERSION_MINOR 15)
|
||||||
set(OSRM_VERSION_PATCH 0)
|
set(OSRM_VERSION_PATCH 1)
|
||||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||||
|
|
||||||
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|||||||
@@ -119,6 +119,25 @@ Feature: Car - Mode flag
|
|||||||
| from | to | route | turns | classes |
|
| from | to | route | turns | classes |
|
||||||
| a | d | ab,bc,cd,cd | depart,new name right,new name left,arrive | [()],[(tunnel)],[()],[()] |
|
| a | d | ab,bc,cd,cd | depart,new name right,new name left,arrive | [()],[(tunnel)],[()],[()] |
|
||||||
|
|
||||||
|
Scenario: Car - We tag classes without intersections
|
||||||
|
Background:
|
||||||
|
Given a grid size of 200 meters
|
||||||
|
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b c d
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | name | tunnel |
|
||||||
|
| ab | road | |
|
||||||
|
| bc | road | yes |
|
||||||
|
| cd | road | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | turns | classes |
|
||||||
|
| a | d | road,road | depart,arrive | [(),(tunnel),()],[()] |
|
||||||
|
|
||||||
Scenario: Car - From roundabout on toll road
|
Scenario: Car - From roundabout on toll road
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -144,4 +163,3 @@ Feature: Car - Mode flag
|
|||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | turns | classes |
|
| from | to | route | turns | classes |
|
||||||
| a | f | ab,df,df,df | depart,roundabout-exit-2,exit roundabout slight right,arrive | [()],[(),(motorway)],[(toll,motorway)],[()] |
|
| a | f | ab,df,df,df | depart,roundabout-exit-2,exit roundabout slight right,arrive | [()],[(),(motorway)],[(toll,motorway)],[()] |
|
||||||
|
|
||||||
|
|||||||
@@ -98,11 +98,11 @@ Feature: Car - Guidance - Bridges and Tunnels
|
|||||||
| dce | primary | | Nebenstraße |
|
| dce | primary | | Nebenstraße |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | turns |
|
| from | to | route | turns |
|
||||||
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,arrive |
|
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
|
||||||
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,arrive |
|
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
|
||||||
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
|
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
|
||||||
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
|
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
|
||||||
|
|
||||||
Scenario: Tunnel with Immediate Turn Front and Back
|
Scenario: Tunnel with Immediate Turn Front and Back
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -129,4 +129,3 @@ Feature: Car - Guidance - Bridges and Tunnels
|
|||||||
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,turn left,arrive |
|
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,turn left,arrive |
|
||||||
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn right,arrive |
|
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn right,arrive |
|
||||||
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn left,arrive |
|
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn left,arrive |
|
||||||
|
|
||||||
|
|||||||
@@ -603,3 +603,26 @@ Feature: Basic Map Matching
|
|||||||
When I match I should get
|
When I match I should get
|
||||||
| trace | timestamps | code |
|
| trace | timestamps | code |
|
||||||
| ab1d | 0 1 2 3 | NoMatch |
|
| ab1d | 0 1 2 3 | NoMatch |
|
||||||
|
|
||||||
|
Scenario: Regression test - avoid collapsing legs of a tidied split trace
|
||||||
|
Given a grid size of 20 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a--b--f
|
||||||
|
|
|
||||||
|
|
|
||||||
|
e--c---d--g
|
||||||
|
"""
|
||||||
|
Given the query options
|
||||||
|
| tidy | true |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| abf | no |
|
||||||
|
| be | no |
|
||||||
|
| ecdg | no |
|
||||||
|
|
||||||
|
When I match I should get
|
||||||
|
| trace | timestamps | matchings | code |
|
||||||
|
| abbecd | 10 11 27 1516914902 1516914913 1516914952 | ab,ecd | Ok |
|
||||||
|
|
||||||
|
|||||||
@@ -48,12 +48,14 @@ inline Result keep_all(const MatchParameters ¶ms)
|
|||||||
|
|
||||||
result.can_be_removed.resize(params.coordinates.size(), false);
|
result.can_be_removed.resize(params.coordinates.size(), false);
|
||||||
result.was_waypoint.resize(params.coordinates.size(), true);
|
result.was_waypoint.resize(params.coordinates.size(), true);
|
||||||
|
// by default all input coordinates are treated as waypoints
|
||||||
if (!params.waypoints.empty())
|
if (!params.waypoints.empty())
|
||||||
{
|
{
|
||||||
for (const auto p : params.waypoints)
|
for (const auto p : params.waypoints)
|
||||||
{
|
{
|
||||||
result.was_waypoint.set(p, false);
|
result.was_waypoint.set(p, false);
|
||||||
}
|
}
|
||||||
|
// logic is a little funny, uses inversion to set the bitfield
|
||||||
result.was_waypoint.flip();
|
result.was_waypoint.flip();
|
||||||
}
|
}
|
||||||
result.tidied_to_original.reserve(params.coordinates.size());
|
result.tidied_to_original.reserve(params.coordinates.size());
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
|
||||||
|
#define OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
|
||||||
|
|
||||||
|
#include "extractor/guidance/constants.hpp"
|
||||||
|
#include "extractor/suffix_table.hpp"
|
||||||
|
#include "util/name_table.hpp"
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
namespace guidance
|
||||||
|
{
|
||||||
|
|
||||||
|
// check if two name ids can be seen as identical (in presence of refs/others)
|
||||||
|
// in our case this translates into no name announcement in either direction (lhs->rhs and
|
||||||
|
// rhs->lhs)
|
||||||
|
bool HaveIdenticalNames(const NameID lhs,
|
||||||
|
const NameID rhs,
|
||||||
|
const util::NameTable &name_table,
|
||||||
|
const SuffixTable &street_name_suffix_table);
|
||||||
|
|
||||||
|
} // namespace guidance
|
||||||
|
} // namespace extractor
|
||||||
|
} // namespace osrm
|
||||||
|
|
||||||
|
#endif /*OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_*/
|
||||||
@@ -293,10 +293,11 @@ struct IntersectionView final : std::vector<IntersectionViewData>, //
|
|||||||
};
|
};
|
||||||
|
|
||||||
// `Intersection` is a relative view of an intersection by an incoming edge.
|
// `Intersection` is a relative view of an intersection by an incoming edge.
|
||||||
// `Intersection` are streets at an intersection ordered from from sharp right counter-clockwise to
|
// `Intersection` are streets at an intersection stored as an ordered list of connected roads
|
||||||
|
// ordered from sharp right counter-clockwise to
|
||||||
// sharp left where `intersection[0]` is _always_ a u-turn
|
// sharp left where `intersection[0]` is _always_ a u-turn
|
||||||
|
|
||||||
// An intersection is an ordered list of connected roads ordered from from sharp right
|
// An intersection is an ordered list of connected roads ordered from sharp right
|
||||||
// counter-clockwise to sharp left where `intersection[0]` is always a u-turn
|
// counter-clockwise to sharp left where `intersection[0]` is always a u-turn
|
||||||
//
|
//
|
||||||
// |
|
// |
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ class IntersectionHandler
|
|||||||
// Decide on a basic turn types
|
// Decide on a basic turn types
|
||||||
TurnType::Enum findBasicTurnType(const EdgeID via_edge, const ConnectedRoad &candidate) const;
|
TurnType::Enum findBasicTurnType(const EdgeID via_edge, const ConnectedRoad &candidate) const;
|
||||||
|
|
||||||
|
TurnType::Enum areSameClasses(const EdgeID via_edge, const ConnectedRoad &road) const;
|
||||||
|
|
||||||
// Find the most obvious turn to follow. The function returns an index into the intersection
|
// Find the most obvious turn to follow. The function returns an index into the intersection
|
||||||
// determining whether there is a road that can be seen as obvious turn in the presence of many
|
// determining whether there is a road that can be seen as obvious turn in the presence of many
|
||||||
// other possible turns. The function will consider road categories and other inputs like the
|
// other possible turns. The function will consider road categories and other inputs like the
|
||||||
@@ -96,9 +98,6 @@ class IntersectionHandler
|
|||||||
const std::size_t begin,
|
const std::size_t begin,
|
||||||
const std::size_t end) const;
|
const std::size_t end) const;
|
||||||
|
|
||||||
// Checks the intersection for a through street connected to `intersection[index]`
|
|
||||||
bool isThroughStreet(const std::size_t index, const Intersection &intersection) const;
|
|
||||||
|
|
||||||
// See `getNextIntersection`
|
// See `getNextIntersection`
|
||||||
struct IntersectionViewAndNode final
|
struct IntersectionViewAndNode final
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_
|
||||||
|
#define OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_
|
||||||
|
|
||||||
|
#include "extractor/guidance/constants.hpp"
|
||||||
|
#include "extractor/suffix_table.hpp"
|
||||||
|
#include "util/guidance/name_announcements.hpp"
|
||||||
|
|
||||||
|
using osrm::util::angularDeviation;
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
namespace guidance
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename IntersectionType>
|
||||||
|
inline bool isThroughStreet(const std::size_t index,
|
||||||
|
const IntersectionType &intersection,
|
||||||
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
|
const util::NameTable &name_table,
|
||||||
|
const SuffixTable &street_name_suffix_table)
|
||||||
|
{
|
||||||
|
|
||||||
|
const auto &data_at_index = node_data_container.GetAnnotation(
|
||||||
|
node_based_graph.GetEdgeData(intersection[index].eid).annotation_data);
|
||||||
|
|
||||||
|
if (data_at_index.name_id == EMPTY_NAMEID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// a through street cannot start at our own position -> index 1
|
||||||
|
for (std::size_t road_index = 1; road_index < intersection.size(); ++road_index)
|
||||||
|
{
|
||||||
|
if (road_index == index)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto &road = intersection[road_index];
|
||||||
|
const auto &road_data = node_data_container.GetAnnotation(
|
||||||
|
node_based_graph.GetEdgeData(road.eid).annotation_data);
|
||||||
|
|
||||||
|
// roads have a near straight angle (180 degree)
|
||||||
|
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
|
||||||
|
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);
|
||||||
|
|
||||||
|
const bool have_same_name = HaveIdenticalNames(
|
||||||
|
data_at_index.name_id, road_data.name_id, name_table, street_name_suffix_table);
|
||||||
|
|
||||||
|
const bool have_same_category =
|
||||||
|
node_based_graph.GetEdgeData(intersection[index].eid).flags.road_classification ==
|
||||||
|
node_based_graph.GetEdgeData(road.eid).flags.road_classification;
|
||||||
|
|
||||||
|
if (is_nearly_straight && have_same_name && have_same_category)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace guidance
|
||||||
|
} // namespace extractor
|
||||||
|
} // namespace osrm
|
||||||
|
|
||||||
|
#endif /*OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_*/
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||||
|
#include "extractor/guidance/have_identical_names.hpp"
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/turn_lane_types.hpp"
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "extractor/restriction_index.hpp"
|
#include "extractor/restriction_index.hpp"
|
||||||
@@ -78,11 +79,6 @@ class MergableRoadDetector
|
|||||||
bool IsDistinctFrom(const MergableRoadData &lhs, const MergableRoadData &rhs) const;
|
bool IsDistinctFrom(const MergableRoadData &lhs, const MergableRoadData &rhs) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// check if two name ids can be seen as identical (in presence of refs/others)
|
|
||||||
// in our case this translates into no name announcement in either direction (lhs->rhs and
|
|
||||||
// rhs->lhs)
|
|
||||||
bool HaveIdenticalNames(const NameID lhs, const NameID rhs) const;
|
|
||||||
|
|
||||||
// When it comes to merging roads, we need to find out if two ways actually represent the
|
// When it comes to merging roads, we need to find out if two ways actually represent the
|
||||||
// same road. This check tries to identify roads which are the same road in opposite directions
|
// same road. This check tries to identify roads which are the same road in opposite directions
|
||||||
bool EdgeDataSupportsMerge(const NodeBasedEdgeClassification &lhs_flags,
|
bool EdgeDataSupportsMerge(const NodeBasedEdgeClassification &lhs_flags,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
|
#include "extractor/guidance/is_through_street.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
#include "util/attributes.hpp"
|
#include "util/attributes.hpp"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
|
#include "extractor/guidance/is_through_street.hpp"
|
||||||
#include "extractor/guidance/roundabout_type.hpp"
|
#include "extractor/guidance/roundabout_type.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
|
#include "extractor/guidance/is_through_street.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
#include "util/name_table.hpp"
|
#include "util/name_table.hpp"
|
||||||
@@ -53,9 +54,6 @@ class SliproadHandler final : public IntersectionHandler
|
|||||||
// Next intersection from `start` onto `onto` is too far away for a Siproad scenario
|
// Next intersection from `start` onto `onto` is too far away for a Siproad scenario
|
||||||
bool nextIntersectionIsTooFarAway(const NodeID start, const EdgeID onto) const;
|
bool nextIntersectionIsTooFarAway(const NodeID start, const EdgeID onto) const;
|
||||||
|
|
||||||
// Through street: does a road continue with from's name at the intersection
|
|
||||||
bool isThroughStreet(const EdgeID from, const IntersectionView &intersection) const;
|
|
||||||
|
|
||||||
// Does the road from `current` to `next` continue
|
// Does the road from `current` to `next` continue
|
||||||
bool roadContinues(const EdgeID current, const EdgeID next) const;
|
bool roadContinues(const EdgeID current, const EdgeID next) const;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
|
#include "extractor/guidance/is_through_street.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
#include "util/attributes.hpp"
|
#include "util/attributes.hpp"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.15.0-rc.2",
|
"version": "5.15.1",
|
||||||
"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": {
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error: Check if user-supplied waypoints can be found in the resulting matches
|
// Error: Check if user-supplied waypoints can be found in the resulting matches
|
||||||
|
if (!parameters.waypoints.empty())
|
||||||
{
|
{
|
||||||
std::set<std::size_t> tidied_waypoints(tidied.parameters.waypoints.begin(),
|
std::set<std::size_t> tidied_waypoints(tidied.parameters.waypoints.begin(),
|
||||||
tidied.parameters.waypoints.end());
|
tidied.parameters.waypoints.end());
|
||||||
@@ -262,6 +263,9 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
"NoMatch", "Requested waypoint parameter could not be matched.", json_result);
|
"NoMatch", "Requested waypoint parameter could not be matched.", json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// we haven't errored yet, only allow leg collapsing if it was originally requested
|
||||||
|
BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1);
|
||||||
|
const auto collapse_legs = !parameters.waypoints.empty();
|
||||||
|
|
||||||
// each sub_route will correspond to a MatchObject
|
// each sub_route will correspond to a MatchObject
|
||||||
std::vector<InternalRouteResult> sub_routes(sub_matchings.size());
|
std::vector<InternalRouteResult> sub_routes(sub_matchings.size());
|
||||||
@@ -286,7 +290,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
sub_routes[index] =
|
sub_routes[index] =
|
||||||
algorithms.ShortestPathSearch(sub_routes[index].segment_end_coordinates, {false});
|
algorithms.ShortestPathSearch(sub_routes[index].segment_end_coordinates, {false});
|
||||||
BOOST_ASSERT(sub_routes[index].shortest_path_weight != INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(sub_routes[index].shortest_path_weight != INVALID_EDGE_WEIGHT);
|
||||||
if (!tidied.parameters.waypoints.empty())
|
if (collapse_legs)
|
||||||
{
|
{
|
||||||
std::vector<bool> waypoint_legs;
|
std::vector<bool> waypoint_legs;
|
||||||
waypoint_legs.reserve(sub_matchings[index].indices.size());
|
waypoint_legs.reserve(sub_matchings[index].indices.size());
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
|
||||||
|
#define OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
|
||||||
|
|
||||||
|
#include "util/guidance/name_announcements.hpp"
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
namespace guidance
|
||||||
|
{
|
||||||
|
|
||||||
|
// check if two name ids can be seen as identical (in presence of refs/others)
|
||||||
|
// in our case this translates into no name announcement in either direction (lhs->rhs and
|
||||||
|
// rhs->lhs)
|
||||||
|
bool HaveIdenticalNames(const NameID lhs,
|
||||||
|
const NameID rhs,
|
||||||
|
const util::NameTable &name_table,
|
||||||
|
const SuffixTable &street_name_suffix_table)
|
||||||
|
{
|
||||||
|
const auto non_empty = (lhs != EMPTY_NAMEID) && (rhs != EMPTY_NAMEID);
|
||||||
|
|
||||||
|
// symmetrical check for announcements
|
||||||
|
return non_empty &&
|
||||||
|
!util::guidance::requiresNameAnnounced(lhs, rhs, name_table, street_name_suffix_table) &&
|
||||||
|
!util::guidance::requiresNameAnnounced(rhs, lhs, name_table, street_name_suffix_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace guidance
|
||||||
|
} // namespace extractor
|
||||||
|
} // namespace osrm
|
||||||
|
|
||||||
|
#endif /*OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_*/
|
||||||
@@ -102,6 +102,19 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
|
|||||||
return TurnType::Turn;
|
return TurnType::Turn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TurnType::Enum IntersectionHandler::areSameClasses(const EdgeID via_edge,
|
||||||
|
const ConnectedRoad &road) const
|
||||||
|
{
|
||||||
|
const auto &in_classes =
|
||||||
|
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(via_edge).annotation_data)
|
||||||
|
.classes;
|
||||||
|
const auto &out_classes =
|
||||||
|
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
|
||||||
|
.classes;
|
||||||
|
|
||||||
|
return in_classes == out_classes;
|
||||||
|
}
|
||||||
|
|
||||||
TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t num_roads,
|
TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t num_roads,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const bool through_street,
|
const bool through_street,
|
||||||
@@ -195,7 +208,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
|
|||||||
if (needs_notification)
|
if (needs_notification)
|
||||||
return {TurnType::Notification, getTurnDirection(road.angle)};
|
return {TurnType::Notification, getTurnDirection(road.angle)};
|
||||||
else
|
else
|
||||||
return {num_roads == 2 ? TurnType::NoTurn : TurnType::Suppressed,
|
return {num_roads == 2 && areSameClasses(via_edge, road) ? TurnType::NoTurn
|
||||||
|
: TurnType::Suppressed,
|
||||||
getTurnDirection(road.angle)};
|
getTurnDirection(road.angle)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +218,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
|
|||||||
{
|
{
|
||||||
return {TurnType::Notification, getTurnDirection(road.angle)};
|
return {TurnType::Notification, getTurnDirection(road.angle)};
|
||||||
}
|
}
|
||||||
if (num_roads > 2)
|
if (num_roads > 2 || !areSameClasses(via_edge, road))
|
||||||
{
|
{
|
||||||
return {TurnType::Suppressed, getTurnDirection(road.angle)};
|
return {TurnType::Suppressed, getTurnDirection(road.angle)};
|
||||||
}
|
}
|
||||||
@@ -418,44 +432,6 @@ void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IntersectionHandler::isThroughStreet(const std::size_t index,
|
|
||||||
const Intersection &intersection) const
|
|
||||||
{
|
|
||||||
const auto &data_at_index = node_data_container.GetAnnotation(
|
|
||||||
node_based_graph.GetEdgeData(intersection[index].eid).annotation_data);
|
|
||||||
|
|
||||||
if (data_at_index.name_id == EMPTY_NAMEID)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// a through street cannot start at our own position -> index 1
|
|
||||||
for (std::size_t road_index = 1; road_index < intersection.size(); ++road_index)
|
|
||||||
{
|
|
||||||
if (road_index == index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const auto &road = intersection[road_index];
|
|
||||||
const auto &road_data = node_data_container.GetAnnotation(
|
|
||||||
node_based_graph.GetEdgeData(road.eid).annotation_data);
|
|
||||||
|
|
||||||
// roads have a near straight angle (180 degree)
|
|
||||||
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
|
|
||||||
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);
|
|
||||||
|
|
||||||
const bool have_same_name =
|
|
||||||
road_data.name_id != EMPTY_NAMEID &&
|
|
||||||
!util::guidance::requiresNameAnnounced(
|
|
||||||
data_at_index.name_id, road_data.name_id, name_table, street_name_suffix_table);
|
|
||||||
|
|
||||||
const bool have_same_category =
|
|
||||||
node_based_graph.GetEdgeData(intersection[index].eid).flags.road_classification ==
|
|
||||||
node_based_graph.GetEdgeData(road.eid).flags.road_classification;
|
|
||||||
|
|
||||||
if (is_nearly_straight && have_same_name && have_same_category)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<IntersectionHandler::IntersectionViewAndNode>
|
boost::optional<IntersectionHandler::IntersectionViewAndNode>
|
||||||
IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) const
|
IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,16 +122,6 @@ bool MergableRoadDetector::CanMergeRoad(const NodeID intersection_node,
|
|||||||
!IsCircularShape(intersection_node, lhs, rhs);
|
!IsCircularShape(intersection_node, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MergableRoadDetector::HaveIdenticalNames(const NameID lhs, const NameID rhs) const
|
|
||||||
{
|
|
||||||
const auto non_empty = (lhs != EMPTY_NAMEID) && (rhs != EMPTY_NAMEID);
|
|
||||||
|
|
||||||
// symmetrical check for announcements
|
|
||||||
return non_empty &&
|
|
||||||
!util::guidance::requiresNameAnnounced(lhs, rhs, name_table, street_name_suffix_table) &&
|
|
||||||
!util::guidance::requiresNameAnnounced(rhs, lhs, name_table, street_name_suffix_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MergableRoadDetector::IsDistinctFrom(const MergableRoadData &lhs,
|
bool MergableRoadDetector::IsDistinctFrom(const MergableRoadData &lhs,
|
||||||
const MergableRoadData &rhs) const
|
const MergableRoadData &rhs) const
|
||||||
{
|
{
|
||||||
@@ -143,7 +133,9 @@ bool MergableRoadDetector::IsDistinctFrom(const MergableRoadData &lhs,
|
|||||||
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(lhs.eid).annotation_data)
|
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(lhs.eid).annotation_data)
|
||||||
.name_id,
|
.name_id,
|
||||||
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(rhs.eid).annotation_data)
|
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(rhs.eid).annotation_data)
|
||||||
.name_id);
|
.name_id,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MergableRoadDetector::EdgeDataSupportsMerge(
|
bool MergableRoadDetector::EdgeDataSupportsMerge(
|
||||||
@@ -165,7 +157,8 @@ bool MergableRoadDetector::EdgeDataSupportsMerge(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// we require valid names
|
// we require valid names
|
||||||
if (!HaveIdenticalNames(lhs_annotation.name_id, rhs_annotation.name_id))
|
if (!HaveIdenticalNames(
|
||||||
|
lhs_annotation.name_id, rhs_annotation.name_id, name_table, street_name_suffix_table))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return lhs_flags.road_classification == rhs_flags.road_classification;
|
return lhs_flags.road_classification == rhs_flags.road_classification;
|
||||||
|
|||||||
@@ -239,7 +239,12 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
|||||||
intersection[1].instruction =
|
intersection[1].instruction =
|
||||||
getInstructionForObvious(intersection.size(),
|
getInstructionForObvious(intersection.size(),
|
||||||
via_eid,
|
via_eid,
|
||||||
isThroughStreet(1, intersection),
|
isThroughStreet(1,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
intersection[1]);
|
intersection[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -253,8 +258,16 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
|||||||
|
|
||||||
if (road.angle == continue_angle)
|
if (road.angle == continue_angle)
|
||||||
{
|
{
|
||||||
road.instruction = getInstructionForObvious(
|
road.instruction =
|
||||||
intersection.size(), via_eid, isThroughStreet(1, intersection), road);
|
getInstructionForObvious(intersection.size(),
|
||||||
|
via_eid,
|
||||||
|
isThroughStreet(1,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
|
road);
|
||||||
}
|
}
|
||||||
else if (road.angle < continue_angle)
|
else if (road.angle < continue_angle)
|
||||||
{
|
{
|
||||||
@@ -353,8 +366,16 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
|||||||
BOOST_ASSERT(!intersection[0].entry_allowed);
|
BOOST_ASSERT(!intersection[0].entry_allowed);
|
||||||
BOOST_ASSERT(isMotorwayClass(intersection[1].eid, node_based_graph));
|
BOOST_ASSERT(isMotorwayClass(intersection[1].eid, node_based_graph));
|
||||||
|
|
||||||
intersection[1].instruction = getInstructionForObvious(
|
intersection[1].instruction =
|
||||||
intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
|
getInstructionForObvious(intersection.size(),
|
||||||
|
via_eid,
|
||||||
|
isThroughStreet(1,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
|
intersection[1]);
|
||||||
}
|
}
|
||||||
else if (intersection.size() == 3)
|
else if (intersection.size() == 3)
|
||||||
{
|
{
|
||||||
@@ -404,7 +425,12 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
|||||||
intersection[1].instruction =
|
intersection[1].instruction =
|
||||||
getInstructionForObvious(intersection.size(),
|
getInstructionForObvious(intersection.size(),
|
||||||
via_eid,
|
via_eid,
|
||||||
isThroughStreet(1, intersection),
|
isThroughStreet(1,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
intersection[1]);
|
intersection[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,7 +455,12 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
|||||||
intersection[2].instruction =
|
intersection[2].instruction =
|
||||||
getInstructionForObvious(intersection.size(),
|
getInstructionForObvious(intersection.size(),
|
||||||
via_eid,
|
via_eid,
|
||||||
isThroughStreet(2, intersection),
|
isThroughStreet(2,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
intersection[2]);
|
intersection[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -478,8 +478,16 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
|
|||||||
if (util::angularDeviation(turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE &&
|
if (util::angularDeviation(turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE &&
|
||||||
crossing_roundabout)
|
crossing_roundabout)
|
||||||
{
|
{
|
||||||
turn.instruction = getInstructionForObvious(
|
turn.instruction =
|
||||||
intersection.size(), via_eid, isThroughStreet(idx, intersection), turn);
|
getInstructionForObvious(intersection.size(),
|
||||||
|
via_eid,
|
||||||
|
isThroughStreet(idx,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
|
turn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -344,9 +344,24 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the sliproad candidate is a through street, we cannot handle it as a sliproad.
|
// If the sliproad candidate is a through street, we cannot handle it as a sliproad.
|
||||||
if (isThroughStreet(sliproad_edge, target_intersection))
|
auto sliproad_in_target_intersection =
|
||||||
|
std::find_if(begin(target_intersection),
|
||||||
|
end(target_intersection),
|
||||||
|
[&](const auto &road) { return road.eid == sliproad_edge; });
|
||||||
|
if (sliproad_in_target_intersection != target_intersection.end())
|
||||||
{
|
{
|
||||||
continue;
|
auto index_of_sliproad_in_target_intersection =
|
||||||
|
sliproad_in_target_intersection - target_intersection.begin();
|
||||||
|
|
||||||
|
if (isThroughStreet<IntersectionView>(index_of_sliproad_in_target_intersection,
|
||||||
|
target_intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The turn off of the Sliproad has to be obvious and a narrow turn and must not be a
|
// The turn off of the Sliproad has to be obvious and a narrow turn and must not be a
|
||||||
@@ -689,32 +704,6 @@ bool SliproadHandler::nextIntersectionIsTooFarAway(const NodeID start, const Edg
|
|||||||
return accumulator.too_far_away;
|
return accumulator.too_far_away;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SliproadHandler::isThroughStreet(const EdgeID from, const IntersectionView &intersection) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(from != SPECIAL_EDGEID);
|
|
||||||
BOOST_ASSERT(!intersection.empty());
|
|
||||||
|
|
||||||
const auto from_annotation_id = node_based_graph.GetEdgeData(from).annotation_data;
|
|
||||||
const auto &edge_name_id = node_data_container.GetAnnotation(from_annotation_id).name_id;
|
|
||||||
|
|
||||||
auto first = begin(intersection) + 1; // Skip UTurn road
|
|
||||||
auto last = end(intersection);
|
|
||||||
|
|
||||||
auto same_name = [&](const auto &road) {
|
|
||||||
const auto annotation_id = node_based_graph.GetEdgeData(road.eid).annotation_data;
|
|
||||||
const auto &road_name_id = node_data_container.GetAnnotation(annotation_id).name_id;
|
|
||||||
|
|
||||||
return edge_name_id != EMPTY_NAMEID && //
|
|
||||||
road_name_id != EMPTY_NAMEID && //
|
|
||||||
!util::guidance::requiresNameAnnounced(edge_name_id,
|
|
||||||
road_name_id,
|
|
||||||
name_table,
|
|
||||||
street_name_suffix_table); //
|
|
||||||
};
|
|
||||||
|
|
||||||
return std::find_if(first, last, same_name) != last;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SliproadHandler::roadContinues(const EdgeID current, const EdgeID next) const
|
bool SliproadHandler::roadContinues(const EdgeID current, const EdgeID next) const
|
||||||
{
|
{
|
||||||
const auto ¤t_data =
|
const auto ¤t_data =
|
||||||
|
|||||||
@@ -287,8 +287,16 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
|||||||
const auto direction_at_two = getTurnDirection(intersection[2].angle);
|
const auto direction_at_two = getTurnDirection(intersection[2].angle);
|
||||||
if (obvious_index == 1)
|
if (obvious_index == 1)
|
||||||
{
|
{
|
||||||
intersection[1].instruction = getInstructionForObvious(
|
intersection[1].instruction =
|
||||||
3, via_edge, isThroughStreet(1, intersection), intersection[1]);
|
getInstructionForObvious(3,
|
||||||
|
via_edge,
|
||||||
|
isThroughStreet(1,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
|
intersection[1]);
|
||||||
const auto second_direction = (direction_at_one == direction_at_two &&
|
const auto second_direction = (direction_at_one == direction_at_two &&
|
||||||
direction_at_two == DirectionModifier::Straight)
|
direction_at_two == DirectionModifier::Straight)
|
||||||
? DirectionModifier::SlightLeft
|
? DirectionModifier::SlightLeft
|
||||||
@@ -300,8 +308,16 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(obvious_index == 2);
|
BOOST_ASSERT(obvious_index == 2);
|
||||||
intersection[2].instruction = getInstructionForObvious(
|
intersection[2].instruction =
|
||||||
3, via_edge, isThroughStreet(2, intersection), intersection[2]);
|
getInstructionForObvious(3,
|
||||||
|
via_edge,
|
||||||
|
isThroughStreet(2,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
|
intersection[2]);
|
||||||
const auto first_direction = (direction_at_one == direction_at_two &&
|
const auto first_direction = (direction_at_one == direction_at_two &&
|
||||||
direction_at_one == DirectionModifier::Straight)
|
direction_at_one == DirectionModifier::Straight)
|
||||||
? DirectionModifier::SlightRight
|
? DirectionModifier::SlightRight
|
||||||
@@ -336,7 +352,12 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
|
|||||||
intersection[obvious_index].instruction =
|
intersection[obvious_index].instruction =
|
||||||
getInstructionForObvious(intersection.size(),
|
getInstructionForObvious(intersection.size(),
|
||||||
via_edge,
|
via_edge,
|
||||||
isThroughStreet(obvious_index, intersection),
|
isThroughStreet(obvious_index,
|
||||||
|
intersection,
|
||||||
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table),
|
||||||
intersection[obvious_index]);
|
intersection[obvious_index]);
|
||||||
|
|
||||||
// assign left/right turns
|
// assign left/right turns
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class MockScriptingEnvironment : public extractor::ScriptingEnvironment
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasLocationDependentData() const { return false; };
|
bool HasLocationDependentData() const override { return false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#define BOOST_TEST_MODULE customizer tests
|
#define BOOST_TEST_MODULE updater tests
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user