Move graph compression code outside of EBGF

This commit is contained in:
Patrick Niklaus 2015-06-24 01:55:30 +02:00
parent 9958937fd1
commit 7345dc6861
8 changed files with 335 additions and 270 deletions

View File

@ -41,20 +41,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
std::shared_ptr<RestrictionMap> restriction_map,
std::unique_ptr<std::vector<NodeID>> barrier_node_list,
std::unique_ptr<std::vector<NodeID>> traffic_light_node_list,
const std::vector<QueryNode> &node_info_list,
const SpeedProfileProperties &speed_profile)
: speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list),
m_node_based_graph(std::move(node_based_graph)),
m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
const GeometryCompressor& geometry_compressor,
const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
const SpeedProfileProperties &speed_profile)
: m_node_info_list(node_info_list),
m_node_based_graph(node_based_graph),
m_restriction_map(restriction_map),
m_barrier_nodes(barrier_nodes),
m_traffic_lights(traffic_lights),
m_geometry_compressor(geometry_compressor),
speed_profile(speed_profile)
{
// insert into unordered sets for fast lookup
m_barrier_nodes.insert(barrier_node_list->begin(), barrier_node_list->end());
m_traffic_lights.insert(traffic_light_node_list->begin(), traffic_light_node_list->end());
}
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
@ -146,15 +146,6 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
NodeID current_edge_source_coordinate_id = node_u;
if (SPECIAL_NODEID != forward_data.edgeBasedNodeID)
{
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
}
if (SPECIAL_NODEID != reverse_data.edgeBasedNodeID)
{
max_id = std::max(reverse_data.edgeBasedNodeID, max_id);
}
// traverse arrays from start and end respectively
for (const auto i : osrm::irange(0u, geometry_size))
{
@ -231,13 +222,8 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
}
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state)
{
TIMER_START(geometry);
CompressGeometry();
TIMER_STOP(geometry);
TIMER_START(renumber);
RenumberEdges();
TIMER_STOP(renumber);
@ -250,189 +236,12 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
TIMER_STOP(generate_edges);
m_geometry_compressor.SerializeInternalVector(geometry_filename);
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
SimpleLogger().Write() << "Geometry compression: " << TIMER_SEC(geometry) << "s";
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
}
void EdgeBasedGraphFactory::CompressGeometry()
{
SimpleLogger().Write() << "Removing graph geometry while preserving topology";
const unsigned original_number_of_nodes = m_node_based_graph->GetNumberOfNodes();
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
Percent progress(original_number_of_nodes);
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
progress.printStatus(node_v);
// only contract degree 2 vertices
if (2 != m_node_based_graph->GetOutDegree(node_v))
{
continue;
}
// don't contract barrier node
if (m_barrier_nodes.end() != m_barrier_nodes.find(node_v))
{
continue;
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (m_restriction_map->IsViaNode(node_v))
{
continue;
}
/*
* reverse_e2 forward_e2
* u <---------- v -----------> w
* ----------> <-----------
* forward_e1 reverse_e1
*
* Will be compressed to:
*
* reverse_e1
* u <---------- w
* ---------->
* forward_e1
*
* If the edges are compatible.
*
*/
const bool reverse_edge_order =
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(node_v)).forward);
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
BOOST_ASSERT(forward_e2 >= m_node_based_graph->BeginEdges(node_v) &&
forward_e2 < m_node_based_graph->EndEdges(node_v));
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
BOOST_ASSERT(reverse_e2 >= m_node_based_graph->BeginEdges(node_v) &&
reverse_e2 < m_node_based_graph->EndEdges(node_v));
const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
const NodeID node_w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_w);
BOOST_ASSERT(node_v != node_w);
const NodeID node_u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_u);
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1));
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if (m_node_based_graph->FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
{
continue;
}
// this case can happen if two ways with different names overlap
if (fwd_edge_data1.nameID != rev_edge_data1.nameID ||
fwd_edge_data2.nameID != rev_edge_data2.nameID)
{
continue;
}
if (fwd_edge_data1.IsCompatibleTo(fwd_edge_data2) && rev_edge_data1.IsCompatibleTo(rev_edge_data2))
{
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e2).nameID ==
m_node_based_graph->GetEdgeData(reverse_e2).nameID);
// Get distances before graph is modified
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2);
const int reverse_weight1 = m_node_based_graph->GetEdgeData(reverse_e1).distance;
const int reverse_weight2 = m_node_based_graph->GetEdgeData(reverse_e2).distance;
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != reverse_weight2);
const bool has_node_penalty = m_traffic_lights.find(node_v) != m_traffic_lights.end();
// add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (has_node_penalty)
{
m_node_based_graph->GetEdgeData(forward_e1).distance +=
speed_profile.traffic_signal_penalty;
m_node_based_graph->GetEdgeData(reverse_e1).distance +=
speed_profile.traffic_signal_penalty;
}
// extend e1's to targets of e2's
m_node_based_graph->SetTarget(forward_e1, node_w);
m_node_based_graph->SetTarget(reverse_e1, node_u);
// remove e2's (if bidir, otherwise only one)
m_node_based_graph->DeleteEdge(node_v, forward_e2);
m_node_based_graph->DeleteEdge(node_v, reverse_e2);
// update any involved turn restrictions
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w,
*m_node_based_graph);
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u,
*m_node_based_graph);
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1, forward_e2, node_v, node_w,
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
m_geometry_compressor.CompressEdge(
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
++removed_node_count;
}
}
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
m_geometry_compressor.PrintStatistics();
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for (const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
if (m_node_based_graph->GetOutDegree(i) > 0)
{
++new_node_count;
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
}
}
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
SimpleLogger().Write() << "Node compression ratio: "
<< new_node_count / (double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: "
<< new_edge_count / (double)original_number_of_edges;
}
/// Renumbers all _forward_ edges and sets the edgeBasedNodeID.
/// A specific numbering is not important. Any unique ID will do.
@ -462,9 +271,7 @@ void EdgeBasedGraphFactory::RenumberEdges()
m_number_of_edge_based_nodes = numbered_edges_count;
}
/**
* Creates the nodes in the edge expanded graph from edges in the node-based graph.
*/
/// Creates the nodes in the edge expanded graph from edges in the node-based graph.
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
{
SimpleLogger().Write() << "Identifying components of the (compressed) road network";
@ -476,10 +283,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
component_explorer.run();
SimpleLogger().Write() << "identified: "
<< component_explorer.get_number_of_components() - removed_node_count
<< component_explorer.get_number_of_components()
<< " (compressed) components";
SimpleLogger().Write() << "identified "
<< component_explorer.get_size_one_count() - removed_node_count
<< component_explorer.get_size_one_count()
<< " (compressed) SCCs of size 1";
SimpleLogger().Write() << "generating edge-expanded nodes";
@ -543,9 +350,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
<< " nodes in edge-expanded graph";
}
/**
* Actually it also generates OriginalEdgeData and serializes them...
*/
/// Actually it also generates OriginalEdgeData and serializes them...
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &original_edge_data_filename, lua_State *lua_state)
{
@ -790,7 +595,3 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
}
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const
{
return m_number_of_edge_based_nodes;
}

View File

@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "speed_profile.hpp"
#include "geometry_compressor.hpp"
#include "../typedefs.h"
#include "../data_structures/deallocating_vector.hpp"
@ -57,17 +58,16 @@ class EdgeBasedGraphFactory
EdgeBasedGraphFactory() = delete;
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
std::shared_ptr<RestrictionMap> restricion_map,
std::unique_ptr<std::vector<NodeID>> barrier_node_list,
std::unique_ptr<std::vector<NodeID>> traffic_light_node_list,
const GeometryCompressor& geometry_compressor,
const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
const SpeedProfileProperties &speed_profile);
void Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state);
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
@ -78,20 +78,6 @@ class EdgeBasedGraphFactory
int GetTurnPenalty(double angle, lua_State *lua_state) const;
unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
} speed_profile;
private:
using EdgeData = NodeBasedDynamicGraph::EdgeData;
@ -102,13 +88,13 @@ class EdgeBasedGraphFactory
const std::vector<QueryNode>& m_node_info_list;
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
std::shared_ptr<RestrictionMap> m_restriction_map;
std::shared_ptr<RestrictionMap const> m_restriction_map;
std::unordered_set<NodeID> m_barrier_nodes;
std::unordered_set<NodeID> m_traffic_lights;
const std::unordered_set<NodeID>& m_barrier_nodes;
const std::unordered_set<NodeID>& m_traffic_lights;
const GeometryCompressor& m_geometry_compressor;
GeometryCompressor m_geometry_compressor;
SpeedProfileProperties speed_profile;
void CompressGeometry();
void RenumberEdges();
@ -121,9 +107,6 @@ class EdgeBasedGraphFactory
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
NodeID max_id;
std::size_t removed_node_count;
};
#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */

View File

@ -0,0 +1,187 @@
#include "graph_compressor.hpp"
#include "geometry_compressor.hpp"
#include "../data_structures/dynamic_graph.hpp"
#include "../data_structures/node_based_graph.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../data_structures/percent.hpp"
GraphCompressor::GraphCompressor(const SpeedProfileProperties& speed_profile)
: speed_profile(speed_profile)
{
}
void GraphCompressor::Compress(const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
RestrictionMap& restriction_map,
NodeBasedDynamicGraph& graph,
GeometryCompressor& geometry_compressor)
{
const unsigned original_number_of_nodes = graph.GetNumberOfNodes();
const unsigned original_number_of_edges = graph.GetNumberOfEdges();
Percent progress(original_number_of_nodes);
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
progress.printStatus(node_v);
// only contract degree 2 vertices
if (2 != graph.GetOutDegree(node_v))
{
continue;
}
// don't contract barrier node
if (barrier_nodes.end() != barrier_nodes.find(node_v))
{
continue;
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (restriction_map.IsViaNode(node_v))
{
continue;
}
// reverse_e2 forward_e2
// u <---------- v -----------> w
// ----------> <-----------
// forward_e1 reverse_e1
//
// Will be compressed to:
//
// reverse_e1
// u <---------- w
// ---------->
// forward_e1
//
// If the edges are compatible.
const bool reverse_edge_order =
!(graph.GetEdgeData(graph.BeginEdges(node_v)).forward);
const EdgeID forward_e2 = graph.BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
BOOST_ASSERT(forward_e2 >= graph.BeginEdges(node_v) &&
forward_e2 < graph.EndEdges(node_v));
const EdgeID reverse_e2 = graph.BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
BOOST_ASSERT(reverse_e2 >= graph.BeginEdges(node_v) &&
reverse_e2 < graph.EndEdges(node_v));
const EdgeData &fwd_edge_data2 = graph.GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = graph.GetEdgeData(reverse_e2);
const NodeID node_w = graph.GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_w);
BOOST_ASSERT(node_v != node_w);
const NodeID node_u = graph.GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_u);
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = graph.FindEdge(node_u, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(node_v == graph.GetTarget(forward_e1));
const EdgeID reverse_e1 = graph.FindEdge(node_w, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
BOOST_ASSERT(node_v == graph.GetTarget(reverse_e1));
const EdgeData &fwd_edge_data1 = graph.GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = graph.GetEdgeData(reverse_e1);
if (graph.FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
{
continue;
}
// this case can happen if two ways with different names overlap
if (fwd_edge_data1.nameID != rev_edge_data1.nameID ||
fwd_edge_data2.nameID != rev_edge_data2.nameID)
{
continue;
}
if (fwd_edge_data1.IsCompatibleTo(fwd_edge_data2) && rev_edge_data1.IsCompatibleTo(rev_edge_data2))
{
BOOST_ASSERT(graph.GetEdgeData(forward_e1).nameID ==
graph.GetEdgeData(reverse_e1).nameID);
BOOST_ASSERT(graph.GetEdgeData(forward_e2).nameID ==
graph.GetEdgeData(reverse_e2).nameID);
// Get distances before graph is modified
const int forward_weight1 = graph.GetEdgeData(forward_e1).distance;
const int forward_weight2 = graph.GetEdgeData(forward_e2).distance;
BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2);
const int reverse_weight1 = graph.GetEdgeData(reverse_e1).distance;
const int reverse_weight2 = graph.GetEdgeData(reverse_e2).distance;
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != reverse_weight2);
const bool has_node_penalty = traffic_lights.find(node_v) != traffic_lights.end();
// add weight of e2's to e1
graph.GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
graph.GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (has_node_penalty)
{
graph.GetEdgeData(forward_e1).distance +=
speed_profile.traffic_signal_penalty;
graph.GetEdgeData(reverse_e1).distance +=
speed_profile.traffic_signal_penalty;
}
// extend e1's to targets of e2's
graph.SetTarget(forward_e1, node_w);
graph.SetTarget(reverse_e1, node_u);
// remove e2's (if bidir, otherwise only one)
graph.DeleteEdge(node_v, forward_e2);
graph.DeleteEdge(node_v, reverse_e2);
// update any involved turn restrictions
restriction_map.FixupStartingTurnRestriction(node_u, node_v, node_w);
restriction_map.FixupArrivingTurnRestriction(node_u, node_v, node_w, graph);
restriction_map.FixupStartingTurnRestriction(node_w, node_v, node_u);
restriction_map.FixupArrivingTurnRestriction(node_w, node_v, node_u, graph);
// store compressed geometry in container
geometry_compressor.CompressEdge(
forward_e1, forward_e2, node_v, node_w,
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
geometry_compressor.CompressEdge(
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
}
}
PrintStatistics(original_number_of_nodes, original_number_of_edges, graph);
}
void GraphCompressor::PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const NodeBasedDynamicGraph& graph) const
{
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for (const auto i : osrm::irange(0u, graph.GetNumberOfNodes()))
{
if (graph.GetOutDegree(i) > 0)
{
++new_node_count;
new_edge_count += (graph.EndEdges(i) - graph.BeginEdges(i));
}
}
SimpleLogger().Write() << "Node compression ratio: "
<< new_node_count / (double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: "
<< new_edge_count / (double)original_number_of_edges;
}

View File

@ -0,0 +1,62 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GEOMETRY_COMPRESSOR_HPP
#define GEOMETRY_COMPRESSOR_HPP
#include "../typedefs.h"
#include "speed_profile.hpp"
#include "../data_structures/node_based_graph.hpp"
#include <memory>
#include <unordered_set>
class GeometryCompressor;
class RestrictionMap;
class GraphCompressor
{
using EdgeData = NodeBasedDynamicGraph::EdgeData;
public:
GraphCompressor(const SpeedProfileProperties& speed_profile);
void Compress(const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
RestrictionMap& restriction_map,
NodeBasedDynamicGraph& graph,
GeometryCompressor& geometry_compressor);
private:
void PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const NodeBasedDynamicGraph& graph) const;
SpeedProfileProperties speed_profile;
};
#endif

