Implements Mapping for NodeBasedGraph -> EdgeBasedgraph Translation

This commit is contained in:
Daniel J. Hofmann
2017-02-02 16:55:19 +01:00
committed by Patrick Niklaus
parent 299d071e9d
commit f71d742b5e
8 changed files with 216 additions and 33 deletions
+30 -12
View File
@@ -1,5 +1,10 @@
#include "extractor/edge_based_graph_factory.hpp"
#include "extractor/edge_based_edge.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_lane_handler.hpp"
#include "extractor/node_based_graph_to_edge_based_graph_mapping_writer.hpp"
#include "extractor/scripting_environment.hpp"
#include "extractor/suffix_table.hpp"
#include "util/bearing.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
@@ -10,11 +15,6 @@
#include "util/percent.hpp"
#include "util/timing_util.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_lane_handler.hpp"
#include "extractor/scripting_environment.hpp"
#include "extractor/suffix_table.hpp"
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
@@ -92,7 +92,8 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &out
EdgeID EdgeBasedGraphFactory::GetHighestEdgeID() { return m_max_edge_id; }
void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v)
boost::optional<EdgeBasedGraphFactory::Mapping>
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v)
{
// merge edges together into one EdgeBasedNode
BOOST_ASSERT(node_u != SPECIAL_NODEID);
@@ -112,7 +113,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
if (forward_data.edge_id == SPECIAL_NODEID && reverse_data.edge_id == SPECIAL_NODEID)
{
return;
return boost::none;
}
if (forward_data.edge_id != SPECIAL_NODEID && reverse_data.edge_id == SPECIAL_NODEID)
@@ -172,6 +173,8 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
}
BOOST_ASSERT(current_edge_source_coordinate_id == node_v);
return Mapping{node_u, node_v, forward_data.edge_id, reverse_data.edge_id};
}
void EdgeBasedGraphFactory::FlushVectorToStream(
@@ -193,7 +196,9 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename,
const bool generate_edge_lookup)
const bool generate_edge_lookup,
const bool generate_nbg_ebg_mapping,
const std::string &nbg_ebg_mapping_path)
{
TIMER_START(renumber);
m_max_edge_id = RenumberEdges() - 1;
@@ -201,7 +206,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
TIMER_START(generate_nodes);
m_edge_based_node_weights.reserve(m_max_edge_id + 1);
GenerateEdgeExpandedNodes();
GenerateEdgeExpandedNodes(generate_nbg_ebg_mapping, nbg_ebg_mapping_path);
TIMER_STOP(generate_nodes);
TIMER_START(generate_edges);
@@ -255,8 +260,16 @@ unsigned EdgeBasedGraphFactory::RenumberEdges()
}
/// Creates the nodes in the edge expanded graph from edges in the node-based graph.
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const bool generate_nbg_ebg_mapping,
const std::string &nbg_ebg_mapping_path)
{
// Optional writer, for writing out a mapping. Neither default ctor not boost::optional work
// with the underlying FileWriter, so hack around that limitation with a unique_ptr.
std::unique_ptr<NodeBasedGraphToEdgeBasedGraphMappingWriter> writer;
if (generate_nbg_ebg_mapping)
writer =
std::make_unique<NodeBasedGraphToEdgeBasedGraphMappingWriter>(nbg_ebg_mapping_path);
util::Log() << "Generating edge expanded nodes ... ";
{
util::UnbufferedLog log;
@@ -286,15 +299,20 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
BOOST_ASSERT(node_u < node_v);
boost::optional<Mapping> mapping;
// if we found a non-forward edge reverse and try again
if (edge_data.edge_id == SPECIAL_NODEID)
{
InsertEdgeBasedNode(node_v, node_u);
mapping = InsertEdgeBasedNode(node_v, node_u);
}
else
{
InsertEdgeBasedNode(node_u, node_v);
mapping = InsertEdgeBasedNode(node_u, node_v);
}
if (generate_nbg_ebg_mapping)
writer->WriteMapping(mapping->u, mapping->v, mapping->head, mapping->tail);
}
}
}
+3 -1
View File
@@ -504,7 +504,9 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
config.turn_weight_penalties_path,
config.turn_duration_penalties_path,
config.turn_penalties_index_path,
config.generate_edge_lookup);
config.generate_edge_lookup,
config.dump_compressed_node_based_graph,
config.nbg_ebg_graph_mapping_output_path);
// The osrm-partition tool requires the compressed node based graph with an embedding.
//
+65 -2
View File
@@ -10,6 +10,7 @@
#include <iterator>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <boost/assert.hpp>
@@ -39,6 +40,8 @@ struct CompressedNodeBasedGraph
// - uint64: number of nodes and therefore also coordinates
// - (uint32_t, uint32_t): num_edges * edges
// - (int32_t, int32_t: num_nodes * coordinates (lon, lat)
//
// Gets written in Extractor::WriteCompressedNodeBasedGraph
const auto num_edges = reader.ReadElementCount64();
const auto num_nodes = reader.ReadElementCount64();
@@ -57,13 +60,69 @@ struct CompressedNodeBasedGraph
CompressedNodeBasedGraph LoadCompressedNodeBasedGraph(const std::string &path)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader(path, fingerprint);
CompressedNodeBasedGraph graph{reader};
return graph;
}
struct NodeBasedGraphToEdgeBasedGraphMapping
{
NodeBasedGraphToEdgeBasedGraphMapping(storage::io::FileReader &reader)
{
// Reads: | Fingerprint | #mappings | u v fwd_node bkw_node | u v fwd_node bkw_node | ..
// - uint64: number of mappings (u, v, fwd_node, bkw_node) chunks
// - NodeID u, NodeID v, EdgeID fwd_node, EdgeID bkw_node
//
// Gets written in NodeBasedGraphToEdgeBasedGraphMappingWriter
const auto num_mappings = reader.ReadElementCount64();
edge_based_node_to_node_based_nodes.reserve(num_mappings * 2);
for (std::uint64_t i{0}; i < num_mappings; ++i)
{
const auto u = reader.ReadOne<NodeID>(); // node based graph `from` node
const auto v = reader.ReadOne<NodeID>(); // node based graph `to` node
const auto fwd_ebg_node = reader.ReadOne<EdgeID>(); // edge based graph forward node
const auto bkw_ebg_node = reader.ReadOne<EdgeID>(); // edge based graph backward node
edge_based_node_to_node_based_nodes.insert({fwd_ebg_node, {u, v}});
edge_based_node_to_node_based_nodes.insert({bkw_ebg_node, {v, u}});
}
}
struct NodeBasedNodes
{
NodeID u, v;
};
NodeBasedNodes Lookup(EdgeID edge_based_node) const
{
auto it = edge_based_node_to_node_based_nodes.find(edge_based_node);
if (it != end(edge_based_node_to_node_based_nodes))
return it->second;
BOOST_ASSERT_MSG(false, "unable to fine edge based node, graph <-> mapping out of sync");
return NodeBasedNodes{SPECIAL_NODEID, SPECIAL_NODEID};
}
private:
std::unordered_map<EdgeID, NodeBasedNodes> edge_based_node_to_node_based_nodes;
};
NodeBasedGraphToEdgeBasedGraphMapping
LoadNodeBasedGraphToEdgeBasedGraphMapping(const std::string &path)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader(path, fingerprint);
NodeBasedGraphToEdgeBasedGraphMapping mapping{reader};
return mapping;
}
void LogStatistics(const std::string &filename, std::vector<std::uint32_t> bisection_ids)
{
auto compressed_node_based_graph = LoadCompressedNodeBasedGraph(filename);
@@ -85,7 +144,7 @@ void LogStatistics(const std::string &filename, std::vector<std::uint32_t> bisec
std::cout << "Annotation took " << TIMER_SEC(annotation) << " seconds" << std::endl;
}
void LogGeojson(const std::string &filename, std::vector<std::uint32_t> bisection_ids)
void LogGeojson(const std::string &filename, const std::vector<std::uint32_t> &bisection_ids)
{
// reload graph, since we destroyed the old one
auto compressed_node_based_graph = LoadCompressedNodeBasedGraph(filename);
@@ -173,6 +232,10 @@ int Partitioner::Run(const PartitionConfig &config)
LogStatistics(config.compressed_node_based_graph_path.string(),
recursive_bisection.BisectionIDs());
auto mapping = LoadNodeBasedGraphToEdgeBasedGraphMapping(config.nbg_ebg_mapping_path.string());
util::Log() << "Loaded node based graph to edge based graph mapping";
return 0;
}