simplify passing annotation data through OSRM pipeline using the node-based datastore
- separates node-based graph creation and compression from edge-based graph creation - moves usage of edge-based node data-container to pre-processing as well, unifying access to node-based data - single struct instead of separate vectors for annotation data in engine (single place of modification)
This commit is contained in:
committed by
Michael Krasnyk
parent
9b044aaa42
commit
2ddd98ee6d
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
@@ -77,7 +78,8 @@ inline void print(const NodeBasedDynamicGraph &node_based_graph,
|
||||
for (const auto &road : intersection)
|
||||
{
|
||||
std::cout << "\t" << toString(road) << "\n";
|
||||
std::cout << "\t\t" << node_based_graph.GetEdgeData(road.eid).road_classification.ToString()
|
||||
std::cout << "\t\t"
|
||||
<< node_based_graph.GetEdgeData(road.eid).flags.road_classification.ToString()
|
||||
<< "\n";
|
||||
}
|
||||
std::cout << std::flush;
|
||||
|
||||
@@ -223,6 +223,7 @@ template <typename EdgeDataT> class DynamicGraph
|
||||
unsigned GetNumberOfNodes() const { return number_of_nodes; }
|
||||
|
||||
unsigned GetNumberOfEdges() const { return number_of_edges; }
|
||||
auto GetEdgeCapacity() const { return edge_list.size(); }
|
||||
|
||||
unsigned GetOutDegree(const NodeIterator n) const { return node_array[n].edges; }
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ NodeID loadNodesFromFile(storage::io::FileReader &file_reader,
|
||||
/**
|
||||
* Reads a .osrm file and produces the edges.
|
||||
*/
|
||||
inline NodeID loadEdgesFromFile(storage::io::FileReader &file_reader,
|
||||
inline EdgeID loadEdgesFromFile(storage::io::FileReader &file_reader,
|
||||
std::vector<extractor::NodeBasedEdge> &edge_list)
|
||||
{
|
||||
auto number_of_edges = file_reader.ReadElementCount64();
|
||||
@@ -104,8 +104,7 @@ inline NodeID loadEdgesFromFile(storage::io::FileReader &file_reader,
|
||||
const auto &prev_edge = edge_list[i - 1];
|
||||
|
||||
BOOST_ASSERT_MSG(edge.weight > 0, "loaded null weight");
|
||||
BOOST_ASSERT_MSG(edge.forward, "edge must be oriented in forward direction");
|
||||
BOOST_ASSERT_MSG(edge.travel_mode != TRAVEL_MODE_INACCESSIBLE, "loaded non-accessible");
|
||||
BOOST_ASSERT_MSG(edge.flags.forward, "edge must be oriented in forward direction");
|
||||
|
||||
BOOST_ASSERT_MSG(edge.source != edge.target, "loaded edges contain a loop");
|
||||
BOOST_ASSERT_MSG(edge.source != prev_edge.source || edge.target != prev_edge.target,
|
||||
@@ -117,6 +116,15 @@ inline NodeID loadEdgesFromFile(storage::io::FileReader &file_reader,
|
||||
|
||||
return number_of_edges;
|
||||
}
|
||||
|
||||
inline EdgeID loadAnnotationData(storage::io::FileReader &file_reader,
|
||||
std::vector<extractor::NodeBasedEdgeAnnotation> &metadata)
|
||||
{
|
||||
auto const meta_data_count = file_reader.ReadElementCount64();
|
||||
metadata.resize(meta_data_count);
|
||||
file_reader.ReadInto(metadata.data(), meta_data_count);
|
||||
return meta_data_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ std::vector<OutputEdgeT> directedEdgesFromCompressed(const std::vector<InputEdge
|
||||
for (const auto &input_edge : input_edge_list)
|
||||
{
|
||||
// edges that are not forward get converted by flipping the end points
|
||||
BOOST_ASSERT(input_edge.forward);
|
||||
BOOST_ASSERT(input_edge.flags.forward);
|
||||
|
||||
edge.source = input_edge.source;
|
||||
edge.target = input_edge.target;
|
||||
@@ -86,10 +86,10 @@ std::vector<OutputEdgeT> directedEdgesFromCompressed(const std::vector<InputEdge
|
||||
|
||||
output_edge_list.push_back(edge);
|
||||
|
||||
if (!input_edge.is_split)
|
||||
if (!input_edge.flags.is_split)
|
||||
{
|
||||
std::swap(edge.source, edge.target);
|
||||
edge.data.reversed = !input_edge.backward;
|
||||
edge.data.reversed = !input_edge.flags.backward;
|
||||
output_edge_list.push_back(edge);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "util/dynamic_graph.hpp"
|
||||
#include "util/graph_utils.hpp"
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -19,70 +21,57 @@ namespace util
|
||||
struct NodeBasedEdgeData
|
||||
{
|
||||
NodeBasedEdgeData()
|
||||
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), reversed(false), roundabout(false),
|
||||
circular(false), startpoint(false), restricted(false), is_left_hand_driving(false),
|
||||
travel_mode(TRAVEL_MODE_INACCESSIBLE), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT), geometry_id({0, false}),
|
||||
reversed(false), annotation_data(-1)
|
||||
{
|
||||
}
|
||||
|
||||
NodeBasedEdgeData(EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
unsigned edge_id,
|
||||
unsigned name_id,
|
||||
GeometryID geometry_id,
|
||||
bool reversed,
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
bool restricted,
|
||||
bool is_left_hand_driving,
|
||||
extractor::TravelMode travel_mode,
|
||||
extractor::ClassData classes,
|
||||
const LaneDescriptionID lane_description_id)
|
||||
: weight(weight), duration(duration), edge_id(edge_id), name_id(name_id),
|
||||
reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint),
|
||||
restricted(restricted), is_left_hand_driving(is_left_hand_driving),
|
||||
travel_mode(travel_mode), classes(classes), lane_description_id(lane_description_id)
|
||||
extractor::NodeBasedEdgeClassification flags,
|
||||
AnnotationID annotation_data)
|
||||
: weight(weight), duration(duration), geometry_id(geometry_id), reversed(reversed),
|
||||
flags(flags), annotation_data(annotation_data)
|
||||
{
|
||||
}
|
||||
|
||||
EdgeWeight weight;
|
||||
EdgeWeight duration;
|
||||
unsigned edge_id;
|
||||
unsigned name_id;
|
||||
GeometryID geometry_id;
|
||||
bool reversed : 1;
|
||||
bool roundabout : 1;
|
||||
bool circular : 1;
|
||||
bool startpoint : 1;
|
||||
bool restricted : 1;
|
||||
bool is_left_hand_driving : 1;
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
extractor::ClassData classes;
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassification road_classification;
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (reversed == other.reversed) && (roundabout == other.roundabout) &&
|
||||
(circular == other.circular) && (startpoint == other.startpoint) &&
|
||||
(travel_mode == other.travel_mode) && (classes == other.classes) &&
|
||||
(road_classification == other.road_classification) &&
|
||||
(restricted == other.restricted) &&
|
||||
(is_left_hand_driving == other.is_left_hand_driving);
|
||||
}
|
||||
|
||||
bool CanCombineWith(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (name_id == other.name_id) && IsCompatibleTo(other);
|
||||
}
|
||||
extractor::NodeBasedEdgeClassification flags;
|
||||
AnnotationID annotation_data;
|
||||
};
|
||||
|
||||
// Check if two edge data elements can be compressed into a single edge (i.e. match in terms of
|
||||
// their meta-data).
|
||||
inline bool CanBeCompressed(const NodeBasedEdgeData &lhs,
|
||||
const NodeBasedEdgeData &rhs,
|
||||
const extractor::EdgeBasedNodeDataContainer &node_data_container)
|
||||
{
|
||||
if (!(lhs.flags == rhs.flags))
|
||||
return false;
|
||||
|
||||
auto const &lhs_annotation = node_data_container.GetAnnotation(lhs.annotation_data);
|
||||
auto const &rhs_annotation = node_data_container.GetAnnotation(rhs.annotation_data);
|
||||
|
||||
if (lhs_annotation.is_left_hand_driving != rhs_annotation.is_left_hand_driving)
|
||||
return false;
|
||||
|
||||
if (lhs_annotation.travel_mode != rhs_annotation.travel_mode)
|
||||
return false;
|
||||
|
||||
return lhs_annotation.classes == rhs_annotation.classes;
|
||||
}
|
||||
|
||||
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
|
||||
|
||||
/// Factory method to create NodeBasedDynamicGraph from NodeBasedEdges
|
||||
/// Since DynamicGraph expects directed edges, we need to insert
|
||||
/// two edges for undirected edges.
|
||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
||||
inline NodeBasedDynamicGraph
|
||||
NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
const std::vector<extractor::NodeBasedEdge> &input_edge_list)
|
||||
{
|
||||
@@ -92,16 +81,8 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
const extractor::NodeBasedEdge &input_edge) {
|
||||
output_edge.data.weight = input_edge.weight;
|
||||
output_edge.data.duration = input_edge.duration;
|
||||
output_edge.data.roundabout = input_edge.roundabout;
|
||||
output_edge.data.circular = input_edge.circular;
|
||||
output_edge.data.name_id = input_edge.name_id;
|
||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||
output_edge.data.classes = input_edge.classes;
|
||||
output_edge.data.startpoint = input_edge.startpoint;
|
||||
output_edge.data.restricted = input_edge.restricted;
|
||||
output_edge.data.is_left_hand_driving = input_edge.is_left_hand_driving;
|
||||
output_edge.data.road_classification = input_edge.road_classification;
|
||||
output_edge.data.lane_description_id = input_edge.lane_description_id;
|
||||
output_edge.data.flags = input_edge.flags;
|
||||
output_edge.data.annotation_data = input_edge.annotation_data;
|
||||
|
||||
BOOST_ASSERT(output_edge.data.weight > 0);
|
||||
BOOST_ASSERT(output_edge.data.duration > 0);
|
||||
@@ -109,9 +90,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
|
||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||
|
||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
|
||||
|
||||
return graph;
|
||||
return NodeBasedDynamicGraph(number_of_nodes, edges_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,6 +450,11 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
|
||||
|
||||
friend void serialization::write<T, Bits, Ownership>(storage::io::FileWriter &writer,
|
||||
const PackedVector &vec);
|
||||
inline void swap(PackedVector &other) noexcept
|
||||
{
|
||||
std::swap(vec, other.vec);
|
||||
std::swap(num_elements, other.num_elements);
|
||||
}
|
||||
|
||||
private:
|
||||
void allocate_blocks(std::size_t num_blocks)
|
||||
|
||||
@@ -72,6 +72,7 @@ static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<OSMWayID::val
|
||||
using NodeID = std::uint32_t;
|
||||
using EdgeID = std::uint32_t;
|
||||
using NameID = std::uint32_t;
|
||||
using AnnotationID = std::uint32_t;
|
||||
using EdgeWeight = std::int32_t;
|
||||
using EdgeDuration = std::int32_t;
|
||||
using SegmentWeight = std::uint32_t;
|
||||
|
||||
Reference in New Issue
Block a user