[ios][android] Replacing altitude difference to ascent and descent #3062

Merged
ArsenyN merged 6 commits from master into master 2022-08-01 22:05:50 +00:00
13 changed files with 61 additions and 54 deletions

View file

@ -1230,12 +1230,12 @@ Java_com_mapswithme_maps_Framework_nativeGenerateRouteAltitudeChartBits(JNIEnv *
}
vector<uint8_t> 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<jint>(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<jint>(totalDescent));
static jfieldID const isMetricUnitsField = env->GetFieldID(routeAltitudeLimitsClass, "isMetricUnits", "Z");
ASSERT(isMetricUnitsField, ());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

View file

@ -112,8 +112,8 @@ public class Framework
public static class RouteAltitudeLimits
{
public int minRouteAltitude;
public int maxRouteAltitude;
public int totalAscent;
public int totalDescent;
public boolean isMetricUnits;
}

View file

@ -264,17 +264,10 @@ final class RoutingBottomMenuController implements View.OnClickListener
{
mAltitudeChart.setImageBitmap(bm);
biodranik commented 2022-07-31 11:46:35 +00:00 (Migrated from github.com)
Review

Looks like there are tabs and spaces mixed in the indentation. Please set the editor to use 2 spaces instead of tabs, and check/fix indentation in all your changes.

Looks like there are tabs and spaces mixed in the indentation. Please set the editor to use 2 spaces instead of tabs, and check/fix indentation in all your changes.
biodranik commented 2022-07-31 11:48:06 +00:00 (Migrated from github.com)
Review

This call is unnecessary in the metric system, and the previous call is useless in the imperial one. Please rewrite the code without unnecessary function calls. We want to have the fastest app that eats less battery 😉

This call is unnecessary in the metric system, and the previous call is useless in the imperial one. Please rewrite the code without unnecessary function calls. We want to have _the fastest_ app that eats _less_ battery 😉
ArsenyN commented 2022-08-01 05:48:50 +00:00 (Migrated from github.com)
Review

Fixed at d80c3a0

Fixed at d80c3a0
ArsenyN commented 2022-08-01 05:51:10 +00:00 (Migrated from github.com)
Review

Removed unnecessary function calls d80c3a0

Removed unnecessary function calls d80c3a0
UiUtils.show(mAltitudeChart);
String meter = mAltitudeDifference.getResources().getString(R.string.meter);
String foot = mAltitudeDifference.getResources().getString(R.string.foot);
mAltitudeDifference.setText(String.format(Locale.getDefault(), "%d %s",
limits.maxRouteAltitude - limits.minRouteAltitude,
limits.isMetricUnits ? meter : foot));
Drawable icon = ContextCompat.getDrawable(mContext,
R.drawable.ic_altitude_difference);
int colorAccent = ContextCompat.getColor(mContext,
UiUtils.getStyledResourceId(mContext, R.attr.colorAccent));
mAltitudeDifference.setCompoundDrawablesRelativeWithIntrinsicBounds(Graphics.tint(icon, colorAccent),
null, null, null);
final String unit = limits.isMetricUnits ? mAltitudeDifference.getResources().getString(R.string.meter) : mAltitudeDifference.getResources().getString(R.string.foot);
mAltitudeDifference.setText(String.format(Locale.getDefault(), "▲ %d %s ▼ %d %s",
limits.totalAscent, unit,
limits.totalDescent, unit));
UiUtils.show(mAltitudeDifference);
}
}

View file

@ -39,6 +39,12 @@ final class BaseRoutePreviewStatus: SolidTouchView {
weak var navigationInfo: MWMNavigationDashboardEntity?
static let elevationAttributes: [NSAttributedString.Key: Any] =
[
.foregroundColor: UIColor.linkBlue(),
.font: UIFont.medium14()
]
var elevation: NSAttributedString? {
didSet {
updateResultsLabel()
@ -118,15 +124,11 @@ final class BaseRoutePreviewStatus: SolidTouchView {
if MWMRouter.hasRouteAltitude() {
heightBox.isHidden = false
MWMRouter.routeAltitudeImage(for: heightProfileImage.frame.size,
completion: { image, elevation in
self.heightProfileImage.image = image
guard let elevation = elevation else { return }
let attributes: [NSAttributedString.Key: Any] =
[
.foregroundColor: UIColor.linkBlue(),
.font: UIFont.medium14()
]
self.elevation = NSAttributedString(string: "▲▼ \(elevation)", attributes: attributes)
completion: { image, totalAscent, totalDescent in
self.heightProfileImage.image = image
if let totalAscent = totalAscent, let totalDescent = totalDescent {
self.elevation = NSAttributedString(string: "\(totalAscent)\(totalDescent)", attributes: BaseRoutePreviewStatus.elevationAttributes)
}
})
} else {
heightBox.isHidden = true

View file

@ -8,7 +8,7 @@ typedef NS_ENUM(NSInteger, MWMRoadType) {
MWMRoadTypeMotorway
};
typedef void (^MWMImageHeightBlock)(UIImage *, NSString *);
typedef void (^MWMImageHeightBlock)(UIImage *, NSString *, NSString *);
@interface MWMRouter : NSObject

View file

@ -23,7 +23,8 @@ using namespace routing;
@interface MWMRouter () <MWMLocationObserver, MWMFrameworkRouteBuilderObserver>
@property(nonatomic) NSMutableDictionary<NSValue *, NSData *> *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<uint8_t> 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;
biodranik commented 2022-07-31 11:52:58 +00:00 (Migrated from github.com)
Review

Are feet (imperial system) work on iOS in this case?

Are feet (imperial system) work on iOS in this case?
ArsenyN commented 2022-08-01 05:52:40 +00:00 (Migrated from github.com)
Review

Checked on iOS and Android there are similar code. All works with both measurement systems.

Checked on iOS and Android there are similar code. All works with both measurement systems.
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;
});
}

View file

@ -1158,8 +1158,8 @@ bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height,
geometry::Altitudes const & altitudes,
vector<double> const & routePointDistanceM,
vector<uint8_t> & 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;

View file

@ -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<double> const & routePointDistanceM,
std::vector<uint8_t> & imageRGBAData, int32_t & minRouteAltitude,
int32_t & maxRouteAltitude,
std::vector<uint8_t> & imageRGBAData,
uint32_t & totalAscent,
uint32_t & totalDescent,
measurement_utils::Units & altitudeUnits) const;
uint32_t OpenRoutePointsTransaction();