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

View File

@ -45,6 +45,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
SpeedProfileProperties speed_profile SpeedProfileProperties speed_profile
) : speed_profile(speed_profile), ) : speed_profile(speed_profile),
m_turn_restrictions_count(0), m_turn_restrictions_count(0),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list) m_node_info_list(node_info_list)
{ {
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) { BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
@ -106,7 +107,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
BOOST_ASSERT( edge.data.distance > 0 ); BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.roundabout = import_edge.isRoundabout(); 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.nameID = import_edge.name();
edge.data.type = import_edge.type(); edge.data.type = import_edge.type();
edge.data.isAccessRestricted = import_edge.isAccessRestricted(); edge.data.isAccessRestricted = import_edge.isAccessRestricted();
@ -134,9 +135,9 @@ void EdgeBasedGraphFactory::FixupArrivingTurnRestriction(
const NodeID v, const NodeID v,
const NodeID w const NodeID w
) { ) {
BOOST_ASSERT( u != UINT_MAX ); BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != UINT_MAX ); BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != UINT_MAX ); BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
std::vector<NodeID> predecessors; std::vector<NodeID> predecessors;
for( for(
@ -173,9 +174,9 @@ void EdgeBasedGraphFactory::FixupStartingTurnRestriction(
const NodeID v, const NodeID v,
const NodeID w const NodeID w
) { ) {
BOOST_ASSERT( u != UINT_MAX ); BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != UINT_MAX ); BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != UINT_MAX ); BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> old_start = std::make_pair(v,w); const std::pair<NodeID, NodeID> old_start = std::make_pair(v,w);
RestrictionMap::const_iterator restriction_iterator; RestrictionMap::const_iterator restriction_iterator;
@ -215,8 +216,8 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
const NodeID u, const NodeID u,
const NodeID v const NodeID v
) const { ) const {
BOOST_ASSERT( u != UINT_MAX ); BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != UINT_MAX ); BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v); const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter; RestrictionMap::const_iterator restriction_iter;
restriction_iter = m_restriction_map.find(restriction_source); 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( bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
@ -239,9 +240,9 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const NodeID v, const NodeID v,
const NodeID w const NodeID w
) const { ) const {
BOOST_ASSERT( u != UINT_MAX ); BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != UINT_MAX ); BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != UINT_MAX ); BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v); const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter; RestrictionMap::const_iterator restriction_iter;
@ -264,29 +265,85 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
} }
void EdgeBasedGraphFactory::InsertEdgeBasedNode( void EdgeBasedGraphFactory::InsertEdgeBasedNode(
EdgeIterator e1,
NodeIterator u, NodeIterator u,
NodeIterator v, NodeIterator v,
bool belongsToTinyComponent bool belongs_to_tiny_cc
) { ) {
BOOST_ASSERT( u != UINT_MAX ); // merge edges together into one EdgeBasedNode
BOOST_ASSERT( v != UINT_MAX ); BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( e1 != UINT_MAX ); BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode; // find forward edge id and
currentNode.nameID = data.nameID; const EdgeID e1 = m_node_based_graph->FindEdge(u, v);
currentNode.lat1 = m_node_info_list[u].lat; BOOST_ASSERT( e1 != std::numeric_limits<unsigned>::max() );
currentNode.lon1 = m_node_info_list[u].lon; const EdgeData & forward_data = m_node_based_graph->GetEdgeData(e1);
currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = m_node_info_list[v].lon; if( forward_data.ignore_in_grid ) {
if( m_geometry_compressor.HasEntryForID(e1) ) { // SimpleLogger().Write(logDEBUG) << "skipped edge at " << m_node_info_list[u].lat << "," <<
//reconstruct geometry and put in each individual edge with its offset // 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; // find reverse edge id and
currentNode.ignoreInGrid = data.ignoreInGrid; const EdgeID e2 = m_node_based_graph->FindEdge(v, u);
currentNode.weight = data.distance; BOOST_ASSERT( e2 != std::numeric_limits<unsigned>::max() );
m_edge_based_node_list.push_back(currentNode); 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 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; 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; 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 & fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData & rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2); const EdgeData & rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
const NodeIterator w = m_node_based_graph->GetTarget(forward_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 ); BOOST_ASSERT( v != w );
const NodeIterator u = m_node_based_graph->GetTarget(reverse_e2); 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 ); BOOST_ASSERT( u != v );
const EdgeIterator forward_e1 = m_node_based_graph->FindEdge(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)); BOOST_ASSERT( v == m_node_based_graph->GetTarget(forward_e1));
const EdgeIterator reverse_e1 = m_node_based_graph->FindEdge(w, v); 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)); BOOST_ASSERT( v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData & fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_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(forward_e1, w);
m_node_based_graph->SetTarget(reverse_e1, u); 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 // add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance; m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_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 ); FixupStartingTurnRestriction( w, v, u );
FixupArrivingTurnRestriction( w, v, u ); FixupArrivingTurnRestriction( w, v, u );
//TODO: store compressed geometry in container // store compressed geometry in container
m_geometry_compressor.CompressEdge( forward_e1, forward_e2, v ); m_geometry_compressor.CompressEdge(
m_geometry_compressor.CompressEdge( reverse_e1, reverse_e2, v ); 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; ++removed_node_count;
} }
@ -405,8 +480,7 @@ void EdgeBasedGraphFactory::Run(
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count/(double)original_number_of_edges; SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count/(double)original_number_of_edges;
//Extract routing graph //Extract routing graph
DeallocatingVector<NodeBasedEdge> edges_list; unsigned numbered_edges_count = 0;
NodeBasedEdge new_edge;
for(NodeID source = 0; source < m_node_based_graph->GetNumberOfNodes(); ++source) { for(NodeID source = 0; source < m_node_based_graph->GetNumberOfNodes(); ++source) {
for( for(
EdgeID current_edge_id = m_node_based_graph->BeginEdges(source); EdgeID current_edge_id = m_node_based_graph->BeginEdges(source);
@ -414,44 +488,37 @@ void EdgeBasedGraphFactory::Run(
++current_edge_id ++current_edge_id
) { ) {
const NodeID target = m_node_based_graph->GetTarget(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); EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge_id);
if( source > target ) { 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; continue;
} }
if( edge_data.forward) { if( edge_data.edgeBasedNodeID != std::numeric_limits<unsigned>::max() ) {//source > target ) {
new_edge.source = source; // SimpleLogger().Write(logDEBUG) << "skipping edge based node id: " << edge_data.edgeBasedNodeID;
new_edge.target = target; continue;
new_edge.data = edge_data;
new_edge.data.edgeBasedNodeID = edges_list.size();
edges_list.push_back(new_edge);
} }
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); const EdgeID reverse_edge_id = m_node_based_graph->FindEdge(target, source);
BOOST_ASSERT( reverse_edge_id != m_node_based_graph->EndEdges(target)); BOOST_ASSERT( reverse_edge_id != m_node_based_graph->EndEdges(target));
const EdgeData & reverse_edge_data = m_node_based_graph->GetEdgeData(reverse_edge_id); EdgeData & reverse_edge_data = m_node_based_graph->GetEdgeData(reverse_edge_id);
if( reverse_edge_data.forward ) { if( !reverse_edge_data.forward ) {
new_edge.source = target; continue;
new_edge.target = source; }
new_edge.data = reverse_edge_data;
new_edge.data.edgeBasedNodeID = edges_list.size(); BOOST_ASSERT( numbered_edges_count < m_node_based_graph->GetNumberOfEdges() );
edges_list.push_back(new_edge); reverse_edge_data.edgeBasedNodeID = numbered_edges_count;
++numbered_edges_count;
} }
} }
} SimpleLogger().Write(logDEBUG) << "numbered " << numbered_edges_count << " edge-expanded nodes";
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() << "Identifying components of the road network"; SimpleLogger().Write() << "Identifying components of the road network";
unsigned node_based_edge_counter = 0; unsigned node_based_edge_counter = 0;
@ -479,12 +546,15 @@ void EdgeBasedGraphFactory::Run(
"generating edge-expanded nodes"; "generating edge-expanded nodes";
p.reinit(m_node_based_graph->GetNumberOfNodes()); p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes //loop over all edges and generate new set of nodes
for( for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
u < end; u < end;
++u ++u
) { ) {
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( u < m_node_based_graph->GetNumberOfNodes() );
p.printIncrement(); p.printIncrement();
for( for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u), EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
@ -492,12 +562,18 @@ void EdgeBasedGraphFactory::Run(
e1 < last_edge; e1 < last_edge;
++e1 ++e1
) { ) {
BOOST_ASSERT( e1 != std::numeric_limits<unsigned>::max() );
NodeIterator v = m_node_based_graph->GetTarget(e1); 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 //Note: edges that end on barrier nodes or on a turn restriction
//may actually be in two distinct components. We choose the smallest //may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min( const unsigned size_of_component = std::min(
@ -505,11 +581,13 @@ void EdgeBasedGraphFactory::Run(
component_index_size[component_index_list[v]] 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() SimpleLogger().Write()
<< "Generated " << m_edge_based_node_list.size() << " nodes in " << << "Generated " << m_edge_based_node_list.size() << " nodes in " <<
"edge-expanded graph"; "edge-expanded graph";
@ -534,6 +612,7 @@ void EdgeBasedGraphFactory::Run(
unsigned restricted_turns_counter = 0; unsigned restricted_turns_counter = 0;
unsigned skipped_uturns_counter = 0; unsigned skipped_uturns_counter = 0;
unsigned skipped_barrier_turns_counter = 0; unsigned skipped_barrier_turns_counter = 0;
unsigned compressed = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes()); p.reinit(m_node_based_graph->GetNumberOfNodes());
for( for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
@ -546,6 +625,10 @@ void EdgeBasedGraphFactory::Run(
e1 < last_edge_u; e1 < last_edge_u;
++e1 ++e1
) { ) {
if( !m_node_based_graph->GetEdgeData(e1).forward ) {
continue;
}
++node_based_edge_counter; ++node_based_edge_counter;
const NodeIterator v = m_node_based_graph->GetTarget(e1); const NodeIterator v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v); const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
@ -557,9 +640,12 @@ void EdgeBasedGraphFactory::Run(
e2 < last_edge_v; e2 < last_edge_v;
++e2 ++e2
) { ) {
if( !m_node_based_graph->GetEdgeData(e2).forward ) {
continue;
}
const NodeIterator w = m_node_based_graph->GetTarget(e2); const NodeIterator w = m_node_based_graph->GetTarget(e2);
if( if(
to_node_of_only_restriction != UINT_MAX && to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction w != to_node_of_only_restriction
) { ) {
//We are at an only_-restriction but not at the right turn. //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 //at the end of a dead-end street
if ( if (
CheckIfTurnIsRestricted(u, v, w) && 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) (w != to_node_of_only_restriction)
) { ) {
++restricted_turns_counter; ++restricted_turns_counter;
@ -594,12 +680,12 @@ void EdgeBasedGraphFactory::Run(
const EdgeData & edge_data1 = m_node_based_graph->GetEdgeData(e1); const EdgeData & edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData & edge_data2 = m_node_based_graph->GetEdgeData(e2); const EdgeData & edge_data2 = m_node_based_graph->GetEdgeData(e2);
BOOST_ASSERT( // BOOST_ASSERT(
edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges() // edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
); // );
BOOST_ASSERT( // BOOST_ASSERT(
edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges() // edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
); // );
BOOST_ASSERT( BOOST_ASSERT(
edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID
); );
@ -612,22 +698,26 @@ void EdgeBasedGraphFactory::Run(
distance += speed_profile.trafficSignalPenalty; distance += speed_profile.trafficSignalPenalty;
} }
const int turn_penalty = GetTurnPenalty(u, v, w, lua_state); const int turn_penalty = GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w); TurnInstruction turn_instruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn){ if(turn_instruction == TurnInstructions.UTurn){
distance += speed_profile.uTurnPenalty; distance += speed_profile.uTurnPenalty;
} }
distance += turn_penalty; distance += turn_penalty;
const bool edge_is_compressed = m_geometry_compressor.HasEntryForID(e1); const bool edge_is_compressed = m_geometry_compressor.HasEntryForID(e1);
if(edge_is_compressed) { 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( original_edge_data_vector.push_back(
OriginalEdgeData( OriginalEdgeData(
edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v, (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data2.nameID, edge_data2.nameID,
turnInstruction, turn_instruction,
edge_is_compressed edge_is_compressed
) )
); );
@ -656,10 +746,13 @@ void EdgeBasedGraphFactory::Run(
} }
FlushVectorToStream( edge_data_file, original_edge_data_vector ); FlushVectorToStream( edge_data_file, original_edge_data_vector );
SimpleLogger().Write(logDEBUG) << "compressed: " << compressed;
edge_data_file.seekp( std::ios::beg ); edge_data_file.seekp( std::ios::beg );
edge_data_file.write( (char*)&original_edges_counter, sizeof(unsigned) ); edge_data_file.write( (char*)&original_edges_counter, sizeof(unsigned) );
edge_data_file.close(); edge_data_file.close();
SimpleLogger().Write(logDEBUG) << "serializing geometry to " << geometry_filename;
m_geometry_compressor.SerializeInternalVector( geometry_filename ); m_geometry_compressor.SerializeInternalVector( geometry_filename );
SimpleLogger().Write() << SimpleLogger().Write() <<
@ -769,8 +862,8 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
return TurnInstructions.GetTurnDirectionOfInstruction(angle); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const {
return m_node_based_graph->GetNumberOfEdges(); return m_number_of_edge_based_nodes;
} }
void EdgeBasedGraphFactory::BFSCompentExplorer( void EdgeBasedGraphFactory::BFSCompentExplorer(
@ -787,12 +880,12 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
component_index_list.resize( component_index_list.resize(
m_node_based_graph->GetNumberOfNodes(), m_node_based_graph->GetNumberOfNodes(),
UINT_MAX std::numeric_limits<unsigned>::max()
); );
//put unexplorered node with parent pointer into queue //put unexplorered node with parent pointer into queue
for( NodeID node = 0, end = m_node_based_graph->GetNumberOfNodes(); node < end; ++node) { 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)); bfs_queue.push(std::make_pair(node, node));
//mark node as read //mark node as read
component_index_list[node] = current_component; component_index_list[node] = current_component;
@ -818,7 +911,7 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
NodeIterator w = m_node_based_graph->GetTarget(e2); NodeIterator w = m_node_based_graph->GetTarget(e2);
if( if(
to_node_of_only_restriction != UINT_MAX && to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction w != to_node_of_only_restriction
) { ) {
// At an only_-restriction but not at the right turn // 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. //when it is at the end of a dead-end street.
if (!CheckIfTurnIsRestricted(u, v, w) ) { if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited //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 //insert next (node, parent) only if w has
//not yet been explored //not yet been explored
//mark node as read //mark node as read

View File

@ -94,7 +94,7 @@ public:
lua_State *myLuaState lua_State *myLuaState
) const; ) const;
unsigned GetNumberOfNodes() const; unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : SpeedProfileProperties() :
@ -110,6 +110,11 @@ public:
private: private:
struct NodeBasedEdgeData { struct NodeBasedEdgeData {
NodeBasedEdgeData() {
//TODO: proper c'tor
edgeBasedNodeID = UINT_MAX;
}
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
@ -119,7 +124,7 @@ private:
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
bool roundabout:1; bool roundabout:1;
bool ignoreInGrid:1; bool ignore_in_grid:1;
bool contraFlow:1; bool contraFlow:1;
void SwapDirectionFlags() { void SwapDirectionFlags() {
@ -132,12 +137,13 @@ private:
return (forward == other.forward) && return (forward == other.forward) &&
(backward == other.backward) && (backward == other.backward) &&
(nameID == other.nameID) && (nameID == other.nameID) &&
(ignoreInGrid == other.ignoreInGrid) && (ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow); (contraFlow == other.contraFlow);
} }
}; };
unsigned m_turn_restrictions_count; unsigned m_turn_restrictions_count;
unsigned m_number_of_edge_based_nodes;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph; typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge; typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
@ -173,7 +179,6 @@ private:
) const; ) const;
void InsertEdgeBasedNode( void InsertEdgeBasedNode(
NodeBasedDynamicGraph::EdgeIterator e1,
NodeBasedDynamicGraph::NodeIterator u, NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent bool belongsToTinyComponent

View File

@ -37,7 +37,7 @@ int current_free_list_maximum = 0;
int UniqueNumber () { return ++current_free_list_maximum; } int UniqueNumber () { return ++current_free_list_maximum; }
GeometryCompressor::GeometryCompressor() { GeometryCompressor::GeometryCompressor() {
m_free_list.resize(100); m_free_list.reserve(100);
IncreaseFreeList(); 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()); 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; boost::unordered_map<EdgeID, unsigned>::const_iterator map_iterator;
map_iterator = m_edge_id_to_list_index_map.find(edge_id); 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 != m_edge_id_to_list_index_map.end() );
BOOST_ASSERT( map_iterator->second < m_compressed_geometries.size() );
return map_iterator->second; return map_iterator->second;
} }
void GeometryCompressor::AddNodeIDToCompressedEdge( void GeometryCompressor::AddLastViaNodeIDToCompressedEdge(
const EdgeID edge_id, const EdgeID edge_id,
const NodeID node_id const NodeID node_id,
const EdgeWeight weight
) { ) {
unsigned index = GetPositionForID(edge_id); unsigned index = GetPositionForID(edge_id);
BOOST_ASSERT( index < m_compressed_geometries.size() ); 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( void GeometryCompressor::SerializeInternalVector(
const std::string & path const std::string & path
) const { ) const {
//TODO: remove super-trivial geometries
std::ofstream geometry_out_stream( path.c_str(), std::ios::binary ); std::ofstream geometry_out_stream( path.c_str(), std::ios::binary );
const unsigned compressed_edge_count = m_compressed_geometries.size()+1; const unsigned number_of_compressed_geometries = m_compressed_geometries.size()+1;
BOOST_ASSERT( UINT_MAX != compressed_edge_count ); BOOST_ASSERT( UINT_MAX != number_of_compressed_geometries );
geometry_out_stream.write( geometry_out_stream.write(
(char*)&compressed_edge_count, (char*)&number_of_compressed_geometries,
sizeof(unsigned) sizeof(unsigned)
); );
SimpleLogger().Write(logDEBUG) << "number_of_compressed_geometries: " << number_of_compressed_geometries;
// write indices array // write indices array
unsigned prefix_sum_of_list_indices = 0; unsigned prefix_sum_of_list_indices = 0;
for(unsigned i = 0; i < m_compressed_geometries.size(); ++i ) { 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( geometry_out_stream.write(
(char*)&prefix_sum_of_list_indices, (char*)&prefix_sum_of_list_indices,
sizeof(unsigned) 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; prefix_sum_of_list_indices += unpacked_size;
} }
// write sentinel element // sentinel element
geometry_out_stream.write( geometry_out_stream.write(
(char*)&prefix_sum_of_list_indices, (char*)&prefix_sum_of_list_indices,
sizeof(unsigned) 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 // write compressed geometries
for(unsigned i = 0; i < m_compressed_geometries.size(); ++i ) { 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(); const unsigned unpacked_size = current_vector.size();
control_sum += unpacked_size;
BOOST_ASSERT( UINT_MAX != 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( geometry_out_stream.write(
(char*)&(current_vector[j]), (char*)&(current_node.first),
sizeof(unsigned) sizeof(NodeID)
); );
} }
} }
BOOST_ASSERT( control_sum == prefix_sum_of_list_indices );
// all done, let's close the resource // all done, let's close the resource
geometry_out_stream.close(); geometry_out_stream.close();
} }
@ -118,8 +141,11 @@ void GeometryCompressor::SerializeInternalVector(
void GeometryCompressor::CompressEdge( void GeometryCompressor::CompressEdge(
const EdgeID surviving_edge_id, const EdgeID surviving_edge_id,
const EdgeID removed_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 != surviving_edge_id );
BOOST_ASSERT( UINT_MAX != removed_edge_id ); BOOST_ASSERT( UINT_MAX != removed_edge_id );
BOOST_ASSERT( UINT_MAX != via_node_id ); BOOST_ASSERT( UINT_MAX != via_node_id );
@ -138,60 +164,80 @@ void GeometryCompressor::CompressEdge(
// create a new entry in the map // create a new entry in the map
if( 0 == m_free_list.size() ) { if( 0 == m_free_list.size() ) {
// make sure there is a place to put the entries // make sure there is a place to put the entries
// SimpleLogger().Write() << "increased free list";
IncreaseFreeList(); 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_edge_id_to_list_index_map[surviving_edge_id] = m_free_list.back();
m_free_list.pop_back(); m_free_list.pop_back();
} }
const unsigned surving_list_id = m_edge_id_to_list_index_map[surviving_edge_id]; 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() ); BOOST_ASSERT( surving_list_id < m_compressed_geometries.size() );
std::vector<NodeID> & compressed_id_list = m_compressed_geometries[surving_list_id]; std::vector<CompressedNode> & surviving_geometry_list = m_compressed_geometries[surving_list_id];
compressed_id_list.push_back(via_node_id); if( !surviving_geometry_list.empty() ) {
BOOST_ASSERT( 0 < compressed_id_list.size() ); 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 // Find any existing list for removed_edge_id
typename boost::unordered_map<EdgeID, unsigned>::const_iterator map_iterator; typename boost::unordered_map<EdgeID, unsigned>::const_iterator remove_list_iterator;
map_iterator = m_edge_id_to_list_index_map.find(removed_edge_id); remove_list_iterator = m_edge_id_to_list_index_map.find(removed_edge_id);
if( m_edge_id_to_list_index_map.end() != map_iterator ) { if( m_edge_id_to_list_index_map.end() != remove_list_iterator ) {
const unsigned index = map_iterator->second; const unsigned list_to_remove_index = remove_list_iterator->second;
BOOST_ASSERT( index < m_compressed_geometries.size() ); 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 // found an existing list, append it to the list of surviving_edge_id
compressed_id_list.insert( surviving_geometry_list.insert(
compressed_id_list.end(), surviving_geometry_list.end(),
m_compressed_geometries[index].begin(), remove_geometry_list.begin(),
m_compressed_geometries[index].end() remove_geometry_list.end()
); );
//remove the list of removed_edge_id //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) ); 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(); remove_geometry_list.clear();
BOOST_ASSERT( 0 == m_compressed_geometries[index].size() ); BOOST_ASSERT( 0 == remove_geometry_list.size() );
m_free_list.push_back(index); m_free_list.push_back(list_to_remove_index);
BOOST_ASSERT( index == m_free_list.back() ); BOOST_ASSERT( list_to_remove_index == m_free_list.back() );
} }
} }
void GeometryCompressor::PrintStatistics() const { void GeometryCompressor::PrintStatistics() const {
unsigned removed_edge_count = 0; unsigned number_of_compressed_geometries = 0;
const unsigned surviving_edge_count = m_compressed_geometries.size()-m_free_list.size(); const unsigned compressed_edges = m_compressed_geometries.size();
BOOST_ASSERT( m_compressed_geometries.size() + m_free_list.size() > 0 ); BOOST_ASSERT( m_compressed_geometries.size() + m_free_list.size() > 0 );
unsigned long longest_chain_length = 0; unsigned long longest_chain_length = 0;
BOOST_FOREACH(const std::vector<unsigned> & current_vector, m_compressed_geometries) { BOOST_FOREACH(const std::vector<CompressedNode> & current_vector, m_compressed_geometries) {
removed_edge_count += current_vector.size(); number_of_compressed_geometries += current_vector.size();
longest_chain_length = std::max(longest_chain_length, 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() << SimpleLogger().Write() <<
"surviving edges: " << surviving_edge_count << "compressed edges: " << compressed_edges <<
", compressed edges: " << removed_edge_count << ", compressed geometries: " << number_of_compressed_geometries <<
", longest chain length: " << longest_chain_length << ", longest chain length: " << longest_chain_length <<
", comp ratio: " << ((float)surviving_edge_count/std::max(removed_edge_count, 1u) ) << ", cmpr ratio: " << ((float)compressed_edges/std::max(number_of_compressed_geometries, 1u) ) <<
", avg: chain length: " << (float)removed_edge_count/std::max(1u, surviving_edge_count); ", avg chain length: " << (float)number_of_compressed_geometries/std::max(1u, compressed_edges);
SimpleLogger().Write() << 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 );
} }

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/filesystem.hpp>
#include <limits> #include <limits>
#include <vector> #include <vector>
@ -37,23 +38,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class GeometryCompressor { class GeometryCompressor {
public: public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
GeometryCompressor(); GeometryCompressor();
void CompressEdge( void CompressEdge(
const EdgeID first_edge_id, const EdgeID first_edge_id,
const EdgeID second_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; 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; 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: private:
void IncreaseFreeList(); void IncreaseFreeList();
std::vector<std::vector<CompressedNode> > m_compressed_geometries;
std::vector<std::vector<NodeID> > m_compressed_geometries;
std::vector<unsigned> m_free_list; std::vector<unsigned> m_free_list;
boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map; boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
}; };

View File

@ -1,28 +1,58 @@
#ifndef EDGE_BASED_NODE_H #ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H #define EDGE_BASED_NODE_H
#include <cmath>
#include <boost/assert.hpp>
#include "../Util/MercatorUtil.h" #include "../Util/MercatorUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
// An EdgeBasedNode represents a node in the edge-expanded graph. // An EdgeBasedNode represents a node in the edge-expanded graph.
#include <limits>
struct EdgeBasedNode { struct EdgeBasedNode {
EdgeBasedNode() : EdgeBasedNode() :
id(INT_MAX), id(INT_MAX),
lat1(INT_MAX), reverse_edge_based_node_id(std::numeric_limits<int>::max()),
lat2(INT_MAX), lat1(std::numeric_limits<int>::max()),
lon1(INT_MAX), lon1(std::numeric_limits<int>::max()),
lon2(INT_MAX >> 1), lat2(std::numeric_limits<int>::max()),
lon2(std::numeric_limits<int>::max() >> 1),
belongsToTinyComponent(false), belongsToTinyComponent(false),
nameID(UINT_MAX), name_id(std::numeric_limits<unsigned>::max()),
weight(UINT_MAX >> 1), forward_weight(std::numeric_limits<int>::max() >> 1),
ignoreInGrid(false) reverse_weight(std::numeric_limits<int>::max() >> 1),
forward_offset_to_edge_based_node(0),
reverse_offset_to_edge_based_node(0)
{ }
EdgeBasedNode(
NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
int lat1,
int lon1,
int lat2,
int lon2,
bool belongsToTinyComponent,
NodeID name_id,
int forward_weight,
int reverse_weight,
int forward_offset_to_edge_based_node,
int reverse_offset_to_edge_based_node
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
lat1(lat1),
lon1(lon1),
lat2(lat2),
lon2(lon2),
belongsToTinyComponent(belongsToTinyComponent),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset_to_edge_based_node(forward_offset_to_edge_based_node),
reverse_offset_to_edge_based_node(reverse_offset_to_edge_based_node)
{ } { }
// Computes: // Computes:
@ -39,9 +69,26 @@ struct EdgeBasedNode {
BOOST_ASSERT( query_location.isValid() ); BOOST_ASSERT( query_location.isValid() );
const double epsilon = 1.0/precision; const double epsilon = 1.0/precision;
const double y = query_location.lon/COORDINATE_PRECISION;
const double a = lat2y(lat1/COORDINATE_PRECISION);
const double b = lon1/COORDINATE_PRECISION;
const double c = lat2y(lat2/COORDINATE_PRECISION);
const double d = lon2/COORDINATE_PRECISION;
double p,q/*,mX*/,nY;
if( std::abs(a-c) > std::numeric_limits<double>::epsilon() ){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
} else {
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
if( ignoreInGrid ) { //discretize the result to coordinate precision. it's a hack!
return std::numeric_limits<double>::max(); if( std::abs(nY) < (1./COORDINATE_PRECISION) ) {
nY = 0.;
} }
// p, q : the end points of the underlying edge // p, q : the end points of the underlying edge
@ -50,13 +97,14 @@ struct EdgeBasedNode {
// r : query location // r : query location
const Point r(lat2y(query_location.lat/COORDINATE_PRECISION), const Point r(lat2y(query_location.lat/COORDINATE_PRECISION),
} else if( std::abs(r-1.) <= std::numeric_limits<double>::epsilon() ) {
query_location.lon/COORDINATE_PRECISION); query_location.lon/COORDINATE_PRECISION);
const Point foot = ComputePerpendicularFoot(p, q, r, epsilon); const Point foot = ComputePerpendicularFoot(p, q, r, epsilon);
ratio = ComputeRatio(p, q, foot, epsilon); ratio = ComputeRatio(p, q, foot, epsilon);
BOOST_ASSERT( !std::isnan(ratio) ); BOOST_ASSERT( !std::isnan(ratio) );
nearest_location.lat = y2lat(p)*COORDINATE_PRECISION;
nearest_location = ComputeNearestPointOnSegment(foot, ratio); nearest_location = ComputeNearestPointOnSegment(foot, ratio);
BOOST_ASSERT( nearest_location.isValid() ); BOOST_ASSERT( nearest_location.isValid() );
@ -65,6 +113,9 @@ struct EdgeBasedNode {
// const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance( // const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
const double approximated_distance = FixedPointCoordinate::ApproximateDistance(query_location, nearest_location); const double approximated_distance = FixedPointCoordinate::ApproximateDistance(query_location, nearest_location);
query_location,
nearest_location
);
BOOST_ASSERT( 0.0 <= approximated_distance ); BOOST_ASSERT( 0.0 <= approximated_distance );
return approximated_distance; return approximated_distance;
} }
@ -82,21 +133,21 @@ struct EdgeBasedNode {
return FixedPointCoordinate((lat1+lat2)/2, (lon1+lon2)/2); return FixedPointCoordinate((lat1+lat2)/2, (lon1+lon2)/2);
} }
NodeID id; NodeID forward_edge_based_node_id;
// The coordinates of the end-points of the underlying edge. // The coordinates of the end-points of the underlying edge.
int lat1; int lat1;
int lat2;
int lon1; int lon1;
int lat2;
int lon2:31; int lon2:31;
bool belongsToTinyComponent:1; bool belongsToTinyComponent:1;
NodeID nameID; NodeID name_id;
// The weight of the underlying edge. // The weight of the underlying edge.
unsigned weight:31; unsigned weight:31;
bool ignoreInGrid:1; int reverse_weight;
private: private:

View File

@ -162,7 +162,7 @@ public:
m_weight(w), m_weight(w),
m_forward(f), m_forward(f),
m_backward(b) m_backward(b)
{} { }
NodeID target() const { return m_target; } NodeID target() const { return m_target; }
NodeID source() const { return m_source; } NodeID source() const { return m_source; }

View File

@ -29,37 +29,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PHANTOMNODES_H_ #define PHANTOMNODES_H_
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
#include "../typedefs.h" #include "../typedefs.h"
struct PhantomNode { struct PhantomNode {
PhantomNode() : PhantomNode() :
edgeBasedNode(UINT_MAX), forward_node_id(UINT_MAX),
nodeBasedEdgeNameID(UINT_MAX), reverse_node_id(UINT_MAX),
weight1(INT_MAX), name_id(UINT_MAX),
weight2(INT_MAX), forward_weight(INT_MAX),
reverse_weight(INT_MAX),
ratio(0.) ratio(0.)
{ } { }
NodeID edgeBasedNode; NodeID forward_node_id;
unsigned nodeBasedEdgeNameID; NodeID reverse_node_id;
int weight1; unsigned name_id;
int weight2; int forward_weight;
int reverse_weight;
double ratio; double ratio;
FixedPointCoordinate location; FixedPointCoordinate location;
void Reset() { void Reset() {
edgeBasedNode = UINT_MAX; forward_node_id = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX; name_id = UINT_MAX;
weight1 = INT_MAX; forward_weight = INT_MAX;
weight2 = INT_MAX; reverse_weight = INT_MAX;
ratio = 0.; ratio = 0.;
location.Reset(); location.Reset();
} }
bool isBidirected() const { bool isBidirected() const {
return weight2 != INT_MAX; return forward_weight != INT_MAX && reverse_weight != INT_MAX;
} }
bool isValid(const unsigned numberOfNodes) const { bool isValid(const unsigned numberOfNodes) const {
return location.isValid() && (edgeBasedNode < numberOfNodes) && (weight1 != INT_MAX) && (ratio >= 0.) && (ratio <= 1.) && (nodeBasedEdgeNameID != UINT_MAX); return
location.isValid() &&
( (forward_node_id < numberOfNodes) || (reverse_node_id < numberOfNodes) ) &&
( (forward_weight != INT_MAX) || (reverse_weight != INT_MAX) ) &&
(ratio >= 0.) &&
(ratio <= 1.) &&
(name_id != UINT_MAX);
} }
bool operator==(const PhantomNode & other) const { bool operator==(const PhantomNode & other) const {
@ -76,11 +84,11 @@ struct PhantomNodes {
} }
bool PhantomsAreOnSameNodeBasedEdge() const { bool PhantomsAreOnSameNodeBasedEdge() const {
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode); return (startPhantom.forward_node_id == targetPhantom.forward_node_id);
} }
bool AtLeastOnePhantomNodeIsUINTMAX() const { bool AtLeastOnePhantomNodeIsUINTMAX() const {
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX); return !(startPhantom.forward_node_id == UINT_MAX || targetPhantom.forward_node_id == UINT_MAX);
} }
bool PhantomNodesHaveEqualLocation() const { bool PhantomNodesHaveEqualLocation() const {
@ -89,15 +97,15 @@ struct PhantomNodes {
}; };
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){ inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl; out << "Node1: " << pn.startPhantom.forward_node_id << std::endl;
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl; out << "Node2: " << pn.targetPhantom.reverse_node_id << std::endl;
out << "startCoord: " << pn.startPhantom.location << std::endl; out << "startCoord: " << pn.startPhantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl; out << "targetCoord: " << pn.targetPhantom.location << std::endl;
return out; return out;
} }
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
out << "node: " << pn.edgeBasedNode << ", name: " << pn.nodeBasedEdgeNameID << ", w1: " << pn.weight1 << ", w2: " << pn.weight2 << ", ratio: " << pn.ratio << ", loc: " << pn.location; out << "node1: " << pn.forward_node_id << ", node2: " << pn.reverse_node_id << ", name: " << pn.name_id << ", w1: " << pn.forward_weight << ", w2: " << pn.reverse_weight << ", ratio: " << pn.ratio << ", loc: " << pn.location;
return out; return out;
} }

View File

@ -34,17 +34,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cstddef>
#include <climits>
#include <limits> #include <limits>
struct NodeInfo { struct NodeInfo {
typedef NodeID key_type; //type of NodeID typedef NodeID key_type; //type of NodeID
typedef int value_type; //type of lat,lons typedef int value_type; //type of lat,lons
NodeInfo(int _lat, int _lon, NodeID _id) : lat(_lat), lon(_lon), id(_id) {} NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) { }
NodeInfo() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} NodeInfo()
:
lat(std::numeric_limits<int>::max()),
lon(std::numeric_limits<int>::max()),
id(std::numeric_limits<unsigned>::max())
{ }
int lat; int lat;
int lon; int lon;
NodeID id; NodeID id;
@ -75,11 +78,11 @@ struct NodeInfo {
break; break;
default: default:
BOOST_ASSERT_MSG(false, "should not happen"); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return std::numeric_limits<unsigned>::max();
break; break;
} }
BOOST_ASSERT_MSG(false, "should not happen"); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return std::numeric_limits<unsigned>::max();
} }
}; };

View File

@ -487,152 +487,7 @@ public:
//SimpleLogger().Write() << m_element_count << " elements in leafs"; //SimpleLogger().Write() << m_element_count << " elements in leafs";
} }
//Read-only operation for queries //Read-only operation for queries
/*
inline void FindKNearestPhantomNodesForCoordinate(
const FixedPointCoordinate & location,
const unsigned zoom_level,
const unsigned candidate_count,
std::vector<std::pair<PhantomNode, double> > & result_vector
) const {
bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge;
uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0;
SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = std::numeric_limits<double>::max();
double min_max_dist = std::numeric_limits<double>::max();
bool found_a_nearest_edge = false;
FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
traversal_queue.push(QueryCandidate(0, m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate)));
BOOST_ASSERT_MSG(std::numberic_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist), "Root element in NN Search has min dist != 0.");
while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
++explored_tree_nodes_count;
bool prune_downward = (current_query_node.min_dist >= min_max_dist);
bool prune_upward = (current_query_node.min_dist >= min_dist);
if( !prune_downward && !prune_upward ) { //downward pruning
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) {
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
continue;
}
double current_ratio = 0.;
double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
input_coordinate,
nearest,
current_ratio
);
if(
current_perpendicular_distance < min_dist
&& !DoubleEpsilonCompare(
current_perpendicular_distance,
min_dist
)
) { //found a new minimum
min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id;
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID;
result_phantom_node.weight1 = current_edge.weight;
result_phantom_node.weight2 = INT_MAX;
result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1;
current_start_coordinate.lon = current_edge.lon1;
current_end_coordinate.lat = current_edge.lat2;
current_end_coordinate.lon = current_edge.lon2;
nearest_edge = current_edge;
found_a_nearest_edge = true;
} else if(
DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& EdgesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
result_phantom_node.edgeBasedNode = std::min(current_edge.id, result_phantom_node.edgeBasedNode);
result_phantom_node.weight2 = current_edge.weight;
}
}
} else {
//traverse children, prune if global mindist is smaller than local one
for (uint32_t i = 0; i < current_tree_node.child_count; ++i) {
const int32_t child_id = current_tree_node.children[i];
TreeNode & child_tree_node = m_search_tree[child_id];
RectangleT & child_rectangle = child_tree_node.minimum_bounding_rectangle;
const double current_min_dist = child_rectangle.GetMinDist(input_coordinate);
const double current_min_max_dist = child_rectangle.GetMinMaxDist(input_coordinate);
if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist) {
continue;
}
if (current_min_dist > min_dist) { //upward pruning
continue;
}
traversal_queue.push(QueryCandidate(child_id, current_min_dist));
}
}
}
}
const double distance_to_edge =
ApproximateDistance (
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location
);
const double length_of_edge =
ApproximateDistance(
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2)
);
const double ratio = (found_a_nearest_edge ?
std::min(1., distance_to_edge/ length_of_edge ) : 0 );
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio);
}
result_phantom_node.ratio = ratio;
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(input_coordinate.lon - result_phantom_node.location.lon) == 1) {
result_phantom_node.location.lon = input_coordinate.lon;
}
if(std::abs(input_coordinate.lat - result_phantom_node.location.lat) == 1) {
result_phantom_node.location.lat = input_coordinate.lat;
}
SimpleLogger().Write() << "mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no");
return found_a_nearest_edge;
}
*/
bool LocateClosestEndPointForCoordinate( bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
FixedPointCoordinate & result_coordinate, FixedPointCoordinate & result_coordinate,
@ -799,10 +654,11 @@ public:
) )
) { //found a new minimum ) { //found a new minimum
min_dist = current_perpendicular_distance; min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id; result_phantom_node.forward_node_id = current_edge.forward_edge_based_node_id;
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID; result_phantom_node.reverse_node_id = current_edge.reverse_edge_based_node_id;
result_phantom_node.weight1 = current_edge.weight; result_phantom_node.name_id = current_edge.name_id;
result_phantom_node.weight2 = INT_MAX; result_phantom_node.forward_weight = current_edge.forward_weight;
result_phantom_node.reverse_weight = current_edge.reverse_weight;
result_phantom_node.location = nearest; result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1; current_start_coordinate.lat = current_edge.lat1;
current_start_coordinate.lon = current_edge.lon1; current_start_coordinate.lon = current_edge.lon1;
@ -810,30 +666,6 @@ public:
current_end_coordinate.lon = current_edge.lon2; current_end_coordinate.lon = current_edge.lon2;
nearest_edge = current_edge; nearest_edge = current_edge;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} else
if( DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
( 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) ) &&
EdgesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different");
result_phantom_node.weight2 = current_edge.weight;
if(current_edge.id < result_phantom_node.edgeBasedNode) {
result_phantom_node.edgeBasedNode = current_edge.id;
std::swap(result_phantom_node.weight1, result_phantom_node.weight2);
std::swap(current_end_coordinate, current_start_coordinate);
}
} }
} }
} else { } else {
@ -884,9 +716,9 @@ public:
ratio = std::min(1., ratio); ratio = std::min(1., ratio);
} }
result_phantom_node.weight1 *= ratio; result_phantom_node.forward_weight *= ratio;
if(INT_MAX != result_phantom_node.weight2) { if( INT_MAX != result_phantom_node.reverse_weight ) {
result_phantom_node.weight2 *= (1.-ratio); result_phantom_node.reverse_weight *= (1.-ratio);
} }
result_phantom_node.ratio = ratio; result_phantom_node.ratio = ratio;

View File

@ -64,7 +64,7 @@ void DescriptionFactory::SetStartSegment(const PhantomNode & start) {
start_phantom = start; start_phantom = start;
AppendSegment( AppendSegment(
start.location, start.location,
PathData(0, start.nodeBasedEdgeNameID, 10, start.weight1) PathData(0, start.name_id, 10, start.forward_weight)
); );
} }
@ -73,9 +73,9 @@ void DescriptionFactory::SetEndSegment(const PhantomNode & target) {
pathDescription.push_back( pathDescription.push_back(
SegmentInformation( SegmentInformation(
target.location, target.location,
target.nodeBasedEdgeNameID, target.name_id,
0, 0,
target.weight1, target.reverse_weight,
0, 0,
true true
) )
@ -137,7 +137,7 @@ void DescriptionFactory::BuildRouteSummary(
const double distance, const double distance,
const unsigned time const unsigned time
) { ) {
summary.startName = start_phantom.nodeBasedEdgeNameID; summary.startName = start_phantom.name_id;
summary.destName = target_phantom.nodeBasedEdgeNameID; summary.destName = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time); summary.BuildDurationAndLengthStrings(distance, time);
} }

View File

@ -180,7 +180,7 @@ public:
pathDescription.pop_back(); pathDescription.pop_back();
pathDescription.back().necessary = true; pathDescription.back().necessary = true;
pathDescription.back().turn_instruction = TurnInstructions.NoTurn; pathDescription.back().turn_instruction = TurnInstructions.NoTurn;
target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->name_id; target_phantom.name_id = (pathDescription.end()-2)->name_id;
} }
} else { } else {
pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio); pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio);
@ -190,7 +190,7 @@ public:
pathDescription.erase(pathDescription.begin()); pathDescription.erase(pathDescription.begin());
pathDescription[0].turn_instruction = TurnInstructions.HeadOn; pathDescription[0].turn_instruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true; pathDescription[0].necessary = true;
start_phantom.nodeBasedEdgeNameID = pathDescription[0].name_id; start_phantom.name_id = pathDescription[0].name_id;
} }
} else { } else {
pathDescription[0].duration *= start_phantom.ratio; pathDescription[0].duration *= start_phantom.ratio;

View File

@ -112,28 +112,28 @@ public:
int upper_bound_to_shortest_path_distance = INT_MAX; int upper_bound_to_shortest_path_distance = INT_MAX;
NodeID middle_node = UINT_MAX; NodeID middle_node = UINT_MAX;
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode, phantom_node_pair.startPhantom.forward_node_id,
-phantom_node_pair.startPhantom.weight1, -phantom_node_pair.startPhantom.forward_weight,
phantom_node_pair.startPhantom.edgeBasedNode phantom_node_pair.startPhantom.forward_node_id
); );
if(phantom_node_pair.startPhantom.isBidirected() ) { if(phantom_node_pair.startPhantom.isBidirected() ) {
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1, phantom_node_pair.startPhantom.reverse_node_id,
-phantom_node_pair.startPhantom.weight2, -phantom_node_pair.startPhantom.reverse_weight,
phantom_node_pair.startPhantom.edgeBasedNode+1 phantom_node_pair.startPhantom.reverse_node_id
); );
} }
reverse_heap1.Insert( reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode, phantom_node_pair.targetPhantom.forward_node_id,
phantom_node_pair.targetPhantom.weight1, phantom_node_pair.targetPhantom.forward_weight,
phantom_node_pair.targetPhantom.edgeBasedNode phantom_node_pair.targetPhantom.forward_node_id
); );
if(phantom_node_pair.targetPhantom.isBidirected() ) { if(phantom_node_pair.targetPhantom.isBidirected() ) {
reverse_heap1.Insert( reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode+1, phantom_node_pair.targetPhantom.reverse_node_id,
phantom_node_pair.targetPhantom.weight2, phantom_node_pair.targetPhantom.reverse_weight,
phantom_node_pair.targetPhantom.edgeBasedNode+1 phantom_node_pair.targetPhantom.reverse_node_id
); );
} }

View File

@ -30,10 +30,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h" #include "../DataStructures/SearchEngineData.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/ContainerUtils.h" #include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <climits> #include <climits>
@ -188,7 +190,7 @@ public:
} }
} }
} }
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge id invalid"); BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge weight invalid");
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id); const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if( ed.shortcut ) {//unpack if( ed.shortcut ) {//unpack
@ -197,15 +199,43 @@ public:
recursion_stack.push(std::make_pair(middle_node_id, edge.second)); recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id)); recursion_stack.push(std::make_pair(edge.first, middle_node_id));
} else { } else {
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be a shortcut"); BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
//TODO: reorder to always iterate over a result vector
if ( !facade->EdgeIsCompressed(ed.id) ){
SimpleLogger().Write() << "Edge " << ed.id << " is not compressed, smaller_edge_id: " << smaller_edge_id;
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
unpacked_path.push_back( unpacked_path.push_back(
PathData( PathData(
ed.id, facade->GetGeometryIndexForEdgeID(ed.id),
facade->GetNameIndexFromEdgeID(ed.id), name_index,
facade->GetTurnInstructionForEdgeID(ed.id), turn_instruction,
ed.distance ed.distance
) )
); );
} else {
SimpleLogger().Write() << "Edge " << ed.id << " is compressed";
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(ed.id, id_vector);
BOOST_FOREACH(const unsigned coordinate_id, id_vector){
//TODO: unpack entire geometry
//TODO: set distance to 0, see if works
unpacked_path.push_back(
PathData(
coordinate_id,
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
unpacked_path.back().turnInstruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance;
}
} }
} }
} }
@ -313,7 +343,7 @@ public:
} }
int ComputeEdgeOffset(const PhantomNode & phantom) const { int ComputeEdgeOffset(const PhantomNode & phantom) const {
return phantom.weight1 + (phantom.isBidirected() ? phantom.weight2 : 0); return phantom.forward_weight + (phantom.isBidirected() ? phantom.reverse_weight : 0);
} }
}; };

