Support maneuver relations (#4676)

This commit is contained in:
Daniel Patterson
2018-02-10 05:32:09 +11:00
committed by GitHub
parent 1aed13500d
commit 5531cace7f
46 changed files with 1474 additions and 89 deletions
+15 -9
View File
@@ -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,
+4 -1
View File
@@ -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 &current_way, const ExtractionWay &result_way);
// warning: caller needs to take care of synchronization!
void ProcessManeuverOverride(const InputManeuverOverride & override);
};
}
}
+2 -1
View File
@@ -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)
+2
View File
@@ -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);
+120
View File
@@ -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
+6 -1
View File
@@ -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
+5 -1
View File
@@ -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(); }
+11
View File
@@ -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);
}
}
}
}