first segment needs to be properly cut

This commit is contained in:
Dennis Luxen 2014-02-26 15:55:04 +01:00
parent 5bde545ce3
commit b679a94930
14 changed files with 435 additions and 256 deletions

View File

@ -92,7 +92,7 @@ endif()
# Configuring compilers # Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang # using Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wno-unneeded-internal-declaration -pedantic -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -Wno-unknown-pragmas -Wno-unneeded-internal-declaration -pedantic -fPIC")
message(STATUS "OpenMP parallelization not available using clang++") message(STATUS "OpenMP parallelization not available using clang++")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC # using GCC

View File

@ -223,8 +223,11 @@ void EdgeBasedGraphFactory::GetEdgeBasedEdges(
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) { void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
#ifndef NDEBUG #ifndef NDEBUG
BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){ BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
BOOST_ASSERT(node.lat1 != INT_MAX); BOOST_ASSERT(node.lon1 != INT_MAX);
BOOST_ASSERT(node.lat2 != INT_MAX); BOOST_ASSERT(node.lon2 != INT_MAX); BOOST_ASSERT( m_node_info_list.at(node.u).lat != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.u).lon != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.v).lon != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.v).lat != INT_MAX );
} }
#endif #endif
nodes.swap(m_edge_based_node_list); nodes.swap(m_edge_based_node_list);
@ -443,13 +446,14 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
BOOST_ASSERT( forward_geometry.size() == reverse_geometry.size() ); BOOST_ASSERT( forward_geometry.size() == reverse_geometry.size() );
const unsigned geometry_size = forward_geometry.size(); const unsigned geometry_size = forward_geometry.size();
NodeID first_node_of_edge = u; BOOST_ASSERT( geometry_size > 1 );
NodeID current_edge_start_coordinate_id = u;
// traverse arrays from start and end respectively // traverse arrays from start and end respectively
for( unsigned i = 0; i < geometry_size; ++i ) { for( unsigned i = 0; i < geometry_size; ++i ) {
BOOST_ASSERT( first_node_of_edge == reverse_geometry[geometry_size-1-i].first ); BOOST_ASSERT( current_edge_start_coordinate_id == reverse_geometry[geometry_size-1-i].first );
const NodeID last_coordinate_id = forward_geometry[i].first; const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
// SimpleLogger().Write() << "adding edge (" << first_node_of_edge << "," << forward_geometry[i].first << ") "; // SimpleLogger().Write() << "adding edge (" << current_edge_start_coordinate_id << "," << forward_geometry[i].first << ") ";
// SimpleLogger().Write() << "fwd w: " << forward_geometry[i].second << ", fwd o: " << forward_dist_prefix_sum[i]; // SimpleLogger().Write() << "fwd w: " << forward_geometry[i].second << ", fwd o: " << forward_dist_prefix_sum[i];
// SimpleLogger().Write() << "rev w: " << reverse_geometry[geometry_size-1-i].second << ", rev o: " << reverse_dist_prefix_sum[geometry_size-1-i]; // SimpleLogger().Write() << "rev w: " << reverse_geometry[geometry_size-1-i].second << ", rev o: " << reverse_dist_prefix_sum[geometry_size-1-i];
@ -458,30 +462,35 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
EdgeBasedNode( EdgeBasedNode(
forward_data.edgeBasedNodeID, forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
m_node_info_list[first_node_of_edge].lat, current_edge_start_coordinate_id,
m_node_info_list[first_node_of_edge].lon, current_edge_target_coordinate_id,
m_node_info_list[forward_geometry[i].first].lat,
m_node_info_list[forward_geometry[i].first].lon,
belongs_to_tiny_cc,//TODO
forward_data.nameID, forward_data.nameID,
forward_geometry[i].second, forward_geometry[i].second,
reverse_geometry[geometry_size-1-i].second, reverse_geometry[geometry_size-1-i].second,
forward_dist_prefix_sum[i], forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[geometry_size-1-i] reverse_dist_prefix_sum[geometry_size-1-i],
i,
geometry_size-1-i,
belongs_to_tiny_cc
) )
); );
current_edge_start_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT( m_edge_based_node_list.back().IsCompressed() ); BOOST_ASSERT( m_edge_based_node_list.back().IsCompressed() );
first_node_of_edge = last_coordinate_id;
BOOST_ASSERT(
u != m_edge_based_node_list.back().u ||
v != m_edge_based_node_list.back().v
);
BOOST_ASSERT(
u != m_edge_based_node_list.back().v ||
v != m_edge_based_node_list.back().u
);
} }
//TODO: Manually reconstruct last edge. //TODO: Manually reconstruct last edge.
BOOST_ASSERT( current_edge_start_coordinate_id == v );
if( first_node_of_edge != v ) { BOOST_ASSERT( m_edge_based_node_list.back().IsCompressed() );
SimpleLogger().Write(logDEBUG) << "first_node_of_edge:" << first_node_of_edge << ", u: " << u << ", v: " << v;
}
// BOOST_ASSERT( false );
BOOST_ASSERT( first_node_of_edge == v );
} else { } else {
BOOST_ASSERT( !m_geometry_compressor.HasEntryForID(e2) ); BOOST_ASSERT( !m_geometry_compressor.HasEntryForID(e2) );
@ -507,16 +516,16 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
EdgeBasedNode( EdgeBasedNode(
forward_data.edgeBasedNodeID, forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
m_node_info_list[u].lat, u,
m_node_info_list[u].lon, v,
m_node_info_list[v].lat, forward_data.nameID,
m_node_info_list[v].lon,
belongs_to_tiny_cc,
forward_data.nameID, //TODO use also reverse name id?
forward_data.distance, forward_data.distance,
reverse_data.distance, reverse_data.distance,
0, 0,
0 0,
0,
0,
belongs_to_tiny_cc
) )
); );
BOOST_ASSERT( !m_edge_based_node_list.back().IsCompressed() ); BOOST_ASSERT( !m_edge_based_node_list.back().IsCompressed() );

View File

