handle conditional via-way restrictions
- refactor conditional restriction handling to not use external data (first OSM nodes on ways) - BREAKING: changes internal file format of osrm.restrictions - add support for general conditional penalties based on edge-based nodes (requires unique edges between nodes)
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
#ifndef OSRM_EXTRACTOR_CONDITIONAL_TURN_PENALTY_HPP_
|
||||
#define OSRM_EXTRACTOR_CONDITIONAL_TURN_PENALTY_HPP_
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/opening_hours.hpp"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace osrm
|
||||
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ConditionalTurnPenalty
|
||||
{
|
||||
// offset into the sequential list of turn penalties (see TurnIndexBlock for reference);
|
||||
std::uint64_t turn_offset;
|
||||
util::Coordinate location;
|
||||
std::vector<util::OpeningHours> conditions;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_CONDITIONAL_TURN_PENALTY_HPP_
|
||||
@@ -4,6 +4,7 @@
|
||||
#define EDGE_BASED_GRAPH_FACTORY_HPP_
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/conditional_turn_penalty.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/extraction_turn.hpp"
|
||||
@@ -16,7 +17,7 @@
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "extractor/way_restriction_map.hpp"
|
||||
|
||||
#include "util/concurrent_id_map.hpp"
|
||||
@@ -92,7 +93,9 @@ class EdgeBasedGraphFactory
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
@@ -124,6 +127,18 @@ class EdgeBasedGraphFactory
|
||||
private:
|
||||
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
|
||||
|
||||
struct Conditional
|
||||
{
|
||||
// the edge based nodes allow for a unique identification of conditionals
|
||||
NodeID from_node;
|
||||
NodeID to_node;
|
||||
ConditionalTurnPenalty penalty;
|
||||
};
|
||||
|
||||
// assign the correct index to the penalty value stored in the conditional
|
||||
std::vector<ConditionalTurnPenalty>
|
||||
IndexConditionals(std::vector<Conditional> &&conditionals) const;
|
||||
|
||||
//! maps index from m_edge_based_node_list to ture/false if the node is an entry point to the
|
||||
//! graph
|
||||
std::vector<bool> m_edge_based_node_is_startpoint;
|
||||
@@ -173,7 +188,9 @@ class EdgeBasedGraphFactory
|
||||
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);
|
||||
|
||||
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
@@ -27,7 +27,6 @@ class ExtractionContainers
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
void WriteNodes(storage::io::FileWriter &file_out) const;
|
||||
void WriteConditionalRestrictions(const std::string &restrictions_file_name);
|
||||
void WriteEdges(storage::io::FileWriter &file_out) const;
|
||||
void WriteCharData(const std::string &file_name);
|
||||
|
||||
@@ -65,7 +64,6 @@ class ExtractionContainers
|
||||
|
||||
void PrepareData(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &osrm_path,
|
||||
const std::string &restrictions_file_name,
|
||||
const std::string &names_data_path);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ class Extractor
|
||||
private:
|
||||
ExtractorConfig config;
|
||||
|
||||
std::tuple<guidance::LaneDescriptionMap, std::vector<TurnRestriction>>
|
||||
std::tuple<guidance::LaneDescriptionMap,
|
||||
std::vector<TurnRestriction>,
|
||||
std::vector<ConditionalTurnRestriction>>
|
||||
ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads);
|
||||
|
||||
std::pair<std::size_t, EdgeID>
|
||||
@@ -70,6 +72,7 @@ class Extractor
|
||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &intersection_class_output_file,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
guidance::LaneDescriptionMap &turn_lane_map);
|
||||
void FindComponents(unsigned max_edge_id,
|
||||
const util::DeallocatingVector<EdgeBasedEdge> &input_edge_list,
|
||||
@@ -89,6 +92,10 @@ class Extractor
|
||||
static void WriteCompressedNodeBasedGraph(const std::string &path,
|
||||
const util::NodeBasedDynamicGraph &graph,
|
||||
const std::vector<util::Coordinate> &coordiantes);
|
||||
|
||||
void WriteConditionalRestrictions(
|
||||
const std::string &path,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ class GraphCompressor
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
util::NodeBasedDynamicGraph &graph,
|
||||
CompressedEdgeContainer &geometry_compressor);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "util/attributes.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
@@ -116,14 +116,6 @@ class IntersectionGenerator
|
||||
|
||||
// own state, used to find the correct coordinates along a road
|
||||
const CoordinateExtractor coordinate_extractor;
|
||||
|
||||
// check turn restrictions to find a node that is the only allowed target when coming from a
|
||||
// node to an intersection
|
||||
// d
|
||||
// |
|
||||
// a - b - c and `only_straight_on ab | bc would return `c` for `a,b`
|
||||
boost::optional<NodeID> GetOnlyAllowedTurnIfExistent(const NodeID coming_from_node,
|
||||
const NodeID node_at_intersection) const;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "extractor/guidance/turn_classification.hpp"
|
||||
#include "extractor/guidance/turn_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include "util/attributes.hpp"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
#define OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
@@ -26,7 +27,8 @@ struct TurnRestriction;
|
||||
class RestrictionCompressor
|
||||
{
|
||||
public:
|
||||
RestrictionCompressor(std::vector<TurnRestriction> &restrictions);
|
||||
RestrictionCompressor(std::vector<TurnRestriction> &restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
|
||||
// account for the compression of `from-via-to` into `from-to`
|
||||
void Compress(const NodeID from, const NodeID via, const NodeID to);
|
||||
|
||||
@@ -14,8 +14,9 @@ namespace extractor
|
||||
// To avoid handling invalid restrictions / creating unnecessary duplicate nodes for via-ways, we do
|
||||
// a pre-flight check for restrictions and remove all invalid restrictions from the data. Use as
|
||||
// `restrictions = removeInvalidRestrictions(std::move(restrictions))`
|
||||
std::vector<TurnRestriction> removeInvalidRestrictions(std::vector<TurnRestriction>,
|
||||
const util::NodeBasedDynamicGraph &);
|
||||
std::vector<ConditionalTurnRestriction>
|
||||
removeInvalidRestrictions(std::vector<ConditionalTurnRestriction>,
|
||||
const util::NodeBasedDynamicGraph &);
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#ifndef OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|
||||
#define OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
// allows easy check for whether a node intersection is present at a given intersection
|
||||
template <typename restriction_type> class RestrictionIndex
|
||||
{
|
||||
public:
|
||||
using value_type = restriction_type;
|
||||
|
||||
template <typename extractor_type>
|
||||
RestrictionIndex(std::vector<restriction_type> &restrictions, extractor_type extractor);
|
||||
|
||||
bool IsIndexed(NodeID first, NodeID second) const;
|
||||
|
||||
auto Restrictions(NodeID first, NodeID second) const
|
||||
{
|
||||
return restriction_hash.equal_range(std::make_pair(first, second));
|
||||
};
|
||||
|
||||
auto Size() const { return restriction_hash.size(); }
|
||||
|
||||
private:
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, restriction_type *> restriction_hash;
|
||||
};
|
||||
|
||||
template <typename restriction_type>
|
||||
template <typename extractor_type>
|
||||
RestrictionIndex<restriction_type>::RestrictionIndex(std::vector<restriction_type> &restrictions,
|
||||
extractor_type extractor)
|
||||
{
|
||||
// build a multi-map
|
||||
for (auto &restriction : restrictions)
|
||||
restriction_hash.insert(std::make_pair(extractor(restriction), &restriction));
|
||||
}
|
||||
|
||||
template <typename restriction_type>
|
||||
bool RestrictionIndex<restriction_type>::IsIndexed(const NodeID first, const NodeID second) const
|
||||
{
|
||||
return restriction_hash.count(std::make_pair(first, second));
|
||||
}
|
||||
|
||||
struct IndexNodeByFromAndVia
|
||||
{
|
||||
std::pair<NodeID, NodeID> operator()(const TurnRestriction &restriction)
|
||||
{
|
||||
const auto &node = restriction.AsNodeRestriction();
|
||||
return std::make_pair(node.from, node.via);
|
||||
};
|
||||
};
|
||||
|
||||
// check wheter a turn is restricted within a restriction_index
|
||||
template <typename restriction_map_type>
|
||||
std::pair<bool, typename restriction_map_type::value_type *>
|
||||
isRestricted(const NodeID from,
|
||||
const NodeID via,
|
||||
const NodeID to,
|
||||
const restriction_map_type &restriction_map)
|
||||
{
|
||||
const auto range = restriction_map.Restrictions(from, via);
|
||||
|
||||
// check if a given node_restriction is targeting node
|
||||
const auto to_is_restricted = [to](const auto &pair) {
|
||||
const auto &restriction = *pair.second;
|
||||
if (restriction.Type() == RestrictionType::NODE_RESTRICTION)
|
||||
{
|
||||
auto const &as_node = restriction.AsNodeRestriction();
|
||||
auto const restricted = restriction.is_only ? (to != as_node.to) : (to == as_node.to);
|
||||
|
||||
return restricted;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto itr = std::find_if(range.first, range.second, to_is_restricted);
|
||||
|
||||
if (itr != range.second)
|
||||
return {true, itr->second};
|
||||
else
|
||||
return {false, NULL};
|
||||
}
|
||||
|
||||
using RestrictionMap = RestrictionIndex<TurnRestriction>;
|
||||
using ConditionalRestrictionMap = RestrictionIndex<ConditionalTurnRestriction>;
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|
||||
@@ -1,110 +0,0 @@
|
||||
#ifndef RESTRICTION_MAP_HPP
|
||||
#define RESTRICTION_MAP_HPP
|
||||
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "util/std_hash.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct RestrictionSource
|
||||
{
|
||||
NodeID start_node;
|
||||
NodeID via_node;
|
||||
|
||||
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via) {}
|
||||
|
||||
friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs)
|
||||
{
|
||||
return (lhs.start_node == rhs.start_node && lhs.via_node == rhs.via_node);
|
||||
}
|
||||
};
|
||||
|
||||
struct RestrictionTarget
|
||||
{
|
||||
NodeID target_node;
|
||||
bool is_only;
|
||||
|
||||
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only) {}
|
||||
|
||||
friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs)
|
||||
{
|
||||
return (lhs.target_node == rhs.target_node && lhs.is_only == rhs.is_only);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<osrm::extractor::RestrictionSource>
|
||||
{
|
||||
size_t operator()(const osrm::extractor::RestrictionSource &r_source) const
|
||||
{
|
||||
return hash_val(r_source.start_node, r_source.via_node);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct hash<osrm::extractor::RestrictionTarget>
|
||||
{
|
||||
size_t operator()(const osrm::extractor::RestrictionTarget &r_target) const
|
||||
{
|
||||
return hash_val(r_target.target_node, r_target.is_only);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
/**
|
||||
\brief Efficent look up if an edge is the start + via node of a TurnRestriction
|
||||
EdgeBasedEdgeFactory decides by it if edges are inserted or geometry is compressed
|
||||
*/
|
||||
class RestrictionMap
|
||||
{
|
||||
public:
|
||||
RestrictionMap() : m_count(0) {}
|
||||
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
|
||||
|
||||
bool IsViaNode(const NodeID node) const;
|
||||
|
||||
// Check if edge (u, v) is the start of any turn restriction.
|
||||
// If so returns id of first target node.
|
||||
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
|
||||
// Checks if turn <u,v,w> is actually a turn restriction.
|
||||
bool
|
||||
CheckIfTurnIsRestricted(const NodeID node_u, const NodeID node_v, const NodeID node_w) const;
|
||||
|
||||
std::size_t size() const { return m_count; }
|
||||
|
||||
private:
|
||||
// check of node is the start of any restriction
|
||||
bool IsSourceNode(const NodeID node) const;
|
||||
|
||||
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
|
||||
|
||||
std::size_t m_count;
|
||||
//! index -> list of (target, isOnly)
|
||||
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||
//! maps (start, via) -> bucket index
|
||||
std::unordered_map<RestrictionSource, unsigned> m_restriction_map;
|
||||
std::unordered_set<NodeID> m_restriction_start_nodes;
|
||||
std::unordered_set<NodeID> m_no_turn_via_node_set;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RESTRICTION_MAP_HPP
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef OSRM_EXTRACTOR_IO_HPP
|
||||
#define OSRM_EXTRACTOR_IO_HPP
|
||||
|
||||
#include "conditional_turn_penalty.hpp"
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
@@ -273,6 +274,54 @@ inline void write(storage::io::FileWriter &writer,
|
||||
};
|
||||
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
|
||||
}
|
||||
|
||||
inline void read(storage::io::FileReader &reader, ConditionalTurnPenalty &turn_penalty)
|
||||
{
|
||||
reader.ReadInto(turn_penalty.turn_offset);
|
||||
reader.ReadInto(turn_penalty.location.lat);
|
||||
reader.ReadInto(turn_penalty.location.lon);
|
||||
auto const num_conditions = reader.ReadElementCount64();
|
||||
turn_penalty.conditions.resize(num_conditions);
|
||||
for (auto &condition : turn_penalty.conditions)
|
||||
{
|
||||
reader.ReadInto(condition.modifier);
|
||||
storage::serialization::read(reader, condition.times);
|
||||
storage::serialization::read(reader, condition.weekdays);
|
||||
storage::serialization::read(reader, condition.monthdays);
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const ConditionalTurnPenalty &turn_penalty)
|
||||
{
|
||||
writer.WriteOne(turn_penalty.turn_offset);
|
||||
writer.WriteOne(static_cast<util::FixedLatitude::value_type>(turn_penalty.location.lat));
|
||||
writer.WriteOne(static_cast<util::FixedLongitude::value_type>(turn_penalty.location.lon));
|
||||
writer.WriteElementCount64(turn_penalty.conditions.size());
|
||||
for (const auto &c : turn_penalty.conditions)
|
||||
{
|
||||
writer.WriteOne(c.modifier);
|
||||
storage::serialization::write(writer, c.times);
|
||||
storage::serialization::write(writer, c.weekdays);
|
||||
storage::serialization::write(writer, c.monthdays);
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer,
|
||||
const std::vector<ConditionalTurnPenalty> &conditional_penalties)
|
||||
{
|
||||
writer.WriteElementCount64(conditional_penalties.size());
|
||||
for (const auto &penalty : conditional_penalties)
|
||||
write(writer, penalty);
|
||||
}
|
||||
|
||||
inline void read(storage::io::FileReader &reader,
|
||||
std::vector<ConditionalTurnPenalty> &conditional_penalties)
|
||||
{
|
||||
auto const num_elements = reader.ReadElementCount64();
|
||||
conditional_penalties.resize(num_elements);
|
||||
for (auto &penalty : conditional_penalties)
|
||||
read(reader, penalty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -18,6 +19,8 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
// The WayRestrictionMap uses ConditionalTurnRestrictions in general. Most restrictions will have
|
||||
// empty conditions, though.
|
||||
class WayRestrictionMap
|
||||
{
|
||||
public:
|
||||
@@ -26,7 +29,7 @@ class WayRestrictionMap
|
||||
NodeID from;
|
||||
NodeID to;
|
||||
};
|
||||
WayRestrictionMap(const std::vector<TurnRestriction> &turn_restrictions);
|
||||
WayRestrictionMap(const std::vector<ConditionalTurnRestriction> &conditional_restrictions);
|
||||
|
||||
// Check if an edge between two nodes is a restricted turn. The check needs to be performed to
|
||||
// find duplicated nodes during the creation of edge-based-edges
|
||||
@@ -43,10 +46,13 @@ class WayRestrictionMap
|
||||
std::vector<ViaWay> DuplicatedNodeRepresentatives() const;
|
||||
|
||||
// Access all duplicated NodeIDs for a set of nodes indicating a via way
|
||||
util::range<DuplicatedNodeID> DuplicatedNodeIDs(const NodeID from, const NodeID to) const;
|
||||
std::vector<DuplicatedNodeID> DuplicatedNodeIDs(const NodeID from, const NodeID to) const;
|
||||
|
||||
// check whether a turn onto a given node is restricted, when coming from a duplicated node
|
||||
bool IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const;
|
||||
// Get the restriction resulting in ^ IsRestricted. Requires IsRestricted to evaluate to true
|
||||
const ConditionalTurnRestriction &GetRestriction(DuplicatedNodeID duplicated_node,
|
||||
const NodeID to) const;
|
||||
|
||||
// changes edge_based_node to the correct duplicated_node_id in case node_based_from,
|
||||
// node_based_via, node_based_to can be identified with a restriction group
|
||||
@@ -76,11 +82,8 @@ class WayRestrictionMap
|
||||
// EBN: 0 . | 2 | 3 | 4 ...
|
||||
// duplicated node groups: ... | 5 | 7 | ...
|
||||
std::vector<DuplicatedNodeID> duplicated_node_groups;
|
||||
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_starts;
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_ends;
|
||||
|
||||
std::vector<TurnRestriction> restriction_data;
|
||||
std::vector<ConditionalTurnRestriction> restriction_data;
|
||||
RestrictionIndex<ConditionalTurnRestriction> restriction_starts;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
|
||||
@@ -97,7 +97,7 @@ template <typename T> void write(io::FileWriter &writer, const std::vector<T> &d
|
||||
{
|
||||
const auto count = data.size();
|
||||
writer.WriteElementCount64(count);
|
||||
return writer.WriteFrom(data.data(), count);
|
||||
writer.WriteFrom(data.data(), count);
|
||||
}
|
||||
|
||||
template <typename T> void read(io::FileReader &reader, util::vector_view<T> &data)
|
||||
|
||||
Reference in New Issue
Block a user