View File

@ -105,41 +105,47 @@ public:
//insert new starting nodes into forward heap, adjusted by previous distances. //insert new starting nodes into forward heap, adjusted by previous distances.
if(search_from_1st_node) { if(search_from_1st_node) {
BOOST_ASSERT(phantom_node_pair.startPhantom.forward_node_id != UINT_MAX);
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode, phantom_node_pair.startPhantom.forward_node_id,
distance1-phantom_node_pair.startPhantom.weight1, distance1-phantom_node_pair.startPhantom.forward_weight,
phantom_node_pair.startPhantom.edgeBasedNode phantom_node_pair.startPhantom.forward_node_id
); );
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode, phantom_node_pair.startPhantom.forward_node_id,
distance1-phantom_node_pair.startPhantom.weight1, distance1-phantom_node_pair.startPhantom.forward_weight,
phantom_node_pair.startPhantom.edgeBasedNode phantom_node_pair.startPhantom.forward_node_id
); );
} }
if(phantom_node_pair.startPhantom.isBidirected() && search_from_2nd_node) { if(phantom_node_pair.startPhantom.isBidirected() && search_from_2nd_node) {
BOOST_ASSERT(phantom_node_pair.startPhantom.reverse_node_id != UINT_MAX);
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1, phantom_node_pair.startPhantom.reverse_node_id,
distance2-phantom_node_pair.startPhantom.weight2, distance2-phantom_node_pair.startPhantom.reverse_weight,
phantom_node_pair.startPhantom.edgeBasedNode+1 phantom_node_pair.startPhantom.reverse_node_id
); );
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1, phantom_node_pair.startPhantom.reverse_node_id,
distance2-phantom_node_pair.startPhantom.weight2, distance2-phantom_node_pair.startPhantom.reverse_weight,
phantom_node_pair.startPhantom.edgeBasedNode+1 phantom_node_pair.startPhantom.reverse_node_id
); );
} }
//insert new backward nodes into backward heap, unadjusted. //insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert( reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode, phantom_node_pair.targetPhantom.forward_node_id,
phantom_node_pair.targetPhantom.weight1, phantom_node_pair.targetPhantom.forward_weight,
phantom_node_pair.targetPhantom.edgeBasedNode phantom_node_pair.targetPhantom.forward_node_id
); );
BOOST_ASSERT(phantom_node_pair.targetPhantom.forward_node_id != UINT_MAX);
if(phantom_node_pair.targetPhantom.isBidirected() ) { if(phantom_node_pair.targetPhantom.isBidirected() ) {
BOOST_ASSERT(phantom_node_pair.startPhantom.forward_node_id != UINT_MAX);
reverse_heap2.Insert( reverse_heap2.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode+1, phantom_node_pair.targetPhantom.reverse_node_id,
phantom_node_pair.targetPhantom.weight2, phantom_node_pair.targetPhantom.reverse_weight,
phantom_node_pair.targetPhantom.edgeBasedNode+1 phantom_node_pair.targetPhantom.reverse_node_id
); );
} }
@ -264,8 +270,6 @@ public:
local_upper_bound2 = local_upper_bound1; local_upper_bound2 = local_upper_bound1;
} }
// SimpleLogger().Write() << "fetched packed paths";
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
!temporary_packed_leg1.empty() || !temporary_packed_leg1.empty() ||
!temporary_packed_leg2.empty(), !temporary_packed_leg2.empty(),
@ -338,8 +342,8 @@ public:
phantom_node_pair.targetPhantom.isBidirected() phantom_node_pair.targetPhantom.isBidirected()
) { ) {
const NodeID last_node_id = packed_legs2[current_leg].back(); const NodeID last_node_id = packed_legs2[current_leg].back();
search_from_1st_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode+1); search_from_1st_node &= !(last_node_id == phantom_node_pair.targetPhantom.reverse_node_id);
search_from_2nd_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode); search_from_2nd_node &= !(last_node_id == phantom_node_pair.targetPhantom.forward_node_id);
BOOST_ASSERT( search_from_1st_node != search_from_2nd_node ); BOOST_ASSERT( search_from_1st_node != search_from_2nd_node );
} }

View File

@ -86,6 +86,15 @@ public:
const unsigned id const unsigned id
) const = 0; ) const = 0;
virtual bool EdgeIsCompressed( const unsigned id ) const = 0;
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
virtual void GetUncompressedGeometry(
const unsigned id,
std::vector<unsigned> & result_nodes
) const = 0;
virtual TurnInstruction GetTurnInstructionForEdgeID( virtual TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id const unsigned id
) const = 0; ) const = 0;

View File

@ -67,6 +67,9 @@ private:
ShM<TurnInstruction, false>::vector m_turn_instruction_list; ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<char, false>::vector m_names_char_list; ShM<char, false>::vector m_names_char_list;
ShM<unsigned, false>::vector m_name_begin_indices; ShM<unsigned, false>::vector m_name_begin_indices;
ShM<bool, false>::vector m_egde_is_compressed;
ShM<unsigned, false>::vector m_compressed_geometry_indices;
ShM<unsigned, false>::vector m_compressed_geometries;
StaticRTree<RTreeLeaf, false> * m_static_rtree; StaticRTree<RTreeLeaf, false> * m_static_rtree;
@ -146,9 +149,12 @@ private:
); );
unsigned number_of_edges = 0; unsigned number_of_edges = 0;
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned)); edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
m_via_node_list.resize(number_of_edges); m_via_node_list.resize (number_of_edges);
m_name_ID_list.resize(number_of_edges); m_name_ID_list.resize (number_of_edges);
m_turn_instruction_list.resize(number_of_edges); m_turn_instruction_list.resize(number_of_edges);
m_egde_is_compressed.resize (number_of_edges);
unsigned compressed = 0;
OriginalEdgeData current_edge_data; OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_edges; ++i) { for(unsigned i = 0; i < number_of_edges; ++i) {
@ -157,16 +163,58 @@ private:
sizeof(OriginalEdgeData) sizeof(OriginalEdgeData)
); );
m_via_node_list[i] = current_edge_data.via_node; m_via_node_list[i] = current_edge_data.via_node;
if(current_edge_data.via_node == 0 && current_edge_data.compressed_geometry) {
SimpleLogger().Write() << "0 at index " << i;
}
m_name_ID_list[i] = current_edge_data.name_id; m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction; m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_egde_is_compressed[i] = current_edge_data.compressed_geometry;
if(m_egde_is_compressed[i]) {
++compressed;
} }
}
SimpleLogger().Write(logDEBUG) << "compressed: " << compressed;
edges_input_stream.close(); edges_input_stream.close();
} }
void LoadGeometries( void LoadGeometries(
const boost::filesystem::path & geometries_file const boost::filesystem::path & geometry_file
) { ) {
std::ifstream geometry_stream(
geometry_file.c_str(),
std::ios::binary
);
unsigned number_of_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_stream.read(
(char *)&number_of_indices,
sizeof(unsigned)
);
m_compressed_geometry_indices.resize(number_of_indices);
geometry_stream.read(
(char *)&(m_compressed_geometry_indices[0]),
number_of_indices*sizeof(unsigned)
);
geometry_stream.read(
(char *)&number_of_compressed_geometries,
sizeof(unsigned)
);
BOOST_ASSERT( m_compressed_geometry_indices.back() == number_of_compressed_geometries );
m_compressed_geometries.resize( number_of_compressed_geometries );
geometry_stream.read(
(char *)&(m_compressed_geometries[0]),
number_of_compressed_geometries*sizeof(unsigned)
);
geometry_stream.close();
SimpleLogger().Write() << "number_of_indices: " << number_of_indices;
SimpleLogger().Write() << "number_of_compressed_geometries: " << number_of_compressed_geometries;
} }
void LoadRTree( void LoadRTree(
@ -330,10 +378,15 @@ public:
FixedPointCoordinate GetCoordinateOfNode( FixedPointCoordinate GetCoordinateOfNode(
const unsigned id const unsigned id
) const { ) const {
const NodeID node = m_via_node_list.at(id); // const unsigned coordinate_index = m_via_node_list.at(id);
return m_coordinate_list.at(node); return m_coordinate_list.at(id);
}; };
bool EdgeIsCompressed( const unsigned id ) const {
// const NodeID node = m_via_node_list.at(id);
return m_egde_is_compressed.at(id);
}
TurnInstruction GetTurnInstructionForEdgeID( TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id const unsigned id
) const { ) const {
@ -400,6 +453,29 @@ public:
); );
} }
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const {
return m_via_node_list.at(id);
}
virtual void GetUncompressedGeometry(
const unsigned id, std::vector<unsigned> & result_nodes
) const {
const NodeID node = m_via_node_list.at(id);
SimpleLogger().Write() << "translated " << id << " to " << node;
SimpleLogger().Write() << "getting geometry from compression bucket " << node << "/" << m_compressed_geometry_indices.size();
unsigned begin = m_compressed_geometry_indices.at(node);
unsigned end = m_compressed_geometry_indices.at(node+1);
SimpleLogger().Write() << "bucket " << node << " has range [" << begin << "," << end-1 << "]";
//TODO: use vector.insert(.)
for(unsigned geometry_index = begin; geometry_index < end; ++geometry_index) {
unsigned coordinate_id = m_compressed_geometries[geometry_index];
// uncomment to use compressed geometry
result_nodes.push_back( coordinate_id );
SimpleLogger().Write() << "coordinate " << coordinate_id << " at " << m_coordinate_list.at(coordinate_id);
}
}
std::string GetTimestamp() const { std::string GetTimestamp() const {
return m_timestamp; return m_timestamp;
} }