@ -96,6 +96,11 @@ public:
return nodes[node]; return nodes[node];
} }
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
return iter->second;
}
void Clear() { void Clear() {
nodes.clear(); nodes.clear();
} }
@ -158,6 +163,11 @@ public:
return insertedNodes[index].data; return insertedNodes[index].data;
} }
Data const & GetData( NodeID node ) const {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
}
Weight& GetKey( NodeID node ) { Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
return insertedNodes[index].weight; return insertedNodes[index].weight;

View File

@ -13,67 +13,66 @@
struct EdgeBasedNode { struct EdgeBasedNode {
EdgeBasedNode() : EdgeBasedNode() :
id(INT_MAX), forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(std::numeric_limits<int>::max()), reverse_edge_based_node_id(SPECIAL_NODEID),
lat1(std::numeric_limits<int>::max()), u(SPECIAL_NODEID),
lon1(std::numeric_limits<int>::max()), v(SPECIAL_NODEID),
lat2(std::numeric_limits<int>::max()), name_id(0),
lon2(std::numeric_limits<int>::max() >> 1),
belongsToTinyComponent(false),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(std::numeric_limits<int>::max() >> 1), forward_weight(std::numeric_limits<int>::max() >> 1),
reverse_weight(std::numeric_limits<int>::max() >> 1), reverse_weight(std::numeric_limits<int>::max() >> 1),
forward_offset(0), forward_offset(0),
reverse_offset(0) reverse_offset(0),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
rev_segment_position( std::numeric_limits<unsigned short>::max() >> 1 ),
belongsToTinyComponent(false)
{ } { }
EdgeBasedNode( EdgeBasedNode(
NodeID forward_edge_based_node_id, NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id, NodeID reverse_edge_based_node_id,
int lat1, NodeID u,
int lon1, NodeID v,
int lat2, unsigned name_id,
int lon2,
bool belongsToTinyComponent,
NodeID name_id,
int forward_weight, int forward_weight,
int reverse_weight, int reverse_weight,
int forward_offset, int forward_offset,
int reverse_offset int reverse_offset,
unsigned short fwd_segment_position,
unsigned short rev_segment_position,
bool belongsToTinyComponent
) : ) :
forward_edge_based_node_id(forward_edge_based_node_id), forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id), reverse_edge_based_node_id(reverse_edge_based_node_id),
lat1(lat1), u(u),
lon1(lon1), v(v),
lat2(lat2),
lon2(lon2),
belongsToTinyComponent(belongsToTinyComponent),
name_id(name_id), name_id(name_id),
forward_weight(forward_weight), forward_weight(forward_weight),
reverse_weight(reverse_weight), reverse_weight(reverse_weight),
forward_offset(forward_offset), forward_offset(forward_offset),
reverse_offset(reverse_offset) reverse_offset(reverse_offset),
fwd_segment_position(fwd_segment_position),
rev_segment_position(rev_segment_position),
belongsToTinyComponent(belongsToTinyComponent)
{ } { }
// Computes: // Computes:
// - the distance from the given query location to nearest point on this edge (and returns it) // - the distance from the given query location to nearest point on this edge (and returns it)
// - the location on this edge which is nearest to the query location inline static double ComputePerpendicularDistance(
// - the ratio ps:pq, where p and q are the end points of this edge, and s is the perpendicular foot of const FixedPointCoordinate & coord_a,
const FixedPointCoordinate & coord_b,
// the query location on the line defined by p and q. // the query location on the line defined by p and q.
double ComputePerpendicularDistance( double ComputePerpendicularDistance(
const FixedPointCoordinate& query_location, const FixedPointCoordinate & query_location,
FixedPointCoordinate & nearest_location, FixedPointCoordinate & nearest_location,
double & ratio, double & r
double precision = COORDINATE_PRECISION ) {
) const {
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 y = query_location.lon/COORDINATE_PRECISION;
const double a = lat2y(lat1/COORDINATE_PRECISION); const double a = lat2y(coord_a.lat/COORDINATE_PRECISION);
const double b = lon1/COORDINATE_PRECISION; const double b = coord_a.lon/COORDINATE_PRECISION;
const double c = lat2y(lat2/COORDINATE_PRECISION); const double c = lat2y(coord_b.lat/COORDINATE_PRECISION);
const double d = lon2/COORDINATE_PRECISION; const double d = coord_b.lon/COORDINATE_PRECISION;
double p,q/*,mX*/,nY; double p,q/*,mX*/,nY;
if( std::abs(a-c) > std::numeric_limits<double>::epsilon() ){ if( std::abs(a-c) > std::numeric_limits<double>::epsilon() ){
const double m = (d-b)/(c-a); // slope const double m = (d-b)/(c-a); // slope
@ -92,18 +91,20 @@ struct EdgeBasedNode {
} }
// p, q : the end points of the underlying edge // p, q : the end points of the underlying edge
const Point p(lat2y(lat1/COORDINATE_PRECISION), lon1/COORDINATE_PRECISION); if( std::isnan(r) ) {
const Point q(lat2y(lat2/COORDINATE_PRECISION), lon2/COORDINATE_PRECISION); r = ((coord_b.lat == query_location.lat) && (coord_b.lon == query_location.lon)) ? 1. : 0.;
// 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() ) { } else if( std::abs(r-1.) <= std::numeric_limits<double>::epsilon() ) {
query_location.lon/COORDINATE_PRECISION); query_location.lon/COORDINATE_PRECISION);
nearest_location.lat = coord_a.lat;
const Point foot = ComputePerpendicularFoot(p, q, r, epsilon); nearest_location.lon = coord_a.lon;
ratio = ComputeRatio(p, q, foot, epsilon); } else if( r >= 1. ){
nearest_location.lat = coord_b.lat;
BOOST_ASSERT( !std::isnan(ratio) ); nearest_location.lon = coord_b.lon;
} else {
// point lies in between
nearest_location.lat = y2lat(p)*COORDINATE_PRECISION; nearest_location.lat = y2lat(p)*COORDINATE_PRECISION;
nearest_location = ComputeNearestPointOnSegment(foot, ratio); nearest_location = ComputeNearestPointOnSegment(foot, ratio);
@ -120,12 +121,20 @@ struct EdgeBasedNode {
return approximated_distance; return approximated_distance;
} }
bool operator<(const EdgeBasedNode & other) const { static inline FixedPointCoordinate Centroid(
const FixedPointCoordinate & a,
const FixedPointCoordinate & b
) {
return other.id < id; return other.id < id;
//The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(a.lon, b.lon) + std::max(a.lon, b.lon))/2;
centroid.lat = (std::min(a.lat, b.lat) + std::max(a.lat, b.lat))/2;
return centroid;
} }
bool operator==(const EdgeBasedNode & other) const { bool IsCompressed() {
return id == other.id; return (fwd_segment_position + rev_segment_position) != 0;
} }
// Returns the midpoint of the underlying edge. // Returns the midpoint of the underlying edge.
@ -134,13 +143,16 @@ struct EdgeBasedNode {
} }
NodeID forward_edge_based_node_id; NodeID forward_edge_based_node_id;
NodeID reverse_edge_based_node_id;
// The coordinates of the end-points of the underlying edge. NodeID u;
int lat1; NodeID v;
int lon1; unsigned name_id;
int lat2; int forward_weight;
int lon2:31; int reverse_weight;
int forward_offset;
int reverse_offset;
unsigned short fwd_segment_position;
unsigned short rev_segment_position:15;
bool belongsToTinyComponent:1; bool belongsToTinyComponent:1;
NodeID name_id; NodeID name_id;

View File

@ -40,7 +40,9 @@ struct PhantomNode {
reverse_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0), forward_offset(0),
reverse_offset(0), reverse_offset(0),
ratio(0.) ratio(0.),
fwd_segment_position(0),
rev_segment_position(0)
{ } { }
NodeID forward_node_id; NodeID forward_node_id;
@ -52,6 +54,9 @@ struct PhantomNode {
int reverse_offset; int reverse_offset;
double ratio; double ratio;
FixedPointCoordinate location; FixedPointCoordinate location;
unsigned short fwd_segment_position;
unsigned short rev_segment_position;
int GetForwardWeightPlusOffset() const { int GetForwardWeightPlusOffset() const {
return forward_weight + forward_offset; return forward_weight + forward_offset;
@ -108,8 +113,10 @@ struct PhantomNodes {
return (startPhantom.forward_node_id == targetPhantom.forward_node_id); return (startPhantom.forward_node_id == targetPhantom.forward_node_id);
} }
//TODO: Rename to: BothPhantomNodesAreInvalid
bool AtLeastOnePhantomNodeIsUINTMAX() const { bool AtLeastOnePhantomNodeIsUINTMAX() const {
return !(startPhantom.forward_node_id == SPECIAL_NODEID || targetPhantom.forward_node_id == SPECIAL_NODEID); return (startPhantom.forward_node_id == SPECIAL_NODEID) && (targetPhantom.forward_node_id == SPECIAL_NODEID);
} }
bool PhantomNodesHaveEqualLocation() const { bool PhantomNodesHaveEqualLocation() const {

View File

@ -72,13 +72,11 @@ struct NodeInfo {
switch(n) { switch(n) {
case 1: case 1:
return lat; return lat;
break; // break;
case 0: case 0:
return lon; return lon;
break; // break;
default: default:
BOOST_ASSERT_MSG(false, "should not happen");
return std::numeric_limits<unsigned>::max();
break; break;
} }
BOOST_ASSERT_MSG(false, "should not happen"); BOOST_ASSERT_MSG(false, "should not happen");

View File

@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DeallocatingVector.h" #include "DeallocatingVector.h"
#include "HilbertValue.h" #include "HilbertValue.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "QueryNode.h"
#include "SharedMemoryFactory.h" #include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h" #include "SharedMemoryVectorWrapper.h"
@ -84,21 +85,34 @@ public:
inline void InitializeMBRectangle( inline void InitializeMBRectangle(
DataT const * objects, DataT const * objects,
const uint32_t element_count const uint32_t element_count,
const std::vector<NodeInfo> & coordinate_list
) { ) {
for(uint32_t i = 0; i < element_count; ++i) { for(uint32_t i = 0; i < element_count; ++i) {
min_lon = std::min( min_lon = std::min(
min_lon, std::min(objects[i].lon1, objects[i].lon2) min_lon, std::min(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
); );
max_lon = std::max( max_lon = std::max(
max_lon, std::max(objects[i].lon1, objects[i].lon2) max_lon, std::max(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
); );
min_lat = std::min( min_lat = std::min(
min_lat, std::min(objects[i].lat1, objects[i].lat2) min_lat, std::min(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lon
)
); );
max_lat = std::max( max_lat = std::max(
max_lat, std::max(objects[i].lat1, objects[i].lat2) max_lat, std::max(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lon
)
); );
} }
} }
@ -298,14 +312,15 @@ public:
explicit StaticRTree( explicit StaticRTree(
std::vector<DataT> & input_data_vector, std::vector<DataT> & input_data_vector,
const std::string tree_node_filename, const std::string tree_node_filename,
const std::string leaf_node_filename const std::string leaf_node_filename,
const std::vector<NodeInfo> & coordinate_list
) )
: m_element_count(input_data_vector.size()), : m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename) m_leaf_node_filename(leaf_node_filename)
{ {
SimpleLogger().Write() << SimpleLogger().Write() <<
"constructing r-tree of " << m_element_count << "constructing r-tree of " << m_element_count <<
" elements"; " edge elements build on-top of " << coordinate_list.size() << " coordinates";
double time1 = get_timestamp(); double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count); std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
@ -318,7 +333,16 @@ public:
input_wrapper_vector[element_counter].m_array_index = element_counter; input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection //Get Hilbert-Value for centroid in mercartor projection
DataT const & current_element = input_data_vector[element_counter]; DataT const & current_element = input_data_vector[element_counter];
FixedPointCoordinate current_centroid = current_element.Centroid(); FixedPointCoordinate current_centroid = DataT::Centroid(
FixedPointCoordinate(
coordinate_list.at(current_element.u).lat,
coordinate_list.at(current_element.u).lon
),
FixedPointCoordinate(
coordinate_list.at(current_element.v).lat,
coordinate_list.at(current_element.v).lon
)
);
current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION); current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION);
uint64_t current_hilbert_value = get_hilbert_number(current_centroid); uint64_t current_hilbert_value = get_hilbert_number(current_centroid);
@ -349,7 +373,11 @@ public:
} }
//generate tree node that resemble the objects in leaf and store it for next level //generate tree node that resemble the objects in leaf and store it for next level
current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count); current_node.minimum_bounding_rectangle.InitializeMBRectangle(
current_leaf.objects,
current_leaf.object_count,
coordinate_list
);
current_node.child_is_on_disk = true; current_node.child_is_on_disk = true;
current_node.children[0] = tree_nodes_in_level.size(); current_node.children[0] = tree_nodes_in_level.size();
tree_nodes_in_level.push_back(current_node); tree_nodes_in_level.push_back(current_node);
@ -543,29 +571,29 @@ public:
double current_minimum_distance = FixedPointCoordinate::ApproximateDistance( double current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat, input_coordinate.lat,
input_coordinate.lon, input_coordinate.lon,
current_edge.lat1, m_coordinate_list->at(current_edge.u).lat,
current_edge.lon1 m_coordinate_list->at(current_edge.u).lon
); );
if( current_minimum_distance < min_dist ) { if( current_minimum_distance < min_dist ) {
//found a new minimum //found a new minimum
min_dist = current_minimum_distance; min_dist = current_minimum_distance;
result_coordinate.lat = current_edge.lat1; result_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
result_coordinate.lon = current_edge.lon1; result_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} }
current_minimum_distance = FixedPointCoordinate::ApproximateDistance( current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat, input_coordinate.lat,
input_coordinate.lon, input_coordinate.lon,
current_edge.lat2, m_coordinate_list->at(current_edge.v).lat,
current_edge.lon2 m_coordinate_list->at(current_edge.v).lon
); );
if( current_minimum_distance < min_dist ) { if( current_minimum_distance < min_dist ) {
//found a new minimum //found a new minimum
min_dist = current_minimum_distance; min_dist = current_minimum_distance;
result_coordinate.lat = current_edge.lat2; result_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
result_coordinate.lon = current_edge.lon2; result_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} }
} }
@ -645,6 +673,8 @@ public:
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = current_edge.ComputePerpendicularDistance( double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
m_coordinate_list->at(current_edge.u),
m_coordinate_list->at(current_edge.v),
input_coordinate, input_coordinate,
nearest, nearest,
current_ratio current_ratio
@ -653,25 +683,27 @@ public:
BOOST_ASSERT( 0. <= current_perpendicular_distance ); BOOST_ASSERT( 0. <= current_perpendicular_distance );
if( if(
( current_perpendicular_distance < min_dist ) && ( current_perpendicular_distance < min_dist ) //&&
!DoubleEpsilonCompare( // !DoubleEpsilonCompare(
current_perpendicular_distance, // current_perpendicular_distance,
min_dist // min_dist
) // )
) { //found a new minimum ) { //found a new minimum
min_dist = current_perpendicular_distance; min_dist = current_perpendicular_distance;
result_phantom_node.forward_node_id = current_edge.forward_edge_based_node_id; result_phantom_node.forward_node_id = current_edge.forward_edge_based_node_id;
result_phantom_node.reverse_node_id = current_edge.reverse_edge_based_node_id; result_phantom_node.reverse_node_id = current_edge.reverse_edge_based_node_id;
result_phantom_node.name_id = current_edge.name_id;
result_phantom_node.forward_weight = current_edge.forward_weight; result_phantom_node.forward_weight = current_edge.forward_weight;
result_phantom_node.reverse_weight = current_edge.reverse_weight; result_phantom_node.reverse_weight = current_edge.reverse_weight;
result_phantom_node.forward_offset = current_edge.forward_offset; result_phantom_node.forward_offset = current_edge.forward_offset;
result_phantom_node.reverse_offset = current_edge.reverse_offset; result_phantom_node.reverse_offset = current_edge.reverse_offset;
result_phantom_node.fwd_segment_position = current_edge.fwd_segment_position;
result_phantom_node.rev_segment_position = current_edge.rev_segment_position;
result_phantom_node.name_id = current_edge.name_id;
result_phantom_node.location = nearest; result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1; current_start_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
current_start_coordinate.lon = current_edge.lon1; current_start_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
current_end_coordinate.lat = current_edge.lat2; current_end_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
current_end_coordinate.lon = current_edge.lon2; current_end_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
nearest_edge = current_edge; nearest_edge = current_edge;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} }
@ -730,10 +762,11 @@ public:
} }
result_phantom_node.ratio = ratio; result_phantom_node.ratio = ratio;
SimpleLogger().Write(logDEBUG) << "result location: " << result_phantom_node.location; SimpleLogger().Write(logDEBUG) << "result location: " << result_phantom_node.location << ", start: " << current_start_coordinate << ", end: " << current_end_coordinate;
SimpleLogger().Write(logDEBUG) << "fwd node: " << result_phantom_node.forward_node_id << ", rev node: " << result_phantom_node.reverse_node_id; SimpleLogger().Write(logDEBUG) << "fwd node: " << result_phantom_node.forward_node_id << ", rev node: " << result_phantom_node.reverse_node_id;
SimpleLogger().Write(logDEBUG) << "fwd weight: " << result_phantom_node.forward_weight << ", rev weight: " << result_phantom_node.reverse_weight << ", ratio: " << result_phantom_node.ratio; SimpleLogger().Write(logDEBUG) << "fwd weight: " << result_phantom_node.forward_weight << ", rev weight: " << result_phantom_node.reverse_weight << ", ratio: " << result_phantom_node.ratio;
SimpleLogger().Write(logDEBUG) << "bidirected: " << (result_phantom_node.isBidirected() ? "y" : "n");
SimpleLogger().Write(logDEBUG) << "name id: " << result_phantom_node.name_id;
return found_a_nearest_edge; return found_a_nearest_edge;
} }

