2018-10-26 18:07:14 +02:00
|
|
|
package net.osmand.router;
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
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;
|
2018-10-26 18:07:14 +02:00
|
|
|
|
|
|
|
public class RouteStatistics {
|
|
|
|
|
2018-11-02 17:33:33 +01:00
|
|
|
private final List<RouteSegmentResult> route;
|
|
|
|
|
|
|
|
private RouteStatistics(List<RouteSegmentResult> route) {
|
|
|
|
this.route = route;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2018-10-31 17:00:07 +01:00
|
|
|
public static RouteStatistics newRouteStatistic(List<RouteSegmentResult> route) {
|
2018-11-02 17:33:33 +01:00
|
|
|
return new RouteStatistics(route);
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-05 16:29:10 +01:00
|
|
|
public Statistics getRouteSurfaceStatistic() {
|
2018-11-02 17:33:33 +01:00
|
|
|
RouteStatisticComputer statisticComputer = new RouteSurfaceStatisticComputer(route);
|
|
|
|
return statisticComputer.computeStatistic();
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-05 16:29:10 +01:00
|
|
|
public Statistics getRouteSmoothnessStatistic() {
|
2018-11-02 17:33:33 +01:00
|
|
|
RouteStatisticComputer statisticComputer = new RouteSmoothnessStatisticComputer(route);
|
|
|
|
return statisticComputer.computeStatistic();
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-05 16:29:10 +01:00
|
|
|
public Statistics getRouteClassStatistic() {
|
2018-11-02 17:33:33 +01:00
|
|
|
RouteStatisticComputer statisticComputer = new RouteClassStatisticComputer(route);
|
|
|
|
return statisticComputer.computeStatistic();
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public Statistics getRouteSteepnessStatistic(List<Incline> inclines) {
|
|
|
|
RouteStatisticComputer statisticComputer = new RouteSteepnessStatisticComputer(inclines);
|
2018-11-02 17:33:33 +01:00
|
|
|
return statisticComputer.computeStatistic();
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
private abstract static class RouteStatisticComputer<E extends Comparable<E>> {
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2018-10-31 17:00:07 +01:00
|
|
|
private final List<RouteSegmentResult> route;
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
private final StatisticType type;
|
|
|
|
|
|
|
|
public RouteStatisticComputer(List<RouteSegmentResult> route, StatisticType type) {
|
2018-11-13 17:37:42 +01:00
|
|
|
this.route = route;
|
2019-03-01 12:35:59 +01:00
|
|
|
this.type = type;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
protected Map<E, RouteSegmentAttribute<E>> makePartition(List<RouteSegmentAttribute<E>> routeAttributes) {
|
|
|
|
Map<E, RouteSegmentAttribute<E>> partition = new TreeMap<>();
|
|
|
|
for (RouteSegmentAttribute<E> attribute : routeAttributes) {
|
|
|
|
E key = attribute.getAttribute();
|
|
|
|
RouteSegmentAttribute<E> pattr = partition.get(key);
|
2018-11-02 17:33:33 +01:00
|
|
|
if (pattr == null) {
|
2019-03-01 12:35:59 +01:00
|
|
|
pattr = new RouteSegmentAttribute<>(attribute);
|
2018-11-02 17:33:33 +01:00
|
|
|
partition.put(key, pattr);
|
|
|
|
}
|
|
|
|
pattr.incrementDistanceBy(attribute.getDistance());
|
|
|
|
}
|
|
|
|
return partition;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
private float computeTotalDistance(List<RouteSegmentAttribute<E>> attributes) {
|
2018-11-02 17:33:33 +01:00
|
|
|
float distance = 0f;
|
|
|
|
for (RouteSegmentAttribute attribute : attributes) {
|
|
|
|
distance += attribute.getDistance();
|
|
|
|
}
|
|
|
|
return distance;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected List<RouteSegmentResult> getRoute() {
|
2018-10-31 17:00:07 +01:00
|
|
|
return route;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
protected List<RouteSegmentAttribute<E>> processRoute() {
|
2018-10-26 18:07:14 +02:00
|
|
|
int index = 0;
|
2018-11-14 12:22:20 +01:00
|
|
|
List<RouteSegmentAttribute<E>> routes = new ArrayList<>();
|
|
|
|
E prev = null;
|
2018-10-31 17:00:07 +01:00
|
|
|
for (RouteSegmentResult segment : getRoute()) {
|
2018-11-14 12:22:20 +01:00
|
|
|
E current = getAttribute(segment);
|
2018-10-26 18:07:14 +02:00
|
|
|
if (prev != null && !prev.equals(current)) {
|
|
|
|
index++;
|
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
if (index >= routes.size()) {
|
2019-03-01 12:35:59 +01:00
|
|
|
String colorAttrName = getColorAttrName(current);
|
|
|
|
String colorName = getColorName(current);
|
|
|
|
routes.add(new RouteSegmentAttribute<>(index, current, colorAttrName, colorName));
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
RouteSegmentAttribute surface = routes.get(index);
|
2018-10-26 18:07:14 +02:00
|
|
|
surface.incrementDistanceBy(segment.getDistance());
|
|
|
|
prev = current;
|
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
return routes;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public Statistics<E> computeStatistic() {
|
|
|
|
List<RouteSegmentAttribute<E>> routeAttributes = processRoute();
|
|
|
|
Map<E, RouteSegmentAttribute<E>> partition = makePartition(routeAttributes);
|
2018-11-02 17:33:33 +01:00
|
|
|
float totalDistance = computeTotalDistance(routeAttributes);
|
2019-03-01 12:35:59 +01:00
|
|
|
return new Statistics<>(routeAttributes, partition, totalDistance, type);
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public abstract E getAttribute(RouteSegmentResult segment);
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
public abstract String getColorAttrName(E attribute);
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
public abstract String getColorName(E attribute);
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
|
2019-03-01 17:39:19 +01:00
|
|
|
private static class RouteSurfaceStatisticComputer extends RouteStatisticComputer<RoadSurface> {
|
2018-11-02 17:33:33 +01:00
|
|
|
|
|
|
|
public RouteSurfaceStatisticComputer(List<RouteSegmentResult> route) {
|
2019-03-01 12:35:59 +01:00
|
|
|
super(route, StatisticType.SURFACE);
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-10-26 18:07:14 +02:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public RoadSurface getAttribute(RouteSegmentResult segment) {
|
2018-10-31 17:00:07 +01:00
|
|
|
String segmentSurface = segment.getSurface();
|
|
|
|
if (segmentSurface == null) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadSurface.UNDEFINED;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
for (RoadSurface roadSurface : RoadSurface.values()) {
|
|
|
|
if (roadSurface.contains(segmentSurface)) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return roadSurface;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadSurface.UNDEFINED;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorAttrName(RoadSurface attribute) {
|
|
|
|
return attribute.getColorAttrName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorName(RoadSurface attribute) {
|
|
|
|
return attribute.getColorName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2019-03-01 17:39:19 +01:00
|
|
|
private static class RouteSmoothnessStatisticComputer extends RouteStatisticComputer<RoadSmoothness> {
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2018-11-02 17:33:33 +01:00
|
|
|
public RouteSmoothnessStatisticComputer(List<RouteSegmentResult> route) {
|
2019-03-01 12:35:59 +01:00
|
|
|
super(route, StatisticType.SMOOTHNESS);
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-10-26 18:07:14 +02:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public RoadSmoothness getAttribute(RouteSegmentResult segment) {
|
2019-03-01 12:35:59 +01:00
|
|
|
String segmentSmoothness = segment.getSmoothness();
|
2018-11-13 17:37:42 +01:00
|
|
|
if (segmentSmoothness == null) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadSmoothness.UNDEFINED;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
for (RoadSmoothness roadSmoothness : RoadSmoothness.values()) {
|
|
|
|
if (roadSmoothness.contains(segmentSmoothness)) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return roadSmoothness;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadSmoothness.UNDEFINED;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorAttrName(RoadSmoothness attribute) {
|
|
|
|
return attribute.getColorAttrName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorName(RoadSmoothness attribute) {
|
|
|
|
return attribute.getColorName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 17:39:19 +01:00
|
|
|
private static class RouteClassStatisticComputer extends RouteStatisticComputer<RoadClass> {
|
2018-11-02 17:33:33 +01:00
|
|
|
|
|
|
|
public RouteClassStatisticComputer(List<RouteSegmentResult> route) {
|
2019-03-01 12:35:59 +01:00
|
|
|
super(route, StatisticType.CLASS);
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-10-26 18:07:14 +02:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public RoadClass getAttribute(RouteSegmentResult segment) {
|
2018-10-31 17:00:07 +01:00
|
|
|
String segmentClass = segment.getHighway();
|
|
|
|
if (segmentClass == null) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadClass.UNDEFINED;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
for (RoadClass roadClass : RoadClass.values()) {
|
|
|
|
if (roadClass.contains(segmentClass)) {
|
2019-03-01 17:39:19 +01:00
|
|
|
return roadClass;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-01 17:39:19 +01:00
|
|
|
return RoadClass.UNDEFINED;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorAttrName(RoadClass attribute) {
|
|
|
|
return attribute.getColorAttrName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
2019-03-01 17:39:19 +01:00
|
|
|
public String getColorName(RoadClass attribute) {
|
|
|
|
return attribute.getColorName();
|
2019-03-01 12:35:59 +01:00
|
|
|
}
|
|
|
|
}
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
private static class RouteSteepnessStatisticComputer extends RouteStatisticComputer<Boundaries> {
|
2018-11-02 17:33:33 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
private static final String POSITIVE_INCLINE_COLOR_ATTR_NAME = "greenColor";
|
|
|
|
private static final String NEGATIVE_INCLINE_COLOR_ATTR_NAME = "redColor";
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
private final List<Incline> inclines;
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public RouteSteepnessStatisticComputer(List<Incline> inclines) {
|
2019-03-01 12:35:59 +01:00
|
|
|
super(null, StatisticType.STEEPNESS);
|
2018-11-13 17:37:42 +01:00
|
|
|
this.inclines = inclines;
|
2018-11-02 17:33:33 +01:00
|
|
|
}
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-02 17:33:33 +01:00
|
|
|
@Override
|
2018-11-14 12:22:20 +01:00
|
|
|
public List<RouteSegmentAttribute<Boundaries>> processRoute() {
|
|
|
|
List<RouteSegmentAttribute<Boundaries>> routeInclines = new ArrayList<>();
|
2018-11-02 17:33:33 +01:00
|
|
|
int index = 0;
|
2018-11-14 12:22:20 +01:00
|
|
|
Boundaries prev = null;
|
2018-11-13 17:37:42 +01:00
|
|
|
Incline prevIncline = null;
|
|
|
|
for (Incline incline : inclines) {
|
2018-11-14 12:22:20 +01:00
|
|
|
Boundaries current = incline.getBoundaries();
|
2018-11-02 17:33:33 +01:00
|
|
|
if (prev != null && !prev.equals(current)) {
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
if (index >= routeInclines.size()) {
|
2019-03-01 12:35:59 +01:00
|
|
|
String colorAttrName = getColorAttrName(current);
|
|
|
|
String colorName = getColorName(current);
|
|
|
|
RouteSegmentAttribute<Boundaries> attribute = new RouteSegmentAttribute<>(index, current, colorAttrName, colorName);
|
2018-11-14 12:22:20 +01:00
|
|
|
if (prevIncline != null) {
|
2018-11-13 17:37:42 +01:00
|
|
|
attribute.setInitDistance(prevIncline.getDistance());
|
|
|
|
}
|
|
|
|
routeInclines.add(attribute);
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
RouteSegmentAttribute routeIncline = routeInclines.get(index);
|
2018-11-13 17:37:42 +01:00
|
|
|
routeIncline.relativeSum(incline.getDistance());
|
2018-11-02 17:33:33 +01:00
|
|
|
prev = current;
|
2018-11-13 17:37:42 +01:00
|
|
|
prevIncline = incline;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
return routeInclines;
|
|
|
|
}
|
|
|
|
|
2018-11-02 17:33:33 +01:00
|
|
|
@Override
|
2018-11-14 12:22:20 +01:00
|
|
|
public Boundaries getAttribute(RouteSegmentResult segment) {
|
|
|
|
/*
|
|
|
|
no-op
|
|
|
|
*/
|
2018-11-02 17:33:33 +01:00
|
|
|
return null;
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
@Override
|
2019-03-01 12:35:59 +01:00
|
|
|
public String getColorAttrName(Boundaries attribute) {
|
2018-11-14 12:22:20 +01:00
|
|
|
return attribute.getLowerBoundary() >= 0 ? POSITIVE_INCLINE_COLOR_ATTR_NAME : NEGATIVE_INCLINE_COLOR_ATTR_NAME;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
@Override
|
|
|
|
public String getColorName(Boundaries attribute) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2018-11-02 17:33:33 +01:00
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public static class RouteSegmentAttribute<E> {
|
2018-10-26 18:07:14 +02:00
|
|
|
|
|
|
|
private final int index;
|
2018-11-14 12:22:20 +01:00
|
|
|
private final E attribute;
|
2018-11-13 17:37:42 +01:00
|
|
|
private final String colorAttrName;
|
2019-03-01 12:35:59 +01:00
|
|
|
private final String colorName;
|
2018-10-26 18:07:14 +02:00
|
|
|
|
|
|
|
private float distance;
|
2018-11-13 17:37:42 +01:00
|
|
|
private float initDistance;
|
2018-10-26 18:07:14 +02:00
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
public RouteSegmentAttribute(int index, E attribute, String colorAttrName, String colorName) {
|
2018-10-26 18:07:14 +02:00
|
|
|
this.index = index;
|
|
|
|
this.attribute = attribute;
|
2018-11-13 17:37:42 +01:00
|
|
|
this.colorAttrName = colorAttrName;
|
2019-03-01 12:35:59 +01:00
|
|
|
this.colorName = colorName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public RouteSegmentAttribute(RouteSegmentAttribute<E> segmentAttribute) {
|
|
|
|
this.index = segmentAttribute.getIndex();
|
|
|
|
this.attribute = segmentAttribute.getAttribute();
|
|
|
|
this.colorAttrName = segmentAttribute.getColorAttrName();
|
|
|
|
this.colorName = segmentAttribute.getColorName();
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getIndex() {
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public E getAttribute() {
|
2018-10-26 18:07:14 +02:00
|
|
|
return attribute;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getDistance() {
|
|
|
|
return distance;
|
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public void setInitDistance(float initDistance) {
|
|
|
|
this.initDistance = initDistance;
|
|
|
|
}
|
|
|
|
|
2018-10-26 18:07:14 +02:00
|
|
|
public void incrementDistanceBy(float distance) {
|
|
|
|
this.distance += distance;
|
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public void relativeSum(float distance) {
|
|
|
|
this.distance = this.distance + ((distance - this.initDistance) - this.distance);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getColorAttrName() {
|
|
|
|
return colorAttrName;
|
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
public String getColorName() {
|
|
|
|
return colorName;
|
|
|
|
}
|
|
|
|
|
2018-10-26 18:07:14 +02:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
2018-11-13 17:37:42 +01:00
|
|
|
return "RouteSegmentAttribute{" +
|
2018-10-26 18:07:14 +02:00
|
|
|
"index=" + index +
|
|
|
|
", attribute='" + attribute + '\'' +
|
2018-11-13 17:37:42 +01:00
|
|
|
", colorAttrName='" + colorAttrName + '\'' +
|
2018-10-26 18:07:14 +02:00
|
|
|
", distance=" + distance +
|
|
|
|
'}';
|
|
|
|
}
|
|
|
|
}
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public static class Incline {
|
2018-10-31 17:00:07 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
private float inclineValue;
|
2018-11-02 17:33:33 +01:00
|
|
|
private final float distance;
|
2018-11-13 17:37:42 +01:00
|
|
|
private final Boundaries boundaries;
|
2018-11-02 17:33:33 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public Incline(float inclineValue, float distance) {
|
2018-11-02 17:33:33 +01:00
|
|
|
this.inclineValue = inclineValue;
|
|
|
|
this.distance = distance;
|
2018-11-13 17:37:42 +01:00
|
|
|
this.boundaries = Boundaries.newBoundariesFor(inclineValue);
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public float getValue() {
|
2018-11-02 17:33:33 +01:00
|
|
|
return inclineValue;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
2018-11-02 17:33:33 +01:00
|
|
|
public float getDistance() {
|
|
|
|
return distance;
|
|
|
|
}
|
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public Boundaries getBoundaries() {
|
|
|
|
return this.boundaries;
|
2018-10-31 17:00:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2018-11-02 17:33:33 +01:00
|
|
|
return "Incline{" +
|
|
|
|
", incline=" + inclineValue +
|
|
|
|
", distance=" + distance +
|
2018-10-31 17:00:07 +01:00
|
|
|
'}';
|
|
|
|
}
|
|
|
|
}
|
2018-11-05 16:29:10 +01:00
|
|
|
|
2018-11-13 17:37:42 +01:00
|
|
|
public static class Boundaries implements Comparable<Boundaries> {
|
|
|
|
|
|
|
|
private static final int MIN_INCLINE = -100;
|
|
|
|
private static final int MAX_INCLINE = 100;
|
|
|
|
private static final int STEP = 4;
|
|
|
|
private static final int NUM;
|
2018-11-14 12:22:20 +01:00
|
|
|
private static final int[] BOUNDARIES_ARRAY;
|
2018-11-13 17:37:42 +01:00
|
|
|
|
|
|
|
static {
|
2018-11-14 12:22:20 +01:00
|
|
|
NUM = ((MAX_INCLINE - MIN_INCLINE) / STEP + 1);
|
|
|
|
BOUNDARIES_ARRAY = new int[NUM];
|
2018-11-13 17:37:42 +01:00
|
|
|
for (int i = 0; i < NUM; i++) {
|
2018-11-14 12:22:20 +01:00
|
|
|
BOUNDARIES_ARRAY[i] = MIN_INCLINE + i * STEP;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private final float upperBoundary;
|
|
|
|
private final float lowerBoundary;
|
|
|
|
|
|
|
|
private Boundaries(float upperBoundary, float lowerBoundary) {
|
|
|
|
this.upperBoundary = upperBoundary;
|
|
|
|
this.lowerBoundary = lowerBoundary;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Boundaries newBoundariesFor(float incline) {
|
|
|
|
if (incline > MAX_INCLINE) {
|
|
|
|
return new Boundaries(MAX_INCLINE, MAX_INCLINE - STEP);
|
|
|
|
}
|
|
|
|
if (incline < MIN_INCLINE) {
|
|
|
|
return new Boundaries(MIN_INCLINE + STEP, MIN_INCLINE);
|
|
|
|
}
|
|
|
|
for (int i = 1; i < NUM; i++) {
|
2018-11-14 12:22:20 +01:00
|
|
|
if (incline >= BOUNDARIES_ARRAY[i - 1] && incline < BOUNDARIES_ARRAY[i]) {
|
|
|
|
return new Boundaries(BOUNDARIES_ARRAY[i], BOUNDARIES_ARRAY[i - 1]);
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getUpperBoundary() {
|
|
|
|
return upperBoundary;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getLowerBoundary() {
|
|
|
|
return lowerBoundary;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (this == o) return true;
|
|
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
|
|
|
|
|
|
Boundaries that = (Boundaries) o;
|
|
|
|
|
|
|
|
if (Float.compare(that.upperBoundary, upperBoundary) != 0) return false;
|
|
|
|
return Float.compare(that.lowerBoundary, lowerBoundary) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
int result = (upperBoundary != +0.0f ? Float.floatToIntBits(upperBoundary) : 0);
|
|
|
|
result = 31 * result + (lowerBoundary != +0.0f ? Float.floatToIntBits(lowerBoundary) : 0);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int compareTo(Boundaries boundaries) {
|
|
|
|
return (int) (getLowerBoundary() - boundaries.getLowerBoundary());
|
|
|
|
}
|
2018-11-14 12:22:20 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2019-03-07 08:36:28 +01:00
|
|
|
return String.format("%d%% - %d%%", Math.round(getLowerBoundary()), Math.round(getUpperBoundary()));
|
2018-11-14 12:22:20 +01:00
|
|
|
}
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public static class Statistics<E> {
|
2018-11-05 16:29:10 +01:00
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
private final List<RouteSegmentAttribute<E>> elements;
|
|
|
|
private final Map<E, RouteSegmentAttribute<E>> partition;
|
2018-11-05 16:29:10 +01:00
|
|
|
private final float totalDistance;
|
2019-03-01 12:35:59 +01:00
|
|
|
private final StatisticType type;
|
2018-11-05 16:29:10 +01:00
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
private Statistics(List<RouteSegmentAttribute<E>> elements,
|
|
|
|
Map<E, RouteSegmentAttribute<E>> partition,
|
2019-03-01 12:35:59 +01:00
|
|
|
float totalDistance, StatisticType type) {
|
2018-11-05 16:29:10 +01:00
|
|
|
this.elements = elements;
|
|
|
|
this.partition = partition;
|
|
|
|
this.totalDistance = totalDistance;
|
2019-03-01 12:35:59 +01:00
|
|
|
this.type = type;
|
2018-11-05 16:29:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public float getTotalDistance() {
|
|
|
|
return totalDistance;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public List<RouteSegmentAttribute<E>> getElements() {
|
2018-11-13 17:37:42 +01:00
|
|
|
return elements;
|
2018-11-05 16:29:10 +01:00
|
|
|
}
|
|
|
|
|
2018-11-14 12:22:20 +01:00
|
|
|
public Map<E, RouteSegmentAttribute<E>> getPartition() {
|
2018-11-13 17:37:42 +01:00
|
|
|
return partition;
|
2018-11-05 16:29:10 +01:00
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
public StatisticType getStatisticType() {
|
|
|
|
return type;
|
2018-11-13 17:37:42 +01:00
|
|
|
}
|
2018-11-05 16:29:10 +01:00
|
|
|
}
|
|
|
|
|
2019-03-01 12:35:59 +01:00
|
|
|
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"),
|
2019-03-01 17:39:19 +01:00
|
|
|
UNPAVED(null, "#cc9900", "unpaved"),
|
|
|
|
PAVED(null, "#a7cdf8", "paved"),
|
2019-03-01 12:35:59 +01:00
|
|
|
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"),
|
2019-03-01 17:39:19 +01:00
|
|
|
WOOD(null, "#a7cdf8", "wood"),
|
|
|
|
GRAVEL(null, "#cbcbe8", "gravel"),
|
|
|
|
GROUND(null, "#cc9900", "ground", "mud"),
|
|
|
|
CLAY(null, "#cc9900", "clay"),
|
2019-03-01 12:35:59 +01:00
|
|
|
GRASS(null, "#1fbe1f", "grass"),
|
|
|
|
SAND(null, "#ffd700", "sand"),
|
|
|
|
SALT(null, "#7eded8", "salt"),
|
|
|
|
SNOW(null, "#9feeef", "snow"),
|
|
|
|
ICE(null, "#9feeef", "ice"),
|
2019-03-01 17:39:19 +01:00
|
|
|
UNDEFINED(null, "#e8e8e8", "undefined");
|
2019-03-01 12:35:59 +01:00
|
|
|
|
|
|
|
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"),
|
2019-03-01 17:39:19 +01:00
|
|
|
IMPASSABLE("blueColor", null, "impassable"),
|
|
|
|
UNDEFINED("redColor", null, "undefined");
|
2019-03-01 12:35:59 +01:00
|
|
|
|
|
|
|
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,
|
|
|
|
SMOOTHNESS,
|
|
|
|
STEEPNESS
|
|
|
|
}
|
2018-10-26 18:07:14 +02:00
|
|
|
}
|