[ios][android] Replacing altitude difference to ascent and descent #3062
|
@ -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, ());
|
||||
|
|
Before Width: | Height: | Size: 88 B |
Before Width: | Height: | Size: 118 B |
Before Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 114 B |
Before Width: | Height: | Size: 194 B |
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -264,17 +264,10 @@ final class RoutingBottomMenuController implements View.OnClickListener
|
|||
{
|
||||
mAltitudeChart.setImageBitmap(bm);
|
||||
![]() Fixed at d80c3a0 Fixed at d80c3a0
![]() 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,7 +8,7 @@ typedef NS_ENUM(NSInteger, MWMRoadType) {
|
|||
MWMRoadTypeMotorway
|
||||
};
|
||||
|
||||
typedef void (^MWMImageHeightBlock)(UIImage *, NSString *);
|
||||
typedef void (^MWMImageHeightBlock)(UIImage *, NSString *, NSString *);
|
||||
|
||||
@interface MWMRouter : NSObject
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
![]() Are feet (imperial system) work on iOS in this case? Are feet (imperial system) work on iOS in this case?
![]() 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;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
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.
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 😉