applied requested changes to EdgeBasedNode.h
This commit is contained in:
parent
b465dabe77
commit
f923f508f5
@ -9,176 +9,166 @@
|
|||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#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.
|
||||||
struct EdgeBasedNode {
|
struct EdgeBasedNode {
|
||||||
|
|
||||||
EdgeBasedNode() :
|
EdgeBasedNode() :
|
||||||
id(INT_MAX),
|
id(INT_MAX),
|
||||||
lat1(INT_MAX),
|
lat1(INT_MAX),
|
||||||
lat2(INT_MAX),
|
lat2(INT_MAX),
|
||||||
lon1(INT_MAX),
|
lon1(INT_MAX),
|
||||||
lon2(INT_MAX >> 1),
|
lon2(INT_MAX >> 1),
|
||||||
belongsToTinyComponent(false),
|
belongsToTinyComponent(false),
|
||||||
nameID(UINT_MAX),
|
nameID(UINT_MAX),
|
||||||
weight(UINT_MAX >> 1),
|
weight(UINT_MAX >> 1),
|
||||||
ignoreInGrid(false)
|
ignoreInGrid(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// 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
|
// - the location on this edge which is nearest to the query location
|
||||||
// - the ratio ps:pq, where p and q are the end points of this edge, and s is the perpendicular foot of
|
// - the ratio ps:pq, where p and q are the end points of this edge, and s is the perpendicular foot of
|
||||||
// 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 & ratio,
|
||||||
double precision = COORDINATE_PRECISION
|
double precision = COORDINATE_PRECISION
|
||||||
) const {
|
) const {
|
||||||
BOOST_ASSERT( query_location.isValid() );
|
BOOST_ASSERT( query_location.isValid() );
|
||||||
|
|
||||||
double epsilon = 1.0/COORDINATE_PRECISION;
|
const double epsilon = 1.0/COORDINATE_PRECISION;
|
||||||
|
|
||||||
if( ignoreInGrid ) {
|
if( ignoreInGrid ) {
|
||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
const Point p(lat2y(lat1/COORDINATE_PRECISION), lon1/COORDINATE_PRECISION);
|
||||||
const Point q(lat2y(lat2/COORDINATE_PRECISION), lon2/COORDINATE_PRECISION);
|
const Point q(lat2y(lat2/COORDINATE_PRECISION), lon2/COORDINATE_PRECISION);
|
||||||
|
|
||||||
// r : query location
|
// r : query location
|
||||||
const Point r(lat2y(query_location.lat/COORDINATE_PRECISION),
|
const Point r(lat2y(query_location.lat/COORDINATE_PRECISION),
|
||||||
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 = ComputeNearestPointOnSegment(foot, ratio);
|
nearest_location = ComputeNearestPointOnSegment(foot, ratio);
|
||||||
|
|
||||||
BOOST_ASSERT( nearest_location.isValid() );
|
BOOST_ASSERT( nearest_location.isValid() );
|
||||||
|
|
||||||
// TODO: Replace with euclidean approximation when k-NN search is done
|
// TODO: Replace with euclidean approximation when k-NN search is done
|
||||||
// const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
|
// const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||||
const double approximated_distance =
|
const double approximated_distance = FixedPointCoordinate::ApproximateDistance(query_location, nearest_location);
|
||||||
FixedPointCoordinate::ApproximateDistance(query_location, nearest_location);
|
|
||||||
|
|
||||||
BOOST_ASSERT( 0. <= approximated_distance );
|
BOOST_ASSERT( 0.0 <= approximated_distance );
|
||||||
return approximated_distance;
|
return approximated_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const EdgeBasedNode & other) const {
|
bool operator<(const EdgeBasedNode & other) const {
|
||||||
return other.id < id;
|
return other.id < id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const EdgeBasedNode & other) const {
|
bool operator==(const EdgeBasedNode & other) const {
|
||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the midpoint of the underlying edge.
|
// Returns the midpoint of the underlying edge.
|
||||||
inline FixedPointCoordinate Centroid() const {
|
inline FixedPointCoordinate Centroid() const {
|
||||||
return FixedPointCoordinate((lat1+lat2)/2, (lon1+lon2)/2);
|
return FixedPointCoordinate((lat1+lat2)/2, (lon1+lon2)/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID id;
|
NodeID 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 lat2;
|
||||||
int lon1;
|
int lon1;
|
||||||
int lon2:31;
|
int lon2:31;
|
||||||
|
|
||||||
bool belongsToTinyComponent:1;
|
bool belongsToTinyComponent:1;
|
||||||
NodeID nameID;
|
NodeID nameID;
|
||||||
|
|
||||||
// The weight of the underlying edge.
|
// The weight of the underlying edge.
|
||||||
unsigned weight:31;
|
unsigned weight:31;
|
||||||
|
|
||||||
bool ignoreInGrid:1;
|
bool ignoreInGrid:1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct Point
|
typedef std::pair<double,double> Point;
|
||||||
{
|
|
||||||
const double x;
|
|
||||||
const double y;
|
|
||||||
|
|
||||||
Point(double x, double y)
|
|
||||||
: x(x), y(y) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the perpendicular foot of point r on the line defined by p and q.
|
// Compute the perpendicular foot of point r on the line defined by p and q.
|
||||||
Point ComputePerpendicularFoot(const Point &p, const Point &q, const Point &r, double epsilon) const {
|
Point ComputePerpendicularFoot(const Point &p, const Point &q, const Point &r, double epsilon) const {
|
||||||
|
|
||||||
// the projection of r onto the line pq
|
// the projection of r onto the line pq
|
||||||
double foot_x;
|
double foot_x, foot_y;
|
||||||
double foot_y;
|
|
||||||
|
|
||||||
const bool parallel_to_y_axis = std::abs(q.x - p.x) < epsilon;
|
const bool is_parallel_to_y_axis = std::abs(q.first - p.first) < epsilon;
|
||||||
|
|
||||||
if( parallel_to_y_axis ) {
|
if( is_parallel_to_y_axis ) {
|
||||||
foot_x = q.x;
|
foot_x = q.first;
|
||||||
foot_y = r.y;
|
foot_y = r.second;
|
||||||
} else {
|
} else {
|
||||||
// the slope of the line through (a|b) and (c|d)
|
// the slope of the line through (a|b) and (c|d)
|
||||||
const double m = (q.y - p.y) / (q.x - p.x);
|
const double m = (q.second - p.second) / (q.first - p.first);
|
||||||
|
|
||||||
// Projection of (x|y) onto the line joining (a|b) and (c|d).
|
// Projection of (x|y) onto the line joining (a|b) and (c|d).
|
||||||
foot_x = ((r.x + (m*r.y)) + (m*m*p.x - m*p.y))/(1.0 + m*m);
|
foot_x = ((r.first + (m*r.second)) + (m*m*p.first - m*p.second))/(1.0 + m*m);
|
||||||
foot_y = p.y + m*(foot_x - p.x);
|
foot_y = p.second + m*(foot_x - p.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Point(foot_x, foot_y);
|
return Point(foot_x, foot_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the ratio of the line segment pr to line segment pq.
|
// Compute the ratio of the line segment pr to line segment pq.
|
||||||
double ComputeRatio(const Point & p, const Point & q, const Point & r, double epsilon) const {
|
double ComputeRatio(const Point & p, const Point & q, const Point & r, double epsilon) const {
|
||||||
|
|
||||||
const bool parallel_to_x_axis = std::abs(q.y-p.y) < epsilon;
|
const bool is_parallel_to_x_axis = std::abs(q.second-p.second) < epsilon;
|
||||||
const bool parallel_to_y_axis = std::abs(q.x-p.x) < epsilon;
|
const bool is_parallel_to_y_axis = std::abs(q.first-p.first) < epsilon;
|
||||||
|
|
||||||
double ratio;
|
double ratio;
|
||||||
|
|
||||||
if( !parallel_to_y_axis ) {
|
if( !is_parallel_to_y_axis ) {
|
||||||
ratio = (r.x - p.x)/(q.x - p.x);
|
ratio = (r.first - p.first)/(q.first - p.first);
|
||||||
} else if( !parallel_to_x_axis ) {
|
} else if( !is_parallel_to_x_axis ) {
|
||||||
ratio = (r.y - p.y)/(q.y - p.y);
|
ratio = (r.second - p.second)/(q.second - p.second);
|
||||||
} else {
|
} else {
|
||||||
// (a|b) and (c|d) are essentially the same point
|
// (a|b) and (c|d) are essentially the same point
|
||||||
// by convention, we set the ratio to 0 in this case
|
// by convention, we set the ratio to 0 in this case
|
||||||
//ratio = ((lat2 == query_location.lat) && (lon2 == query_location.lon)) ? 1. : 0.;
|
//ratio = ((lat2 == query_location.lat) && (lon2 == query_location.lon)) ? 1. : 0.;
|
||||||
ratio = 0.0;
|
ratio = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round to integer if the ratio is close to 0 or 1.
|
// Round to integer if the ratio is close to 0 or 1.
|
||||||
if( std::abs(ratio) <= epsilon ) {
|
if( std::abs(ratio) <= epsilon ) {
|
||||||
ratio = 0.0;
|
ratio = 0.0;
|
||||||
} else if( std::abs(ratio-1.0) <= epsilon ) {
|
} else if( std::abs(ratio-1.0) <= epsilon ) {
|
||||||
ratio = 1.0;
|
ratio = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ratio;
|
return ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the point on the segment pq which is nearest to a point r = p + lambda * (q-p).
|
// Computes the point on the segment pq which is nearest to a point r = p + lambda * (q-p).
|
||||||
// p and q are the end points of the underlying edge.
|
// p and q are the end points of the underlying edge.
|
||||||
FixedPointCoordinate ComputeNearestPointOnSegment(const Point & r, double lambda) const {
|
FixedPointCoordinate ComputeNearestPointOnSegment(const Point & r, double lambda) const {
|
||||||
|
|
||||||
if( lambda <= 0.0 ) {
|
if( lambda <= 0.0 ) {
|
||||||
return FixedPointCoordinate(lat1, lon1);
|
return FixedPointCoordinate(lat1, lon1);
|
||||||
} else if( lambda >= 1.0 ) {
|
} else if( lambda >= 1.0 ) {
|
||||||
return FixedPointCoordinate(lat2, lon2);
|
return FixedPointCoordinate(lat2, lon2);
|
||||||
} else {
|
} else {
|
||||||
// r lies between p and q
|
// r lies between p and q
|
||||||
return FixedPointCoordinate(y2lat(r.x)*COORDINATE_PRECISION,
|
return FixedPointCoordinate(y2lat(r.first)*COORDINATE_PRECISION,
|
||||||
r.y*COORDINATE_PRECISION);
|
r.second*COORDINATE_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user