View File

@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "processing_chain.hpp"
#include "contractor.hpp"
#include "geometry_compressor.hpp"
#include "graph_compressor.hpp"
#include "../algorithms/crc32_processor.hpp"
#include "../data_structures/deallocating_vector.hpp"
@ -263,7 +265,7 @@ unsigned Prepare::CalculateEdgeChecksum(std::unique_ptr<std::vector<EdgeBasedNod
Also initializes speed profile.
*/
void Prepare::SetupScriptingEnvironment(
lua_State *lua_state, EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
lua_State *lua_state, SpeedProfileProperties &speed_profile)
{
// open utility libraries string library;
luaL_openlibs(lua_state);
@ -319,21 +321,32 @@ std::shared_ptr<RestrictionMap> Prepare::LoadRestrictionMap()
\brief Load node based graph from .osrm file
*/
std::shared_ptr<NodeBasedDynamicGraph>
Prepare::LoadNodeBasedGraph(std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_list,
Prepare::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
std::unordered_set<NodeID> &traffic_lights,
std::vector<QueryNode>& internal_to_external_node_map)
{
std::vector<NodeBasedEdge> edge_list;
boost::filesystem::ifstream input_stream(config.osrm_input_path, std::ios::in | std::ios::binary);
std::vector<NodeID> barrier_list;
std::vector<NodeID> traffic_light_list;
NodeID number_of_node_based_nodes = loadNodesFromFile(input_stream,
barrier_node_list, traffic_light_list,
barrier_list, traffic_light_list,
internal_to_external_node_map);
SimpleLogger().Write() << " - " << barrier_node_list.size() << " bollard nodes, "
SimpleLogger().Write() << " - " << barrier_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
// insert into unordered sets for fast lookup
barrier_nodes.insert(barrier_list.begin(), barrier_list.end());
traffic_lights.insert(traffic_light_list.begin(), traffic_light_list.end());
barrier_list.clear();
barrier_list.shrink_to_fit();
traffic_light_list.clear();
traffic_light_list.shrink_to_fit();
loadEdgesFromFile(input_stream, edge_list);
if (edge_list.empty())
@ -357,37 +370,38 @@ Prepare::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_nod
lua_State *lua_state = luaL_newstate();
luabind::open(lua_state);
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
SpeedProfileProperties speed_profile;
SetupScriptingEnvironment(lua_state, speed_profile);
auto barrier_node_list = osrm::make_unique<std::vector<NodeID>>();
auto traffic_light_list = osrm::make_unique<std::vector<NodeID>>();
std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights;
auto restriction_map = LoadRestrictionMap();
auto node_based_graph = LoadNodeBasedGraph(*barrier_node_list, *traffic_light_list, internal_to_external_node_map);
auto node_based_graph = LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map);
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
GeometryCompressor geometry_compressor;
GraphCompressor graph_compressor(speed_profile);
graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph, geometry_compressor);
EdgeBasedGraphFactory edge_based_graph_factory(node_based_graph,
restriction_map,
std::move(barrier_node_list),
std::move(traffic_light_list),
geometry_compressor,
barrier_nodes,
traffic_lights,
std::const_pointer_cast<RestrictionMap const>(restriction_map),
internal_to_external_node_map,
speed_profile);
edge_based_graph_factory.Run(config.edge_output_path, config.geometry_output_path, lua_state);
geometry_compressor.SerializeInternalVector(config.geometry_output_path);
edge_based_graph_factory.Run(config.edge_output_path, lua_state);
lua_close(lua_state);
const std::size_t number_of_edge_based_nodes =
edge_based_graph_factory.GetNumberOfEdgeBasedNodes();
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
return std::make_pair(number_of_node_based_nodes, number_of_edge_based_nodes);
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
return std::make_pair(number_of_node_based_nodes, node_based_edge_list.size());
}
/**

View File

@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp"
struct SpeedProfileProperties;
struct EdgeBasedNode;
struct lua_State;
@ -59,8 +60,7 @@ class Prepare
protected:
void SetupScriptingEnvironment(lua_State *myLuaState,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
SpeedProfileProperties &speed_profile);
unsigned CalculateEdgeChecksum(std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list);
void ContractGraph(const std::size_t number_of_edge_based_nodes,
DeallocatingVector<EdgeBasedEdge>& edge_based_edge_list,
@ -68,9 +68,11 @@ class Prepare
std::size_t WriteContractedGraph(unsigned number_of_edge_based_nodes,
std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list,
std::unique_ptr<DeallocatingVector<QueryEdge>> contracted_edge_list);
std::shared_ptr<NodeBasedDynamicGraph> LoadNodeBasedGraph(std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_list,
std::vector<QueryNode>& internal_to_external_node_map);
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
std::shared_ptr<NodeBasedDynamicGraph>
LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
std::unordered_set<NodeID> &traffic_lights,
std::vector<QueryNode>& internal_to_external_node_map);
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,

View File

@ -0,0 +1,16 @@
#ifndef SPEED_PROFILE_PROPERTIES_HPP
#define SPEED_PROFILE_PROPERTIES_HPP
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
};
#endif

View File

@ -156,7 +156,7 @@ class RestrictionMap
bool
CheckIfTurnIsRestricted(const NodeID node_u, const NodeID node_v, const NodeID node_w) const;
std::size_t size() { return m_count; }
std::size_t size() const { return m_count; }
private:
// check of node is the start of any restriction