Unpacking of intermediate paths
This commit is contained in:
parent
3be644265b
commit
c71c8b0047
@ -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();
|
|
||||||
edges_list.push_back(new_edge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
SimpleLogger().Write(logDEBUG) << "numbered " << numbered_edges_count << " edge-expanded nodes";
|
||||||
|
|
||||||
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,24 +562,32 @@ 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(
|
||||||
component_index_size[component_index_list[u]],
|
component_index_size[component_index_list[u]],
|
||||||
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
|
||||||
|
@ -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
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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()),
|
||||||
belongsToTinyComponent(false),
|
lon2(std::numeric_limits<int>::max() >> 1),
|
||||||
nameID(UINT_MAX),
|
belongsToTinyComponent(false),
|
||||||
weight(UINT_MAX >> 1),
|
name_id(std::numeric_limits<unsigned>::max()),
|
||||||
ignoreInGrid(false)
|
forward_weight(std::numeric_limits<int>::max() >> 1),
|
||||||
|
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:
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
unpacked_path.push_back(
|
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
|
||||||
PathData(
|
TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
|
||||||
ed.id,
|
//TODO: reorder to always iterate over a result vector
|
||||||
facade->GetNameIndexFromEdgeID(ed.id),
|
if ( !facade->EdgeIsCompressed(ed.id) ){
|
||||||
facade->GetTurnInstructionForEdgeID(ed.id),
|
SimpleLogger().Write() << "Edge " << ed.id << " is not compressed, smaller_edge_id: " << smaller_edge_id;
|
||||||
ed.distance
|
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
|
||||||
)
|
unpacked_path.push_back(
|
||||||
);
|
PathData(
|
||||||
|
facade->GetGeometryIndexForEdgeID(ed.id),
|
||||||
|
name_index,
|
||||||
|
turn_instruction,
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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() &&
|
||||||
|
@ -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;
|
||||||
|
@ -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"];
|
||||||
|
Loading…
Reference in New Issue
Block a user