From e6aaadf28f2bf335c51662e963c1470d57143c17 Mon Sep 17 00:00:00 2001 From: Arseny Novikov Date: Tue, 2 Aug 2022 01:05:49 +0300 Subject: [PATCH] [ios][android] Replacing altitude difference to ascent and descent (#3062) * [ios][android] Replacing altitude difference to ascent and descent The app for pedestrian and cyclists route show altitude difference between highest and lowest points. It's not too useful data in multiple cases. More informative for hikers and cyclists from values of elevation total ascent and total descent on route. I replaced altitude difference to total ascent and total descent. Routing: - Removed calculation of minRouteAltitude and maxRouteAltitude. Added calculation of totalAscent and totalDescent (map/routing_manager.cpp) iOS: - Replaced altitudeDifference to 2 separate value totalAscent and totalDescent android: - Replaced altitudeDifference to 2 separate value totalAscent and totalDescent - Removed unnessesary icon (ic_altitude_difference.webp) Signed-off-by: Arseny Novikov * Applying style guide to map/routing_manager.cpp Signed-off-by: Arseny Novikov * Fixes for route ascent/descent. Used unsigned var types and fix idents Changes based on pull request (organicmaps/organicmaps#3062) code review. - fixed idents - used uint32_t instead int32_t for totalAscent and totalDescent fields - replaced 2 guard variable initialization to one if Signed-off-by: Arseny Novikov * Route ascent/descent. Fixed field description, final to java constant. Signed-off-by: Arseny Novikov * Explicit cast from uint32_t to jint in jni for ascent/descent Signed-off-by: Arseny Novikov * [ios] Route ascent/descent. Moved font attributes to static field Signed-off-by: Arseny Novikov --- android/jni/com/mapswithme/maps/Framework.cpp | 18 ++++++------ .../drawable-hdpi/ic_altitude_difference.webp | Bin 88 -> 0 bytes .../drawable-mdpi/ic_altitude_difference.webp | Bin 118 -> 0 bytes .../ic_altitude_difference.webp | Bin 154 -> 0 bytes .../ic_altitude_difference.webp | Bin 114 -> 0 bytes .../ic_altitude_difference.webp | Bin 194 -> 0 bytes .../src/com/mapswithme/maps/Framework.java | 4 +-- .../routing/RoutingBottomMenuController.java | 15 +++------- .../BaseRoutePreviewStatus.swift | 20 ++++++++------ iphone/Maps/Core/Routing/MWMRouter.h | 2 +- iphone/Maps/Core/Routing/MWMRouter.mm | 21 ++++++++------ map/routing_manager.cpp | 26 ++++++++++++------ map/routing_manager.hpp | 9 +++--- 13 files changed, 61 insertions(+), 54 deletions(-) delete mode 100644 android/res/drawable-hdpi/ic_altitude_difference.webp delete mode 100644 android/res/drawable-mdpi/ic_altitude_difference.webp delete mode 100644 android/res/drawable-xhdpi/ic_altitude_difference.webp delete mode 100644 android/res/drawable-xxhdpi/ic_altitude_difference.webp delete mode 100644 android/res/drawable-xxxhdpi/ic_altitude_difference.webp diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 648a8abca8..e6efa7c152 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -1230,12 +1230,12 @@ Java_com_mapswithme_maps_Framework_nativeGenerateRouteAltitudeChartBits(JNIEnv * } vector imageRGBAData; - int32_t minRouteAltitude = 0; - int32_t maxRouteAltitude = 0; + uint32_t totalAscent = 0; + uint32_t totalDescent = 0; measurement_utils::Units units = measurement_utils::Units::Metric; if (!fr->GetRoutingManager().GenerateRouteAltitudeChart( width, height, altitudes, routePointDistanceM, imageRGBAData, - minRouteAltitude, maxRouteAltitude, units)) + totalAscent, totalDescent, units)) { LOG(LWARNING, ("Can't generate route altitude image.")); return nullptr; @@ -1245,13 +1245,13 @@ Java_com_mapswithme_maps_Framework_nativeGenerateRouteAltitudeChartBits(JNIEnv * jclass const routeAltitudeLimitsClass = env->GetObjectClass(routeAltitudeLimits); ASSERT(routeAltitudeLimitsClass, ()); - static jfieldID const minRouteAltitudeField = env->GetFieldID(routeAltitudeLimitsClass, "minRouteAltitude", "I"); - ASSERT(minRouteAltitudeField, ()); - env->SetIntField(routeAltitudeLimits, minRouteAltitudeField, minRouteAltitude); + static jfieldID const totalAscentField = env->GetFieldID(routeAltitudeLimitsClass, "totalAscent", "I"); + ASSERT(totalAscentField, ()); + env->SetIntField(routeAltitudeLimits, totalAscentField, static_cast(totalAscent)); - static jfieldID const maxRouteAltitudeField = env->GetFieldID(routeAltitudeLimitsClass, "maxRouteAltitude", "I"); - ASSERT(maxRouteAltitudeField, ()); - env->SetIntField(routeAltitudeLimits, maxRouteAltitudeField, maxRouteAltitude); + static jfieldID const totalDescentField = env->GetFieldID(routeAltitudeLimitsClass, "totalDescent", "I"); + ASSERT(totalDescentField, ()); + env->SetIntField(routeAltitudeLimits, totalDescentField, static_cast(totalDescent)); static jfieldID const isMetricUnitsField = env->GetFieldID(routeAltitudeLimitsClass, "isMetricUnits", "Z"); ASSERT(isMetricUnitsField, ()); diff --git a/android/res/drawable-hdpi/ic_altitude_difference.webp b/android/res/drawable-hdpi/ic_altitude_difference.webp deleted file mode 100644 index 261b1c8ff87e3a8ec72e8621de655079709929a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88 zcmV-e0H^;_Nk&Fc00012MM6+kP&iCP0000l7r+G&7cl?xKmP)PqUTHx_y`OlNpdou u0ST|>C7=T}NXXGT^rX|ew0ks7%rvLx| diff --git a/android/res/drawable-xhdpi/ic_altitude_difference.webp b/android/res/drawable-xhdpi/ic_altitude_difference.webp deleted file mode 100644 index 979e203606534abd0961be1bd8a87b0e09ada3a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmV;L0A>GDNk&GJ00012MM6+kP&iD50000lAHW9?hcN&1KmQ8aNK#|REaOSk2jGH% z;9+4f5C|B8K|t^!3dU_DDO$#({KMtzqxbe)ME@1JZQIB;klX0^g!&Stf@TuTVVaeJ z#BmN%HkpN##*_UdKS`@j%ZqR|z~ga4a}cWr@1zaQVXX9cE_fgC`y$gimBid>g&F=p IMSY0?034D>bpQYW diff --git a/android/res/drawable-xxhdpi/ic_altitude_difference.webp b/android/res/drawable-xxhdpi/ic_altitude_difference.webp deleted file mode 100644 index 697df0d6f9fe7339a46810e4ce47a3cab3312b4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmV-&0FD1rNk&F$00012MM6+kP&iCp0000lFTe{B7cl?xKmP)PqUTHx_z0{b+iG)D z74U@`?0_0Xq#mD-mI#RG{{-k)T~RCvOa+;};J_EWBr5=uk%8TiQ0eFRH~mKjb|V0j Up_e54z!zlpg1}Uus8Uz-gPZR#kN^Mx diff --git a/android/res/drawable-xxxhdpi/ic_altitude_difference.webp b/android/res/drawable-xxxhdpi/ic_altitude_difference.webp deleted file mode 100644 index 713ba646cdc21484ca8ecbeceab4336ca6ee8887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmV;z06qUwNk&Gx00012MM6+kP&iDj0000lKfn(VhcN&1KmUpvNm7H$cp~t55-tE2 zJO~080|Np9LohJ#F(GgyNp9Of0X6^|^#1?5jKw`!r-=SffIJl~$P5T71ArhhG=t`i zZjiiwJp_eeI0zh*zMWw@HghcWt @property(nonatomic) NSMutableDictionary *altitudeImagesData; -@property(nonatomic) NSString *altitudeElevation; +@property(nonatomic) NSString *totalAscent; +@property(nonatomic) NSString *totalDescent; @property(nonatomic) dispatch_queue_t renderAltitudeImagesQueue; @property(nonatomic) uint32_t routeManagerTransactionId; @property(nonatomic) BOOL canAutoAddLastLocation; @@ -370,13 +371,13 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm NSData *imageData = router.altitudeImagesData[sizeValue]; if (!imageData) { std::vector imageRGBAData; - int32_t minRouteAltitude = 0; - int32_t maxRouteAltitude = 0; + uint32_t totalAscent = 0; + uint32_t totalDescent = 0; measurement_utils::Units units = measurement_utils::Units::Metric; if (!GetFramework().GetRoutingManager().GenerateRouteAltitudeChart(width, height, *altitudes, *routePointDistanceM, imageRGBAData, - minRouteAltitude, maxRouteAltitude, units)) { + totalAscent, totalDescent, units)) { return; } @@ -386,15 +387,16 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm router.altitudeImagesData[sizeValue] = imageData; auto const localizedUnits = platform::GetLocalizedAltitudeUnits(); - auto const height = maxRouteAltitude - minRouteAltitude; - router.altitudeElevation = - @(measurement_utils::FormatAltitudeWithLocalization(height, localizedUnits.m_low).c_str()); + router.totalAscent = + @(measurement_utils::FormatAltitudeWithLocalization(totalAscent, localizedUnits.m_low).c_str()); + router.totalDescent = + @(measurement_utils::FormatAltitudeWithLocalization(totalDescent, localizedUnits.m_low).c_str()); } dispatch_async(dispatch_get_main_queue(), ^{ UIImage *altitudeImage = [UIImage imageWithRGBAData:imageData width:width height:height]; if (altitudeImage) - block(altitudeImage, router.altitudeElevation); + block(altitudeImage, router.totalAscent, router.totalDescent); }); }); } @@ -403,7 +405,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm auto router = self.router; dispatch_async(router.renderAltitudeImagesQueue, ^{ [router.altitudeImagesData removeAllObjects]; - router.altitudeElevation = nil; + router.totalAscent = nil; + router.totalDescent = nil; }); } diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index 1096cb27aa..12814a9eb2 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -1158,8 +1158,8 @@ bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, geometry::Altitudes const & altitudes, vector const & routePointDistanceM, vector & imageRGBAData, - int32_t & minRouteAltitude, - int32_t & maxRouteAltitude, + uint32_t & totalAscent, + uint32_t & totalDescent, measurement_utils::Units & altitudeUnits) const { CHECK_EQUAL(altitudes.size(), routePointDistanceM.size(), ()); @@ -1170,9 +1170,17 @@ bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, GetStyleReader().GetCurrentStyle(), imageRGBAData)) return false; - auto const minMaxIt = minmax_element(altitudes.cbegin(), altitudes.cend()); - geometry::Altitude const minRouteAltitudeM = *minMaxIt.first; - geometry::Altitude const maxRouteAltitudeM = *minMaxIt.second; + uint32_t totalAscentM = 0; + uint32_t totalDescentM = 0; + int16_t delta; + + for (size_t i = 1; i < altitudes.size(); i++) { + delta = altitudes[i] - altitudes[i - 1]; + if (delta > 0) + totalAscentM += delta; + else + totalDescentM += -delta; + } if (!settings::Get(settings::kMeasurementUnits, altitudeUnits)) altitudeUnits = measurement_utils::Units::Metric; @@ -1180,12 +1188,12 @@ bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, switch (altitudeUnits) { case measurement_utils::Units::Imperial: - minRouteAltitude = measurement_utils::MetersToFeet(minRouteAltitudeM); - maxRouteAltitude = measurement_utils::MetersToFeet(maxRouteAltitudeM); + totalAscent = measurement_utils::MetersToFeet(totalAscentM); + totalDescent = measurement_utils::MetersToFeet(totalDescentM); break; case measurement_utils::Units::Metric: - minRouteAltitude = minRouteAltitudeM; - maxRouteAltitude = maxRouteAltitudeM; + totalAscent = totalAscentM; + totalDescent = totalDescentM; break; } return true; diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index b127e84121..c0f1e2c80f 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -277,8 +277,8 @@ public: /// \param altitudes route points altitude. /// \param routePointDistanceM distance in meters from route beginning to route points. /// \param imageRGBAData is bits of result image in RGBA. - /// \param minRouteAltitude is min altitude along the route in altitudeUnits. - /// \param maxRouteAltitude is max altitude along the route in altitudeUnits. + /// \param totalAscent is total ascent of the route in altitudeUnits. + /// \param totalDescent is total descent of the route in altitudeUnits. /// \param altitudeUnits is units (meters or feet) which is used to pass min and max altitudes. /// \returns If there is valid route info and the chart was generated returns true /// and false otherwise. If the method returns true it is guaranteed that the size of @@ -288,8 +288,9 @@ public: bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, geometry::Altitudes const & altitudes, std::vector const & routePointDistanceM, - std::vector & imageRGBAData, int32_t & minRouteAltitude, - int32_t & maxRouteAltitude, + std::vector & imageRGBAData, + uint32_t & totalAscent, + uint32_t & totalDescent, measurement_utils::Units & altitudeUnits) const; uint32_t OpenRoutePointsTransaction();