Conditional turn restriction support (#3841)
* optionally include condition and via node coords in InputRestrictionContainer * only write conditionals to disk, custom serialization for restrictions * conditional turn lookup, reuse timezone validation from extract-conditionals * adapt updater to use coordinates/osm ids, remove internal to external map * add utc time now parameter to contraction * only compile timezone code where libshp is found, adapt test running * slight refactor, more tests * catch invalid via nodes in restriction parsing, set default cucumber origin to guinée * add another run to test mld routed paths * cosmetic review changes * Simplify Timezoner for windows build * Split declaration and parsing parts for opening hours * adjust conditional tests to run without shapefiles * always include parse conditionals option * Adjust travis timeout * Added dummy TZ shapefile with test timezone polygons * [skip ci] update changelog
This commit is contained in:
@@ -52,13 +52,13 @@ namespace lookup
|
||||
#pragma pack(push, 1)
|
||||
struct TurnIndexBlock
|
||||
{
|
||||
OSMNodeID from_id;
|
||||
OSMNodeID via_id;
|
||||
OSMNodeID to_id;
|
||||
NodeID from_id;
|
||||
NodeID via_id;
|
||||
NodeID to_id;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(std::is_trivial<TurnIndexBlock>::value, "TurnIndexBlock is not trivial");
|
||||
static_assert(sizeof(TurnIndexBlock) == 24, "TurnIndexBlock is not packed correctly");
|
||||
static_assert(sizeof(TurnIndexBlock) == 12, "TurnIndexBlock is not packed correctly");
|
||||
} // ns lookup
|
||||
|
||||
struct NodeBasedGraphToEdgeBasedGraphMappingWriter; // fwd. decl
|
||||
|
||||
@@ -40,7 +40,7 @@ class ExtractionContainers
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
void WriteNodes(storage::io::FileWriter &file_out) const;
|
||||
void WriteRestrictions(const std::string &restrictions_file_name) const;
|
||||
void WriteRestrictions(const std::string &restrictions_file_name);
|
||||
void WriteEdges(storage::io::FileWriter &file_out) const;
|
||||
void WriteCharData(const std::string &file_name);
|
||||
|
||||
@@ -48,7 +48,7 @@ class ExtractionContainers
|
||||
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
|
||||
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
|
||||
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
|
||||
using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
|
||||
using RestrictionsVector = std::vector<InputRestrictionContainer>;
|
||||
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>;
|
||||
using STXXLNameCharData = stxxl::vector<unsigned char>;
|
||||
using STXXLNameOffsets = stxxl::vector<unsigned>;
|
||||
@@ -59,10 +59,11 @@ class ExtractionContainers
|
||||
STXXLNameCharData name_char_data;
|
||||
STXXLNameOffsets name_offsets;
|
||||
// an adjacency array containing all turn lane masks
|
||||
STXXLRestrictionsVector restrictions_list;
|
||||
RestrictionsVector restrictions_list;
|
||||
STXXLWayIDStartEndVector way_start_end_id_list;
|
||||
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
|
||||
unsigned max_internal_node_id;
|
||||
std::vector<TurnRestriction> unconditional_turn_restrictions;
|
||||
|
||||
ExtractionContainers();
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ class Extractor
|
||||
private:
|
||||
ExtractorConfig config;
|
||||
|
||||
std::vector<TurnRestriction> ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
const unsigned number_of_threads);
|
||||
|
||||
std::pair<std::size_t, EdgeID>
|
||||
BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<util::Coordinate> &coordinates,
|
||||
@@ -64,7 +67,8 @@ class Extractor
|
||||
std::vector<bool> &node_is_startpoint,
|
||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &intersection_class_output_file);
|
||||
const std::string &intersection_class_output_file,
|
||||
std::vector<TurnRestriction> &turn_restrictions);
|
||||
void WriteProfileProperties(const std::string &output_path,
|
||||
const ProfileProperties &properties) const;
|
||||
void FindComponents(unsigned max_edge_id,
|
||||
|
||||
@@ -112,6 +112,7 @@ struct ExtractorConfig
|
||||
std::string turn_penalties_index_path;
|
||||
|
||||
bool use_metadata;
|
||||
bool parse_conditionals;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef RESTRICTION_HPP
|
||||
#define RESTRICTION_HPP
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/opening_hours.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <limits>
|
||||
@@ -20,6 +22,8 @@ struct TurnRestriction
|
||||
WayOrNode from;
|
||||
WayOrNode to;
|
||||
|
||||
std::vector<util::OpeningHours> condition;
|
||||
|
||||
struct Bits
|
||||
{ // mostly unused
|
||||
Bits()
|
||||
|
||||
@@ -95,7 +95,7 @@ class RestrictionMap
|
||||
return;
|
||||
}
|
||||
|
||||
// find all potential start edges. It is more efficent to get a (small) list
|
||||
// find all potential start edges. It is more efficient to get a (small) list
|
||||
// of potential start edges than iterating over all buckets
|
||||
std::vector<NodeID> predecessors;
|
||||
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
|
||||
|
||||
@@ -41,14 +41,17 @@ class ScriptingEnvironment;
|
||||
class RestrictionParser
|
||||
{
|
||||
public:
|
||||
RestrictionParser(ScriptingEnvironment &scripting_environment);
|
||||
boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
|
||||
RestrictionParser(bool use_turn_restrictions,
|
||||
bool parse_conditionals,
|
||||
std::vector<std::string> &restrictions);
|
||||
std::vector<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
|
||||
|
||||
private:
|
||||
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
|
||||
|
||||
std::vector<std::string> restrictions;
|
||||
bool use_turn_restrictions;
|
||||
bool parse_conditionals;
|
||||
std::vector<std::string> restrictions;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/segment_data_container.hpp"
|
||||
#include "extractor/turn_data_container.hpp"
|
||||
|
||||
@@ -19,6 +20,7 @@ namespace extractor
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
// read/write for datasources file
|
||||
inline void read(storage::io::FileReader &reader, Datasources &sources)
|
||||
{
|
||||
reader.ReadInto(sources);
|
||||
@@ -29,6 +31,7 @@ inline void write(storage::io::FileWriter &writer, Datasources &sources)
|
||||
writer.WriteFrom(sources);
|
||||
}
|
||||
|
||||
// read/write for segment data file
|
||||
template <storage::Ownership Ownership>
|
||||
inline void read(storage::io::FileReader &reader,
|
||||
detail::SegmentDataContainerImpl<Ownership> &segment_data)
|
||||
@@ -55,6 +58,7 @@ inline void write(storage::io::FileWriter &writer,
|
||||
storage::serialization::write(writer, segment_data.datasources);
|
||||
}
|
||||
|
||||
// read/write for turn data file
|
||||
template <storage::Ownership Ownership>
|
||||
inline void read(storage::io::FileReader &reader,
|
||||
detail::TurnDataContainerImpl<Ownership> &turn_data_container)
|
||||
@@ -94,6 +98,51 @@ inline void write(storage::io::FileWriter &writer,
|
||||
storage::serialization::write(writer, node_data_container.name_ids);
|
||||
storage::serialization::write(writer, node_data_container.travel_modes);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
|
||||
restrictions.push_back(std::move(restriction));
|
||||
num_indices--;
|
||||
}
|
||||
}
|
||||
|
||||
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.WriteElementCount64(restriction.condition.size());
|
||||
for (const auto &c : restriction.condition)
|
||||
{
|
||||
writer.WriteOne(c.modifier);
|
||||
storage::serialization::write(writer, c.times);
|
||||
storage::serialization::write(writer, c.weekdays);
|
||||
storage::serialization::write(writer, c.monthdays);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user