RouteResult.java
/* This file is part of Openrouteservice.
*
* Openrouteservice is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, see <https://www.gnu.org/licenses/>.
*/
package org.heigit.ors.routing;
import com.graphhopper.ResponsePath;
import com.graphhopper.util.PointList;
import org.heigit.ors.common.DistanceUnit;
import org.heigit.ors.util.FormatUtility;
import org.heigit.ors.util.GeomUtility;
import org.locationtech.jts.geom.Coordinate;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
public class RouteResult {
private Coordinate[] geometry;
private List<RouteSegment> segments;
private final List<RouteLeg> legs;
private List<RouteExtraInfo> extraInfo;
private PointList pointlist;
private String graphDate = "";
private final List<Integer> wayPointsIndices;
private final List<RouteWarning> routeWarnings;
private final RouteSummary summary;
private ZonedDateTime departure;
private ZonedDateTime arrival;
public static final String KEY_TIMEZONE_DEPARTURE = "timezone.departure";
public static final String KEY_TIMEZONE_ARRIVAL = "timezone.arrival";
public static final String DEFAULT_TIMEZONE = "Europe/Berlin";
public RouteResult(int routeExtras) {
segments = new ArrayList<>();
summary = new RouteSummary();
if (routeExtras != 0)
extraInfo = new ArrayList<>();
routeWarnings = new ArrayList<>();
wayPointsIndices = new ArrayList<>();
legs = new ArrayList<>();
}
public void addSegment(RouteSegment seg) {
segments.add(seg);
}
public List<RouteSegment> getSegments() {
return segments;
}
public void resetSegments() {
segments = new ArrayList<>();
}
public RouteSummary getSummary() {
return summary;
}
public Coordinate[] getGeometry() {
return geometry;
}
public void addPointsToGeometry(PointList points, boolean skipFirstPoint, boolean includeElevation) {
int index = skipFirstPoint ? 1 : 0;
if (geometry == null) {
int newSize = points.size() - index;
geometry = new Coordinate[newSize];
if (includeElevation && points.is3D()) {
for (int i = index; i < newSize; ++i)
geometry[i] = new Coordinate(points.getLon(i), points.getLat(i), points.getEle(i));
} else {
for (int i = index; i < newSize; ++i)
geometry[i] = new Coordinate(points.getLon(i), points.getLat(i));
}
} else {
int oldSize = geometry.length;
int pointsSize = points.size() - index;
int newSize = oldSize + pointsSize;
Coordinate[] coords = new Coordinate[newSize];
System.arraycopy(geometry, 0, coords, 0, oldSize);
for (int i = 0; i < pointsSize; ++i) {
int j = i + index;
if (includeElevation && points.is3D())
coords[oldSize + i] = new Coordinate(points.getLon(j), points.getLat(j), points.getEle(j));
else
coords[oldSize + i] = new Coordinate(points.getLon(j), points.getLat(j));
}
geometry = coords;
}
}
public List<RouteExtraInfo> getExtraInfo() {
return extraInfo;
}
private void addExtraInfo(RouteExtraInfo info) {
if (extraInfo == null)
extraInfo = new ArrayList<>();
extraInfo.add(info);
}
public void addWarning(RouteWarning warning) {
routeWarnings.add(warning);
}
public List<RouteWarning> getWarnings() {
return routeWarnings;
}
public void addPointlist(PointList pointlistToAdd) {
if (pointlist == null) {
pointlist = new PointList(pointlistToAdd.size(), pointlistToAdd.is3D());
}
pointlist.add(pointlistToAdd);
}
public List<Integer> getWayPointsIndices() {
return wayPointsIndices;
}
public void addWayPointIndex(int index) {
wayPointsIndices.add(index);
}
void addExtras(RoutingRequest request, List<RouteExtraInfo> extras) {
if (extras == null)
return;
// add the extras if they generate a "warning" or they were requested
for (RouteExtraInfo extra : extras) {
if (extra.isUsedForWarnings() && extra.getWarningGraphExtension().generatesWarning(extra)) {
addWarning(extra.getWarningGraphExtension().getWarning());
addExtraInfo(extra);
} else if (RouteExtraInfoFlag.isSet(request.getExtraInfo(), RouteExtraInfoFlag.getFromString(extra.getName()))) {
addExtraInfo(extra);
}
}
}
/**
* set route summary values according to segments in this route and request parameters
*
* @param request for parameter lookup (units, include elevation)
*/
void calculateRouteSummary(RoutingRequest request) {
calculateRouteSummary(request, null);
}
void calculateRouteSummary(RoutingRequest request, ResponsePath path) {
double distance = 0.0;
double duration = 0.0;
for (RouteSegment seg : getSegments()) {
distance += seg.getDistance();
duration += seg.getDuration();
}
summary.setDuration(duration);
summary.setDistance(FormatUtility.roundToDecimalsForUnits(distance, request.getUnits()));
double averageSpeed = 0;
if (duration > 0)
averageSpeed = distance / (request.getUnits() == DistanceUnit.METERS ? 1000 : 1) / (duration / 3600);
summary.setAverageSpeed(FormatUtility.roundToDecimals(averageSpeed, 1));
summary.setBBox(GeomUtility.calculateBoundingBox(pointlist));
if (request.getIncludeElevation()) {
double ascent = 0.0;
double descent = 0.0;
for (RouteSegment seg : getSegments()) {
ascent += seg.getAscent();
descent += seg.getDescent();
}
summary.setAscent(FormatUtility.roundToDecimals(ascent, 1));
summary.setDescent(FormatUtility.roundToDecimals(descent, 1));
}
if (path != null) {
summary.setTransfers(path.getNumChanges());
if (path.getFare() != null)
summary.setFare(path.getFare().intValue());
}
}
public String getGraphDate() {
return graphDate;
}
public void setGraphDate(String graphDate) {
this.graphDate = graphDate;
}
public boolean hasDepartureAndArrival() {
return (departure != null && arrival != null);
}
public ZonedDateTime getDeparture() {
return departure;
}
public void setDeparture(ZonedDateTime departure) {
this.departure = departure;
}
public ZonedDateTime getArrival() {
return arrival;
}
public void setArrival(ZonedDateTime arrival) {
this.arrival = arrival;
}
public void addLeg(RouteLeg leg) {
legs.add(leg);
}
public List<RouteLeg> getLegs() {
return legs;
}
}