diff --git a/android/app/src/main/cpp/app/organicmaps/Framework.cpp b/android/app/src/main/cpp/app/organicmaps/Framework.cpp index 1086106d5..581986277 100644 --- a/android/app/src/main/cpp/app/organicmaps/Framework.cpp +++ b/android/app/src/main/cpp/app/organicmaps/Framework.cpp @@ -1297,7 +1297,7 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass) JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_Framework_nativeGetRouteJunctionPoints(JNIEnv * env, jclass) { - vector junctionPoints; + vector junctionPoints; if (!frm()->GetRoutingManager().RoutingSession().GetRouteJunctionPoints(junctionPoints)) { LOG(LWARNING, ("Can't get the route junction points")); diff --git a/android/app/src/main/cpp/app/organicmaps/sdk/routing/JunctionInfo.hpp b/android/app/src/main/cpp/app/organicmaps/sdk/routing/JunctionInfo.hpp index 8e8ac8101..328b7d9fa 100644 --- a/android/app/src/main/cpp/app/organicmaps/sdk/routing/JunctionInfo.hpp +++ b/android/app/src/main/cpp/app/organicmaps/sdk/routing/JunctionInfo.hpp @@ -2,19 +2,20 @@ #include "app/organicmaps/core/jni_helper.hpp" -#include "geometry/point2d.hpp" +#include "geometry/point_with_altitude.hpp" #include -jobjectArray CreateJunctionInfoArray(JNIEnv * env, std::vector const & junctionPoints) +jobjectArray CreateJunctionInfoArray(JNIEnv * env, std::vector const & junctionPoints) { static jclass const junctionClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/JunctionInfo"); // Java signature : JunctionInfo(double lat, double lon) static jmethodID const junctionConstructor = jni::GetConstructorID(env, junctionClazz, "(DD)V"); return jni::ToJavaArray(env, junctionClazz, junctionPoints, - [](JNIEnv * env, m2::PointD const & point) + [](JNIEnv * env, geometry::PointWithAltitude const & pointWithAltitude) { + auto & point = pointWithAltitude.GetPoint(); return env->NewObject(junctionClazz, junctionConstructor, mercator::YToLat(point.y), mercator::XToLon(point.x)); }); diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 057dc8b48..6951edb47 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -1181,8 +1181,10 @@ std::string BookmarkManager::GenerateSavedRouteName(std::string const & from, st return GenerateTrackRecordingName(); } -kml::TrackId BookmarkManager::SaveRoute(std::vector const & points, std::string const & from, std::string const & to) +kml::TrackId BookmarkManager::SaveRoute(std::vector const & points, std::string const & from, std::string const & to) { + CHECK(!points.empty(), ("Route points should not be empty")); + kml::MultiGeometry geometry; geometry.m_lines.emplace_back(); geometry.m_timestamps.emplace_back(); diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index d4f6822c0..faeaffa3e 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -435,7 +435,7 @@ public: std::string GenerateTrackRecordingName() const; dp::Color GenerateTrackRecordingColor() const; - kml::TrackId SaveRoute(std::vector const & points, std::string const & from, std::string const & to); + kml::TrackId SaveRoute(std::vector const & points, std::string const & from, std::string const & to); private: class MarksChangesTracker : public df::UserMarksProvider diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp index 8fb51b381..ebea4995e 100644 --- a/map/map_tests/bookmarks_test.cpp +++ b/map/map_tests/bookmarks_test.cpp @@ -1644,12 +1644,12 @@ UNIT_CLASS_TEST(Runner, Bookmarks_TestSaveRoute) { BookmarkManager bmManager(BM_CALLBACKS); bmManager.EnableTestMode(true); - auto const points = {m2::PointD(0.0, 0.0), m2::PointD(0.001, 0.001)}; + auto const points = {geometry::PointWithAltitude({0.0, 0.0}, 0.0), geometry::PointWithAltitude({0.001, 0.001}, 0.001)}; auto const trackId = bmManager.SaveRoute(points, "London", "Paris"); auto const * track = bmManager.GetTrack(trackId); TEST_EQUAL(track->GetName(), "London - Paris", ()); auto const line = track->GetData().m_geometry.m_lines[0]; - std::vector const expectedLine = {{geometry::PointWithAltitude(m2::PointD(0.0, 0.0)), geometry::PointWithAltitude(m2::PointD(0.001, 0.001))}}; + std::vector const expectedLine = {{geometry::PointWithAltitude(m2::PointD(0.0, 0.0), 0.0), geometry::PointWithAltitude(m2::PointD(0.001, 0.001), 0.001)}}; TEST_EQUAL(line, expectedLine, ()); } diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index 5620f376f..f477489cf 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -1100,16 +1100,26 @@ static std::string GetNameFromPoint(RouteMarkData const & rmd) kml::TrackId RoutingManager::SaveRoute() { - auto points = GetRoutePolyline().GetPolyline().GetPoints(); + std::vector junctions; + RoutingSession().GetRouteJunctionPoints(junctions); + + junctions.erase( + std::unique( + junctions.begin(), + junctions.end(), + [](const geometry::PointWithAltitude & p1, const geometry::PointWithAltitude & p2) + { + return AlmostEqualAbs(p1, p2, kMwmPointAccuracy); + } + ), + junctions.end() + ); + auto const routePoints = GetRoutePoints(); std::string const from = GetNameFromPoint(routePoints.front()); std::string const to = GetNameFromPoint(routePoints.back()); - // remove equal sequential points - points.erase( - std::unique(points.begin(), points.end(), [](const m2::PointD & p1, const m2::PointD & p2) { return AlmostEqualAbs(p1, p2, kMwmPointAccuracy); }), - points.end()); - return m_bmManager->SaveRoute(points, from, to); + return m_bmManager->SaveRoute(junctions, from, to); } bool RoutingManager::DisableFollowMode() diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index 2068825f8..1629ba8f2 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -801,7 +801,7 @@ bool RoutingSession::IsRouteValid() const return m_route && m_route->IsValid(); } -bool RoutingSession::GetRouteJunctionPoints(std::vector & routeJunctionPoints) const +bool RoutingSession::GetRouteJunctionPoints(std::vector & routeJunctionPoints) const { CHECK_THREAD_CHECKER(m_threadChecker, ()); ASSERT(m_route, ()); @@ -815,7 +815,7 @@ bool RoutingSession::GetRouteJunctionPoints(std::vector & routeJunct for (size_t i = 0; i < segments.size(); ++i) { auto const & junction = segments[i].GetJunction(); - routeJunctionPoints.push_back(junction.GetPoint()); + routeJunctionPoints.push_back(junction); } ASSERT_EQUAL(routeJunctionPoints.size(), routeJunctionPoints.size(), ()); diff --git a/routing/routing_session.hpp b/routing/routing_session.hpp index 41b517977..a186e3e77 100644 --- a/routing/routing_session.hpp +++ b/routing/routing_session.hpp @@ -94,9 +94,9 @@ public: bool GetRouteAltitudesAndDistancesM(std::vector & routeSegDistanceM, geometry::Altitudes & routeAltitudesM) const; - /// \brief returns coordinates of route junctions. + /// \brief returns points of route junctions. /// \returns true if there is valid route information. If the route is not valid returns false. - bool GetRouteJunctionPoints(std::vector & routeJunctionPoints) const; + bool GetRouteJunctionPoints(std::vector & routeJunctionPoints) const; SessionState OnLocationPositionChanged(location::GpsInfo const & info); void GetRouteFollowingInfo(FollowingInfo & info) const;