View File

@ -140,8 +140,8 @@ void DescriptionFactory::BuildRouteSummary(
summary.startName = start_phantom.name_id; summary.startName = start_phantom.name_id;
summary.destName = target_phantom.name_id; summary.destName = target_phantom.name_id;
SimpleLogger().Write(logDEBUG) << "phantom start name: " << start_phantom.name_id << ", path: " << pathDescription.front().name_id; // SimpleLogger().Write(logDEBUG) << "phantom start name: " << start_phantom.name_id << ", path: " << pathDescription.front().name_id;
SimpleLogger().Write(logDEBUG) << "phantom target name: " << target_phantom.name_id << ", path: " << pathDescription.back().name_id; // SimpleLogger().Write(logDEBUG) << "phantom target name: " << target_phantom.name_id << ", path: " << pathDescription.back().name_id;
summary.BuildDurationAndLengthStrings(distance, time); summary.BuildDurationAndLengthStrings(distance, time);
} }

View File

@ -76,15 +76,16 @@ public:
~AlternativeRouting() {} ~AlternativeRouting() {}
void operator()( void operator() (
const PhantomNodes & phantom_node_pair, const PhantomNodes & phantom_node_pair,
RawRouteData & raw_route_data RawRouteData & raw_route_data
) { ) {
if( (!phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX()) || if( //phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX() ||
phantom_node_pair.PhantomNodesHaveEqualLocation() phantom_node_pair.PhantomNodesHaveEqualLocation()
) { ) {
raw_route_data.lengthOfShortestPath = INT_MAX; raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX; raw_route_data.lengthOfAlternativePath = INT_MAX;
SimpleLogger().Write(logDEBUG) << "not executing path search";
return; return;
} }
@ -109,14 +110,18 @@ public:
QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2); QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2); QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
int upper_bound_to_shortest_path_distance = INT_MAX; int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT;
NodeID middle_node = UINT_MAX; NodeID middle_node = UINT_MAX;
forward_heap1.Insert( if(phantom_node_pair.startPhantom.forward_node_id != SPECIAL_NODEID ) {
phantom_node_pair.startPhantom.forward_node_id, SimpleLogger().Write(logDEBUG) << "fwd insert: " << phantom_node_pair.startPhantom.forward_node_id;
-phantom_node_pair.startPhantom.GetForwardWeightPlusOffset(), forward_heap1.Insert(
phantom_node_pair.startPhantom.forward_node_id phantom_node_pair.startPhantom.forward_node_id,
); -phantom_node_pair.startPhantom.GetForwardWeightPlusOffset(),
if(phantom_node_pair.startPhantom.isBidirected() ) { phantom_node_pair.startPhantom.forward_node_id
);
}
if(phantom_node_pair.startPhantom.reverse_node_id != SPECIAL_NODEID ) {
SimpleLogger().Write(logDEBUG) << "fwd insert: " << phantom_node_pair.startPhantom.reverse_node_id;
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.reverse_node_id, phantom_node_pair.startPhantom.reverse_node_id,
-phantom_node_pair.startPhantom.GetReverseWeightPlusOffset(), -phantom_node_pair.startPhantom.GetReverseWeightPlusOffset(),
@ -124,12 +129,16 @@ public:
); );
} }
reverse_heap1.Insert( if(phantom_node_pair.targetPhantom.forward_node_id != SPECIAL_NODEID ) {
phantom_node_pair.targetPhantom.forward_node_id, SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.targetPhantom.forward_node_id;
phantom_node_pair.targetPhantom.GetForwardWeightPlusOffset(), reverse_heap1.Insert(
phantom_node_pair.targetPhantom.forward_node_id phantom_node_pair.targetPhantom.forward_node_id,
); phantom_node_pair.targetPhantom.GetForwardWeightPlusOffset(),
if(phantom_node_pair.targetPhantom.isBidirected() ) { phantom_node_pair.targetPhantom.forward_node_id
);
}
if(phantom_node_pair.targetPhantom.reverse_node_id != SPECIAL_NODEID ) {
SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.targetPhantom.reverse_node_id;
reverse_heap1.Insert( reverse_heap1.Insert(
phantom_node_pair.targetPhantom.reverse_node_id, phantom_node_pair.targetPhantom.reverse_node_id,
phantom_node_pair.targetPhantom.GetReverseWeightPlusOffset(), phantom_node_pair.targetPhantom.GetReverseWeightPlusOffset(),
@ -237,16 +246,16 @@ public:
} }
} }
std::vector<NodeID> & packedShortestPath = packed_forward_path; std::vector<NodeID> & packed_shortest_path = packed_forward_path;
std::reverse(packedShortestPath.begin(), packedShortestPath.end()); std::reverse(packed_shortest_path.begin(), packed_shortest_path.end());
packedShortestPath.push_back(middle_node); packed_shortest_path.push_back(middle_node);
packedShortestPath.insert(packedShortestPath.end(),packed_reverse_path.begin(), packed_reverse_path.end()); packed_shortest_path.insert(packed_shortest_path.end(),packed_reverse_path.begin(), packed_reverse_path.end());
std::vector<RankedCandidateNode > rankedCandidates; std::vector<RankedCandidateNode > rankedCandidates;
//prioritizing via nodes for deep inspection //prioritizing via nodes for deep inspection
BOOST_FOREACH(const NodeID node, nodes_that_passed_preselection) { BOOST_FOREACH(const NodeID node, nodes_that_passed_preselection) {
int lengthOfViaPath = 0, sharingOfViaPath = 0; int lengthOfViaPath = 0, sharingOfViaPath = 0;
computeLengthAndSharingOfViaPath(node, &lengthOfViaPath, &sharingOfViaPath, forward_offset+reverse_offset, packedShortestPath); computeLengthAndSharingOfViaPath(node, &lengthOfViaPath, &sharingOfViaPath, forward_offset+reverse_offset, packed_shortest_path);
if(sharingOfViaPath <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA) { if(sharingOfViaPath <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA) {
rankedCandidates.push_back(RankedCandidateNode(node, lengthOfViaPath, sharingOfViaPath)); rankedCandidates.push_back(RankedCandidateNode(node, lengthOfViaPath, sharingOfViaPath));
} }
@ -267,33 +276,92 @@ public:
//Unpack shortest path and alternative, if they exist //Unpack shortest path and alternative, if they exist
if(INT_MAX != upper_bound_to_shortest_path_distance) { if(INT_MAX != upper_bound_to_shortest_path_distance) {
BOOST_ASSERT( !packed_shortest_path.empty() );
raw_route_data.unpacked_path_segments.resize(1); raw_route_data.unpacked_path_segments.resize(1);
super::UnpackPath(packedShortestPath, raw_route_data.unpacked_path_segments[0]); // SimpleLogger().Write() << "fwd offset1: " << phantom_node_pair.startPhantom.fwd_segment_position;
// SimpleLogger().Write() << "fwd offset2: " << phantom_node_pair.startPhantom.rev_segment_position;
// SimpleLogger().Write() << "rev offset1: " << phantom_node_pair.targetPhantom.fwd_segment_position;
// SimpleLogger().Write() << "rev offset2: " << phantom_node_pair.targetPhantom.rev_segment_position;
// int start_offset = ( packed_shortest_path.front() == phantom_node_pair.startPhantom.forward_node_id ? 1 : -1 )*phantom_node_pair.startPhantom.fwd_segment_position;
// SimpleLogger().Write(logDEBUG) << "unpacking from index " << phantom_node_pair.startPhantom.fwd_segment_position;
SimpleLogger().Write(logDEBUG) << "phantom_node_pair.startPhantom.forward_node_id: " << phantom_node_pair.startPhantom.forward_node_id;
SimpleLogger().Write(logDEBUG) << "phantom_node_pair.startPhantom.reverse_node_id: " << phantom_node_pair.startPhantom.reverse_node_id;
SimpleLogger().Write(logDEBUG) << "packed_shortest_path.front(): " << packed_shortest_path.front();
// SimpleLogger().Write(logDEBUG) << "packed_shortest_path.back(): " << packed_shortest_path.back();
super::UnpackPath(
packed_shortest_path,
phantom_node_pair.startPhantom.fwd_segment_position,
(packed_shortest_path.front() == phantom_node_pair.startPhantom.reverse_node_id),
phantom_node_pair.targetPhantom.fwd_segment_position,//( packed_forward_path.back() == phantom_node_pair.targetPhantom.forward_node_id ? 1 : -1 )*phantom_node_pair.targetPhantom.fwd_segment_position,
raw_route_data.unpacked_path_segments.front()
);
raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance; raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
} else { } else {
//TODO: kill this branch by initialization
raw_route_data.lengthOfShortestPath = INT_MAX; raw_route_data.lengthOfShortestPath = INT_MAX;
} }
if(selectedViaNode != UINT_MAX) { if(selectedViaNode != UINT_MAX) {
retrievePackedViaPath(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, s_v_middle, v_t_middle, raw_route_data.unpacked_alternative); RetrieveAndUnpackAlternatePath(
forward_heap1,
reverse_heap1,
forward_heap2,
reverse_heap2,
s_v_middle,
v_t_middle,
raw_route_data.unpacked_alternative
);
raw_route_data.lengthOfAlternativePath = lengthOfViaPath; raw_route_data.lengthOfAlternativePath = lengthOfViaPath;
} else { } else {
//TODO: kill this branch by initialization
raw_route_data.lengthOfAlternativePath = INT_MAX; raw_route_data.lengthOfAlternativePath = INT_MAX;
} }
} }
private: private:
//unpack <s,..,v,..,t> by exploring search spaces from v //unpack <s,..,v,..,t> by exploring search spaces from v
inline void retrievePackedViaPath(QueryHeap & _forwardHeap1, QueryHeap & _backwardHeap1, QueryHeap & _forwardHeap2, QueryHeap & _backwardHeap2, inline void RetrieveAndUnpackAlternatePath(
const NodeID s_v_middle, const NodeID v_t_middle, std::vector<PathData> & unpackedPath) { const QueryHeap & forward_heap1,
//unpack [s,v) const QueryHeap & reverse_heap1,
const QueryHeap & forward_heap2,
const QueryHeap & reverse_heap2,
const NodeID s_v_middle,
const NodeID v_t_middle,
std::vector<PathData> & unpacked_path
) const {
//fetch packed path [s,v)
std::vector<NodeID> packed_s_v_path, packed_v_t_path; std::vector<NodeID> packed_s_v_path, packed_v_t_path;
super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, s_v_middle, packed_s_v_path); super::RetrievePackedPathFromHeap(
packed_s_v_path.resize(packed_s_v_path.size()-1); forward_heap1,
//unpack [v,t] reverse_heap2,
super::RetrievePackedPathFromHeap(_forwardHeap2, _backwardHeap1, v_t_middle, packed_v_t_path); s_v_middle,
packed_s_v_path.insert(packed_s_v_path.end(),packed_v_t_path.begin(), packed_v_t_path.end() ); packed_s_v_path
super::UnpackPath(packed_s_v_path, unpackedPath); );
packed_s_v_path.pop_back(); //remove v, other we get it twice
//fetch patched path [v,t]
super::RetrievePackedPathFromHeap(
forward_heap2,
reverse_heap1,
v_t_middle,
packed_v_t_path
);
packed_s_v_path.insert(
packed_s_v_path.end(),
packed_v_t_path.begin(),
packed_v_t_path.end()
);
// unpack, supply correct offsets to packed start and end nodes.
super::UnpackPath(
packed_s_v_path,
0, false, 0, //TODO: replace by real offsets
unpacked_path
);
} }
inline void computeLengthAndSharingOfViaPath(const NodeID via_node, int *real_length_of_via_path, int *sharing_of_via_path, inline void computeLengthAndSharingOfViaPath(const NodeID via_node, int *real_length_of_via_path, int *sharing_of_via_path,
@ -312,7 +380,7 @@ private:
std::vector < NodeID > packed_s_v_path; std::vector < NodeID > packed_s_v_path;
std::vector < NodeID > packed_v_t_path; std::vector < NodeID > packed_v_t_path;
std::vector<NodeID> partiallyUnpackedShortestPath; std::vector<NodeID> partiallyUnpacked_shortest_path;
std::vector<NodeID> partiallyUnpackedViaPath; std::vector<NodeID> partiallyUnpackedViaPath;
NodeID s_v_middle = UINT_MAX; NodeID s_v_middle = UINT_MAX;
@ -346,13 +414,13 @@ private:
} else { } else {
if (packed_s_v_path[i] == packed_shortest_path[i]) { if (packed_s_v_path[i] == packed_shortest_path[i]) {
super::UnpackEdge(packed_s_v_path[i], packed_s_v_path[i+1], partiallyUnpackedViaPath); super::UnpackEdge(packed_s_v_path[i], packed_s_v_path[i+1], partiallyUnpackedViaPath);
super::UnpackEdge(packed_shortest_path[i], packed_shortest_path[i+1], partiallyUnpackedShortestPath); super::UnpackEdge(packed_shortest_path[i], packed_shortest_path[i+1], partiallyUnpacked_shortest_path);
break; break;
} }
} }
} }
//traverse partially unpacked edge and note common prefix //traverse partially unpacked edge and note common prefix
for (int i = 0, lengthOfPackedPath = std::min( partiallyUnpackedViaPath.size(), partiallyUnpackedShortestPath.size()) - 1; (i < lengthOfPackedPath) && (partiallyUnpackedViaPath[i] == partiallyUnpackedShortestPath[i] && partiallyUnpackedViaPath[i+1] == partiallyUnpackedShortestPath[i+1]); ++i) { for (int i = 0, lengthOfPackedPath = std::min( partiallyUnpackedViaPath.size(), partiallyUnpacked_shortest_path.size()) - 1; (i < lengthOfPackedPath) && (partiallyUnpackedViaPath[i] == partiallyUnpacked_shortest_path[i] && partiallyUnpackedViaPath[i+1] == partiallyUnpacked_shortest_path[i+1]); ++i) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]); EdgeID edgeID = facade->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} }
@ -367,16 +435,16 @@ private:
} else { } else {
if (packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) { if (packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) {
super::UnpackEdge(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex], partiallyUnpackedViaPath); super::UnpackEdge(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex], partiallyUnpackedViaPath);
super::UnpackEdge(packed_shortest_path[shortestPathIndex-1] , packed_shortest_path[shortestPathIndex], partiallyUnpackedShortestPath); super::UnpackEdge(packed_shortest_path[shortestPathIndex-1] , packed_shortest_path[shortestPathIndex], partiallyUnpacked_shortest_path);
break; break;
} }
} }
} }
viaPathIndex = partiallyUnpackedViaPath.size() - 1; viaPathIndex = partiallyUnpackedViaPath.size() - 1;
shortestPathIndex = partiallyUnpackedShortestPath.size() - 1; shortestPathIndex = partiallyUnpacked_shortest_path.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex) { for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex) {
if (partiallyUnpackedViaPath[viaPathIndex - 1] == partiallyUnpackedShortestPath[shortestPathIndex - 1] && partiallyUnpackedViaPath[viaPathIndex] == partiallyUnpackedShortestPath[shortestPathIndex]) { if (partiallyUnpackedViaPath[viaPathIndex - 1] == partiallyUnpacked_shortest_path[shortestPathIndex - 1] && partiallyUnpackedViaPath[viaPathIndex] == partiallyUnpacked_shortest_path[shortestPathIndex]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]); EdgeID edgeID = facade->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else { } else {
@ -386,17 +454,17 @@ private:
//finished partial unpacking spree! Amount of sharing is stored to appropriate pointer variable //finished partial unpacking spree! Amount of sharing is stored to appropriate pointer variable
} }
inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, QueryHeap & _forwardHeap, QueryHeap & _backwardHeap, const std::vector<NodeID> & packedShortestPath) { inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, QueryHeap & _forwardHeap, QueryHeap & _backwardHeap, const std::vector<NodeID> & packed_shortest_path) {
std::vector<NodeID> packedAlternativePath; std::vector<NodeID> packedAlternativePath;
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath); super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath);
if(packedShortestPath.size() < 2 || packedAlternativePath.size() < 2) if(packed_shortest_path.size() < 2 || packedAlternativePath.size() < 2)
return 0; return 0;
int sharing = 0; int sharing = 0;
int aindex = 0; int aindex = 0;
//compute forward sharing //compute forward sharing
while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) { while( (packedAlternativePath[aindex] == packed_shortest_path[aindex]) && (packedAlternativePath[aindex+1] == packed_shortest_path[aindex+1]) ) {
// SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")"; // SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")";
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]); EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += facade->GetEdgeData(edgeID).distance; sharing += facade->GetEdgeData(edgeID).distance;
@ -404,9 +472,9 @@ private:
} }
aindex = packedAlternativePath.size()-1; aindex = packedAlternativePath.size()-1;
int bindex = packedShortestPath.size()-1; int bindex = packed_shortest_path.size()-1;
//compute backward sharing //compute backward sharing
while( aindex > 0 && bindex > 0 && (packedAlternativePath[aindex] == packedShortestPath[bindex]) && (packedAlternativePath[aindex-1] == packedShortestPath[bindex-1]) ) { while( aindex > 0 && bindex > 0 && (packedAlternativePath[aindex] == packed_shortest_path[bindex]) && (packedAlternativePath[aindex-1] == packed_shortest_path[bindex-1]) ) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]); EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]);
sharing += facade->GetEdgeData(edgeID).distance; sharing += facade->GetEdgeData(edgeID).distance;
--aindex; --bindex; --aindex; --bindex;

