From 35f7b90ae6d4f9c82f75d69ab7de3ef4237625e0 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Tue, 17 Dec 2024 19:32:32 +0400 Subject: [PATCH] [map] [geometry] fix track length calculation Signed-off-by: Kiryl Kaveryn --- geometry/point_with_altitude.cpp | 10 ++++++++++ geometry/point_with_altitude.hpp | 1 + map/map_tests/bookmarks_test.cpp | 4 ++-- map/track.cpp | 12 ++++++------ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/geometry/point_with_altitude.cpp b/geometry/point_with_altitude.cpp index 4ace90c568..a689524123 100644 --- a/geometry/point_with_altitude.cpp +++ b/geometry/point_with_altitude.cpp @@ -1,4 +1,7 @@ #include "geometry/point_with_altitude.hpp" +#include "geometry/mercator.hpp" + +#include "base/math.hpp" #include "std/boost_container_hash.hpp" @@ -46,6 +49,13 @@ bool AlmostEqualAbs(PointWithAltitude const & lhs, PointWithAltitude const & rhs { return AlmostEqualAbs(lhs.GetPoint(), rhs.GetPoint(), eps) && lhs.GetAltitude() == rhs.GetAltitude(); } + +double Distance(PointWithAltitude const & p1, PointWithAltitude const & p2) +{ + auto const projection = mercator::DistanceOnEarth(p1.GetPoint(), p2.GetPoint()); + auto const altitudeDifference = p2.GetAltitude() - p1.GetAltitude(); + return std::sqrt(base::Pow2(projection) + base::Pow2(altitudeDifference)); +} } // namespace geometry namespace std diff --git a/geometry/point_with_altitude.hpp b/geometry/point_with_altitude.hpp index 4fa50e81c2..7397e46bd1 100644 --- a/geometry/point_with_altitude.hpp +++ b/geometry/point_with_altitude.hpp @@ -47,6 +47,7 @@ inline m2::PointD GetPoint(PointWithAltitude const & pwa) { return pwa.GetPoint( PointWithAltitude MakePointWithAltitudeForTesting(m2::PointD const & point); bool AlmostEqualAbs(PointWithAltitude const & lhs, PointWithAltitude const & rhs, double eps); +double Distance(PointWithAltitude const & p1, PointWithAltitude const & p2); } // namespace geometry namespace std diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp index 0107c4a5da..39d6c29e0b 100644 --- a/map/map_tests/bookmarks_test.cpp +++ b/map/map_tests/bookmarks_test.cpp @@ -1149,7 +1149,7 @@ UNIT_CLASS_TEST(Runner, TrackParsingTest_1) dp::Color(171, 230, 0, 255), dp::Color(0, 230, 117, 255), dp::Color(0, 59, 230, 255)}}; - array constexpr length = {{3525.46839061, 27172.44338132, 27046.0456586, 23967.35765800}}; + array constexpr length = {{3525.77, 27193.9, 27048.7, 23971.1}}; array constexpr altitudes = {{0, 27, -3, -2}}; size_t i = 0; for (auto const trackId : bmManager.GetTrackIds(catId)) @@ -1159,7 +1159,7 @@ UNIT_CLASS_TEST(Runner, TrackParsingTest_1) TEST_EQUAL(geom[0].GetAltitude(), altitudes[i], ()); TEST_EQUAL(names[i], track->GetName(), ()); - TEST_ALMOST_EQUAL_ABS(track->GetLengthMeters(), length[i], 1.0E-6, ()); + TEST_ALMOST_EQUAL_ABS(track->GetLengthMeters(), length[i], 1.0E-1, ()); TEST_GREATER(track->GetLayerCount(), 0, ()); TEST_EQUAL(col[i], track->GetColor(0), ()); ++i; diff --git a/map/track.cpp b/map/track.cpp index fcdd167e55..1f1003b0cc 100644 --- a/map/track.cpp +++ b/map/track.cpp @@ -17,9 +17,9 @@ double GetLengthInMeters(kml::MultiGeometry::LineT const & points, size_t pointI double length = 0.0; for (size_t i = 1; i <= pointIndex; ++i) { - auto const & pt1 = points[i - 1].GetPoint(); - auto const & pt2 = points[i].GetPoint(); - auto const segmentLength = mercator::DistanceOnEarth(pt1, pt2); + auto const & pt1 = points[i - 1]; + auto const & pt2 = points[i]; + auto const segmentLength = geometry::Distance(pt1, pt2); length += segmentLength; } return length; @@ -51,9 +51,9 @@ std::vector Track::GetLengthsImpl() const lineLengths.emplace_back(distance); for (size_t j = 1; j < line.size(); ++j) { - auto const & pt1 = line[j - 1].GetPoint(); - auto const & pt2 = line[j].GetPoint(); - distance += mercator::DistanceOnEarth(pt1, pt2); + auto const & pt1 = line[j - 1]; + auto const & pt2 = line[j]; + distance += geometry::Distance(pt1, pt2); lineLengths.emplace_back(distance); } lengths.emplace_back(std::move(lineLengths)); -- 2.45.3