diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 1527728339..8c4ac1a82f 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -27,6 +27,8 @@ #include "geometry/angles.hpp" +#include "indexer/feature_altitude.hpp" + #include "platform/country_file.hpp" #include "platform/local_country_file.hpp" #include "platform/local_country_file_utils.hpp" @@ -43,6 +45,7 @@ #include #include +#include using namespace std; using namespace std::placeholders; @@ -1103,12 +1106,21 @@ Java_com_mapswithme_maps_Framework_nativeGenerateRouteAltitudeChartBits(JNIEnv * ::Framework * fr = frm(); ASSERT(fr, ()); + feature::TAltitudes altitudes; + vector segDistanceM; + if (!fr->GetRoutingManager().GetRouteAltitudesAndDistancesM(segDistanceM, altitudes)) + { + LOG(LWARNING, ("Can't get distance to route points and altitude.")); + return nullptr; + } + vector imageRGBAData; int32_t minRouteAltitude = 0; int32_t maxRouteAltitude = 0; measurement_utils::Units units = measurement_utils::Units::Metric; if (!fr->GetRoutingManager().GenerateRouteAltitudeChart( - width, height, imageRGBAData, minRouteAltitude, maxRouteAltitude, units)) + width, height, altitudes, segDistanceM, imageRGBAData, + minRouteAltitude, maxRouteAltitude, units)) { LOG(LWARNING, ("Can't generate route altitude image.")); return nullptr; diff --git a/iphone/Maps/Core/Routing/MWMRouter.mm b/iphone/Maps/Core/Routing/MWMRouter.mm index ae71f5914d..ccfa41ff25 100644 --- a/iphone/Maps/Core/Routing/MWMRouter.mm +++ b/iphone/Maps/Core/Routing/MWMRouter.mm @@ -19,8 +19,12 @@ #include "Framework.h" +#include "indexer/feature_altitude.hpp" + #include "platform/local_country_file_utils.hpp" +#include + using namespace routing; @interface MWMRouter () @@ -517,21 +521,17 @@ void logPointEvent(MWMRoutePoint * point, NSString * eventType) + (void)routeAltitudeImageForSize:(CGSize)size completion:(MWMImageHeightBlock)block { - auto router = self.router; - // @TODO The method below is implemented on render renderAltitudeImagesQueue to prevent ui thread - // from heavy methods. On the other hand some of calls of the method should be done on ui thread. - // This method should be rewritten to perform on renderAltitudeImagesQueue only the heavest - // functions. Or all the method should be done on ui thread. - dispatch_async(router.renderAltitudeImagesQueue, ^{ + if (![self hasRouteAltitude]) + return; + + auto segDistanceM = make_shared>(std::vector()); + auto altitudes = make_shared(feature::TAltitudes()); + if (!GetFramework().GetRoutingManager().GetRouteAltitudesAndDistancesM(*segDistanceM, *altitudes)) + return; + + // Note. |segDistanceM| and |altitudes| should not be used in the method after line below. + dispatch_async(self.router.renderAltitudeImagesQueue, [=] () { auto router = self.router; - - bool hasAltitude = false; - dispatch_sync(dispatch_get_main_queue(), [self, &hasAltitude]{ - hasAltitude = [self hasRouteAltitude]; - }); - if (!hasAltitude) - return; - CGFloat const screenScale = [UIScreen mainScreen].scale; CGSize const scaledSize = {size.width * screenScale, size.height * screenScale}; CHECK_GREATER_OR_EQUAL(scaledSize.width, 0.0, ()); @@ -550,12 +550,12 @@ void logPointEvent(MWMRoutePoint * point, NSString * eventType) int32_t maxRouteAltitude = 0; measurement_utils::Units units = measurement_utils::Units::Metric; bool result = false; - dispatch_sync(dispatch_get_main_queue(), [&] { - result = GetFramework().GetRoutingManager().GenerateRouteAltitudeChart(width, height, - imageRGBAData, - minRouteAltitude, - maxRouteAltitude, units); - }); + result = GetFramework().GetRoutingManager().GenerateRouteAltitudeChart(width, height, + *altitudes, + *segDistanceM, + imageRGBAData, + minRouteAltitude, + maxRouteAltitude, units); if (!result) return; diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index dfd353c902..e9768727c4 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -1000,19 +1000,25 @@ bool RoutingManager::HasRouteAltitude() const return m_loadAltitudes && m_routingSession.HasRouteAltitude(); } +bool RoutingManager::GetRouteAltitudesAndDistancesM(vector & segDistanceM, + feature::TAltitudes & altitudes) const +{ + if (!m_routingSession.GetRouteAltitudesAndDistancesM(segDistanceM, altitudes)) + return false; + + segDistanceM.insert(segDistanceM.begin(), 0.0); + return true; +} + bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, + feature::TAltitudes const & altitudes, + vector const & segDistance, vector & imageRGBAData, int32_t & minRouteAltitude, int32_t & maxRouteAltitude, measurement_utils::Units & altitudeUnits) const { - feature::TAltitudes altitudes; - vector segDistance; - - if (!m_routingSession.GetRouteAltitudesAndDistancesM(segDistance, altitudes)) - return false; - segDistance.insert(segDistance.begin(), 0.0); - + CHECK_EQUAL(altitudes.size(), segDistance.size(), ()); if (altitudes.empty()) return false; diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index f785cce0f2..046a226031 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -225,9 +225,16 @@ public: /// false otherwise. bool HasRouteAltitude() const; + /// \brief Fills altitude of current route points and distance form the beginning in meters + /// of the route point. + bool GetRouteAltitudesAndDistancesM(vector & segDistanceM, + feature::TAltitudes & altitudes) const; + /// \brief Generates 4 bytes per point image (RGBA) and put the data to |imageRGBAData|. /// \param width is width of chart shall be generated in pixels. /// \param height is height of chart shall be generated in pixels. + /// \param altitudes route points altitude. + /// \param segDistance distance in meters from route beginning to end of segments. /// \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. @@ -237,8 +244,11 @@ public: /// |imageRGBAData| is not zero. /// \note If HasRouteAltitude() method returns true, GenerateRouteAltitudeChart(...) /// could return false if route was deleted or rebuilt between the calls. - bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, std::vector & imageRGBAData, - int32_t & minRouteAltitude, int32_t & maxRouteAltitude, + bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, + feature::TAltitudes const & altitudes, + vector const & segDistance, + std::vector & imageRGBAData, int32_t & minRouteAltitude, + int32_t & maxRouteAltitude, measurement_utils::Units & altitudeUnits) const; uint32_t OpenRoutePointsTransaction();