Fix min max values for steepness and improve ui
This commit is contained in:
parent
e9febc4932
commit
cb23520a0a
7 changed files with 99 additions and 29 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue