refactor restriction parsing / extraction to actual types
Makes turn restrictions into dedicated structures and diferentiates between them via a variant. Ensures that we do not accidentally mess up ID types within our application. In addition this improves the restriction performance by only parsing all edges once at the cost of (at the time of writing) 22MB in terms of main memory usage.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
#define EXTRACTION_CONTAINERS_HPP
|
||||
|
||||
#include "extractor/first_and_last_segment_of_way.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/internal_extractor_edge.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
@@ -28,7 +27,7 @@ class ExtractionContainers
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
void WriteNodes(storage::io::FileWriter &file_out) const;
|
||||
void WriteRestrictions(const std::string &restrictions_file_name);
|
||||
void WriteConditionalRestrictions(const std::string &restrictions_file_name);
|
||||
void WriteEdges(storage::io::FileWriter &file_out) const;
|
||||
void WriteCharData(const std::string &file_name);
|
||||
|
||||
@@ -36,7 +35,6 @@ class ExtractionContainers
|
||||
using NodeIDVector = std::vector<OSMNodeID>;
|
||||
using NodeVector = std::vector<QueryNode>;
|
||||
using EdgeVector = std::vector<InternalExtractorEdge>;
|
||||
using RestrictionsVector = std::vector<InputRestrictionContainer>;
|
||||
using WayIDStartEndVector = std::vector<FirstAndLastSegmentOfWay>;
|
||||
using NameCharData = std::vector<unsigned char>;
|
||||
using NameOffsets = std::vector<unsigned>;
|
||||
@@ -49,9 +47,15 @@ class ExtractionContainers
|
||||
NameCharData name_char_data;
|
||||
NameOffsets name_offsets;
|
||||
// an adjacency array containing all turn lane masks
|
||||
RestrictionsVector restrictions_list;
|
||||
WayIDStartEndVector way_start_end_id_list;
|
||||
|
||||
unsigned max_internal_node_id;
|
||||
|
||||
// list of restrictions before we transform them into the output types
|
||||
std::vector<InputConditionalTurnRestriction> restrictions_list;
|
||||
|
||||
// turn restrictions split into conditional and unconditional turn restrictions
|
||||
std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
|
||||
std::vector<TurnRestriction> unconditional_turn_restrictions;
|
||||
|
||||
ExtractionContainers();
|
||||
|
||||
@@ -42,10 +42,10 @@ namespace extractor
|
||||
{
|
||||
|
||||
class ExtractionContainers;
|
||||
struct InputRestrictionContainer;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
struct ProfileProperties;
|
||||
struct InputConditionalTurnRestriction;
|
||||
|
||||
/**
|
||||
* This class is used by the extractor with the results of the
|
||||
@@ -83,7 +83,7 @@ class ExtractorCallbacks
|
||||
void ProcessNode(const osmium::Node ¤t_node, const ExtractionNode &result_node);
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessRestriction(const boost::optional<InputRestrictionContainer> &restriction);
|
||||
void ProcessRestriction(const InputConditionalTurnRestriction &restriction);
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -14,7 +15,7 @@ namespace extractor
|
||||
{
|
||||
|
||||
class CompressedEdgeContainer;
|
||||
class RestrictionMap;
|
||||
struct TurnRestriction;
|
||||
|
||||
class GraphCompressor
|
||||
{
|
||||
@@ -23,7 +24,7 @@ class GraphCompressor
|
||||
public:
|
||||
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
RestrictionMap &restriction_map,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
util::NodeBasedDynamicGraph &graph,
|
||||
CompressedEdgeContainer &geometry_compressor);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "util/opening_hours.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace osrm
|
||||
@@ -12,104 +13,254 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
// OSM offers two types of restrictions, via node and via-way restrictions. We parse both into the
|
||||
// same input container
|
||||
//
|
||||
// A restriction turning at a single node. This is the most common type of restriction:
|
||||
//
|
||||
// a - b - c
|
||||
// |
|
||||
// d
|
||||
//
|
||||
// ab via b to bd
|
||||
struct InputNodeRestriction
|
||||
{
|
||||
OSMEdgeID_weak from;
|
||||
OSMNodeID_weak via;
|
||||
OSMEdgeID_weak to;
|
||||
};
|
||||
|
||||
// A restriction that uses a single via-way in between
|
||||
//
|
||||
// f - e - d
|
||||
// |
|
||||
// a - b - c
|
||||
//
|
||||
// ab via be to ef -- no u turn
|
||||
struct InputWayRestriction
|
||||
{
|
||||
OSMEdgeID_weak from;
|
||||
OSMEdgeID_weak via;
|
||||
OSMEdgeID_weak to;
|
||||
};
|
||||
|
||||
// Outside view of the variant, these are equal to the `which()` results
|
||||
enum RestrictionType
|
||||
{
|
||||
NODE_RESTRICTION = 0,
|
||||
WAY_RESTRICTION = 1,
|
||||
NUM_RESTRICTION_TYPES = 2
|
||||
};
|
||||
|
||||
namespace restriction_details
|
||||
{
|
||||
|
||||
// currently these bits only hold an `is_only` value.
|
||||
struct Bits
|
||||
{ // mostly unused, initialised to false by default
|
||||
Bits() : is_only(false) {}
|
||||
|
||||
bool is_only;
|
||||
// when adding more bits, consider using bitfields just as in
|
||||
// bool unused : 7;
|
||||
};
|
||||
|
||||
} // namespace restriction
|
||||
|
||||
struct InputTurnRestriction
|
||||
{
|
||||
// keep in the same order as the turn restrictions below
|
||||
boost::variant<InputNodeRestriction, InputWayRestriction> node_or_way;
|
||||
restriction_details::Bits flags;
|
||||
|
||||
OSMEdgeID_weak From() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).from
|
||||
: boost::get<InputWayRestriction>(node_or_way).from;
|
||||
}
|
||||
|
||||
OSMEdgeID_weak To() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).to
|
||||
: boost::get<InputWayRestriction>(node_or_way).to;
|
||||
}
|
||||
|
||||
RestrictionType Type() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() < RestrictionType::NUM_RESTRICTION_TYPES);
|
||||
return static_cast<RestrictionType>(node_or_way.which());
|
||||
}
|
||||
|
||||
InputWayRestriction &AsWayRestriction()
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
|
||||
return boost::get<InputWayRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
const InputWayRestriction &AsWayRestriction() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
|
||||
return boost::get<InputWayRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
InputNodeRestriction &AsNodeRestriction()
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
|
||||
return boost::get<InputNodeRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
const InputNodeRestriction &AsNodeRestriction() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
|
||||
return boost::get<InputNodeRestriction>(node_or_way);
|
||||
}
|
||||
};
|
||||
struct InputConditionalTurnRestriction : InputTurnRestriction
|
||||
{
|
||||
std::vector<util::OpeningHours> condition;
|
||||
};
|
||||
|
||||
// OSRM manages restrictions based on node IDs which refer to the last node along the edge. Note
|
||||
// that this has the side-effect of not allowing parallel edges!
|
||||
struct NodeRestriction
|
||||
{
|
||||
NodeID from;
|
||||
NodeID via;
|
||||
NodeID to;
|
||||
|
||||
// check if all parts of the restriction reference an actual node
|
||||
bool Valid() const
|
||||
{
|
||||
return from != SPECIAL_NODEID && to != SPECIAL_NODEID && via != SPECIAL_NODEID;
|
||||
};
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return "From " + std::to_string(from) + " via " + std::to_string(via) + " to " +
|
||||
std::to_string(to);
|
||||
}
|
||||
};
|
||||
|
||||
// A way restriction in the context of OSRM requires translation into NodeIDs. This is due to the
|
||||
// compression happening in the graph creation process which would make it difficult to track
|
||||
// way-ids over a series of operations. Having access to the nodes directly allows look-up of the
|
||||
// edges in the processed structures
|
||||
struct WayRestriction
|
||||
{
|
||||
// a way restriction in OSRM is essentially a dual node turn restriction;
|
||||
//
|
||||
// | |
|
||||
// c -x- b
|
||||
// | |
|
||||
// d a
|
||||
//
|
||||
// from ab via bxc to cd: no_uturn
|
||||
//
|
||||
// Technically, we would need only a,b,c,d to describe the full turn in terms of nodes. When
|
||||
// parsing the relation, though, we do not know about the final representation in the node-based
|
||||
// graph for the restriction. In case of a traffic light, for example, we might end up with bxc
|
||||
// not being compressed to bc. For that reason, we need to maintain two node restrictions in
|
||||
// case a way restrction is not fully collapsed
|
||||
NodeRestriction in_restriction;
|
||||
NodeRestriction out_restriction;
|
||||
};
|
||||
|
||||
// Wrapper for turn restrictions that gives more information on its type / handles the switch
|
||||
// between node/way/multi-way restrictions
|
||||
struct TurnRestriction
|
||||
{
|
||||
union WayOrNode {
|
||||
OSMNodeID_weak node;
|
||||
OSMEdgeID_weak way;
|
||||
};
|
||||
WayOrNode via;
|
||||
WayOrNode from;
|
||||
WayOrNode to;
|
||||
// keep in the same order as the turn restrictions above
|
||||
boost::variant<NodeRestriction, WayRestriction> node_or_way;
|
||||
restriction_details::Bits flags;
|
||||
|
||||
std::vector<util::OpeningHours> condition;
|
||||
|
||||
struct Bits
|
||||
{ // mostly unused
|
||||
Bits()
|
||||
: is_only(false), uses_via_way(false), unused2(false), unused3(false), unused4(false),
|
||||
unused5(false), unused6(false), unused7(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_only : 1;
|
||||
bool uses_via_way : 1;
|
||||
bool unused2 : 1;
|
||||
bool unused3 : 1;
|
||||
bool unused4 : 1;
|
||||
bool unused5 : 1;
|
||||
bool unused6 : 1;
|
||||
bool unused7 : 1;
|
||||
} flags;
|
||||
|
||||
explicit TurnRestriction(NodeID node)
|
||||
// construction for NodeRestrictions
|
||||
explicit TurnRestriction(NodeRestriction node_restriction, bool is_only = false)
|
||||
: node_or_way(node_restriction)
|
||||
{
|
||||
via.node = node;
|
||||
from.node = SPECIAL_NODEID;
|
||||
to.node = SPECIAL_NODEID;
|
||||
}
|
||||
|
||||
explicit TurnRestriction(const bool is_only = false)
|
||||
{
|
||||
via.node = SPECIAL_NODEID;
|
||||
from.node = SPECIAL_NODEID;
|
||||
to.node = SPECIAL_NODEID;
|
||||
flags.is_only = is_only;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is just a wrapper around TurnRestriction used in the extractor.
|
||||
*
|
||||
* Could be merged with TurnRestriction. For now the type-destiction makes sense
|
||||
* as the format in which the restriction is presented in the extractor and in the
|
||||
* preprocessing is different. (see restriction_parser.cpp)
|
||||
*/
|
||||
struct InputRestrictionContainer
|
||||
{
|
||||
TurnRestriction restriction;
|
||||
|
||||
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw)
|
||||
// construction for WayRestrictions
|
||||
explicit TurnRestriction(WayRestriction way_restriction, bool is_only = false)
|
||||
: node_or_way(way_restriction)
|
||||
{
|
||||
restriction.from.way = fromWay;
|
||||
restriction.to.way = toWay;
|
||||
restriction.via.way = vw;
|
||||
}
|
||||
explicit InputRestrictionContainer(bool is_only = false)
|
||||
{
|
||||
restriction.from.way = SPECIAL_EDGEID;
|
||||
restriction.to.way = SPECIAL_EDGEID;
|
||||
restriction.via.node = SPECIAL_NODEID;
|
||||
restriction.flags.is_only = is_only;
|
||||
flags.is_only = is_only;
|
||||
}
|
||||
|
||||
static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0); }
|
||||
static InputRestrictionContainer max_value()
|
||||
explicit TurnRestriction()
|
||||
{
|
||||
return InputRestrictionContainer(SPECIAL_EDGEID, SPECIAL_EDGEID, SPECIAL_EDGEID);
|
||||
node_or_way = NodeRestriction{SPECIAL_EDGEID, SPECIAL_NODEID, SPECIAL_EDGEID};
|
||||
}
|
||||
|
||||
WayRestriction &AsWayRestriction()
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
|
||||
return boost::get<WayRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
const WayRestriction &AsWayRestriction() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
|
||||
return boost::get<WayRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
NodeRestriction &AsNodeRestriction()
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
|
||||
return boost::get<NodeRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
const NodeRestriction &AsNodeRestriction() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
|
||||
return boost::get<NodeRestriction>(node_or_way);
|
||||
}
|
||||
|
||||
RestrictionType Type() const
|
||||
{
|
||||
BOOST_ASSERT(node_or_way.which() < RestrictionType::NUM_RESTRICTION_TYPES);
|
||||
return static_cast<RestrictionType>(node_or_way.which());
|
||||
}
|
||||
|
||||
// check if all elements of the edge are considered valid
|
||||
bool Valid() const
|
||||
{
|
||||
if (node_or_way.which() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
auto const &restriction = AsWayRestriction();
|
||||
return restriction.in_restriction.Valid() && restriction.out_restriction.Valid();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const &restriction = AsNodeRestriction();
|
||||
return restriction.Valid();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string representation;
|
||||
if (node_or_way.which() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
auto const &way = AsWayRestriction();
|
||||
representation =
|
||||
"In: " + way.in_restriction.ToString() + " Out: " + way.out_restriction.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const &node = AsNodeRestriction();
|
||||
representation = node.ToString();
|
||||
}
|
||||
representation += " is_only: " + std::to_string(flags.is_only);
|
||||
return representation;
|
||||
}
|
||||
};
|
||||
|
||||
struct CmpRestrictionContainerByFrom
|
||||
struct ConditionalTurnRestriction : TurnRestriction
|
||||
{
|
||||
using value_type = InputRestrictionContainer;
|
||||
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
|
||||
{
|
||||
return a.restriction.from.way < b.restriction.from.way;
|
||||
}
|
||||
value_type max_value() const { return InputRestrictionContainer::max_value(); }
|
||||
value_type min_value() const { return InputRestrictionContainer::min_value(); }
|
||||
};
|
||||
|
||||
struct CmpRestrictionContainerByTo
|
||||
{
|
||||
using value_type = InputRestrictionContainer;
|
||||
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
|
||||
{
|
||||
return a.restriction.to.way < b.restriction.to.way;
|
||||
}
|
||||
value_type max_value() const { return InputRestrictionContainer::max_value(); }
|
||||
value_type min_value() const { return InputRestrictionContainer::min_value(); }
|
||||
std::vector<util::OpeningHours> condition;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
#define OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct NodeRestriction;
|
||||
struct TurnRestriction;
|
||||
|
||||
// OSRM stores restrictions in the form node -> node -> node instead of way -> node -> way (or
|
||||
// way->way->way) as it is done in OSM. These restrictions need to match the state of graph
|
||||
// compression which we perform in the graph compressor that removes certain degree two nodes from
|
||||
// the graph (all but the ones with penalties/barriers, as of the state of writing).
|
||||
// Since this graph compression ins performed after creating the restrictions in the extraction
|
||||
// phase, we need to update the involved nodes whenever one of the nodes is compressed.
|
||||
//
|
||||
//
|
||||
// !!!! Will bind to the restrictions vector and modify it in-place !!!!
|
||||
class RestrictionCompressor
|
||||
{
|
||||
public:
|
||||
RestrictionCompressor(std::vector<TurnRestriction> &restrictions);
|
||||
|
||||
// account for the compression of `from-via-to` into `from-to`
|
||||
void Compress(const NodeID from, const NodeID via, const NodeID to);
|
||||
|
||||
private:
|
||||
// a turn restriction is given as `from head via node to tail`. Edges ending at `head` being
|
||||
// contracted move the head pointer to their respective head. Edges starting at tail move the
|
||||
// tail values to their respective tails. Way turn restrictions are represented by two
|
||||
// node-restrictions, so we can focus on them alone
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> heads;
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> tails;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
|
||||
@@ -69,6 +69,7 @@ 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
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#include "extractor/restriction.hpp"
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -38,13 +37,15 @@ class ScriptingEnvironment;
|
||||
* ...----(a)-----(via)------(b)----...
|
||||
* So it can be represented by the tripe (a, via, b).
|
||||
*/
|
||||
|
||||
class RestrictionParser
|
||||
{
|
||||
public:
|
||||
RestrictionParser(bool use_turn_restrictions,
|
||||
bool parse_conditionals,
|
||||
std::vector<std::string> &restrictions);
|
||||
std::vector<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
|
||||
boost::optional<InputConditionalTurnRestriction>
|
||||
TryParse(const osmium::Relation &relation) const;
|
||||
|
||||
private:
|
||||
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
|
||||
|
||||
@@ -57,12 +57,12 @@ class ScriptingEnvironment
|
||||
virtual void ProcessTurn(ExtractionTurn &turn) = 0;
|
||||
virtual void ProcessSegment(ExtractionSegment &segment) = 0;
|
||||
|
||||
virtual void ProcessElements(
|
||||
const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) = 0;
|
||||
virtual void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +67,12 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
void ProcessTurn(ExtractionTurn &turn) override;
|
||||
void ProcessSegment(ExtractionSegment &segment) override;
|
||||
|
||||
void ProcessElements(
|
||||
const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) override;
|
||||
void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
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;
|
||||
|
||||
private:
|
||||
void InitContext(LuaScriptingContext &context);
|
||||
|
||||
@@ -137,41 +137,67 @@ inline void write(storage::io::FileWriter &writer,
|
||||
storage::serialization::write(writer, node_data_container.classes);
|
||||
}
|
||||
|
||||
// read/write for conditional turn restrictions file
|
||||
inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &restrictions)
|
||||
inline void read(storage::io::FileReader &reader, NodeRestriction &restriction)
|
||||
{
|
||||
auto num_indices = reader.ReadElementCount64();
|
||||
restrictions.reserve(num_indices);
|
||||
TurnRestriction restriction;
|
||||
while (num_indices > 0)
|
||||
{
|
||||
bool is_only;
|
||||
reader.ReadInto(restriction.via);
|
||||
reader.ReadInto(restriction.from);
|
||||
reader.ReadInto(restriction.to);
|
||||
reader.ReadInto(is_only);
|
||||
auto num_conditions = reader.ReadElementCount64();
|
||||
restriction.condition.resize(num_conditions);
|
||||
for (uint64_t i = 0; i < num_conditions; i++)
|
||||
{
|
||||
reader.ReadInto(restriction.condition[i].modifier);
|
||||
storage::serialization::read(reader, restriction.condition[i].times);
|
||||
storage::serialization::read(reader, restriction.condition[i].weekdays);
|
||||
storage::serialization::read(reader, restriction.condition[i].monthdays);
|
||||
}
|
||||
restriction.flags.is_only = is_only;
|
||||
reader.ReadInto(restriction.from);
|
||||
reader.ReadInto(restriction.via);
|
||||
reader.ReadInto(restriction.to);
|
||||
}
|
||||
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
inline void write(storage::io::FileWriter &writer, const NodeRestriction &restriction)
|
||||
{
|
||||
writer.WriteOne(restriction.from);
|
||||
writer.WriteOne(restriction.via);
|
||||
writer.WriteOne(restriction.to);
|
||||
}
|
||||
|
||||
inline void read(storage::io::FileReader &reader, WayRestriction &restriction)
|
||||
{
|
||||
read(reader, restriction.in_restriction);
|
||||
read(reader, restriction.out_restriction);
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const WayRestriction &restriction)
|
||||
{
|
||||
write(writer, restriction.in_restriction);
|
||||
write(writer, restriction.out_restriction);
|
||||
}
|
||||
|
||||
inline void read(storage::io::FileReader &reader, TurnRestriction &restriction)
|
||||
{
|
||||
reader.ReadInto(restriction.flags);
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
WayRestriction way_restriction;
|
||||
read(reader, way_restriction);
|
||||
restriction.node_or_way = std::move(way_restriction);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
NodeRestriction node_restriction;
|
||||
read(reader, node_restriction);
|
||||
restriction.node_or_way = std::move(node_restriction);
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const TurnRestriction &restriction)
|
||||
{
|
||||
writer.WriteOne(restriction.via);
|
||||
writer.WriteOne(restriction.from);
|
||||
writer.WriteOne(restriction.to);
|
||||
writer.WriteOne(restriction.flags.is_only);
|
||||
writer.WriteOne(restriction.flags);
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
write(writer, boost::get<WayRestriction>(restriction.node_or_way));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
write(writer, boost::get<NodeRestriction>(restriction.node_or_way));
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const ConditionalTurnRestriction &restriction)
|
||||
{
|
||||
write(writer, static_cast<TurnRestriction>(restriction));
|
||||
writer.WriteElementCount64(restriction.condition.size());
|
||||
for (const auto &c : restriction.condition)
|
||||
{
|
||||
@@ -181,6 +207,72 @@ inline void write(storage::io::FileWriter &writer, const TurnRestriction &restri
|
||||
storage::serialization::write(writer, c.monthdays);
|
||||
}
|
||||
}
|
||||
|
||||
inline void read(storage::io::FileReader &reader, ConditionalTurnRestriction &restriction)
|
||||
{
|
||||
TurnRestriction base;
|
||||
read(reader, base);
|
||||
reinterpret_cast<TurnRestriction &>(restriction) = std::move(base);
|
||||
auto num_conditions = reader.ReadElementCount64();
|
||||
restriction.condition.resize(num_conditions);
|
||||
for (uint64_t i = 0; i < num_conditions; i++)
|
||||
{
|
||||
reader.ReadInto(restriction.condition[i].modifier);
|
||||
storage::serialization::read(reader, restriction.condition[i].times);
|
||||
storage::serialization::read(reader, restriction.condition[i].weekdays);
|
||||
storage::serialization::read(reader, restriction.condition[i].monthdays);
|
||||
}
|
||||
}
|
||||
|
||||
// read/write for conditional turn restrictions file
|
||||
inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
auto num_indices = reader.ReadElementCount64();
|
||||
restrictions.reserve(num_indices);
|
||||
TurnRestriction restriction;
|
||||
while (num_indices > 0)
|
||||
{
|
||||
read(reader, restriction);
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
std::uint64_t num_indices = restrictions.size();
|
||||
writer.WriteElementCount64(num_indices);
|
||||
auto const write_restriction = [&writer](const auto &restriction) {
|
||||
write(writer, restriction);
|
||||
};
|
||||
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
|
||||
}
|
||||
|
||||
// read/write for conditional turn restrictions file
|
||||
inline void read(storage::io::FileReader &reader,
|
||||
std::vector<ConditionalTurnRestriction> &restrictions)
|
||||
{
|
||||
auto num_indices = reader.ReadElementCount64();
|
||||
restrictions.reserve(num_indices);
|
||||
ConditionalTurnRestriction restriction;
|
||||
while (num_indices > 0)
|
||||
{
|
||||
read(reader, restriction);
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
}
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer,
|
||||
const std::vector<ConditionalTurnRestriction> &restrictions)
|
||||
{
|
||||
std::uint64_t num_indices = restrictions.size();
|
||||
writer.WriteElementCount64(num_indices);
|
||||
auto const write_restriction = [&writer](const auto &restriction) {
|
||||
write(writer, restriction);
|
||||
};
|
||||
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user