Fix min max values for steepness and improve ui

This commit is contained in:
Chumva 2019-03-15 19:12:50 +02:00
parent e9febc4932
commit cb23520a0a
7 changed files with 99 additions and 29 deletions

View file

@ -1,8 +1,11 @@
package net.osmand.router; package net.osmand.router;
import net.osmand.PlatformUtil;
import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
import org.apache.commons.logging.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -10,7 +13,8 @@ import java.util.TreeMap;
public class RouteStatistics { public class RouteStatistics {
private static final String UNDEFINED_ATTR = "undefined"; public static final String UNDEFINED_ATTR = "undefined";
private static final Log log = PlatformUtil.getLog(RouteStatistics.class);
private final List<RouteSegmentResult> route; private final List<RouteSegmentResult> route;
private final RenderingRulesStorage currentRenderer; private final RenderingRulesStorage currentRenderer;
@ -354,7 +358,7 @@ public class RouteStatistics {
public String getPropertyName(Boundaries attribute) { public String getPropertyName(Boundaries attribute) {
int lowerBoundary = Math.round(attribute.getLowerBoundary()); int lowerBoundary = Math.round(attribute.getLowerBoundary());
int upperBoundary = Math.round(attribute.getUpperBoundary()); int upperBoundary = Math.round(attribute.getUpperBoundary());
if (lowerBoundary > Boundaries.MIN_INCLINE) { if (lowerBoundary >= Boundaries.MIN_DIVIDED_INCLINE) {
lowerBoundary++; lowerBoundary++;
} }
return String.format("%d%% ... %d%%", lowerBoundary, upperBoundary); return String.format("%d%% ... %d%%", lowerBoundary, upperBoundary);
@ -365,9 +369,15 @@ public class RouteStatistics {
int lowerBoundary = Math.round(attribute.getLowerBoundary()); int lowerBoundary = Math.round(attribute.getLowerBoundary());
int upperBoundary = Math.round(attribute.getUpperBoundary()); int upperBoundary = Math.round(attribute.getUpperBoundary());
StringBuilder range = new StringBuilder(); StringBuilder range = new StringBuilder();
if (lowerBoundary > Boundaries.MIN_INCLINE) { if (lowerBoundary >= Boundaries.MIN_DIVIDED_INCLINE) {
lowerBoundary++; lowerBoundary++;
} }
if (lowerBoundary < Boundaries.MIN_DIVIDED_INCLINE) {
lowerBoundary = Boundaries.MIN_INCLINE;
}
if (upperBoundary > Boundaries.MAX_DIVIDED_INCLINE) {
upperBoundary = Boundaries.MAX_INCLINE;
}
range.append(lowerBoundary); range.append(lowerBoundary);
range.append(upperBoundary < 0 ? "_" : "-"); range.append(upperBoundary < 0 ? "_" : "-");
range.append(upperBoundary); range.append(upperBoundary);
@ -446,14 +456,17 @@ public class RouteStatistics {
public static class Incline { public static class Incline {
private float inclineValue; private final float inclineValue;
private final float distance; private final float distance;
private final Boundaries boundaries; private Boundaries boundaries;
public Incline(float inclineValue, float distance) { public Incline(float inclineValue, float distance) {
this.inclineValue = inclineValue; this.inclineValue = inclineValue;
this.distance = distance; this.distance = distance;
this.boundaries = Boundaries.newBoundariesFor(inclineValue); }
public void computeBoundaries(float minIncline, float maxIncline) {
this.boundaries = Boundaries.newBoundariesFor(inclineValue, minIncline, maxIncline);
} }
public float getValue() { public float getValue() {
@ -505,18 +518,26 @@ public class RouteStatistics {
this.lowerBoundary = lowerBoundary; this.lowerBoundary = lowerBoundary;
} }
public static Boundaries newBoundariesFor(float incline) { public static Boundaries newBoundariesFor(float incline, float minIncline, float maxIncline) {
int maxRoundedIncline = Math.round(maxIncline);
int minRoundedIncline = Math.round(minIncline);
if (incline > MAX_INCLINE) { if (incline > MAX_INCLINE) {
return new Boundaries(MAX_INCLINE, MAX_INCLINE - STEP); return new Boundaries(MAX_INCLINE, MAX_DIVIDED_INCLINE);
} }
if (incline < MIN_INCLINE) { if (incline < MIN_INCLINE) {
return new Boundaries(MIN_INCLINE + STEP, MIN_INCLINE); return new Boundaries(MIN_DIVIDED_INCLINE, MIN_INCLINE);
} }
for (int i = 1; i < NUM; i++) { for (int i = 1; i < NUM; i++) {
if (incline >= BOUNDARIES_ARRAY[i - 1] && incline < BOUNDARIES_ARRAY[i]) { if (incline >= BOUNDARIES_ARRAY[i - 1] && incline < BOUNDARIES_ARRAY[i]) {
if (i == 1) {
return new Boundaries(BOUNDARIES_ARRAY[i], minRoundedIncline);
} else if (i == NUM - 1) {
return new Boundaries(maxRoundedIncline, BOUNDARIES_ARRAY[i - 1]);
} else {
return new Boundaries(BOUNDARIES_ARRAY[i], BOUNDARIES_ARRAY[i - 1]); return new Boundaries(BOUNDARIES_ARRAY[i], BOUNDARIES_ARRAY[i - 1]);
} }
} }
}
return null; return null;
} }

View file

@ -53,7 +53,7 @@
<com.github.mikephil.charting.charts.HorizontalBarChart <com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/chart" android:id="@+id/chart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" /> android:layout_height="@dimen/route_info_chart_height" />
<LinearLayout <LinearLayout
android:id="@+id/route_items" android:id="@+id/route_items"

View file

@ -190,6 +190,7 @@
<dimen name="route_info_list_text_padding">78dp</dimen> <dimen name="route_info_list_text_padding">78dp</dimen>
<dimen name="route_info_legend_padding">12dp</dimen> <dimen name="route_info_legend_padding">12dp</dimen>
<dimen name="route_info_warning_padding">27dp</dimen> <dimen name="route_info_warning_padding">27dp</dimen>
<dimen name="route_info_chart_height">78dp</dimen>
<dimen name="multi_selection_header_height">78dp</dimen> <dimen name="multi_selection_header_height">78dp</dimen>

View file

@ -282,6 +282,7 @@
<dimen name="route_info_list_text_padding">54dp</dimen> <dimen name="route_info_list_text_padding">54dp</dimen>
<dimen name="route_info_legend_padding">8dp</dimen> <dimen name="route_info_legend_padding">8dp</dimen>
<dimen name="route_info_warning_padding">18dp</dimen> <dimen name="route_info_warning_padding">18dp</dimen>
<dimen name="route_info_chart_height">52dp</dimen>
<dimen name="multi_selection_header_height">52dp</dimen> <dimen name="multi_selection_header_height">52dp</dimen>

View file

@ -1226,7 +1226,7 @@ public class GpxUiHelper {
chart.setDragEnabled(useGesturesAndScale); chart.setDragEnabled(useGesturesAndScale);
chart.setScaleYEnabled(false); chart.setScaleYEnabled(false);
chart.setAutoScaleMinMaxEnabled(true); chart.setAutoScaleMinMaxEnabled(true);
chart.setDrawBorders(false); chart.setDrawBorders(true);
chart.getDescription().setEnabled(false); chart.getDescription().setEnabled(false);
chart.setDragDecelerationEnabled(false); chart.setDragDecelerationEnabled(false);
@ -1252,6 +1252,9 @@ public class GpxUiHelper {
yr.setDrawAxisLine(false); yr.setDrawAxisLine(false);
yr.setDrawGridLines(false); yr.setDrawGridLines(false);
yr.setAxisMinimum(0f); yr.setAxisMinimum(0f);
chart.setMinOffset(0);
chart.setExtraRightOffset(16);
chart.setExtraLeftOffset(16);
yl.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.primary_text_dark : R.color.primary_text_light)); yl.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.primary_text_dark : R.color.primary_text_light));
yr.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.primary_text_dark : R.color.primary_text_light)); yr.setTextColor(ContextCompat.getColor(app, nightMode ? R.color.primary_text_dark : R.color.primary_text_light));
@ -1266,7 +1269,8 @@ public class GpxUiHelper {
@NonNull HorizontalBarChart mChart, @NonNull HorizontalBarChart mChart,
@NonNull RouteStatistics.Statistics<E> routeStatistics, @NonNull RouteStatistics.Statistics<E> routeStatistics,
@NonNull GPXTrackAnalysis analysis, @NonNull GPXTrackAnalysis analysis,
boolean useRightAxis) { boolean useRightAxis,
boolean nightMode) {
XAxis xAxis = mChart.getXAxis(); XAxis xAxis = mChart.getXAxis();
xAxis.setEnabled(false); xAxis.setEnabled(false);
@ -1292,9 +1296,10 @@ public class GpxUiHelper {
entries.add(new BarEntry(0, stacks)); entries.add(new BarEntry(0, stacks));
BarDataSet barDataSet = new BarDataSet(entries, ""); BarDataSet barDataSet = new BarDataSet(entries, "");
barDataSet.setColors(colors); barDataSet.setColors(colors);
barDataSet.setBarBorderColor(ContextCompat.getColor(app, nightMode ? R.color.divider_dark : R.color.divider_light));
BarData dataSet = new BarData(barDataSet); BarData dataSet = new BarData(barDataSet);
dataSet.setDrawValues(false); dataSet.setDrawValues(false);
dataSet.setBarWidth(1);
mChart.getAxisRight().setAxisMaximum(dataSet.getYMax()); mChart.getAxisRight().setAxisMaximum(dataSet.getYMax());
mChart.getAxisLeft().setAxisMaximum(dataSet.getYMax()); mChart.getAxisLeft().setAxisMaximum(dataSet.getYMax());

View file

@ -1662,12 +1662,17 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment implements P
} }
private List<Incline> createInclinesAndAdd100MetersWith0Incline(List<Entry> entries) { private List<Incline> createInclinesAndAdd100MetersWith0Incline(List<Entry> entries) {
float minIncline = 0;
float maxIncline = 0;
int size = entries.size(); int size = entries.size();
List<Incline> inclines = new ArrayList<>(); List<Incline> inclines = new ArrayList<>();
for (Entry entry : entries) { for (Entry entry : entries) {
Incline incline = new Incline(entry.getY(), entry.getX() * 1000); float inclineValue = entry.getY();
inclines.add(incline); maxIncline = Math.max(inclineValue, maxIncline);
minIncline = Math.min(inclineValue, minIncline);
Incline incline = new Incline(inclineValue, entry.getX() * 1000);
inclines.add(incline);
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
float distance = i * 5; float distance = i * 5;
@ -1678,6 +1683,9 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment implements P
float distance = lastDistance * 1000f + i * 5f; float distance = lastDistance * 1000f + i * 5f;
inclines.add(new Incline(0f, distance)); inclines.add(new Incline(0f, distance));
} }
for (Incline incline : inclines) {
incline.computeBoundaries(minIncline, maxIncline);
}
return inclines; return inclines;
} }

View file

@ -20,17 +20,26 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SettingsNavigationActivity; import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.router.RouteStatistics; import net.osmand.router.RouteStatistics.Boundaries;
import net.osmand.router.RouteStatistics.RouteSegmentAttribute;
import net.osmand.router.RouteStatistics.StatisticType;
import net.osmand.router.RouteStatistics.Statistics;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map; import java.util.Map;
import static net.osmand.router.RouteStatistics.UNDEFINED_ATTR;
public class RouteInfoCard extends BaseCard { public class RouteInfoCard extends BaseCard {
private RouteStatistics.Statistics routeStatistics; private Statistics routeStatistics;
private GPXUtilities.GPXTrackAnalysis analysis; private GPXUtilities.GPXTrackAnalysis analysis;
public RouteInfoCard(MapActivity mapActivity, RouteStatistics.Statistics routeStatistics, GPXUtilities.GPXTrackAnalysis analysis) { public RouteInfoCard(MapActivity mapActivity, Statistics routeStatistics, GPXUtilities.GPXTrackAnalysis analysis) {
super(mapActivity); super(mapActivity);
this.routeStatistics = routeStatistics; this.routeStatistics = routeStatistics;
this.analysis = analysis; this.analysis = analysis;
@ -46,7 +55,7 @@ public class RouteInfoCard extends BaseCard {
updateHeader(); updateHeader();
final HorizontalBarChart chart = (HorizontalBarChart) view.findViewById(R.id.chart); final HorizontalBarChart chart = (HorizontalBarChart) view.findViewById(R.id.chart);
GpxUiHelper.setupHorizontalGPXChart(app, chart, 5, 10, 10, true, nightMode); GpxUiHelper.setupHorizontalGPXChart(app, chart, 5, 10, 10, true, nightMode);
BarData barData = GpxUiHelper.buildStatisticChart(app, chart, routeStatistics, analysis, true); BarData barData = GpxUiHelper.buildStatisticChart(app, chart, routeStatistics, analysis, true, nightMode);
chart.setData(barData); chart.setData(barData);
LinearLayout container = view.findViewById(R.id.route_items); LinearLayout container = view.findViewById(R.id.route_items);
attachLegend(container, routeStatistics); attachLegend(container, routeStatistics);
@ -62,23 +71,25 @@ public class RouteInfoCard extends BaseCard {
} }
private String getInfoType() { private String getInfoType() {
if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.CLASS) { if (routeStatistics.getStatisticType() == StatisticType.CLASS) {
return app.getString(R.string.road_types); return app.getString(R.string.road_types);
} else if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.STEEPNESS) { } else if (routeStatistics.getStatisticType() == StatisticType.STEEPNESS) {
return app.getString(R.string.route_steepness_stat_container); return app.getString(R.string.route_steepness_stat_container);
} else if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.SMOOTHNESS) { } else if (routeStatistics.getStatisticType() == StatisticType.SMOOTHNESS) {
return app.getString(R.string.route_smoothness_stat_container); return app.getString(R.string.route_smoothness_stat_container);
} else if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.SURFACE) { } else if (routeStatistics.getStatisticType() == StatisticType.SURFACE) {
return app.getString(R.string.route_surface_stat_container); return app.getString(R.string.route_surface_stat_container);
} else { } else {
return ""; return "";
} }
} }
private <E> void attachLegend(ViewGroup container, RouteStatistics.Statistics<E> routeStatistics) { private <E> void attachLegend(ViewGroup container, Statistics<E> routeStatistics) {
Map<E, RouteStatistics.RouteSegmentAttribute<E>> partition = routeStatistics.getPartition(); Map<E, RouteSegmentAttribute<E>> partition = routeStatistics.getPartition();
for (E key : partition.keySet()) { List<E> list = new ArrayList<E>(partition.keySet());
RouteStatistics.RouteSegmentAttribute<E> segment = partition.get(key); sortRouteSegmentAttributes(list);
for (E key : list) {
RouteSegmentAttribute<E> segment = partition.get(key);
int color = segment.getColor(); int color = segment.getColor();
Drawable circle = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color); Drawable circle = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color);
String propertyName = segment.getPropertyName(); String propertyName = segment.getPropertyName();
@ -98,7 +109,30 @@ public class RouteInfoCard extends BaseCard {
} }
} }
private Spannable getSpanLegend(String title, RouteStatistics.RouteSegmentAttribute segment) { private <E> void sortRouteSegmentAttributes(List<E> list) {
Collections.sort(list, new Comparator<E>() {
@Override
public int compare(E o1, E o2) {
if (o1 instanceof String && o2 instanceof String) {
String name1 = (String) o1;
String name2 = (String) o2;
if (name1.equalsIgnoreCase(UNDEFINED_ATTR)) {
return 1;
}
if (name2.equalsIgnoreCase(UNDEFINED_ATTR)) {
return -1;
}
return name1.compareTo(name2);
} else if (o1 instanceof Boundaries && o2 instanceof Boundaries) {
return ((Boundaries) o1).compareTo((Boundaries) o2);
}
return 0;
}
});
}
private Spannable getSpanLegend(String title, RouteSegmentAttribute segment) {
String formattedDistance = OsmAndFormatter.getFormattedDistance(segment.getDistance(), getMyApplication()); String formattedDistance = OsmAndFormatter.getFormattedDistance(segment.getDistance(), getMyApplication());
title = Algorithms.capitalizeFirstLetter(title); title = Algorithms.capitalizeFirstLetter(title);
SpannableStringBuilder spannable = new SpannableStringBuilder(title); SpannableStringBuilder spannable = new SpannableStringBuilder(title);