From 97f93972c7c3d6e57c12ed7f52575b540bc08990 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 9 Oct 2014 18:58:58 +0200 Subject: [PATCH] use double precision fp math for mercartor projection and point-line projections (for now), fixes #1191 --- DataStructures/Coordinate.cpp | 26 +++++++++++++------------- Util/MercatorUtil.h | 8 ++++---- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/DataStructures/Coordinate.cpp b/DataStructures/Coordinate.cpp index c213dc9ef97..e33727c3ed6 100644 --- a/DataStructures/Coordinate.cpp +++ b/DataStructures/Coordinate.cpp @@ -258,16 +258,16 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin BOOST_ASSERT(query_location.isValid()); // initialize values - const float x = lat2y(query_location.lat / COORDINATE_PRECISION); - const float y = query_location.lon / COORDINATE_PRECISION; - const float a = lat2y(segment_source.lat / COORDINATE_PRECISION); - const float b = segment_source.lon / COORDINATE_PRECISION; - const float c = lat2y(segment_target.lat / COORDINATE_PRECISION); - const float d = segment_target.lon / COORDINATE_PRECISION; - float p, q /*,mX*/, nY; - if (std::abs(a - c) > std::numeric_limits::epsilon()) + const double x = lat2y(query_location.lat / COORDINATE_PRECISION); + const double y = query_location.lon / COORDINATE_PRECISION; + const double a = lat2y(segment_source.lat / COORDINATE_PRECISION); + const double b = segment_source.lon / COORDINATE_PRECISION; + const double c = lat2y(segment_target.lat / COORDINATE_PRECISION); + const double d = segment_target.lon / COORDINATE_PRECISION; + double p, q /*,mX*/, nY; + if (std::abs(a - c) > std::numeric_limits::epsilon()) { - const float m = (d - b) / (c - a); // slope + 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.f + m * m); q = b + m * (p - a); @@ -293,11 +293,11 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin { ratio = (segment_target == query_location ? 1.f : 0.f); } - else if (std::abs(ratio) <= std::numeric_limits::epsilon()) + else if (std::abs(ratio) <= std::numeric_limits::epsilon()) { - ratio = 0.; + ratio = 0.f; } - else if (std::abs(ratio - 1.f) <= std::numeric_limits::epsilon()) + else if (std::abs(ratio - 1.f) <= std::numeric_limits::epsilon()) { ratio = 1.f; } @@ -308,7 +308,7 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin { nearest_location = segment_source; } - else if (ratio >= 1.) + else if (ratio >= 1.f) { nearest_location = segment_target; } diff --git a/Util/MercatorUtil.h b/Util/MercatorUtil.h index 31d1139bef3..b4a15b779cc 100644 --- a/Util/MercatorUtil.h +++ b/Util/MercatorUtil.h @@ -30,14 +30,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -inline float y2lat(const float a) +inline double y2lat(const double a) { - return 180.f * static_cast(M_1_PI) * (2.f * std::atan(std::exp(a * static_cast(M_PI) / 180.f)) - static_cast(M_PI_2)); + return 180. * M_1_PI * (2. * std::atan(std::exp(a * M_PI / 180.)) - M_PI_2); } -inline float lat2y(const float a) +inline double lat2y(const double a) { - return 180.f * static_cast(M_1_PI) * std::log(std::tan(static_cast(M_PI_4) + a * (static_cast(M_PI) / 180.f) / 2.f)); + return 180. * M_1_PI * std::log(std::tan(M_PI_4 + a * (M_PI / 180.) / 2.)); } #endif // MERCATOR_UTIL_H