View File

@ -138,8 +138,24 @@ public:
inline void UnpackPath( inline void UnpackPath(
const std::vector<NodeID> & packed_path, const std::vector<NodeID> & packed_path,
int fwd_index_offset,
bool start_traversed_in_reverse,
int rev_index_offset,
std::vector<PathData> & unpacked_path std::vector<PathData> & unpacked_path
) const { ) const {
// SimpleLogger().Write(logDEBUG) << "unpacking path";
// for(unsigned i = 0; i < packed_path.size(); ++i) {
// std::cout << packed_path[i] << " ";
// }
bool segment_reversed = false;
SimpleLogger().Write(logDEBUG) << "fwd offset: " << fwd_index_offset;
SimpleLogger().Write(logDEBUG) << "rev offset: " << rev_index_offset;
SimpleLogger().Write(logDEBUG) << "start_traversed_in_reverse: " << ( start_traversed_in_reverse ? "y" : "n" );
// SimpleLogger().Write() << "starting unpack";
const unsigned packed_path_size = packed_path.size(); const unsigned packed_path_size = packed_path.size();
std::stack<std::pair<NodeID, NodeID> > recursion_stack; std::stack<std::pair<NodeID, NodeID> > recursion_stack;
@ -155,42 +171,13 @@ public:
edge = recursion_stack.top(); edge = recursion_stack.top();
recursion_stack.pop(); recursion_stack.pop();
EdgeID smaller_edge_id = SPECIAL_EDGEID; EdgeID smaller_edge_id = facade->FindEdgeIndicateIfReverse(
int edge_weight = INT_MAX; edge.first,
for( edge.second,
EdgeID edge_id = facade->BeginEdges(edge.first); segment_reversed
edge_id < facade->EndEdges(edge.first); );
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
if( SPECIAL_EDGEID == smaller_edge_id ){ BOOST_ASSERT( SPECIAL_EDGEID != smaller_edge_id );
for(
EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.first) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
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
@ -201,11 +188,10 @@ public:
} else { } else {
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut"); BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id); unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id); const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
//TODO: refactor to iterate over a result vector in both cases //TODO: refactor to iterate over a result vector in both cases
if ( !facade->EdgeIsCompressed(ed.id) ){ if ( !facade->EdgeIsCompressed(ed.id) ){
SimpleLogger().Write() << "Edge " << ed.id << " is not compressed, smaller_edge_id: " << smaller_edge_id;
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) ); BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
unpacked_path.push_back( unpacked_path.push_back(
PathData( PathData(
@ -216,38 +202,74 @@ public:
) )
); );
} else { } else {
SimpleLogger().Write() << "Edge " << ed.id << " is compressed";
std::vector<unsigned> id_vector; std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(ed.id, id_vector); facade->GetUncompressedGeometry(ed.id, id_vector);
//TODO use only a single for loop
if( unpacked_path.empty() ) { if( unpacked_path.empty() ) {
SimpleLogger().Write(logDEBUG) << "first segment(" << facade->GetEscapedNameForNameID(ed.id) << ") is packed"; // // SimpleLogger().Write(logDEBUG) << "1st node in packed path: " << packed_path.front() << ", edge (" << edge.first << "," << edge.second << ")";
// // SimpleLogger().Write(logDEBUG) << "REVERSED1: " << ( facade->GetTarget(smaller_edge_id) != edge.second ? "y" : "n" );
// // SimpleLogger().Write(logDEBUG) << "REVERSED2: " << ( facade->GetTarget(smaller_edge_id) != edge.first ? "y" : "n" );
// SimpleLogger().Write(logDEBUG) << "segment_reversed: " << ( segment_reversed ? "y" : "n" );
// // SimpleLogger().Write(logDEBUG) << "target of edge: " << facade->GetTarget(smaller_edge_id);
// // SimpleLogger().Write(logDEBUG) << "first geometry: " << id_vector.front() << ", last geometry: " << id_vector.back();
const bool edge_is_reversed = (!ed.forward && ed.backward);
// if( edge_is_reversed ) {
// SimpleLogger().Write(logDEBUG) << "reversing geometry";
// std::reverse( id_vector.begin(), id_vector.end() );
// fwd_index_offset = id_vector.size() - (1+fwd_index_offset);
// SimpleLogger().Write() << "new fwd offset: " << fwd_index_offset;
// }
SimpleLogger().Write(logDEBUG) << "edge data fwd: " << (ed.forward ? "y": "n") << ", reverse: " << (ed.backward ? "y" : "n" );
SimpleLogger().Write() << "Edge " << ed.id << "=(" << edge.first << "," << edge.second << ") is compressed";
SimpleLogger().Write(logDEBUG) << "packed ids: ";
BOOST_FOREACH(unsigned number, id_vector) {
SimpleLogger().Write() << "[" << number << "] " << facade->GetCoordinateOfNode(number);
}
const int start_index = ( ( start_traversed_in_reverse ) ? fwd_index_offset : 0 );
const int end_index = ( ( start_traversed_in_reverse ) ? id_vector.size() : fwd_index_offset );
// BOOST_ASSERT( start_index >= 0 );
// // BOOST_ASSERT( start_index <= end_index );
SimpleLogger().Write(logDEBUG) << "geometry count: " << id_vector.size() << ", fetching[" << start_index << "..." << end_index << "]";
for(
unsigned i = start_index;
i != end_index;
(start_index > end_index) ? --i : ++i
) {
SimpleLogger().Write(logDEBUG) << "[" << i << "]pushing id: " << id_vector[i];
unpacked_path.push_back(
PathData(
id_vector[i],
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
} else {
BOOST_FOREACH(const unsigned coordinate_id, id_vector){
// SimpleLogger().Write(logDEBUG) << "pushing id: " << coordinate_id;
unpacked_path.push_back(
PathData(
coordinate_id,
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
unpacked_path.back().turnInstruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance;
} }
// if( recursion_stack.empty() ) {
// SimpleLogger().Write(logDEBUG) << "last segment is packed";
// }
BOOST_FOREACH(const unsigned coordinate_id, id_vector){
//TODO: skip if first edge is compressed until start point is reached
unpacked_path.push_back(
PathData(
coordinate_id,
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
unpacked_path.back().turnInstruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance;
} }
} }
} }
} }
inline void UnpackEdge( inline void UnpackEdge(
@ -319,8 +341,8 @@ public:
} }
inline void RetrievePackedPathFromHeap( inline void RetrievePackedPathFromHeap(
SearchEngineData::QueryHeap & forward_heap, const SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap & reverse_heap, const SearchEngineData::QueryHeap & reverse_heap,
const NodeID middle_node_id, const NodeID middle_node_id,
std::vector<NodeID> & packed_path std::vector<NodeID> & packed_path
) const { ) const {
@ -329,6 +351,7 @@ public:
current_node_id = forward_heap.GetData(current_node_id).parent; current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.push_back(current_node_id);
} }
//throw away first segment, unpack individually
std::reverse(packed_path.begin(), packed_path.end()); std::reverse(packed_path.begin(), packed_path.end());
packed_path.push_back(middle_node_id); packed_path.push_back(middle_node_id);

View File

@ -356,10 +356,17 @@ public:
std::swap( packed_legs1, packed_legs2 ); std::swap( packed_legs1, packed_legs2 );
} }
raw_route_data.unpacked_path_segments.resize( packed_legs1.size() ); raw_route_data.unpacked_path_segments.resize( packed_legs1.size() );
const int start_offset = ( packed_legs1[0].front() == phantom_nodes_vector.front().startPhantom.forward_node_id ? 1 : -1 )*phantom_nodes_vector.front().startPhantom.fwd_segment_position;
for(unsigned i = 0; i < packed_legs1.size(); ++i){ for(unsigned i = 0; i < packed_legs1.size(); ++i){
BOOST_ASSERT( !phantom_nodes_vector.empty() );
bool at_beginning = (0 == i);
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size() ); BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size() );
super::UnpackPath( super::UnpackPath(
packed_legs1[i], packed_legs1[i],
( at_beginning ? start_offset : 0),
0,
false,
raw_route_data.unpacked_path_segments[i] raw_route_data.unpacked_path_segments[i]
); );
} }

View File

@ -428,11 +428,13 @@ public:
PhantomNode & resulting_phantom_node, PhantomNode & resulting_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) const { ) const {
return m_static_rtree->FindPhantomNodeForCoordinate( // SimpleLogger().Write(logDEBUG) << "name id: " << resulting_phantom_node.name_id;
input_coordinate, const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
resulting_phantom_node, input_coordinate,
zoom_level resulting_phantom_node,
); zoom_level
);
return found;
} }
unsigned GetCheckSum() const { return m_check_sum; } unsigned GetCheckSum() const { return m_check_sum; }
@ -479,17 +481,17 @@ public:
const unsigned id, std::vector<unsigned> & result_nodes const unsigned id, std::vector<unsigned> & result_nodes
) const { ) const {
const NodeID node = m_via_node_list.at(id); const NodeID node = m_via_node_list.at(id);
SimpleLogger().Write() << "translated " << id << " to " << node; // SimpleLogger().Write() << "translated " << id << " to " << node;
SimpleLogger().Write() << "getting geometry from compression bucket " << node << "/" << m_compressed_geometry_indices.size(); // SimpleLogger().Write() << "getting geometry from compression bucket " << node << "/" << m_compressed_geometry_indices.size();
unsigned begin = m_compressed_geometry_indices.at(node); unsigned begin = m_compressed_geometry_indices.at(node);
unsigned end = m_compressed_geometry_indices.at(node+1); unsigned end = m_compressed_geometry_indices.at(node+1);
SimpleLogger().Write() << "bucket " << node << " has range [" << begin << "," << end-1 << "]"; // SimpleLogger().Write() << "bucket " << node << " has range [" << begin << "," << end-1 << "]";
//TODO: use vector.insert(.) //TODO: use vector.insert(.)
for(unsigned geometry_index = begin; geometry_index < end; ++geometry_index) { for(unsigned geometry_index = begin; geometry_index < end; ++geometry_index) {
unsigned coordinate_id = m_compressed_geometries[geometry_index]; unsigned coordinate_id = m_compressed_geometries[geometry_index];
// uncomment to use compressed geometry // uncomment to use compressed geometry
result_nodes.push_back( coordinate_id ); result_nodes.push_back( coordinate_id );
SimpleLogger().Write() << "coordinate " << coordinate_id << " at " << m_coordinate_list->at(coordinate_id); // SimpleLogger().Write() << "coordinate " << coordinate_id << " at " << m_coordinate_list->at(coordinate_id);
} }
} }

