Support maneuver relations (#4676)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef ENGINE_API_ROUTE_HPP
|
||||
#define ENGINE_API_ROUTE_HPP
|
||||
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "engine/api/base_api.hpp"
|
||||
#include "engine/api/json_factory.hpp"
|
||||
#include "engine/api/route_parameters.hpp"
|
||||
@@ -19,6 +20,8 @@
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/json_util.hpp"
|
||||
@@ -130,6 +133,7 @@ class RouteAPI : public BaseAPI
|
||||
reversed_target,
|
||||
parameters.steps);
|
||||
|
||||
util::Log(logDEBUG) << "Assembling steps " << std::endl;
|
||||
if (parameters.steps)
|
||||
{
|
||||
auto steps = guidance::assembleSteps(BaseAPI::facade,
|
||||
@@ -140,6 +144,10 @@ class RouteAPI : public BaseAPI
|
||||
reversed_source,
|
||||
reversed_target);
|
||||
|
||||
// Apply maneuver overrides before any other post
|
||||
// processing is performed
|
||||
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
|
||||
|
||||
/* Perform step-based post-processing.
|
||||
*
|
||||
* Using post-processing on basis of route-steps for a single leg at a time
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
@@ -205,6 +206,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<std::size_t> m_datasource_name_lengths;
|
||||
util::vector_view<util::guidance::LaneTupleIdPair> m_lane_tupel_id_pairs;
|
||||
|
||||
util::vector_view<extractor::StorageManeuverOverride> m_maneuver_overrides;
|
||||
util::vector_view<NodeID> m_maneuver_override_node_sequences;
|
||||
|
||||
std::unique_ptr<SharedRTree> m_static_rtree;
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
boost::filesystem::path file_index_path;
|
||||
@@ -499,6 +503,21 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
m_entry_class_table = std::move(entry_class_table);
|
||||
}
|
||||
|
||||
void InitializeManeuverOverridePointers(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto maneuver_overrides_ptr = data_layout.GetBlockPtr<extractor::StorageManeuverOverride>(
|
||||
memory_block, storage::DataLayout::MANEUVER_OVERRIDES);
|
||||
m_maneuver_overrides = util::vector_view<extractor::StorageManeuverOverride>(
|
||||
maneuver_overrides_ptr,
|
||||
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDES]);
|
||||
|
||||
auto maneuver_override_node_sequences_ptr = data_layout.GetBlockPtr<NodeID>(
|
||||
memory_block, storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES);
|
||||
m_maneuver_override_node_sequences = util::vector_view<NodeID>(
|
||||
maneuver_override_node_sequences_ptr,
|
||||
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES]);
|
||||
}
|
||||
|
||||
void InitializeInternalPointers(storage::DataLayout &data_layout,
|
||||
char *memory_block,
|
||||
const std::size_t exclude_index)
|
||||
@@ -515,6 +534,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
InitializeProfilePropertiesPointer(data_layout, memory_block, exclude_index);
|
||||
InitializeRTreePointers(data_layout, memory_block);
|
||||
InitializeIntersectionClassPointers(data_layout, memory_block);
|
||||
InitializeManeuverOverridePointers(data_layout, memory_block);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -890,6 +910,39 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
{
|
||||
return edge_based_node_data.IsSegregated(id);
|
||||
}
|
||||
|
||||
std::vector<extractor::ManeuverOverride>
|
||||
GetOverridesThatStartAt(const NodeID edge_based_node_id) const override final
|
||||
{
|
||||
std::vector<extractor::ManeuverOverride> results;
|
||||
|
||||
// heterogeneous comparison:
|
||||
struct Comp
|
||||
{
|
||||
bool operator()(const extractor::StorageManeuverOverride &s, NodeID i) const
|
||||
{
|
||||
return s.start_node < i;
|
||||
}
|
||||
bool operator()(NodeID i, const extractor::StorageManeuverOverride &s) const
|
||||
{
|
||||
return i < s.start_node;
|
||||
}
|
||||
};
|
||||
|
||||
auto found_range = std::equal_range(
|
||||
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
||||
|
||||
std::for_each(found_range.first, found_range.second, [&](const auto & override) {
|
||||
std::vector<NodeID> sequence(
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
|
||||
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
||||
override.instruction_node,
|
||||
override.override_type,
|
||||
override.direction});
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
//#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
//#include "extractor/original_edge_data.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
@@ -192,6 +195,9 @@ class BaseDataFacade
|
||||
virtual bool IsLeftHandDriving(const NodeID id) const = 0;
|
||||
|
||||
virtual bool IsSegregated(const NodeID) const = 0;
|
||||
|
||||
virtual std::vector<extractor::ManeuverOverride>
|
||||
GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
// intersections contain the classes of exiting road
|
||||
intersection.classes = facade.GetClasses(path_point.classes);
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
steps.push_back(RouteStep{path_point.from_edge_based_node,
|
||||
step_name_id,
|
||||
is_segregated,
|
||||
name.to_string(),
|
||||
ref.to_string(),
|
||||
@@ -209,7 +210,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
// intersections contain the classes of exiting road
|
||||
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
|
||||
step_name_id,
|
||||
is_segregated,
|
||||
facade.GetNameForID(step_name_id).to_string(),
|
||||
facade.GetRefForID(step_name_id).to_string(),
|
||||
@@ -253,7 +255,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
BOOST_ASSERT(target_duration >= source_duration || weight == 0);
|
||||
const EdgeWeight duration = std::max(0, target_duration - source_duration);
|
||||
|
||||
steps.push_back(RouteStep{source_name_id,
|
||||
steps.push_back(RouteStep{source_node_id,
|
||||
source_name_id,
|
||||
is_segregated,
|
||||
facade.GetNameForID(source_name_id).to_string(),
|
||||
facade.GetRefForID(source_name_id).to_string(),
|
||||
@@ -295,7 +298,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
0};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_name_id,
|
||||
steps.push_back(RouteStep{target_node_id,
|
||||
target_name_id,
|
||||
facade.IsSegregated(target_node_id),
|
||||
facade.GetNameForID(target_name_id).to_string(),
|
||||
facade.GetRefForID(target_name_id).to_string(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
#define ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
@@ -45,6 +46,18 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
|
||||
|
||||
/**
|
||||
* Apply maneuver override relations to the selected route.
|
||||
* Should be called before any other post-processing is performed
|
||||
* to ensure that all sequences of edge-based-nodes are still in the
|
||||
* steps list.
|
||||
*
|
||||
* @param steps the steps of the route
|
||||
*/
|
||||
void applyOverrides(const datafacade::BaseDataFacade &facade,
|
||||
std::vector<RouteStep> &steps,
|
||||
const LegGeometry &geometry);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -59,6 +59,7 @@ inline IntermediateIntersection getInvalidIntersection()
|
||||
|
||||
struct RouteStep
|
||||
{
|
||||
NodeID from_id;
|
||||
unsigned name_id;
|
||||
bool is_segregated;
|
||||
std::string name;
|
||||
|
||||
@@ -24,7 +24,9 @@ namespace engine
|
||||
|
||||
struct PathData
|
||||
{
|
||||
// id of via node of the turn
|
||||
// from edge-based-node id
|
||||
NodeID from_edge_based_node;
|
||||
// the internal OSRM id of the OSM node id that is the via node of the turn
|
||||
NodeID turn_via_node;
|
||||
// name of the street that leads to the turn
|
||||
unsigned name_id;
|
||||
|
||||
@@ -192,7 +192,8 @@ void annotatePath(const FacadeT &facade,
|
||||
BOOST_ASSERT(start_index < end_index);
|
||||
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
|
||||
{
|
||||
unpacked_path.push_back(PathData{id_vector[segment_idx + 1],
|
||||
unpacked_path.push_back(PathData{*node_from,
|
||||
id_vector[segment_idx + 1],
|
||||
name_index,
|
||||
is_segregated,
|
||||
weight_vector[segment_idx],
|
||||
@@ -266,7 +267,8 @@ void annotatePath(const FacadeT &facade,
|
||||
BOOST_ASSERT(segment_idx < id_vector.size() - 1);
|
||||
BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0);
|
||||
unpacked_path.push_back(
|
||||
PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
||||
PathData{target_node_id,
|
||||
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
||||
facade.GetNameIndex(target_node_id),
|
||||
facade.IsSegregated(target_node_id),
|
||||
weight_vector[segment_idx],
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/extraction_turn.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@@ -83,9 +84,11 @@ class EdgeBasedGraphFactory
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
||||
@@ -168,14 +171,17 @@ class EdgeBasedGraphFactory
|
||||
|
||||
// Edge-expanded edges are generate for all valid turns. The validity can be checked via the
|
||||
// restriction maps
|
||||
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &conditional_turn_penalties_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
void
|
||||
GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &conditional_turn_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace extractor
|
||||
class ExtractionContainers
|
||||
{
|
||||
void PrepareNodes();
|
||||
void PrepareManeuverOverrides();
|
||||
void PrepareRestrictions();
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
@@ -63,6 +64,9 @@ class ExtractionContainers
|
||||
std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
|
||||
std::vector<TurnRestriction> unconditional_turn_restrictions;
|
||||
|
||||
std::vector<InputManeuverOverride> external_maneuver_overrides_list;
|
||||
std::vector<UnresolvedManeuverOverride> internal_maneuver_overrides;
|
||||
|
||||
ExtractionContainers();
|
||||
|
||||
void PrepareData(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "extractor/edge_based_graph_factory.hpp"
|
||||
#include "extractor/extractor_config.hpp"
|
||||
#include "extractor/graph_compressor.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
|
||||
#include "guidance/guidance_processing.hpp"
|
||||
@@ -62,7 +63,8 @@ class Extractor
|
||||
|
||||
std::tuple<LaneDescriptionMap,
|
||||
std::vector<TurnRestriction>,
|
||||
std::vector<ConditionalTurnRestriction>>
|
||||
std::vector<ConditionalTurnRestriction>,
|
||||
std::vector<UnresolvedManeuverOverride>>
|
||||
ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads);
|
||||
|
||||
EdgeID BuildEdgeExpandedGraph(
|
||||
@@ -76,6 +78,7 @@ class Extractor
|
||||
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
const util::NameTable &name_table,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const LaneDescriptionMap &turn_lane_map,
|
||||
// for calculating turn penalties
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
|
||||
@@ -48,6 +48,7 @@ struct ExtractionWay;
|
||||
struct ExtractionRelation;
|
||||
struct ProfileProperties;
|
||||
struct InputConditionalTurnRestriction;
|
||||
struct InputManeuverOverride;
|
||||
|
||||
/**
|
||||
* This class is used by the extractor with the results of the
|
||||
@@ -90,6 +91,9 @@ class ExtractorCallbacks
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way);
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessManeuverOverride(const InputManeuverOverride & override);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ struct ExtractorConfig final : storage::IOConfig
|
||||
".osrm.properties",
|
||||
".osrm.icd",
|
||||
".osrm.cnbg",
|
||||
".osrm.cnbg_to_ebg"}),
|
||||
".osrm.cnbg_to_ebg",
|
||||
".osrm.maneuver_overrides"}),
|
||||
requested_num_threads(0),
|
||||
parse_conditionals(false),
|
||||
use_locations_cache(true)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <memory>
|
||||
@@ -28,6 +29,7 @@ class GraphCompressor
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
util::NodeBasedDynamicGraph &graph,
|
||||
const std::vector<NodeBasedEdgeAnnotation> &node_data_container,
|
||||
CompressedEdgeContainer &geometry_compressor);
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef MANUEVER_OVERRIDE_HPP
|
||||
#define MANUEVER_OVERRIDE_HPP
|
||||
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "storage/shared_memory_ownership.hpp"
|
||||
#include "util/vector_view.hpp"
|
||||
#include <algorithm>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
// Data that is loaded from the OSM datafile directly
|
||||
struct InputManeuverOverride
|
||||
{
|
||||
std::vector<OSMWayID> via_ways;
|
||||
OSMNodeID via_node;
|
||||
std::string maneuver;
|
||||
std::string direction;
|
||||
};
|
||||
|
||||
// Object returned by the datafacade
|
||||
struct ManeuverOverride
|
||||
{
|
||||
// util::ViewOrVector<NodeID, storage::Ownership::View> node_sequence;
|
||||
std::vector<NodeID> node_sequence;
|
||||
// before the turn, then later, the edge_based_node_id of the turn
|
||||
NodeID instruction_node; // node-based node ID
|
||||
guidance::TurnType::Enum override_type;
|
||||
guidance::DirectionModifier::Enum direction;
|
||||
};
|
||||
|
||||
// Object returned by the datafacade
|
||||
struct StorageManeuverOverride
|
||||
{
|
||||
std::uint32_t node_sequence_offset_begin;
|
||||
std::uint32_t node_sequence_offset_end;
|
||||
NodeID start_node;
|
||||
// before the turn, then later, the edge_based_node_id of the turn
|
||||
NodeID instruction_node; // node-based node ID
|
||||
guidance::TurnType::Enum override_type;
|
||||
guidance::DirectionModifier::Enum direction;
|
||||
};
|
||||
|
||||
struct NodeBasedTurn
|
||||
{
|
||||
NodeID from;
|
||||
NodeID via;
|
||||
NodeID to;
|
||||
|
||||
bool operator==(const NodeBasedTurn &other) const
|
||||
{
|
||||
return other.from == from && other.via == via && other.to == to;
|
||||
}
|
||||
};
|
||||
|
||||
struct UnresolvedManeuverOverride
|
||||
{
|
||||
|
||||
std::vector<NodeBasedTurn>
|
||||
turn_sequence; // initially the internal node-based-node ID of the node
|
||||
// before the turn, then later, the edge_based_node_id of the turn
|
||||
NodeID instruction_node; // node-based node ID
|
||||
guidance::TurnType::Enum override_type;
|
||||
guidance::DirectionModifier::Enum direction;
|
||||
|
||||
// check if all parts of the restriction reference an actual node
|
||||
bool Valid() const
|
||||
{
|
||||
return !turn_sequence.empty() && std::none_of(turn_sequence.begin(),
|
||||
turn_sequence.end(),
|
||||
[](const auto &n) {
|
||||
return n.from == SPECIAL_NODEID ||
|
||||
n.via == SPECIAL_NODEID ||
|
||||
n.to == SPECIAL_NODEID;
|
||||
}) &&
|
||||
(direction != guidance::DirectionModifier::MaxDirectionModifier ||
|
||||
override_type != guidance::TurnType::Invalid);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// custom specialization of std::hash can be injected in namespace std
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<osrm::extractor::NodeBasedTurn>
|
||||
|
||||
{
|
||||
typedef osrm::extractor::NodeBasedTurn argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(argument_type const &s) const noexcept
|
||||
{
|
||||
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, s.from);
|
||||
boost::hash_combine(seed, s.via);
|
||||
boost::hash_combine(seed, s.to);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
from=1
|
||||
to=3
|
||||
via=b
|
||||
|
||||
101 a 102 b 103
|
||||
---------------+---------------+-------------- (way 1)
|
||||
99 \ 98 \ 97
|
||||
51 \ 2 50 \ 3
|
||||
\ \
|
||||
*/
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef MANEUVER_OVERRIDE_RELATION_PARSER_HPP
|
||||
#define MANEUVER_OVERRIDE_RELATION_PARSER_HPP
|
||||
|
||||
#include "maneuver_override.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace osmium
|
||||
{
|
||||
class Relation;
|
||||
}
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
class ScriptingEnvironment;
|
||||
|
||||
/**
|
||||
* Parses the relations that represents maneuver overrides.
|
||||
* These are structured similarly to turn restrictions, with some slightly
|
||||
* different fields.
|
||||
*
|
||||
* Simple, via-node overrides (the maneuver at the "via" point is overridden)
|
||||
* <relation>
|
||||
* <tag k="type" v="maneuver"/>
|
||||
* <member type="way" ref="1234" role="from"/>
|
||||
* <member type="way" ref="5678" role="to"/>
|
||||
* <member type="node" ref="9999" role="via"/>
|
||||
* <tag k="maneuver" v="turn"/>
|
||||
* <tag k="direction" v="slight_right"/>
|
||||
* </relation>
|
||||
*
|
||||
* Via-way descriptions are also supported - this is helpful if
|
||||
* you only want to update an instruction if a certain sequence of
|
||||
* road transitions are taken.
|
||||
*
|
||||
* <relation>
|
||||
* <tag k="type" v="maneuver"/>
|
||||
* <member type="way" ref="1234" role="from"/>
|
||||
* <member type="way" ref="5678" role="to"/>
|
||||
* <member type="way" ref="9012" role="via"/> <!-- note via way here -->
|
||||
* <member type="node" ref="9999" role="via"/>
|
||||
* <tag k="maneuver" v="turn"/>
|
||||
* <tag k="direction" v="slight_right"/>
|
||||
* </relation>
|
||||
*
|
||||
* For via-way restrictions, ways must be connected end-to-end, i.e.
|
||||
* referenced ways must be split if the turn points are partway
|
||||
* along the original way.
|
||||
*
|
||||
*/
|
||||
class ManeuverOverrideRelationParser
|
||||
{
|
||||
public:
|
||||
ManeuverOverrideRelationParser();
|
||||
boost::optional<InputManeuverOverride> TryParse(const osmium::Relation &relation) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RESTRICTION_PARSER_HPP */
|
||||
@@ -2,6 +2,7 @@
|
||||
#define OSRM_EXTRACTOR_NODE_BASED_GRAPH_FACTORY_HPP_
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
@@ -39,7 +40,8 @@ class NodeBasedGraphFactory
|
||||
NodeBasedGraphFactory(const boost::filesystem::path &input_file,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
auto const &GetGraph() const { return compressed_output_graph; }
|
||||
auto const &GetBarriers() const { return barriers; }
|
||||
@@ -67,7 +69,8 @@ class NodeBasedGraphFactory
|
||||
// edges into a single representative form
|
||||
void Compress(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
// Most ways are bidirectional, making the geometry in forward and backward direction the same,
|
||||
// except for reversal. We make use of this fact by keeping only one representation of the
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
#define OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -28,7 +29,8 @@ class RestrictionCompressor
|
||||
{
|
||||
public:
|
||||
RestrictionCompressor(std::vector<TurnRestriction> &restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
// account for the compression of `from-via-to` into `from-to`
|
||||
void Compress(const NodeID from, const NodeID via, const NodeID to);
|
||||
@@ -40,6 +42,9 @@ class RestrictionCompressor
|
||||
// node-restrictions, so we can focus on them alone
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> starts;
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> ends;
|
||||
|
||||
boost::unordered_multimap<NodeID, NodeBasedTurn *> maneuver_starts;
|
||||
boost::unordered_multimap<NodeID, NodeBasedTurn *> maneuver_ends;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SCRIPTING_ENVIRONMENT_HPP
|
||||
|
||||
#include "extractor/internal_extractor_edge.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
|
||||
@@ -31,6 +32,7 @@ namespace extractor
|
||||
{
|
||||
|
||||
class RestrictionParser;
|
||||
class ManeuverOverrideRelationParser;
|
||||
class ExtractionRelationContainer;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
@@ -62,10 +64,12 @@ class ScriptingEnvironment
|
||||
virtual void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
const ManeuverOverrideRelationParser &maneuver_override_parser,
|
||||
const ExtractionRelationContainer &relations,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) = 0;
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions,
|
||||
std::vector<InputManeuverOverride> &resulting_maneuver_overrides) = 0;
|
||||
|
||||
virtual bool HasLocationDependentData() const = 0;
|
||||
};
|
||||
|
||||
@@ -88,10 +88,12 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
const ManeuverOverrideRelationParser &maneuver_override_parser,
|
||||
const ExtractionRelationContainer &relations,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) override;
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions,
|
||||
std::vector<InputManeuverOverride> &resulting_maneuver_overrides) override;
|
||||
|
||||
bool HasLocationDependentData() const override { return !location_dependent_data.empty(); }
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "conditional_turn_penalty.hpp"
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
@@ -298,6 +299,16 @@ inline void read(storage::io::FileReader &reader,
|
||||
for (auto &penalty : conditional_penalties)
|
||||
read(reader, penalty);
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer,
|
||||
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
||||
const std::vector<NodeID> &node_sequences)
|
||||
{
|
||||
writer.WriteElementCount64(maneuver_overrides.size());
|
||||
writer.WriteElementCount64(node_sequences.size());
|
||||
writer.WriteFrom(maneuver_overrides);
|
||||
writer.WriteFrom(node_sequences);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +321,8 @@ const constexpr char *modifier_names[] = {"uturn",
|
||||
"straight",
|
||||
"slight left",
|
||||
"left",
|
||||
"sharp left"};
|
||||
"sharp left",
|
||||
"UNDEFINED"};
|
||||
|
||||
/**
|
||||
* Human readable values for TurnType enum values
|
||||
@@ -363,13 +364,14 @@ const constexpr TurnTypeName turn_type_names[] = {
|
||||
{"roundabout turn", "roundabout turn"},
|
||||
{"exit roundabout", "exit roundabout turn"},
|
||||
{"invalid", "(stay on roundabout)"},
|
||||
{"invalid", "(sliproad)"}};
|
||||
{"invalid", "(sliproad)"},
|
||||
{"MAXVALUE", "MAXVALUE"}};
|
||||
|
||||
} // ns detail
|
||||
|
||||
inline std::string instructionTypeToString(const TurnType::Enum type)
|
||||
{
|
||||
static_assert(sizeof(detail::turn_type_names) / sizeof(detail::turn_type_names[0]) >=
|
||||
static_assert((sizeof(detail::turn_type_names) + 1) / sizeof(detail::turn_type_names[0]) >=
|
||||
TurnType::MaxTurnType,
|
||||
"Some turn types have no string representation.");
|
||||
return detail::turn_type_names[static_cast<std::size_t>(type)].external_name;
|
||||
@@ -377,7 +379,7 @@ inline std::string instructionTypeToString(const TurnType::Enum type)
|
||||
|
||||
inline std::string internalInstructionTypeToString(const TurnType::Enum type)
|
||||
{
|
||||
static_assert(sizeof(detail::turn_type_names) / sizeof(detail::turn_type_names[0]) >=
|
||||
static_assert((sizeof(detail::turn_type_names) + 1) / sizeof(detail::turn_type_names[0]) >=
|
||||
TurnType::MaxTurnType,
|
||||
"Some turn types have no string representation.");
|
||||
return detail::turn_type_names[static_cast<std::size_t>(type)].internal_name;
|
||||
@@ -385,7 +387,7 @@ inline std::string internalInstructionTypeToString(const TurnType::Enum type)
|
||||
|
||||
inline std::string instructionModifierToString(const DirectionModifier::Enum modifier)
|
||||
{
|
||||
static_assert(sizeof(detail::modifier_names) / sizeof(detail::modifier_names[0]) >=
|
||||
static_assert((sizeof(detail::modifier_names) + 1) / sizeof(detail::modifier_names[0]) >=
|
||||
DirectionModifier::MaxDirectionModifier,
|
||||
"Some direction modifiers have no string representation.");
|
||||
return detail::modifier_names[static_cast<std::size_t>(modifier)];
|
||||
|
||||
@@ -88,7 +88,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"MLD_CELL_LEVEL_OFFSETS",
|
||||
"MLD_GRAPH_NODE_LIST",
|
||||
"MLD_GRAPH_EDGE_LIST",
|
||||
"MLD_GRAPH_NODE_TO_OFFSET"};
|
||||
"MLD_GRAPH_NODE_TO_OFFSET",
|
||||
"MANEUVER_OVERRIDES",
|
||||
"MANEUVER_OVERRIDE_NODE_SEQUENCES"};
|
||||
|
||||
struct DataLayout
|
||||
{
|
||||
@@ -165,6 +167,8 @@ struct DataLayout
|
||||
MLD_GRAPH_NODE_LIST,
|
||||
MLD_GRAPH_EDGE_LIST,
|
||||
MLD_GRAPH_NODE_TO_OFFSET,
|
||||
MANEUVER_OVERRIDES,
|
||||
MANEUVER_OVERRIDE_NODE_SEQUENCES,
|
||||
NUM_BLOCKS
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ struct StorageConfig final : IOConfig
|
||||
".osrm.datasource_names",
|
||||
".osrm.names",
|
||||
".osrm.properties",
|
||||
".osrm.icd"},
|
||||
".osrm.icd",
|
||||
".osrm.maneuver_overrides"},
|
||||
{".osrm.hsgr",
|
||||
".osrm.nbg_nodes",
|
||||
".osrm.ebg_nodes",
|
||||
|
||||
Reference in New Issue
Block a user