Merge branch 'master' of https://github.com/osmandapp/Osmand
This commit is contained in:
commit
80b7d7af98
10 changed files with 574 additions and 558 deletions
|
@ -1,42 +1,51 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class RouteStatistics {
|
||||
|
||||
private final List<RouteSegmentResult> route;
|
||||
private static final String UNDEFINED_ATTR = "undefined";
|
||||
|
||||
private RouteStatistics(List<RouteSegmentResult> route) {
|
||||
private final List<RouteSegmentResult> route;
|
||||
private final RenderingRulesStorage currentRenderer;
|
||||
private final RenderingRulesStorage defaultRenderer;
|
||||
|
||||
private final boolean nightMode;
|
||||
|
||||
private RouteStatistics(List<RouteSegmentResult> route, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
this.route = route;
|
||||
this.currentRenderer = currentRenderer;
|
||||
this.defaultRenderer = defaultRenderer;
|
||||
this.nightMode = nightMode;
|
||||
}
|
||||
|
||||
public static RouteStatistics newRouteStatistic(List<RouteSegmentResult> route) {
|
||||
return new RouteStatistics(route);
|
||||
public static RouteStatistics newRouteStatistic(List<RouteSegmentResult> route, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
return new RouteStatistics(route, currentRenderer, defaultRenderer, nightMode);
|
||||
}
|
||||
|
||||
public Statistics getRouteSurfaceStatistic() {
|
||||
RouteStatisticComputer statisticComputer = new RouteSurfaceStatisticComputer(route);
|
||||
RouteStatisticComputer statisticComputer = new RouteSurfaceStatisticComputer(route, currentRenderer, defaultRenderer, nightMode);
|
||||
return statisticComputer.computeStatistic();
|
||||
}
|
||||
|
||||
public Statistics getRouteSmoothnessStatistic() {
|
||||
RouteStatisticComputer statisticComputer = new RouteSmoothnessStatisticComputer(route);
|
||||
RouteStatisticComputer statisticComputer = new RouteSmoothnessStatisticComputer(route, currentRenderer, defaultRenderer, nightMode);
|
||||
return statisticComputer.computeStatistic();
|
||||
}
|
||||
|
||||
public Statistics getRouteClassStatistic() {
|
||||
RouteStatisticComputer statisticComputer = new RouteClassStatisticComputer(route);
|
||||
RouteStatisticComputer statisticComputer = new RouteClassStatisticComputer(route, currentRenderer, defaultRenderer, nightMode);
|
||||
return statisticComputer.computeStatistic();
|
||||
}
|
||||
|
||||
public Statistics getRouteSteepnessStatistic(List<Incline> inclines) {
|
||||
RouteStatisticComputer statisticComputer = new RouteSteepnessStatisticComputer(inclines);
|
||||
RouteStatisticComputer statisticComputer = new RouteSteepnessStatisticComputer(inclines, currentRenderer, defaultRenderer, nightMode);
|
||||
return statisticComputer.computeStatistic();
|
||||
}
|
||||
|
||||
|
@ -44,12 +53,18 @@ public class RouteStatistics {
|
|||
private abstract static class RouteStatisticComputer<E extends Comparable<E>> {
|
||||
|
||||
private final List<RouteSegmentResult> route;
|
||||
|
||||
private final StatisticType type;
|
||||
|
||||
public RouteStatisticComputer(List<RouteSegmentResult> route, StatisticType type) {
|
||||
protected final RenderingRulesStorage currentRenderer;
|
||||
protected final RenderingRulesStorage defaultRenderer;
|
||||
protected final boolean nightMode;
|
||||
|
||||
public RouteStatisticComputer(RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, List<RouteSegmentResult> route, StatisticType type, boolean nightMode) {
|
||||
this.route = route;
|
||||
this.currentRenderer = currentRenderer;
|
||||
this.defaultRenderer = defaultRenderer;
|
||||
this.type = type;
|
||||
this.nightMode = nightMode;
|
||||
}
|
||||
|
||||
protected Map<E, RouteSegmentAttribute<E>> makePartition(List<RouteSegmentAttribute<E>> routeAttributes) {
|
||||
|
@ -88,9 +103,9 @@ public class RouteStatistics {
|
|||
index++;
|
||||
}
|
||||
if (index >= routes.size()) {
|
||||
String colorAttrName = getColorAttrName(current);
|
||||
String colorName = getColorName(current);
|
||||
routes.add(new RouteSegmentAttribute<>(index, current, colorAttrName, colorName));
|
||||
int color = getColor(current);
|
||||
String propertyName = getPropertyName(current);
|
||||
routes.add(new RouteSegmentAttribute<>(index, current, propertyName, color));
|
||||
}
|
||||
RouteSegmentAttribute surface = routes.get(index);
|
||||
surface.incrementDistanceBy(segment.getDistance());
|
||||
|
@ -106,115 +121,189 @@ public class RouteStatistics {
|
|||
return new Statistics<>(routeAttributes, partition, totalDistance, type);
|
||||
}
|
||||
|
||||
public int getColor(E attribute) {
|
||||
int color = 0;
|
||||
RenderingRuleSearchRequest currentRequest = new RenderingRuleSearchRequest(currentRenderer);
|
||||
if (searchRenderingAttribute(currentRenderer, currentRequest, attribute)) {
|
||||
color = currentRequest.getIntPropertyValue(currentRenderer.PROPS.R_ATTR_COLOR_VALUE);
|
||||
} else {
|
||||
RenderingRuleSearchRequest defaultRequest = new RenderingRuleSearchRequest(defaultRenderer);
|
||||
if (searchRenderingAttribute(defaultRenderer, defaultRequest, attribute)) {
|
||||
color = defaultRequest.getIntPropertyValue(defaultRenderer.PROPS.R_ATTR_COLOR_VALUE);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public abstract E getAttribute(RouteSegmentResult segment);
|
||||
|
||||
public abstract String getColorAttrName(E attribute);
|
||||
public abstract String getPropertyName(E attribute);
|
||||
|
||||
public abstract String getColorName(E attribute);
|
||||
protected abstract boolean searchRenderingAttribute(RenderingRulesStorage rrs, RenderingRuleSearchRequest req, E attribute);
|
||||
}
|
||||
|
||||
private static class RouteSurfaceStatisticComputer extends RouteStatisticComputer<RoadSurface> {
|
||||
private static class RouteSurfaceStatisticComputer extends RouteStatisticComputer<String> {
|
||||
|
||||
public RouteSurfaceStatisticComputer(List<RouteSegmentResult> route) {
|
||||
super(route, StatisticType.SURFACE);
|
||||
private static final String SURFACE_ATTR = "surface";
|
||||
private static final String SURFACE_COLOR_ATTR = "surfaceColor";
|
||||
|
||||
public RouteSurfaceStatisticComputer(List<RouteSegmentResult> route, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
super(currentRenderer, defaultRenderer, route, StatisticType.SURFACE, nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoadSurface getAttribute(RouteSegmentResult segment) {
|
||||
public String getAttribute(RouteSegmentResult segment) {
|
||||
String segmentSurface = segment.getSurface();
|
||||
if (segmentSurface == null) {
|
||||
return RoadSurface.UNDEFINED;
|
||||
return UNDEFINED_ATTR;
|
||||
}
|
||||
for (RoadSurface roadSurface : RoadSurface.values()) {
|
||||
if (roadSurface.contains(segmentSurface)) {
|
||||
return roadSurface;
|
||||
RenderingRuleSearchRequest currentRequest = new RenderingRuleSearchRequest(currentRenderer);
|
||||
if (searchRenderingAttribute(currentRenderer, currentRequest, segmentSurface)) {
|
||||
return segmentSurface;
|
||||
} else {
|
||||
RenderingRuleSearchRequest defaultRequest = new RenderingRuleSearchRequest(defaultRenderer);
|
||||
if (searchRenderingAttribute(defaultRenderer, defaultRequest, segmentSurface)) {
|
||||
return segmentSurface;
|
||||
}
|
||||
}
|
||||
return RoadSurface.UNDEFINED;
|
||||
return UNDEFINED_ATTR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorAttrName(RoadSurface attribute) {
|
||||
return attribute.getColorAttrName();
|
||||
public String getPropertyName(String attribute) {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorName(RoadSurface attribute) {
|
||||
return attribute.getColorName();
|
||||
public boolean searchRenderingAttribute(RenderingRulesStorage rrs, RenderingRuleSearchRequest req, String attribute) {
|
||||
String additional = SURFACE_ATTR + "=" + attribute;
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
req.setStringFilter(rrs.PROPS.R_ATTR_STRING_VALUE, SURFACE_ATTR + "_" + attribute);
|
||||
req.setStringFilter(rrs.PROPS.R_ADDITIONAL, additional);
|
||||
return req.searchRenderingAttribute(SURFACE_COLOR_ATTR);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RouteSmoothnessStatisticComputer extends RouteStatisticComputer<RoadSmoothness> {
|
||||
private static class RouteSmoothnessStatisticComputer extends RouteStatisticComputer<String> {
|
||||
|
||||
public RouteSmoothnessStatisticComputer(List<RouteSegmentResult> route) {
|
||||
super(route, StatisticType.SMOOTHNESS);
|
||||
private static final String SMOOTHNESS_ATTR = "smoothness";
|
||||
private static final String SMOOTHNESS_COLOR_ATTR = "smoothnessColor";
|
||||
|
||||
public RouteSmoothnessStatisticComputer(List<RouteSegmentResult> route, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
super(currentRenderer, defaultRenderer, route, StatisticType.SMOOTHNESS, nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoadSmoothness getAttribute(RouteSegmentResult segment) {
|
||||
public String getAttribute(RouteSegmentResult segment) {
|
||||
String segmentSmoothness = segment.getSmoothness();
|
||||
if (segmentSmoothness == null) {
|
||||
return RoadSmoothness.UNDEFINED;
|
||||
return UNDEFINED_ATTR;
|
||||
}
|
||||
for (RoadSmoothness roadSmoothness : RoadSmoothness.values()) {
|
||||
if (roadSmoothness.contains(segmentSmoothness)) {
|
||||
return roadSmoothness;
|
||||
RenderingRuleSearchRequest currentRequest = new RenderingRuleSearchRequest(currentRenderer);
|
||||
if (searchRenderingAttribute(currentRenderer, currentRequest, segmentSmoothness)) {
|
||||
return segmentSmoothness;
|
||||
} else {
|
||||
RenderingRuleSearchRequest defaultRequest = new RenderingRuleSearchRequest(defaultRenderer);
|
||||
if (searchRenderingAttribute(defaultRenderer, defaultRequest, segmentSmoothness)) {
|
||||
return segmentSmoothness;
|
||||
}
|
||||
}
|
||||
return RoadSmoothness.UNDEFINED;
|
||||
return UNDEFINED_ATTR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorAttrName(RoadSmoothness attribute) {
|
||||
return attribute.getColorAttrName();
|
||||
public String getPropertyName(String attribute) {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorName(RoadSmoothness attribute) {
|
||||
return attribute.getColorName();
|
||||
public boolean searchRenderingAttribute(RenderingRulesStorage rrs, RenderingRuleSearchRequest req, String attribute) {
|
||||
String additional = SMOOTHNESS_ATTR + "=" + attribute;
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
req.setStringFilter(rrs.PROPS.R_ATTR_STRING_VALUE, SMOOTHNESS_ATTR + "_" + attribute);
|
||||
req.setStringFilter(rrs.PROPS.R_ADDITIONAL, additional);
|
||||
return req.searchRenderingAttribute(SMOOTHNESS_COLOR_ATTR);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RouteClassStatisticComputer extends RouteStatisticComputer<RoadClass> {
|
||||
private static class RouteClassStatisticComputer extends RouteStatisticComputer<String> {
|
||||
|
||||
public RouteClassStatisticComputer(List<RouteSegmentResult> route) {
|
||||
super(route, StatisticType.CLASS);
|
||||
private static final String HIGHWAY_ATTR = "highway";
|
||||
private static final String ROAD_CLASS_COLOR_ATTR = "roadClassColor";
|
||||
|
||||
public RouteClassStatisticComputer(List<RouteSegmentResult> route, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
super(currentRenderer, defaultRenderer, route, StatisticType.CLASS, nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoadClass getAttribute(RouteSegmentResult segment) {
|
||||
public String getAttribute(RouteSegmentResult segment) {
|
||||
String segmentClass = segment.getHighway();
|
||||
if (segmentClass == null) {
|
||||
return RoadClass.UNDEFINED;
|
||||
return UNDEFINED_ATTR;
|
||||
}
|
||||
for (RoadClass roadClass : RoadClass.values()) {
|
||||
if (roadClass.contains(segmentClass)) {
|
||||
return roadClass;
|
||||
}
|
||||
}
|
||||
return RoadClass.UNDEFINED;
|
||||
String type = getAttributeType(segmentClass);
|
||||
return type != null ? type : UNDEFINED_ATTR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorAttrName(RoadClass attribute) {
|
||||
return attribute.getColorAttrName();
|
||||
public int getColor(String attribute) {
|
||||
int color = 0;
|
||||
RenderingRuleSearchRequest currentRequest = new RenderingRuleSearchRequest(currentRenderer);
|
||||
if (currentRequest.searchRenderingAttribute(attribute)) {
|
||||
color = currentRequest.getIntPropertyValue(currentRenderer.PROPS.R_ATTR_COLOR_VALUE);
|
||||
} else {
|
||||
RenderingRuleSearchRequest defaultRequest = new RenderingRuleSearchRequest(defaultRenderer);
|
||||
if (defaultRequest.searchRenderingAttribute(attribute)) {
|
||||
color = defaultRequest.getIntPropertyValue(defaultRenderer.PROPS.R_ATTR_COLOR_VALUE);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorName(RoadClass attribute) {
|
||||
return attribute.getColorName();
|
||||
public String getPropertyName(String attribute) {
|
||||
String type = getAttributeType(attribute);
|
||||
return type != null ? type : attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean searchRenderingAttribute(RenderingRulesStorage rrs, RenderingRuleSearchRequest req, String attribute) {
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
req.setStringFilter(rrs.PROPS.R_TAG, HIGHWAY_ATTR);
|
||||
req.setStringFilter(rrs.PROPS.R_VALUE, attribute);
|
||||
return req.searchRenderingAttribute(ROAD_CLASS_COLOR_ATTR);
|
||||
}
|
||||
|
||||
private String getAttributeType(String attribute) {
|
||||
String type = null;
|
||||
RenderingRuleSearchRequest currentRequest = new RenderingRuleSearchRequest(currentRenderer);
|
||||
if (searchRenderingAttribute(currentRenderer, currentRequest, attribute)) {
|
||||
type = currentRequest.getStringPropertyValue(currentRenderer.PROPS.R_ATTR_STRING_VALUE);
|
||||
if (currentRequest.searchRenderingAttribute(type)) {
|
||||
type = currentRequest.getStringPropertyValue(currentRenderer.PROPS.R_ATTR_STRING_VALUE);
|
||||
}
|
||||
} else {
|
||||
RenderingRuleSearchRequest defaultRequest = new RenderingRuleSearchRequest(defaultRenderer);
|
||||
if (searchRenderingAttribute(defaultRenderer, defaultRequest, attribute)) {
|
||||
type = defaultRequest.getStringPropertyValue(currentRenderer.PROPS.R_ATTR_STRING_VALUE);
|
||||
if (defaultRequest.searchRenderingAttribute(type)) {
|
||||
type = defaultRequest.getStringPropertyValue(currentRenderer.PROPS.R_ATTR_STRING_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RouteSteepnessStatisticComputer extends RouteStatisticComputer<Boundaries> {
|
||||
|
||||
private static final String POSITIVE_INCLINE_COLOR_ATTR_NAME = "greenColor";
|
||||
private static final String NEGATIVE_INCLINE_COLOR_ATTR_NAME = "redColor";
|
||||
private static final String STEEPNESS_ATTR = "steepness";
|
||||
private static final String STEEPNESS_COLOR_ATTR = "steepnessColor";
|
||||
|
||||
private final List<Incline> inclines;
|
||||
|
||||
public RouteSteepnessStatisticComputer(List<Incline> inclines) {
|
||||
super(null, StatisticType.STEEPNESS);
|
||||
public RouteSteepnessStatisticComputer(List<Incline> inclines, RenderingRulesStorage currentRenderer, RenderingRulesStorage defaultRenderer, boolean nightMode) {
|
||||
super(currentRenderer, defaultRenderer, null, StatisticType.STEEPNESS, nightMode);
|
||||
this.inclines = inclines;
|
||||
}
|
||||
|
||||
|
@ -230,9 +319,9 @@ public class RouteStatistics {
|
|||
index++;
|
||||
}
|
||||
if (index >= routeInclines.size()) {
|
||||
String colorAttrName = getColorAttrName(current);
|
||||
String colorName = getColorName(current);
|
||||
RouteSegmentAttribute<Boundaries> attribute = new RouteSegmentAttribute<>(index, current, colorAttrName, colorName);
|
||||
String propertyName = getPropertyName(current);
|
||||
int color = getColor(current);
|
||||
RouteSegmentAttribute<Boundaries> attribute = new RouteSegmentAttribute<>(index, current, propertyName, color);
|
||||
if (prevIncline != null) {
|
||||
attribute.setInitDistance(prevIncline.getDistance());
|
||||
}
|
||||
|
@ -255,13 +344,30 @@ public class RouteStatistics {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getColorAttrName(Boundaries attribute) {
|
||||
return attribute.getLowerBoundary() >= 0 ? POSITIVE_INCLINE_COLOR_ATTR_NAME : NEGATIVE_INCLINE_COLOR_ATTR_NAME;
|
||||
public String getPropertyName(Boundaries attribute) {
|
||||
int lowerBoundary = Math.round(attribute.getLowerBoundary());
|
||||
int upperBoundary = Math.round(attribute.getUpperBoundary());
|
||||
if (lowerBoundary > Boundaries.MIN_INCLINE) {
|
||||
lowerBoundary++;
|
||||
}
|
||||
return String.format("%d%% ... %d%%", lowerBoundary, upperBoundary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColorName(Boundaries attribute) {
|
||||
return null;
|
||||
public boolean searchRenderingAttribute(RenderingRulesStorage rrs, RenderingRuleSearchRequest req, Boundaries attribute) {
|
||||
int lowerBoundary = Math.round(attribute.getLowerBoundary());
|
||||
int upperBoundary = Math.round(attribute.getUpperBoundary());
|
||||
StringBuilder range = new StringBuilder();
|
||||
if (lowerBoundary > Boundaries.MIN_INCLINE) {
|
||||
lowerBoundary++;
|
||||
}
|
||||
range.append(lowerBoundary);
|
||||
range.append(upperBoundary < 0 ? "_" : "-");
|
||||
range.append(upperBoundary);
|
||||
String additional = STEEPNESS_ATTR + "=" + range;
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
req.setStringFilter(rrs.PROPS.R_ADDITIONAL, additional);
|
||||
return req.searchRenderingAttribute(STEEPNESS_COLOR_ATTR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,24 +375,24 @@ public class RouteStatistics {
|
|||
|
||||
private final int index;
|
||||
private final E attribute;
|
||||
private final String colorAttrName;
|
||||
private final String colorName;
|
||||
private final int color;
|
||||
private final String propertyName;
|
||||
|
||||
private float distance;
|
||||
private float initDistance;
|
||||
|
||||
public RouteSegmentAttribute(int index, E attribute, String colorAttrName, String colorName) {
|
||||
public RouteSegmentAttribute(int index, E attribute, String propertyName, int color) {
|
||||
this.index = index;
|
||||
this.attribute = attribute;
|
||||
this.colorAttrName = colorAttrName;
|
||||
this.colorName = colorName;
|
||||
this.propertyName = propertyName;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public RouteSegmentAttribute(RouteSegmentAttribute<E> segmentAttribute) {
|
||||
this.index = segmentAttribute.getIndex();
|
||||
this.attribute = segmentAttribute.getAttribute();
|
||||
this.colorAttrName = segmentAttribute.getColorAttrName();
|
||||
this.colorName = segmentAttribute.getColorName();
|
||||
this.propertyName = segmentAttribute.getPropertyName();
|
||||
this.color = segmentAttribute.getColor();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
|
@ -313,12 +419,12 @@ public class RouteStatistics {
|
|||
this.distance = this.distance + ((distance - this.initDistance) - this.distance);
|
||||
}
|
||||
|
||||
public String getColorAttrName() {
|
||||
return colorAttrName;
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public String getColorName() {
|
||||
return colorName;
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -326,7 +432,7 @@ public class RouteStatistics {
|
|||
return "RouteSegmentAttribute{" +
|
||||
"index=" + index +
|
||||
", attribute='" + attribute + '\'' +
|
||||
", colorAttrName='" + colorAttrName + '\'' +
|
||||
", color='" + color + '\'' +
|
||||
", distance=" + distance +
|
||||
'}';
|
||||
}
|
||||
|
@ -368,17 +474,21 @@ public class RouteStatistics {
|
|||
public static class Boundaries implements Comparable<Boundaries> {
|
||||
|
||||
private static final int MIN_INCLINE = -100;
|
||||
private static final int MIN_DIVIDED_INCLINE = -20;
|
||||
private static final int MAX_INCLINE = 100;
|
||||
private static final int MAX_DIVIDED_INCLINE = 20;
|
||||
private static final int STEP = 4;
|
||||
private static final int NUM;
|
||||
private static final int[] BOUNDARIES_ARRAY;
|
||||
|
||||
static {
|
||||
NUM = ((MAX_INCLINE - MIN_INCLINE) / STEP + 1);
|
||||
NUM = ((MAX_DIVIDED_INCLINE - MIN_DIVIDED_INCLINE) / STEP) + 3;
|
||||
BOUNDARIES_ARRAY = new int[NUM];
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
BOUNDARIES_ARRAY[i] = MIN_INCLINE + i * STEP;
|
||||
BOUNDARIES_ARRAY[0] = MIN_INCLINE;
|
||||
for (int i = 1; i < NUM - 1; i++) {
|
||||
BOUNDARIES_ARRAY[i] = MIN_DIVIDED_INCLINE + (i - 1) * STEP;
|
||||
}
|
||||
BOUNDARIES_ARRAY[NUM - 1] = MAX_INCLINE;
|
||||
}
|
||||
|
||||
private final float upperBoundary;
|
||||
|
@ -437,7 +547,7 @@ public class RouteStatistics {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d%% - %d%%", Math.round(getLowerBoundary()), Math.round(getUpperBoundary()));
|
||||
return String.format("%d%% ... %d%%", Math.round(getLowerBoundary()), Math.round(getUpperBoundary()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,123 +584,6 @@ public class RouteStatistics {
|
|||
}
|
||||
}
|
||||
|
||||
public enum RoadClass {
|
||||
MOTORWAY(null, "#ffa200", "motorway", "motorway_link"),
|
||||
STATE_ROAD(null, "#ffae1d", "trunk", "trunk_link", "primary", "primary_link"),
|
||||
ROAD(null, "#ffb939", "secondary", "secondary_link", "tertiary", "tertiary_link", "unclassified"),
|
||||
STREET(null, "#ffc554", "residential", "living_street"),
|
||||
SERVICE(null, "#ffd070", "service"),
|
||||
TRACK(null, "#ffdb8a", "track", "road"),
|
||||
FOOTWAY(null, "#ffe7a7", "footway"),
|
||||
CYCLE_WAY(null, "#fff4c6", "cycleway"),
|
||||
PATH(null, "#fffadd", "path"),
|
||||
UNDEFINED(null, "#DCDBDD", "undefined");
|
||||
|
||||
final Set<String> roadClasses = new TreeSet<>();
|
||||
final String colorAttrName;
|
||||
final String colorName;
|
||||
|
||||
RoadClass(String colorAttrName, String colorName, String... classes) {
|
||||
roadClasses.addAll(Arrays.asList(classes));
|
||||
this.colorAttrName = colorAttrName;
|
||||
this.colorName = colorName;
|
||||
}
|
||||
|
||||
boolean contains(String roadClass) {
|
||||
return roadClasses.contains(roadClass);
|
||||
}
|
||||
|
||||
String getColorAttrName() {
|
||||
return colorAttrName;
|
||||
}
|
||||
|
||||
public String getColorName() {
|
||||
return this.colorName;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RoadSurface {
|
||||
ASPHALT(null, "#6f687e", "asphalt"),
|
||||
CONCRETE(null, "#a7cdf8", "concrete"),
|
||||
UNPAVED(null, "#cc9900", "unpaved"),
|
||||
PAVED(null, "#a7cdf8", "paved"),
|
||||
COMPACTED(null, "#cbcbe8", "compacted"),
|
||||
FINE_GRAVEL(null, "#cbcbe8", "fine_gravel"),
|
||||
PAVING_STONES(null, "#a7cdf8", "paving_stones"),
|
||||
SETT(null, "#a7cdf8", "sett"),
|
||||
COBBLESTONE(null, "#a7cdf8", "cobblestone"),
|
||||
PEBBLESTONE("#a7cdf8", "pebblestone"),
|
||||
STONE(null, "#a7cdf8", "stone"),
|
||||
METAL(null, "#a7cdf8", "metal"),
|
||||
GRASS_PAVER(null, "#a7bef8", "grass_paver"),
|
||||
WOOD(null, "#a7cdf8", "wood"),
|
||||
GRAVEL(null, "#cbcbe8", "gravel"),
|
||||
GROUND(null, "#cc9900", "ground", "mud"),
|
||||
CLAY(null, "#cc9900", "clay"),
|
||||
GRASS(null, "#1fbe1f", "grass"),
|
||||
SAND(null, "#ffd700", "sand"),
|
||||
SALT(null, "#7eded8", "salt"),
|
||||
SNOW(null, "#9feeef", "snow"),
|
||||
ICE(null, "#9feeef", "ice"),
|
||||
UNDEFINED(null, "#e8e8e8", "undefined");
|
||||
|
||||
final Set<String> surfaces = new TreeSet<>();
|
||||
final String colorAttrName;
|
||||
final String colorName;
|
||||
|
||||
RoadSurface(String colorAttrName, String colorName, String... surfaces) {
|
||||
this.surfaces.addAll(Arrays.asList(surfaces));
|
||||
this.colorAttrName = colorAttrName;
|
||||
this.colorName = colorName;
|
||||
}
|
||||
|
||||
boolean contains(String surface) {
|
||||
return surfaces.contains(surface);
|
||||
}
|
||||
|
||||
public String getColorAttrName() {
|
||||
return this.colorAttrName;
|
||||
}
|
||||
|
||||
public String getColorName() {
|
||||
return this.colorName;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RoadSmoothness {
|
||||
EXCELLENT("orangeColor", null, "excellent"),
|
||||
GOOD("brownColor", null, "good"),
|
||||
INTERMEDIATE("darkyellowColor", null, "intermediate"),
|
||||
BAD("yellowColor", null, "bad"),
|
||||
VERY_BAD("lightgreenColor", null, "very_bad"),
|
||||
HORRIBLE("greenColor", null, "horrible"),
|
||||
VERY_HORRIBLE("lightblueColor", null, "very_horrible"),
|
||||
IMPASSABLE("blueColor", null, "impassable"),
|
||||
UNDEFINED("redColor", null, "undefined");
|
||||
|
||||
final Set<String> surfaces = new TreeSet<>();
|
||||
final String colorAttrName;
|
||||
final String colorName;
|
||||
|
||||
RoadSmoothness(String colorAttrName, String colorName, String... surfaces) {
|
||||
this.surfaces.addAll(Arrays.asList(surfaces));
|
||||
this.colorAttrName = colorAttrName;
|
||||
this.colorName = colorName;
|
||||
}
|
||||
|
||||
boolean contains(String surface) {
|
||||
return surfaces.contains(surface);
|
||||
}
|
||||
|
||||
public String getColorAttrName() {
|
||||
return this.colorAttrName;
|
||||
}
|
||||
|
||||
public String getColorName() {
|
||||
return this.colorName;
|
||||
}
|
||||
}
|
||||
|
||||
public enum StatisticType {
|
||||
CLASS,
|
||||
SURFACE,
|
||||
|
|
|
@ -2922,7 +2922,7 @@ Abgedeckte Fläche: %1$s x %2$s</string>
|
|||
<string name="previous_route">Vorherige Route</string>
|
||||
<string name="shared_string_swap">Tauschen</string>
|
||||
<string name="show_more">Mehr anzeigen</string>
|
||||
<string name="tracks_on_map">Tracks auf der Karte</string>
|
||||
<string name="tracks_on_map">Angezeigte Tracks</string>
|
||||
<string name="time_of_day">Tageszeit</string>
|
||||
<string name="by_transport_type">Von %1$s</string>
|
||||
<string name="step_by_step">Schritt für Schritt</string>
|
||||
|
|
|
@ -11,6 +11,49 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="rendering_attr_surface_unpaved_name">Unpaved</string>
|
||||
<string name="rendering_attr_surface_sand_name">Sand</string>
|
||||
<string name="rendering_attr_surface_grass_name">Grass</string>
|
||||
<string name="rendering_attr_surface_grass_paver_name">Grass paver</string>
|
||||
<string name="rendering_attr_surface_ground_name">Ground</string>
|
||||
<string name="rendering_attr_surface_dirt_name">Dirt</string>
|
||||
<string name="rendering_attr_surface_mud_name">Mud</string>
|
||||
<string name="rendering_attr_surface_ice_name">Ice</string>
|
||||
<string name="rendering_attr_surface_salt_name">Salt</string>
|
||||
<string name="rendering_attr_surface_snow_name">Snow</string>
|
||||
<string name="rendering_attr_surface_asphalt_name">Asphalt</string>
|
||||
<string name="rendering_attr_surface_paved_name">Paved</string>
|
||||
<string name="rendering_attr_surface_concrete_name">Concrete</string>
|
||||
<string name="rendering_attr_surface_sett_name">Sett</string>
|
||||
<string name="rendering_attr_surface_cobblestone_name">Cobblestone</string>
|
||||
<string name="rendering_attr_surface_paving_stones_name">Paving stones</string>
|
||||
<string name="rendering_attr_surface_pebblestone_name">Pebblestone</string>
|
||||
<string name="rendering_attr_surface_stone_name">Stone</string>
|
||||
<string name="rendering_attr_surface_metal_name">Metal</string>
|
||||
<string name="rendering_attr_surface_wood_name">Wood</string>
|
||||
<string name="rendering_attr_surface_gravel_name">Gravel</string>
|
||||
<string name="rendering_attr_surface_fine_gravel_name">Fine gravel</string>
|
||||
<string name="rendering_attr_surface_compacted_name">Compacted</string>
|
||||
<string name="rendering_attr_smoothness_excellent_name">Excellent</string>
|
||||
<string name="rendering_attr_smoothness_good_name">Good</string>
|
||||
<string name="rendering_attr_smoothness_intermediate_name">Intermediate</string>
|
||||
<string name="rendering_attr_smoothness_bad_name">Bad</string>
|
||||
<string name="rendering_attr_smoothness_very_bad_name">Very bad</string>
|
||||
<string name="rendering_attr_smoothness_horrible_name">Horrible</string>
|
||||
<string name="rendering_attr_smoothness_very_horrible_name">Very horrible</string>
|
||||
<string name="rendering_attr_smoothness_impassable_name">Impassable</string>
|
||||
<string name="rendering_attr_highway_class_motorway_name">Motorway</string>
|
||||
<string name="rendering_attr_highway_class_state_road_name">State road</string>
|
||||
<string name="rendering_attr_highway_class_road_name">Road</string>
|
||||
<string name="rendering_attr_highway_class_street_name">Street</string>
|
||||
<string name="rendering_attr_highway_class_service_name">Service</string>
|
||||
<string name="rendering_attr_highway_class_footway_name">Footway</string>
|
||||
<string name="rendering_attr_highway_class_track_name">Track</string>
|
||||
<string name="rendering_attr_highway_class_bridleway_name">Bridleway</string>
|
||||
<string name="rendering_attr_highway_class_steps_name">Steps</string>
|
||||
<string name="rendering_attr_highway_class_path_name">Path</string>
|
||||
<string name="rendering_attr_highway_class_cycleway_name">Cycleway</string>
|
||||
<string name="rendering_attr_undefined_name">Undefined</string>
|
||||
<string name="release_3_3">
|
||||
• New \'Directions\' screen: Displays Home and Work destination buttons, \'previous route\' shortcut, list of active GPX tracks and markers, search history\n\n
|
||||
• Additional info under \'Route details\': road types, surface, steepness, smoothness\n\n
|
||||
|
@ -31,7 +74,7 @@
|
|||
<string name="sit_on_the_stop">Board at stop</string>
|
||||
<string name="shared_string_swap">Swap</string>
|
||||
<string name="show_more">Show more</string>
|
||||
<string name="tracks_on_map">Tracks on the map</string>
|
||||
<string name="tracks_on_map">Displayed tracks</string>
|
||||
<string name="quick_action_show_hide_gpx_tracks">Show/Hide GPX Tracks</string>
|
||||
<string name="quick_action_show_hide_gpx_tracks_descr">Tapping this action button shows or hides selected GPX tracks on the map</string>
|
||||
<string name="quick_action_gpx_tracks_hide">Hide GPX Tracks</string>
|
||||
|
|
|
@ -102,6 +102,7 @@ import net.osmand.plus.views.TurnPathHelper;
|
|||
import net.osmand.plus.views.controls.HorizontalSwipeConfirm;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.router.RouteSegmentResult;
|
||||
import net.osmand.router.RouteStatistics;
|
||||
import net.osmand.router.RouteStatistics.Incline;
|
||||
|
@ -508,7 +509,9 @@ public class ShowRouteInfoDialogFragment extends BaseOsmAndFragment {
|
|||
elevationDataSet = statisticCard.getElevationDataSet();
|
||||
List<RouteSegmentResult> route = routingHelper.getRoute().getOriginalRoute();
|
||||
if (route != null) {
|
||||
RouteStatistics routeStatistics = RouteStatistics.newRouteStatistic(route);
|
||||
RenderingRulesStorage currentRenderer = app.getRendererRegistry().getCurrentSelectedRenderer();
|
||||
RenderingRulesStorage defaultRender = app.getRendererRegistry().defaultRender();
|
||||
RouteStatistics routeStatistics = RouteStatistics.newRouteStatistic(route, currentRenderer,defaultRender, nightMode);
|
||||
GPXUtilities.GPXTrackAnalysis analysis = gpx.getAnalysis(0);
|
||||
|
||||
RouteInfoCard routeClassCard = new RouteInfoCard(mapActivity, routeStatistics.getRouteClassStatistic(), analysis);
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
|
@ -92,7 +91,6 @@ import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter;
|
|||
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
|
||||
import net.osmand.plus.routing.RouteCalculationResult;
|
||||
import net.osmand.render.RenderingRuleProperty;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.router.RouteStatistics;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -1268,8 +1266,7 @@ public class GpxUiHelper {
|
|||
@NonNull HorizontalBarChart mChart,
|
||||
@NonNull RouteStatistics.Statistics<E> routeStatistics,
|
||||
@NonNull GPXTrackAnalysis analysis,
|
||||
boolean useRightAxis,
|
||||
boolean nightMode) {
|
||||
boolean useRightAxis) {
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
@ -1290,7 +1287,7 @@ public class GpxUiHelper {
|
|||
for (int i = 0; i < stacks.length; i++) {
|
||||
RouteStatistics.RouteSegmentAttribute segment = segments.get(i);
|
||||
stacks[i] = segment.getDistance() / divX;
|
||||
colors[i] = getColorFromRouteSegmentAttribute(app, segment, nightMode);
|
||||
colors[i] = segment.getColor();
|
||||
}
|
||||
entries.add(new BarEntry(0, stacks));
|
||||
BarDataSet barDataSet = new BarDataSet(entries, "");
|
||||
|
@ -1304,31 +1301,6 @@ public class GpxUiHelper {
|
|||
return dataSet;
|
||||
}
|
||||
|
||||
public static int getColorFromRouteSegmentAttribute(OsmandApplication app, RouteStatistics.RouteSegmentAttribute segment, boolean nightMode) {
|
||||
String colorAttrName = segment.getColorAttrName();
|
||||
String colorName = segment.getColorName();
|
||||
int color = 0;
|
||||
if (colorName != null) {
|
||||
try {
|
||||
color = Color.parseColor(colorName);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} else if (colorAttrName != null) {
|
||||
color = GpxUiHelper.getColorFromStyle(app, colorAttrName, nightMode);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public static int getColorFromStyle(OsmandApplication app, String colorAttrName, boolean nightMode) {
|
||||
RenderingRulesStorage rrs = app.getRendererRegistry().getCurrentSelectedRenderer();
|
||||
RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs);
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
if (req.searchRenderingAttribute(colorAttrName)) {
|
||||
return req.getIntPropertyValue(rrs.PROPS.R_ATTR_COLOR_VALUE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static OrderedLineDataSet createGPXElevationDataSet(@NonNull OsmandApplication ctx,
|
||||
@NonNull LineChart mChart,
|
||||
@NonNull GPXTrackAnalysis analysis,
|
||||
|
|
|
@ -484,7 +484,7 @@ public class WaypointDialogHelper {
|
|||
final BaseBottomSheetItem[] addWaypointItem = new BaseBottomSheetItem[1];
|
||||
addWaypointItem[0] = new SimpleBottomSheetItem.Builder()
|
||||
.setIcon(getContentIcon(R.drawable.ic_action_plus))
|
||||
.setTitle(getString(R.string.add_waypoint))
|
||||
.setTitle(getString(R.string.add_intermediate_point))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
|
|
@ -800,6 +800,12 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
|
|||
});
|
||||
|
||||
View cancelButton = mainView.findViewById(R.id.cancel_button);
|
||||
TextView cancelButtonText = (TextView) mainView.findViewById(R.id.cancel_button_descr);
|
||||
if (routingHelper.isRouteCalculated() || routingHelper.isRouteBeingCalculated() || isTransportRouteCalculated()) {
|
||||
cancelButtonText.setText(R.string.shared_string_dismiss);
|
||||
} else {
|
||||
cancelButtonText.setText(R.string.shared_string_cancel);
|
||||
}
|
||||
AndroidUtils.setBackground(app, cancelButton, nightMode, R.color.card_and_list_background_light, R.color.card_and_list_background_dark);
|
||||
cancelButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
|
@ -1236,8 +1242,8 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
|
|||
viaLayout.setVisibility(View.VISIBLE);
|
||||
viaLayoutDivider.setVisibility(View.VISIBLE);
|
||||
((TextView) mainView.findViewById(R.id.ViaView)).setText(via);
|
||||
((TextView) mainView.findViewById(R.id.ViaSubView)).setText(mapActivity.getString(R.string.intermediate_destinations) + ": " +
|
||||
mapActivity.getMyApplication().getTargetPointsHelper().getIntermediatePoints().size());
|
||||
((TextView) mainView.findViewById(R.id.ViaSubView)).setText(mapActivity.getString(R.string.intermediate_destinations) + " (" +
|
||||
mapActivity.getMyApplication().getTargetPointsHelper().getIntermediatePoints().size() + ")");
|
||||
}
|
||||
FrameLayout viaButton = (FrameLayout) mainView.findViewById(R.id.via_button);
|
||||
|
||||
|
|
|
@ -600,7 +600,7 @@ public class WaypointsFragment extends BaseOsmAndFragment implements ObservableS
|
|||
if (isAdded()) {
|
||||
final TextViewEx title = (TextViewEx) view.findViewById(R.id.title);
|
||||
int pointsSize = app.getTargetPointsHelper().getAllPoints().size();
|
||||
String text = getString(R.string.shared_string_target_points) + ": " + (pointsSize != 0 ? pointsSize : 1);
|
||||
String text = getString(R.string.shared_string_target_points) + " (" + (pointsSize != 0 ? pointsSize : 1) + ")";
|
||||
title.setText(text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,12 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.plus.OsmAndFormatter;
|
||||
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.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RouteInfoCard extends BaseCard {
|
||||
|
||||
|
@ -49,7 +46,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, nightMode);
|
||||
BarData barData = GpxUiHelper.buildStatisticChart(app, chart, routeStatistics, analysis, true);
|
||||
chart.setData(barData);
|
||||
LinearLayout container = view.findViewById(R.id.route_items);
|
||||
attachLegend(container, routeStatistics);
|
||||
|
@ -82,9 +79,11 @@ public class RouteInfoCard extends BaseCard {
|
|||
Map<E, RouteStatistics.RouteSegmentAttribute<E>> partition = routeStatistics.getPartition();
|
||||
for (E key : partition.keySet()) {
|
||||
RouteStatistics.RouteSegmentAttribute<E> segment = partition.get(key);
|
||||
int color = GpxUiHelper.getColorFromRouteSegmentAttribute(app, segment, nightMode);
|
||||
int color = segment.getColor();
|
||||
Drawable circle = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color);
|
||||
Spannable text = getSpanLegend(key.toString().toLowerCase(), segment);
|
||||
String propertyName = segment.getPropertyName();
|
||||
String name = SettingsNavigationActivity.getStringPropertyName(app, propertyName, propertyName.replaceAll("_", " "));
|
||||
Spannable text = getSpanLegend(name, segment);
|
||||
|
||||
TextView legend = new TextView(app);
|
||||
AndroidUtils.setTextPrimaryColor(app, legend, nightMode);
|
||||
|
|
|
@ -135,6 +135,6 @@ public class TracksCard extends BaseCard {
|
|||
}
|
||||
|
||||
((TextView) view.findViewById(R.id.gpx_card_title)).setText(
|
||||
String.format("%s — %d", app.getString(R.string.tracks_on_map), list.size()));
|
||||
String.format("%s (%d)", app.getString(R.string.tracks_on_map), list.size()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue