Unpacking of intermediate paths

This commit is contained in:
Dennis Luxen
2014-02-11 11:42:24 +01:00
parent 3be644265b
commit c71c8b0047
20 changed files with 639 additions and 443 deletions
+193 -100
View File
@@ -45,6 +45,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
SpeedProfileProperties speed_profile
) : speed_profile(speed_profile),
m_turn_restrictions_count(0),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list)
{
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
@@ -106,7 +107,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false;
edge.data.roundabout = import_edge.isRoundabout();
edge.data.ignoreInGrid = import_edge.ignoreInGrid();
edge.data.ignore_in_grid = import_edge.ignoreInGrid();
edge.data.nameID = import_edge.name();
edge.data.type = import_edge.type();
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
@@ -134,9 +135,9 @@ void EdgeBasedGraphFactory::FixupArrivingTurnRestriction(
const NodeID v,
const NodeID w
) {
BOOST_ASSERT( u != UINT_MAX );
BOOST_ASSERT( v != UINT_MAX );
BOOST_ASSERT( w != UINT_MAX );
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
std::vector<NodeID> predecessors;
for(
@@ -173,9 +174,9 @@ void EdgeBasedGraphFactory::FixupStartingTurnRestriction(
const NodeID v,
const NodeID w
) {
BOOST_ASSERT( u != UINT_MAX );
BOOST_ASSERT( v != UINT_MAX );
BOOST_ASSERT( w != UINT_MAX );
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> old_start = std::make_pair(v,w);
RestrictionMap::const_iterator restriction_iterator;
@@ -215,8 +216,8 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const {
BOOST_ASSERT( u != UINT_MAX );
BOOST_ASSERT( v != UINT_MAX );
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter;
restriction_iter = m_restriction_map.find(restriction_source);
@@ -231,7 +232,7 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
}
}
}
return UINT_MAX;
return std::numeric_limits<unsigned>::max();
}
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
@@ -239,9 +240,9 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const NodeID v,
const NodeID w
) const {
BOOST_ASSERT( u != UINT_MAX );
BOOST_ASSERT( v != UINT_MAX );
BOOST_ASSERT( w != UINT_MAX );
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter;
@@ -264,29 +265,85 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
}
void EdgeBasedGraphFactory::InsertEdgeBasedNode(
EdgeIterator e1,
NodeIterator u,
NodeIterator v,
bool belongsToTinyComponent
bool belongs_to_tiny_cc
) {
BOOST_ASSERT( u != UINT_MAX );
BOOST_ASSERT( v != UINT_MAX );
BOOST_ASSERT( e1 != UINT_MAX );
EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode;
currentNode.nameID = data.nameID;
currentNode.lat1 = m_node_info_list[u].lat;
currentNode.lon1 = m_node_info_list[u].lon;
currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = m_node_info_list[v].lon;
if( m_geometry_compressor.HasEntryForID(e1) ) {
//reconstruct geometry and put in each individual edge with its offset
// merge edges together into one EdgeBasedNode
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
// find forward edge id and
const EdgeID e1 = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT( e1 != std::numeric_limits<unsigned>::max() );
const EdgeData & forward_data = m_node_based_graph->GetEdgeData(e1);
if( forward_data.ignore_in_grid ) {
// SimpleLogger().Write(logDEBUG) << "skipped edge at " << m_node_info_list[u].lat << "," <<
// m_node_info_list[u].lon << " - " <<
// m_node_info_list[v].lat << "," <<
// m_node_info_list[v].lon;
return;
}
currentNode.belongsToTinyComponent = belongsToTinyComponent;
currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance;
m_edge_based_node_list.push_back(currentNode);
// find reverse edge id and
const EdgeID e2 = m_node_based_graph->FindEdge(v, u);
BOOST_ASSERT( e2 != std::numeric_limits<unsigned>::max() );
const EdgeData & reverse_data = m_node_based_graph->GetEdgeData(e2);
if( m_geometry_compressor.HasEntryForID(e1) ) {
BOOST_ASSERT( m_geometry_compressor.HasEntryForID(e2) );
// reconstruct geometry and put in each individual edge with its offset
const std::vector<GeometryCompressor::CompressedNode> & forward_geometry = m_geometry_compressor.GetBucketReference(e1);
const std::vector<GeometryCompressor::CompressedNode> & reverse_geometry = m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT( forward_geometry.size() == reverse_geometry.size() );
BOOST_ASSERT( 0 != forward_geometry.size() );
for( unsigned i = 0; i < reverse_geometry.size(); ++i ) {
if( forward_geometry[i].first != reverse_geometry[reverse_geometry.size()-1-i].first ) {
#ifndef NDEBUG
SimpleLogger().Write() << "size1: " << forward_geometry.size() << ", size2: " << reverse_geometry.size();
SimpleLogger().Write() << "index1: " << i << ", index2: " << reverse_geometry.size()-1-i;
SimpleLogger().Write() << forward_geometry[0].first << "!=" << reverse_geometry[reverse_geometry.size()-1-i].first;
BOOST_FOREACH(const GeometryCompressor::CompressedNode geometry_node, forward_geometry) {
SimpleLogger().Write(logDEBUG) << "fwd node " << geometry_node.first << "," << m_node_info_list[geometry_node.first].lat/COORDINATE_PRECISION << "," << m_node_info_list[geometry_node.first].lon/COORDINATE_PRECISION;
}
BOOST_FOREACH(const GeometryCompressor::CompressedNode geometry_node, reverse_geometry) {
SimpleLogger().Write(logDEBUG) << "rev node " << geometry_node.first << "," << m_node_info_list[geometry_node.first].lat/COORDINATE_PRECISION << "," << m_node_info_list[geometry_node.first].lon/COORDINATE_PRECISION;
}
#endif
}
BOOST_ASSERT( forward_geometry[i].first == reverse_geometry[reverse_geometry.size()-1-i].first );
//TODO reconstruct bidirectional edge with weights.
}
// SimpleLogger().Write(logDEBUG) << "start " << m_node_info_list[u].lat << "," << m_node_info_list[u].lon;
// SimpleLogger().Write(logDEBUG) << "target " << m_node_info_list[v].lat << "," << m_node_info_list[v].lon;
// BOOST_ASSERT( false );
} //else {
//TODO: emplace back with C++11
m_edge_based_node_list.push_back(
EdgeBasedNode(
forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
m_node_info_list[u].lat,
m_node_info_list[u].lon,
m_node_info_list[v].lat,
m_node_info_list[v].lon,
belongs_to_tiny_cc,
forward_data.nameID, //TODO use also reverse name id?
forward_data.distance,
reverse_data.distance,
0,
0
)
);
// }
}
@@ -329,25 +386,25 @@ void EdgeBasedGraphFactory::Run(
const bool reverse_edge_order = !(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(v)).forward);
const EdgeIterator forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order;
BOOST_ASSERT( UINT_MAX != forward_e2 );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != forward_e2 );
const EdgeIterator reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order;
BOOST_ASSERT( UINT_MAX != reverse_e2 );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != reverse_e2 );
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 NodeIterator w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT( UINT_MAX != w );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != w );
BOOST_ASSERT( v != w );
const NodeIterator u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT( UINT_MAX != u );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != u );
BOOST_ASSERT( u != v );
const EdgeIterator forward_e1 = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT( UINT_MAX != forward_e1 );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != forward_e1 );
BOOST_ASSERT( v == m_node_based_graph->GetTarget(forward_e1));
const EdgeIterator reverse_e1 = m_node_based_graph->FindEdge(w, v);
BOOST_ASSERT( UINT_MAX != reverse_e1 );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != reverse_e1 );
BOOST_ASSERT( v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData & fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
@@ -367,6 +424,12 @@ void EdgeBasedGraphFactory::Run(
m_node_based_graph->SetTarget(forward_e1, w);
m_node_based_graph->SetTarget(reverse_e1, u);
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
// const int forward_weight2 = fwd_edge_data2.distance;
const int reverse_weight1 = m_node_based_graph->GetEdgeData(reverse_e1).distance;
// const int reverse_weight2 = rev_edge_data2.distance;
// 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;
@@ -382,9 +445,21 @@ void EdgeBasedGraphFactory::Run(
FixupStartingTurnRestriction( w, v, u );
FixupArrivingTurnRestriction( w, v, u );
//TODO: store compressed geometry in container
m_geometry_compressor.CompressEdge( forward_e1, forward_e2, v );
m_geometry_compressor.CompressEdge( reverse_e1, reverse_e2, v );
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1,
forward_e2,
v,
forward_weight1//,
// forward_weight2
);
m_geometry_compressor.CompressEdge(
reverse_e1,
reverse_e2,
v,
reverse_weight1//,
// reverse_weight2
);
++removed_node_count;
}
@@ -405,8 +480,7 @@ void EdgeBasedGraphFactory::Run(
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count/(double)original_number_of_edges;
//Extract routing graph
DeallocatingVector<NodeBasedEdge> edges_list;
NodeBasedEdge new_edge;
unsigned numbered_edges_count = 0;
for(NodeID source = 0; source < m_node_based_graph->GetNumberOfNodes(); ++source) {
for(
EdgeID current_edge_id = m_node_based_graph->BeginEdges(source);
@@ -414,44 +488,37 @@ void EdgeBasedGraphFactory::Run(
++current_edge_id
) {
const NodeID target = m_node_based_graph->GetTarget(current_edge_id);
const EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge_id);
if( source > target ) {
EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge_id);
if( 0 == numbered_edges_count ){
SimpleLogger().Write(logDEBUG) << "uninitialized edge based node id: " << edge_data.edgeBasedNodeID;
}
if( !edge_data.forward ) {
// SimpleLogger().Write(logDEBUG) << "skipped edge (" << source << "," << target << ")=[" << current_edge_id << "]";
continue;
}
if( edge_data.forward) {
new_edge.source = source;
new_edge.target = target;
new_edge.data = edge_data;
new_edge.data.edgeBasedNodeID = edges_list.size();
edges_list.push_back(new_edge);
if( edge_data.edgeBasedNodeID != std::numeric_limits<unsigned>::max() ) {//source > target ) {
// SimpleLogger().Write(logDEBUG) << "skipping edge based node id: " << edge_data.edgeBasedNodeID;
continue;
}
BOOST_ASSERT( numbered_edges_count < m_node_based_graph->GetNumberOfEdges() );
edge_data.edgeBasedNodeID = numbered_edges_count;
++numbered_edges_count;
const EdgeID reverse_edge_id = m_node_based_graph->FindEdge(target, source);
BOOST_ASSERT( reverse_edge_id != m_node_based_graph->EndEdges(target));
const EdgeData & reverse_edge_data = m_node_based_graph->GetEdgeData(reverse_edge_id);
if( reverse_edge_data.forward ) {
new_edge.source = target;
new_edge.target = source;
new_edge.data = reverse_edge_data;
new_edge.data.edgeBasedNodeID = edges_list.size();
edges_list.push_back(new_edge);
EdgeData & reverse_edge_data = m_node_based_graph->GetEdgeData(reverse_edge_id);
if( !reverse_edge_data.forward ) {
continue;
}
BOOST_ASSERT( numbered_edges_count < m_node_based_graph->GetNumberOfEdges() );
reverse_edge_data.edgeBasedNodeID = numbered_edges_count;
++numbered_edges_count;
}
}
m_node_based_graph.reset();
std::sort( edges_list.begin(), edges_list.end() );
//Instantiate routing graph
m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
original_number_of_nodes,
edges_list
);
DeallocatingVector<NodeBasedEdge>().swap(edges_list);
BOOST_ASSERT(0 == edges_list.size() );
SimpleLogger().Write(logDEBUG) << "numbered " << numbered_edges_count << " edge-expanded nodes";
SimpleLogger().Write() << "Identifying components of the road network";
unsigned node_based_edge_counter = 0;
@@ -479,12 +546,15 @@ void EdgeBasedGraphFactory::Run(
"generating edge-expanded nodes";
p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes
for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
u < end;
++u
) {
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( u < m_node_based_graph->GetNumberOfNodes() );
p.printIncrement();
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
@@ -492,24 +562,32 @@ void EdgeBasedGraphFactory::Run(
e1 < last_edge;
++e1
) {
BOOST_ASSERT( e1 != std::numeric_limits<unsigned>::max() );
NodeIterator v = m_node_based_graph->GetTarget(e1);
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != v );
// pick only every other edge
if( u > v ) {
continue;
}
BOOST_ASSERT( u < v );
BOOST_ASSERT(
m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX
);
if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
//Note: edges that end on barrier nodes or on a turn restriction
//may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(
component_index_size[component_index_list[u]],
component_index_size[component_index_list[v]]
);
const unsigned size_of_component = std::min(
component_index_size[component_index_list[u]],
component_index_size[component_index_list[v]]
);
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
}
InsertEdgeBasedNode( u, v, size_of_component < 1000 );
}
}
//TODO: check if correct, suspect two off by ones here
m_number_of_edge_based_nodes = numbered_edges_count;
SimpleLogger().Write()
<< "Generated " << m_edge_based_node_list.size() << " nodes in " <<
"edge-expanded graph";
@@ -534,6 +612,7 @@ void EdgeBasedGraphFactory::Run(
unsigned restricted_turns_counter = 0;
unsigned skipped_uturns_counter = 0;
unsigned skipped_barrier_turns_counter = 0;
unsigned compressed = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
@@ -546,6 +625,10 @@ void EdgeBasedGraphFactory::Run(
e1 < last_edge_u;
++e1
) {
if( !m_node_based_graph->GetEdgeData(e1).forward ) {
continue;
}
++node_based_edge_counter;
const NodeIterator v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
@@ -557,9 +640,12 @@ void EdgeBasedGraphFactory::Run(
e2 < last_edge_v;
++e2
) {
if( !m_node_based_graph->GetEdgeData(e2).forward ) {
continue;
}
const NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
@@ -583,7 +669,7 @@ void EdgeBasedGraphFactory::Run(
//at the end of a dead-end street
if (
CheckIfTurnIsRestricted(u, v, w) &&
(to_node_of_only_restriction == UINT_MAX) &&
(to_node_of_only_restriction == std::numeric_limits<unsigned>::max()) &&
(w != to_node_of_only_restriction)
) {
++restricted_turns_counter;
@@ -594,12 +680,12 @@ void EdgeBasedGraphFactory::Run(
const EdgeData & edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData & edge_data2 = m_node_based_graph->GetEdgeData(e2);
BOOST_ASSERT(
edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
);
BOOST_ASSERT(
edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
);
// BOOST_ASSERT(
// edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
// );
// BOOST_ASSERT(
// edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
// );
BOOST_ASSERT(
edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID
);
@@ -612,22 +698,26 @@ void EdgeBasedGraphFactory::Run(
distance += speed_profile.trafficSignalPenalty;
}
const int turn_penalty = GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn){
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w);
if(turn_instruction == TurnInstructions.UTurn){
distance += speed_profile.uTurnPenalty;
}
distance += turn_penalty;
const bool edge_is_compressed = m_geometry_compressor.HasEntryForID(e1);
if(edge_is_compressed) {
m_geometry_compressor.AddNodeIDToCompressedEdge(e1, v);
++compressed;
m_geometry_compressor.AddLastViaNodeIDToCompressedEdge(e1, v, /*TODO*/ 1);
if ( 0 == m_geometry_compressor.GetPositionForID(e1) ) {
SimpleLogger().Write(logDEBUG) << "e1: " << e1 << " is zero with via node: " << v;
}
}
original_edge_data_vector.push_back(
OriginalEdgeData(
edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v,
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data2.nameID,
turnInstruction,
turn_instruction,
edge_is_compressed
)
);
@@ -656,10 +746,13 @@ void EdgeBasedGraphFactory::Run(
}
FlushVectorToStream( edge_data_file, original_edge_data_vector );
SimpleLogger().Write(logDEBUG) << "compressed: " << compressed;
edge_data_file.seekp( std::ios::beg );
edge_data_file.write( (char*)&original_edges_counter, sizeof(unsigned) );
edge_data_file.close();
SimpleLogger().Write(logDEBUG) << "serializing geometry to " << geometry_filename;
m_geometry_compressor.SerializeInternalVector( geometry_filename );
SimpleLogger().Write() <<
@@ -769,8 +862,8 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
}
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return m_node_based_graph->GetNumberOfEdges();
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const {
return m_number_of_edge_based_nodes;
}
void EdgeBasedGraphFactory::BFSCompentExplorer(
@@ -787,12 +880,12 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
component_index_list.resize(
m_node_based_graph->GetNumberOfNodes(),
UINT_MAX
std::numeric_limits<unsigned>::max()
);
//put unexplorered node with parent pointer into queue
for( NodeID node = 0, end = m_node_based_graph->GetNumberOfNodes(); node < end; ++node) {
if(UINT_MAX == component_index_list[node]) {
if(std::numeric_limits<unsigned>::max() == component_index_list[node]) {
bfs_queue.push(std::make_pair(node, node));
//mark node as read
component_index_list[node] = current_component;
@@ -818,7 +911,7 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction
) {
// At an only_-restriction but not at the right turn
@@ -829,7 +922,7 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
//when it is at the end of a dead-end street.
if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited
if(UINT_MAX == component_index_list[w]) {
if(std::numeric_limits<unsigned>::max() == component_index_list[w]) {
//insert next (node, parent) only if w has
//not yet been explored
//mark node as read
+9 -4
View File
@@ -94,7 +94,7 @@ public:
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() const;
unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties{
SpeedProfileProperties() :
@@ -110,6 +110,11 @@ public:
private:
struct NodeBasedEdgeData {
NodeBasedEdgeData() {
//TODO: proper c'tor
edgeBasedNodeID = UINT_MAX;
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
@@ -119,7 +124,7 @@ private:
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
bool ignore_in_grid:1;
bool contraFlow:1;
void SwapDirectionFlags() {
@@ -132,12 +137,13 @@ private:
return (forward == other.forward) &&
(backward == other.backward) &&
(nameID == other.nameID) &&
(ignoreInGrid == other.ignoreInGrid) &&
(ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow);
}
};
unsigned m_turn_restrictions_count;
unsigned m_number_of_edge_based_nodes;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
@@ -173,7 +179,6 @@ private:
) const;
void InsertEdgeBasedNode(
NodeBasedDynamicGraph::EdgeIterator e1,
NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent
+92 -46
View File
@@ -37,7 +37,7 @@ int current_free_list_maximum = 0;
int UniqueNumber () { return ++current_free_list_maximum; }
GeometryCompressor::GeometryCompressor() {
m_free_list.resize(100);
m_free_list.reserve(100);
IncreaseFreeList();
}
@@ -49,68 +49,91 @@ void GeometryCompressor::IncreaseFreeList() {
}
}
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) {
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const {
return (m_edge_id_to_list_index_map.find(edge_id) != m_edge_id_to_list_index_map.end());
}
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) {
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const {
boost::unordered_map<EdgeID, unsigned>::const_iterator map_iterator;
map_iterator = m_edge_id_to_list_index_map.find(edge_id);
BOOST_ASSERT( map_iterator != m_edge_id_to_list_index_map.end() );
BOOST_ASSERT( map_iterator->second < m_compressed_geometries.size() );
return map_iterator->second;
}
void GeometryCompressor::AddNodeIDToCompressedEdge(
void GeometryCompressor::AddLastViaNodeIDToCompressedEdge(
const EdgeID edge_id,
const NodeID node_id
const NodeID node_id,
const EdgeWeight weight
) {
unsigned index = GetPositionForID(edge_id);
BOOST_ASSERT( index < m_compressed_geometries.size() );
m_compressed_geometries[index].push_back( node_id );
if( !m_compressed_geometries[index].empty() ) {
if( m_compressed_geometries[index].back().first == node_id ) {
return;
}
}
BOOST_ASSERT( node_id != m_compressed_geometries[index].back().first );
m_compressed_geometries[index].push_back( std::make_pair(node_id, weight) );
BOOST_ASSERT( node_id == m_compressed_geometries[index].back().first );
}
void GeometryCompressor::SerializeInternalVector(
const std::string & path
) const {
//TODO: remove super-trivial geometries
std::ofstream geometry_out_stream( path.c_str(), std::ios::binary );
const unsigned compressed_edge_count = m_compressed_geometries.size()+1;
BOOST_ASSERT( UINT_MAX != compressed_edge_count );
const unsigned number_of_compressed_geometries = m_compressed_geometries.size()+1;
BOOST_ASSERT( UINT_MAX != number_of_compressed_geometries );
geometry_out_stream.write(
(char*)&compressed_edge_count,
(char*)&number_of_compressed_geometries,
sizeof(unsigned)
);
SimpleLogger().Write(logDEBUG) << "number_of_compressed_geometries: " << number_of_compressed_geometries;
// write indices array
unsigned prefix_sum_of_list_indices = 0;
for(unsigned i = 0; i < m_compressed_geometries.size(); ++i ) {
const std::vector<unsigned> & current_vector = m_compressed_geometries[i];
const unsigned unpacked_size = current_vector.size();
BOOST_ASSERT( UINT_MAX != unpacked_size );
geometry_out_stream.write(
(char*)&prefix_sum_of_list_indices,
sizeof(unsigned)
);
const std::vector<CompressedNode> & current_vector = m_compressed_geometries.at(i);
const unsigned unpacked_size = current_vector.size();
BOOST_ASSERT( UINT_MAX != unpacked_size );
prefix_sum_of_list_indices += unpacked_size;
}
// write sentinel element
// sentinel element
geometry_out_stream.write(
(char*)&prefix_sum_of_list_indices,
sizeof(unsigned)
);
// number of geometry entries to follow, it is the (inclusive) prefix sum
geometry_out_stream.write(
(char*)&prefix_sum_of_list_indices,
sizeof(unsigned)
);
SimpleLogger().Write(logDEBUG) << "number of geometry nodes: " << prefix_sum_of_list_indices;
unsigned control_sum = 0;
// write compressed geometries
for(unsigned i = 0; i < m_compressed_geometries.size(); ++i ) {
const std::vector<unsigned> & current_vector = m_compressed_geometries[i];
const std::vector<CompressedNode> & current_vector = m_compressed_geometries[i];
const unsigned unpacked_size = current_vector.size();
control_sum += unpacked_size;
BOOST_ASSERT( UINT_MAX != unpacked_size );
for(unsigned j = 0; j < unpacked_size; ++j) {
BOOST_FOREACH(const CompressedNode current_node, current_vector ) {
geometry_out_stream.write(
(char*)&(current_vector[j]),
sizeof(unsigned)
(char*)&(current_node.first),
sizeof(NodeID)
);
}
}
BOOST_ASSERT( control_sum == prefix_sum_of_list_indices );
// all done, let's close the resource
geometry_out_stream.close();
}
@@ -118,8 +141,11 @@ void GeometryCompressor::SerializeInternalVector(
void GeometryCompressor::CompressEdge(
const EdgeID surviving_edge_id,
const EdgeID removed_edge_id,
const NodeID via_node_id
const NodeID via_node_id,
const EdgeWeight weight1//,
// const EdgeWeight weight2
) {
BOOST_ASSERT( UINT_MAX != surviving_edge_id );
BOOST_ASSERT( UINT_MAX != removed_edge_id );
BOOST_ASSERT( UINT_MAX != via_node_id );
@@ -138,60 +164,80 @@ void GeometryCompressor::CompressEdge(
// create a new entry in the map
if( 0 == m_free_list.size() ) {
// make sure there is a place to put the entries
// SimpleLogger().Write() << "increased free list";
IncreaseFreeList();
}
BOOST_ASSERT( !m_free_list.empty() );
// SimpleLogger().Write() << "free list size: " << m_free_list.size();
m_edge_id_to_list_index_map[surviving_edge_id] = m_free_list.back();
m_free_list.pop_back();
}
const unsigned surving_list_id = m_edge_id_to_list_index_map[surviving_edge_id];
BOOST_ASSERT( surving_list_id == GetPositionForID(surviving_edge_id));
// SimpleLogger().Write() << "surviving edge id " << surviving_edge_id << " is listed at " << surving_list_id;
BOOST_ASSERT( surving_list_id < m_compressed_geometries.size() );
std::vector<NodeID> & compressed_id_list = m_compressed_geometries[surving_list_id];
compressed_id_list.push_back(via_node_id);
BOOST_ASSERT( 0 < compressed_id_list.size() );
std::vector<CompressedNode> & surviving_geometry_list = m_compressed_geometries[surving_list_id];
if( !surviving_geometry_list.empty() ) {
BOOST_ASSERT( via_node_id != surviving_geometry_list.back().first );
}
surviving_geometry_list.push_back( std::make_pair(via_node_id, weight1) );
BOOST_ASSERT( 0 < surviving_geometry_list.size() );
BOOST_ASSERT( !surviving_geometry_list.empty() );
// Find any existing list for removed_edge_id
typename boost::unordered_map<EdgeID, unsigned>::const_iterator map_iterator;
map_iterator = m_edge_id_to_list_index_map.find(removed_edge_id);
if( m_edge_id_to_list_index_map.end() != map_iterator ) {
const unsigned index = map_iterator->second;
BOOST_ASSERT( index < m_compressed_geometries.size() );
typename boost::unordered_map<EdgeID, unsigned>::const_iterator remove_list_iterator;
remove_list_iterator = m_edge_id_to_list_index_map.find(removed_edge_id);
if( m_edge_id_to_list_index_map.end() != remove_list_iterator ) {
const unsigned list_to_remove_index = remove_list_iterator->second;
BOOST_ASSERT( list_to_remove_index == GetPositionForID(removed_edge_id));
BOOST_ASSERT( list_to_remove_index < m_compressed_geometries.size() );
std::vector<CompressedNode> & remove_geometry_list = m_compressed_geometries[list_to_remove_index];
// found an existing list, append it to the list of surviving_edge_id
compressed_id_list.insert(
compressed_id_list.end(),
m_compressed_geometries[index].begin(),
m_compressed_geometries[index].end()
surviving_geometry_list.insert(
surviving_geometry_list.end(),
remove_geometry_list.begin(),
remove_geometry_list.end()
);
//remove the list of removed_edge_id
m_edge_id_to_list_index_map.erase(map_iterator);
m_edge_id_to_list_index_map.erase(remove_list_iterator);
BOOST_ASSERT( m_edge_id_to_list_index_map.end() == m_edge_id_to_list_index_map.find(removed_edge_id) );
m_compressed_geometries[index].clear();
BOOST_ASSERT( 0 == m_compressed_geometries[index].size() );
m_free_list.push_back(index);
BOOST_ASSERT( index == m_free_list.back() );
remove_geometry_list.clear();
BOOST_ASSERT( 0 == remove_geometry_list.size() );
m_free_list.push_back(list_to_remove_index);
BOOST_ASSERT( list_to_remove_index == m_free_list.back() );
}
}
void GeometryCompressor::PrintStatistics() const {
unsigned removed_edge_count = 0;
const unsigned surviving_edge_count = m_compressed_geometries.size()-m_free_list.size();
unsigned number_of_compressed_geometries = 0;
const unsigned compressed_edges = m_compressed_geometries.size();
BOOST_ASSERT( m_compressed_geometries.size() + m_free_list.size() > 0 );
unsigned long longest_chain_length = 0;
BOOST_FOREACH(const std::vector<unsigned> & current_vector, m_compressed_geometries) {
removed_edge_count += current_vector.size();
BOOST_FOREACH(const std::vector<CompressedNode> & current_vector, m_compressed_geometries) {
number_of_compressed_geometries += current_vector.size();
longest_chain_length = std::max(longest_chain_length, current_vector.size());
}
BOOST_ASSERT(0 == surviving_edge_count % 2);
BOOST_ASSERT(0 == compressed_edges % 2);
SimpleLogger().Write() <<
"surviving edges: " << surviving_edge_count <<
", compressed edges: " << removed_edge_count <<
"compressed edges: " << compressed_edges <<
", compressed geometries: " << number_of_compressed_geometries <<
", longest chain length: " << longest_chain_length <<
", comp ratio: " << ((float)surviving_edge_count/std::max(removed_edge_count, 1u) ) <<
", avg: chain length: " << (float)removed_edge_count/std::max(1u, surviving_edge_count);
", cmpr ratio: " << ((float)compressed_edges/std::max(number_of_compressed_geometries, 1u) ) <<
", avg chain length: " << (float)number_of_compressed_geometries/std::max(1u, compressed_edges);
SimpleLogger().Write() <<
"No bytes: " << 4*surviving_edge_count + removed_edge_count*4;
"No bytes: " << 4*compressed_edges + number_of_compressed_geometries*4 +8;
}
const std::vector<GeometryCompressor::CompressedNode> & GeometryCompressor::GetBucketReference(
const EdgeID edge_id
) const {
const unsigned index = m_edge_id_to_list_index_map.at( edge_id );
return m_compressed_geometries.at( index );
}
+16 -7
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include <boost/unordered_map.hpp>
#include <boost/filesystem.hpp>
#include <limits>
#include <vector>
@@ -37,23 +38,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class GeometryCompressor {
public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
GeometryCompressor();
void CompressEdge(
const EdgeID first_edge_id,
const EdgeID second_edge_id,
const NodeID via_node_id
const NodeID via_node_id,
const EdgeWeight weight1//,
// const EdgeWeight weight2
);
void AddLastViaNodeIDToCompressedEdge(
const EdgeID edge_id,
const NodeID node_id,
const EdgeWeight weight
);
bool HasEntryForID(const EdgeID edge_id) const;
void PrintStatistics() const;
bool HasEntryForID(const EdgeID edge_id);
void AddNodeIDToCompressedEdge(const EdgeID edge_id, const NodeID node_id);
unsigned GetPositionForID(const EdgeID edge_id);
void SerializeInternalVector(const std::string & path) const;
unsigned GetPositionForID(const EdgeID edge_id) const;
const std::vector<GeometryCompressor::CompressedNode> & GetBucketReference(const EdgeID edge_id) const;
private:
void IncreaseFreeList();
std::vector<std::vector<NodeID> > m_compressed_geometries;
std::vector<std::vector<CompressedNode> > m_compressed_geometries;
std::vector<unsigned> m_free_list;
boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};