View File

@ -363,11 +363,21 @@ public:
PhantomNode & resulting_phantom_node, PhantomNode & resulting_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) const { ) const {
return m_static_rtree->FindPhantomNodeForCoordinate( const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate, input_coordinate,
resulting_phantom_node, resulting_phantom_node,
zoom_level zoom_level
); );
if ( found ) {
resulting_phantom_node.name_id = GetNameIndexFromEdgeID(
FindEdge(
resulting_phantom_node.forward_node_id,
resulting_phantom_node.reverse_node_id
)
);
}
return found;
} }
unsigned GetCheckSum() const { return m_check_sum; } unsigned GetCheckSum() const { return m_check_sum; }

View File

@ -269,6 +269,26 @@ int main (int argc, char *argv[]) {
edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList); edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
delete edgeBasedGraphFactory; delete edgeBasedGraphFactory;
double expansionHasFinishedTime = get_timestamp() - startupTime;
/***
* Building grid-like nearest-neighbor data structure
*/
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedNode> * rtree =
new StaticRTree<EdgeBasedNode>(
nodeBasedEdgeList,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str(),
internalToExternalNodeMapping
);
delete rtree;
IteratorbasedCRC32<std::vector<EdgeBasedNode> > crc32;
unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() );
nodeBasedEdgeList.clear();
std::vector<EdgeBasedNode>(nodeBasedEdgeList).swap(nodeBasedEdgeList);
SimpleLogger().Write() << "CRC32: " << crc32OfNodeBasedEdgeList;
/*** /***
* Writing info on original (node-based) nodes * Writing info on original (node-based) nodes
*/ */
@ -284,26 +304,6 @@ int main (int argc, char *argv[]) {
mapOutFile.close(); mapOutFile.close();
std::vector<NodeInfo>().swap(internalToExternalNodeMapping); std::vector<NodeInfo>().swap(internalToExternalNodeMapping);
double expansionHasFinishedTime = get_timestamp() - startupTime;
/***
* Building grid-like nearest-neighbor data structure
*/
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedNode> * rtree =
new StaticRTree<EdgeBasedNode>(
nodeBasedEdgeList,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str()
);
delete rtree;
IteratorbasedCRC32<std::vector<EdgeBasedNode> > crc32;
unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() );
nodeBasedEdgeList.clear();
std::vector<EdgeBasedNode>(nodeBasedEdgeList).swap(nodeBasedEdgeList);
SimpleLogger().Write() << "CRC32: " << crc32OfNodeBasedEdgeList;
/*** /***
* Contracting the edge-expanded graph * Contracting the edge-expanded graph
*/ */