Support maneuver relations (#4676)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user