Merge pull request #6693 from osmandapp/RouteDetailsImprovements
Fix min max values for steepness and improve ui
This commit is contained in:
commit
5d2d7fb4ec
7 changed files with 94 additions and 29 deletions
|
@ -10,7 +10,7 @@ import java.util.TreeMap;
|
|||
|
||||
public class RouteStatistics {
|
||||
|
||||
private static final String UNDEFINED_ATTR = "undefined";
|
||||
public static final String UNDEFINED_ATTR = "undefined";
|
||||
|
||||
private final List<RouteSegmentResult> route;
|
||||
private final RenderingRulesStorage currentRenderer;
|
||||
|
@ -354,7 +354,7 @@ public class RouteStatistics {
|
|||
public String getPropertyName(Boundaries attribute) {
|
||||
int lowerBoundary = Math.round(attribute.getLowerBoundary());
|
||||
int upperBoundary = Math.round(attribute.getUpperBoundary());
|
||||
if (lowerBoundary > Boundaries.MIN_INCLINE) {
|
||||
if (lowerBoundary >= Boundaries.MIN_DIVIDED_INCLINE) {
|
||||
lowerBoundary++;
|
||||
}
|
||||
return String.format("%d%% ... %d%%", lowerBoundary, upperBoundary);
|
||||
|
@ -365,8 +365,13 @@ public class RouteStatistics {
|
|||
int lowerBoundary = Math.round(attribute.getLowerBoundary());
|
||||
int upperBoundary = Math.round(attribute.getUpperBoundary());
|
||||
StringBuilder range = new StringBuilder();
|
||||
if (lowerBoundary > Boundaries.MIN_INCLINE) {
|
||||
if (lowerBoundary >= Boundaries.MIN_DIVIDED_INCLINE) {
|
||||
lowerBoundary++;
|
||||
} else {
|
||||
lowerBoundary = Boundaries.MIN_INCLINE;
|
||||
}
|
||||
if (upperBoundary > Boundaries.MAX_DIVIDED_INCLINE) {
|
||||
upperBoundary = Boundaries.MAX_INCLINE;
|
||||
}
|
||||
range.append(lowerBoundary);
|
||||
range.append(upperBoundary < 0 ? "_" : "-");
|
||||
|
@ -446,14 +451,17 @@ public class RouteStatistics {
|
|||
|
||||
public static class Incline {
|
||||
|
||||
private float inclineValue;
|
||||
private final float inclineValue;
|
||||
private final float distance;
|
||||
private final Boundaries boundaries;
|
||||
private Boundaries boundaries;
|
||||
|
||||
public Incline(float inclineValue, float distance) {
|
||||
this.inclineValue = inclineValue;
|
||||
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() {
|
||||
|
@ -505,16 +513,24 @@ public class RouteStatistics {
|
|||
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) {
|
||||
return new Boundaries(MAX_INCLINE, MAX_INCLINE - STEP);
|
||||
return new Boundaries(MAX_INCLINE, MAX_DIVIDED_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++) {
|
||||
if (incline >= BOUNDARIES_ARRAY[i - 1] && incline < BOUNDARIES_ARRAY[i]) {
|
||||
return new Boundaries(BOUNDARIES_ARRAY[i], BOUNDARIES_ARRAY[i - 1]);
|
||||
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 null;
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<com.github.mikephil.charting.charts.HorizontalBarChart
|
||||
android:id="@+id/chart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp" />
|
||||
android:layout_height="@dimen/route_info_chart_height" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/route_items"
|
||||
|
|
|
@ -190,6 +190,7 @@
|
|||
<dimen name="route_info_list_text_padding">78dp</dimen>
|
||||
<dimen name="route_info_legend_padding">12dp</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>
|
||||
|
||||
|
|
|
@ -282,6 +282,7 @@
|
|||
<dimen name="route_info_list_text_padding">54dp</dimen>
|
||||
<dimen name="route_info_legend_padding">8dp</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>
|
||||
|
||||
|
|
|
@ -1226,7 +1226,7 @@ public class GpxUiHelper {
|
|||
chart.setDragEnabled(useGesturesAndScale);
|
||||
chart.setScaleYEnabled(false);
|
||||
chart.setAutoScaleMinMaxEnabled(true);
|
||||
chart.setDrawBorders(false);
|
||||
chart.setDrawBorders(true);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setDragDecelerationEnabled(false);
|
||||
|
||||
|
@ -1252,6 +1252,9 @@ public class GpxUiHelper {
|
|||
yr.setDrawAxisLine(false);
|
||||
yr.setDrawGridLines(false);
|
||||
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));
|
||||
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 RouteStatistics.Statistics<E> routeStatistics,
|
||||
@NonNull GPXTrackAnalysis analysis,
|
||||
boolean useRightAxis) {
|
||||
boolean useRightAxis,
|
||||
boolean nightMode) {
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
@ -1292,9 +1296,10 @@ public class GpxUiHelper {
|
|||
entries.add(new BarEntry(0, stacks));
|
||||
BarDataSet barDataSet = new BarDataSet(entries, "");
|
||||
barDataSet.setColors(colors);
|
||||
barDataSet.setBarBorderColor(ContextCompat.getColor(app, nightMode ? R.color.divider_dark : R.color.divider_light));
|
||||
BarData dataSet = new BarData(barDataSet);
|
||||
dataSet.setDrawValues(false);
|
||||
|
||||
dataSet.setBarWidth(1);
|
||||
mChart.getAxisRight().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) {
|
||||
float minIncline = 0;
|
||||
float maxIncline = 0;
|
||||
int size = entries.size();
|
||||
List<Incline> inclines = new ArrayList<>();
|
||||
for (Entry entry : entries) {
|
||||
Incline incline = new Incline(entry.getY(), entry.getX() * 1000);
|
||||
inclines.add(incline);
|
||||
float inclineValue = entry.getY();
|
||||
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++) {
|
||||
float distance = i * 5;
|
||||
|
@ -1678,6 +1683,9 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment implements P
|
|||
float distance = lastDistance * 1000f + i * 5f;
|
||||
inclines.add(new Incline(0f, distance));
|
||||
}
|
||||
for (Incline incline : inclines) {
|
||||
incline.computeBoundaries(minIncline, maxIncline);
|
||||
}
|
||||
return inclines;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,17 +20,26 @@ import net.osmand.plus.R;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.SettingsNavigationActivity;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.router.RouteStatistics.UNDEFINED_ATTR;
|
||||
|
||||
public class RouteInfoCard extends BaseCard {
|
||||
|
||||
private RouteStatistics.Statistics routeStatistics;
|
||||
private Statistics routeStatistics;
|
||||
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);
|
||||
this.routeStatistics = routeStatistics;
|
||||
this.analysis = analysis;
|
||||
|
@ -46,7 +55,7 @@ public class RouteInfoCard extends BaseCard {
|
|||
updateHeader();
|
||||
final HorizontalBarChart chart = (HorizontalBarChart) view.findViewById(R.id.chart);
|
||||
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);
|
||||
LinearLayout container = view.findViewById(R.id.route_items);
|
||||
attachLegend(container, routeStatistics);
|
||||
|
@ -62,23 +71,25 @@ public class RouteInfoCard extends BaseCard {
|
|||
}
|
||||
|
||||
private String getInfoType() {
|
||||
if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.CLASS) {
|
||||
if (routeStatistics.getStatisticType() == StatisticType.CLASS) {
|
||||
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);
|
||||
} else if (routeStatistics.getStatisticType() == RouteStatistics.StatisticType.SMOOTHNESS) {
|
||||
} else if (routeStatistics.getStatisticType() == StatisticType.SMOOTHNESS) {
|
||||
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);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private <E> void attachLegend(ViewGroup container, RouteStatistics.Statistics<E> routeStatistics) {
|
||||
Map<E, RouteStatistics.RouteSegmentAttribute<E>> partition = routeStatistics.getPartition();
|
||||
for (E key : partition.keySet()) {
|
||||
RouteStatistics.RouteSegmentAttribute<E> segment = partition.get(key);
|
||||
private <E> void attachLegend(ViewGroup container, Statistics<E> routeStatistics) {
|
||||
Map<E, RouteSegmentAttribute<E>> partition = routeStatistics.getPartition();
|
||||
List<E> list = new ArrayList<E>(partition.keySet());
|
||||
sortRouteSegmentAttributes(list);
|
||||
for (E key : list) {
|
||||
RouteSegmentAttribute<E> segment = partition.get(key);
|
||||
int color = segment.getColor();
|
||||
Drawable circle = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color);
|
||||
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());
|
||||
title = Algorithms.capitalizeFirstLetter(title);
|
||||
SpannableStringBuilder spannable = new SpannableStringBuilder(title);
|
||||
|
|
Loading…
Reference in a new issue