View File

@ -308,10 +308,25 @@ public:
FixedPointCoordinate GetCoordinateOfNode( FixedPointCoordinate GetCoordinateOfNode(
const unsigned id const unsigned id
) const { ) const {
const NodeID node = m_via_node_list.at(id); // const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node); return m_coordinate_list.at(id);
}; };
virtual bool EdgeIsCompressed( const unsigned id ) const {
//TODO!!
return false;
}
virtual void GetUncompressedGeometry(
const unsigned id, std::vector<unsigned> & result_nodes
) const {
//TODO!!
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const {
return m_via_node_list.at(id);
}
TurnInstruction GetTurnInstructionForEdgeID( TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id const unsigned id
) const { ) const {

View File

@ -111,9 +111,9 @@ inline unsigned GenerateServerProgramOptions(
boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]), boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file") ".edges file")
( (
"geometries", "geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometries"]), boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
".geometries file") ".geometry file")
( (
"ramindex", "ramindex",
boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]), boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
@ -256,6 +256,17 @@ inline unsigned GenerateServerProgramOptions(
} }
path_iterator = paths.find("geometries");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".geometry";
} else {
throw OSRMException(base_string + ".geometry not found");
}
path_iterator = paths.find("ramindex"); path_iterator = paths.find("ramindex");
if( if(
path_iterator != paths.end() && path_iterator != paths.end() &&

View File

@ -259,7 +259,10 @@ int main (int argc, char *argv[]) {
std::vector<TurnRestriction>().swap(inputRestrictions); std::vector<TurnRestriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes); std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes); std::vector<NodeID>().swap(trafficLightNodes);
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes(); unsigned edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfEdgeBasedNodes();
BOOST_ASSERT(
edgeBasedNodeNumber != std::numeric_limits<unsigned>::max()
);
DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList; DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList); edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);
std::vector<EdgeBasedNode> nodeBasedEdgeList; std::vector<EdgeBasedNode> nodeBasedEdgeList;

View File

@ -108,6 +108,7 @@ int main (int argc, const char * argv[])
SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"]; SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"]; SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"]; SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"]; SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"]; SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"]; SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];