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:
Karen Shea
2017-05-11 12:13:52 +02:00
committed by GitHub
parent 12f47708cd
commit 799a677e7a
42 changed files with 2116 additions and 1310 deletions
@@ -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
+4 -3
View File
@@ -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();
+5 -1
View File
@@ -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,
+1
View File
@@ -112,6 +112,7 @@ struct ExtractorConfig
std::string turn_penalties_index_path;
bool use_metadata;
bool parse_conditionals;
};
}
}
+4
View File
@@ -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()
+1 -1
View File
@@ -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))
+6 -3
View File
@@ -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;
};
}
}
+49
View File
@@ -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);
}
}
}
}
}