From 74a086fd776d422d03fdfae13f18b4481cfcf448 Mon Sep 17 00:00:00 2001 From: takb Date: Wed, 13 Feb 2019 11:57:01 +0100 Subject: [PATCH] dynamicWeights check, cleanup & refactoring --- .../ors/services/routing/ResultTest.java | 13 +- .../java/heigit/ors/routing/RouteResult.java | 152 ++-- .../ors/routing/RouteResultBuilder.java | 754 +++++------------- .../ors/routing/RouteSearchParameters.java | 63 +- .../java/heigit/ors/routing/RouteSegment.java | 36 +- .../heigit/ors/routing/RouteStepManeuver.java | 4 + .../heigit/ors/routing/RoutingProfile.java | 29 +- .../ors/routing/RoutingProfileManager.java | 9 +- .../heigit/ors/routing/RoutingRequest.java | 4 +- .../routing/instructions/InstructionType.java | 6 +- .../json/JsonMapMatchingResponseWriter.java | 6 +- .../json/JsonRoutingResponseWriter.java | 6 +- .../java/heigit/ors/util/FormatUtility.java | 5 + .../java/heigit/ors/util/GeomUtility.java | 39 +- .../util/mockupUtil/RouteResultMockup.java | 6 +- .../routing/RouteSearchParametersTest.java | 63 +- .../java/heigit/ors/util/GeomUtilityTest.java | 7 +- 17 files changed, 471 insertions(+), 731 deletions(-) diff --git a/openrouteservice-api-tests/src/test/java/heigit/ors/services/routing/ResultTest.java b/openrouteservice-api-tests/src/test/java/heigit/ors/services/routing/ResultTest.java index f5b69aa154..bbeb4f8335 100644 --- a/openrouteservice-api-tests/src/test/java/heigit/ors/services/routing/ResultTest.java +++ b/openrouteservice-api-tests/src/test/java/heigit/ors/services/routing/ResultTest.java @@ -56,7 +56,7 @@ public ResultTest() { addParameter("carProfile", "driving-car"); // query for testing the alternative routes algorithm - addParameter("coordinatesAR", "8.680401,49.437436|8.746362,49.414191"); + addParameter("coordinatesAR", "8.673191,49.446812|8.689499,49.398295"); } @Test @@ -1513,18 +1513,19 @@ public void testAlternativeRoutes() { .param("instructions", "true") .param("preference", getParameter("preference")) .param("profile", getParameter("carProfile")) - .param("options", "{\"alternative_routes\": 2}") + .param("options", "{\"alternative_routes_count\": 2}") .when().log().ifValidationFails() .get(getEndPointName()) .then() .assertThat() .body("any { it.key == 'routes' }", is(true)) .body("routes.size()", is(2)) - .body("routes[0].summary.distance", is(8178.2f)) - .body("routes[0].summary.duration", is(1087.3f)) - .body("routes[1].summary.distance", is(10670.8f)) - .body("routes[1].summary.duration", is(1414)) + .body("routes[0].summary.distance", is(5942.1f)) + .body("routes[0].summary.duration", is(776.1f)) + .body("routes[1].summary.distance", is(6435)) + .body("routes[1].summary.duration", is(801.5f)) .statusCode(200); } + } diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RouteResult.java b/openrouteservice/src/main/java/heigit/ors/routing/RouteResult.java index 39175dd0d2..82c587fd1a 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RouteResult.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RouteResult.java @@ -14,123 +14,109 @@ package heigit.ors.routing; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import com.graphhopper.util.PointList; +import com.graphhopper.util.shapes.BBox; import com.vividsolutions.jts.geom.Coordinate; +import heigit.ors.common.DistanceUnit; +import heigit.ors.util.FormatUtility; +import heigit.ors.util.GeomUtility; public class RouteResult { - private RouteSummary _summary; - private Coordinate[] _geometry; - private List _segments; - private List _extraInfo; - private int[] _wayPointsIndices = null; - private int _locationIndex = 0; + private RouteSummary summary; + private Coordinate[] geometry; + private List segments; + private List extraInfo; + private List wayPointsIndices; private List routeWarnings; + private PointList pointlist; - public RouteResult(int routeExtras) throws Exception - { - _segments = new ArrayList(); - _summary = new RouteSummary(); - + public RouteResult(int routeExtras) { + segments = new ArrayList<>(); + summary = new RouteSummary(); if (routeExtras != 0) - _extraInfo = new ArrayList(); - + extraInfo = new ArrayList<>(); routeWarnings = new ArrayList<>(); + wayPointsIndices = new ArrayList<>(); } public void addSegment(RouteSegment seg) { - _segments.add(seg); + segments.add(seg); } public List getSegments() { - return _segments; + return segments; } public RouteSummary getSummary() { - return _summary; + return summary; } public Coordinate[] getGeometry() { - return _geometry; + return geometry; } - public void addPoints(PointList points, boolean skipFirstPoint, boolean includeElevation) + public void addPointsToGeometry(PointList points, boolean skipFirstPoint, boolean includeElevation) { int index = skipFirstPoint ? 1 : 0; - if (_geometry == null) + if (geometry == null) { int newSize = points.size() - index; - _geometry = new Coordinate[newSize]; + 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)); + 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)); + geometry[i] = new Coordinate(points.getLon(i), points.getLat(i)); } } else { - int oldSize = _geometry.length; + int oldSize = geometry.length; int pointsSize = points.size() - index; int newSize = oldSize + pointsSize; Coordinate[] coords = new Coordinate[newSize]; - for (int i = 0; i < oldSize; i++) - coords[i] = _geometry[i]; + for (int i = 0; i < oldSize; i++) { + coords[i] = geometry[i]; + } - if (includeElevation && points.is3D()) - { - for (int i = 0; i < pointsSize; ++i) - { - int j = i + index; + 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 - { - for (int i = 0; i < pointsSize; ++i) - { - int j = i + index; + else coords[oldSize + i] = new Coordinate(points.getLon(j), points.getLat(j)); - } } - - _geometry = coords; + + geometry = coords; } } public List getExtraInfo() { - return _extraInfo; + return extraInfo; } - public void addExtraInfo(RouteExtraInfo info) + private void addExtraInfo(RouteExtraInfo info) { - if(_extraInfo == null) - _extraInfo = new ArrayList<>(); - _extraInfo.add(info); + if(extraInfo == null) + extraInfo = new ArrayList<>(); + extraInfo.add(info); } - public void addExtraInfo(Collection infos) - { - if(_extraInfo == null) - _extraInfo = new ArrayList<>(); - _extraInfo.addAll(infos); - } - public void addWarning(RouteWarning warning) { routeWarnings.add(warning); } @@ -139,19 +125,63 @@ public List getWarnings() { return routeWarnings; } - public int[] getWayPointsIndices() { - return _wayPointsIndices; + public void addPointlist(PointList pointlistToAdd) { + if (pointlist == null) { + pointlist = pointlistToAdd; + } else { + pointlist.add(pointlistToAdd); + } + } + + public List getWayPointsIndices() { + return wayPointsIndices; } - public void setWayPointsIndices(int[] wayPointsIndices) { - _wayPointsIndices = wayPointsIndices; + public void addWayPointIndex(int index) { + wayPointsIndices.add(index); } - public int getLocationIndex() { - return _locationIndex; + void addExtras(RoutingRequest request, List 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); + } + } } - public void setLocationIndex(int locationIndex) { - _locationIndex = locationIndex; + /** + * set route summary values according to segments in this route and request parameters + * @param request for parameter lookup (consider traffic, units, include elevation) + */ + void calculateRouteSummary(RoutingRequest request) { + double distance = 0.0; + double duration = 0.0; + for (RouteSegment seg : getSegments()) { + distance += seg.getDistance(); + duration += request.getSearchParameters().getConsiderTraffic() ? seg.getDurationTraffic() : 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)); + } } } diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RouteResultBuilder.java b/openrouteservice/src/main/java/heigit/ors/routing/RouteResultBuilder.java index fb2fd3cfb2..e11ecf821f 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RouteResultBuilder.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RouteResultBuilder.java @@ -23,538 +23,221 @@ import com.graphhopper.GHResponse; import com.graphhopper.PathWrapper; import com.graphhopper.util.*; -import com.graphhopper.util.shapes.BBox; import com.vividsolutions.jts.geom.Coordinate; import heigit.ors.common.ArrivalDirection; import heigit.ors.common.CardinalDirection; import heigit.ors.common.DistanceUnit; import heigit.ors.exceptions.InternalServerException; -import heigit.ors.localization.LocalizationManager; -import heigit.ors.routing.graphhopper.extensions.storages.WarningGraphExtension; import heigit.ors.routing.instructions.InstructionTranslator; import heigit.ors.routing.instructions.InstructionTranslatorsCache; import heigit.ors.routing.instructions.InstructionType; import heigit.ors.util.DistanceUnitUtil; import heigit.ors.util.FormatUtility; -import heigit.ors.util.GeomUtility; -import heigit.ors.util.StringUtility; import java.util.List; -public class RouteResultBuilder +class RouteResultBuilder { - private AngleCalc _angleCalc; - private DistanceCalc _distCalc; - private String _nameAppendix; - private static final CardinalDirection _directions[] = {CardinalDirection.North, CardinalDirection.NorthEast, CardinalDirection.East, CardinalDirection.SouthEast, CardinalDirection.South, CardinalDirection.SouthWest, CardinalDirection.West, CardinalDirection.NorthWest}; + private AngleCalc angleCalc; + private DistanceCalc distCalc; + private static final CardinalDirection[] directions = {CardinalDirection.North, CardinalDirection.NorthEast, CardinalDirection.East, CardinalDirection.SouthEast, CardinalDirection.South, CardinalDirection.SouthWest, CardinalDirection.West, CardinalDirection.NorthWest}; + private int startWayPointIndex = 0; - public RouteResultBuilder() + RouteResultBuilder() { - _angleCalc = new AngleCalc(); - _distCalc = new DistanceCalcEarth(); + angleCalc = new AngleCalc(); + distCalc = new DistanceCalcEarth(); } - public RouteResult[] createRouteResults(List routes, RoutingRequest request, List extras) throws Exception { - if (routes.isEmpty()) - return new RouteResult[]{new RouteResult(request.getExtraInfo())}; - if (routes.size() > 1) { - return new RouteResult[]{createRouteResult(routes, request, extras)}; - } - return createRouteResultSet(routes.get(0), request, extras); + RouteResult[] createRouteResults(List responses, RoutingRequest request, List extras) throws Exception { + if (responses.isEmpty()) + throw new InternalServerException(RoutingErrorCodes.UNKNOWN, "Unable to find a route."); + if (responses.size() > 1) { // request had multiple segments (route with via points) + return createMergedRouteResultSetFromBestPaths(responses, request, extras); + } else + return createRouteResultSetFromMultiplePaths(responses.get(0), request, extras); } - public RouteResult createRouteResult(List routes, RoutingRequest request, List extras) throws Exception { + private RouteResult[] createMergedRouteResultSetFromBestPaths(List responses, RoutingRequest request, List extras) throws Exception { + return new RouteResult[]{createMergedRouteResultFromBestPaths(responses, request, extras)}; + } + RouteResult createMergedRouteResultFromBestPaths(List responses, RoutingRequest request, List extras) throws Exception { RouteResult result = new RouteResult(request.getExtraInfo()); + result.addExtras(request, extras); - InstructionTranslator instrTranslator = InstructionTranslatorsCache.getInstance().getTranslator(request.getLanguage()); - - boolean formatInstructions = request.getInstructionsFormat() == RouteInstructionsFormat.HTML; - int nRoutes = routes.size(); - double distance = 0.0; - double duration = 0.0; - double ascent = 0.0; - double descent = 0.0; - //MARQ24 removed not implemented -> double distanceActual = 0.0; - double durationTraffic = 0.0; - - double lon0 = 0, lat0 = 0, lat1 = 0, lon1 = 0; - boolean includeDetourFactor = request.hasAttribute("detourfactor"); - boolean includeElev = request.getIncludeElevation(); - DistanceUnit units = request.getUnits(); - int unitDecimals = FormatUtility.getUnitDecimals(units); - PointList prevSegPoints = null, segPoints, nextSegPoints; - - PointList summary_pointlist = null; - BBox bbox = null; - int[] routeWayPoints = null; - + startWayPointIndex = 0; if (request.getIncludeGeometry()) { - routeWayPoints = new int[nRoutes + 1]; - routeWayPoints[0] = 0; + result.addWayPointIndex(0); } - if (extras != null) { - // only add the extras we requested unless a "warning" has been generated - for (RouteExtraInfo extra : extras) { - if (RouteExtraInfoFlag.isSet(request.getExtraInfo(), RouteExtraInfoFlag.getFromString(extra.getName()))) { - result.addExtraInfo(extra); - } else { - if (extra.isUsedForWarnings() && extra.getWarningGraphExtension() instanceof WarningGraphExtension) { - WarningGraphExtension warningExtension = extra.getWarningGraphExtension(); - if (warningExtension.generatesWarning(extra)) { - result.addWarning(warningExtension.getWarning()); - result.addExtraInfo(extra); - } - } - } - } - } - - for (int ri = 0; ri < nRoutes; ++ri) { - GHResponse resp = routes.get(ri); - - if (resp.hasErrors()) + for (int ri = 0; ri < responses.size(); ++ri) { + GHResponse response = responses.get(ri); + if (response.hasErrors()) throw new InternalServerException(RoutingErrorCodes.UNKNOWN, String.format("Unable to find a route between points %d (%s) and %d (%s)", ri, FormatUtility.formatCoordinate(request.getCoordinates()[ri]), ri + 1, FormatUtility.formatCoordinate(request.getCoordinates()[ri + 1]))); - PathWrapper path = resp.getBest(); - PointList routePoints = path.getPoints(); - if (summary_pointlist == null) { - summary_pointlist = path.getPoints(); - } else { - PointList new_points = path.getPoints(); - summary_pointlist.add(new_points); - } - if (bbox == null) - bbox = new BBox(routePoints.getLon(0), routePoints.getLon(0), routePoints.getLat(0), routePoints.getLat(0)); - bbox = GeomUtility.CalculateBoundingBox(path.getPoints(), bbox); + PathWrapper path = response.getBest(); + result.addPointlist(path.getPoints()); if (request.getIncludeGeometry()) { - result.addPoints(routePoints, ri > 0, includeElev); - - routeWayPoints[ri + 1] = result.getGeometry().length - 1; - - if (request.getIncludeInstructions()) { - InstructionList instructions = path.getInstructions(); - int startWayPointIndex = routeWayPoints[ri]; - int nInstructions = instructions.size(); - //if (nInstructions > 1) // last is finishinstruction - // nInstructions -= 1; - - Instruction instr, prevInstr = null; - InstructionType instrType = InstructionType.UNKNOWN; - RouteSegment seg = new RouteSegment(path, units); - - if (includeDetourFactor) { - lat0 = routePoints.getLat(0); - lon0 = routePoints.getLon(0); - - lat1 = routePoints.getLat(routePoints.getSize() - 1); - lon1 = routePoints.getLon(routePoints.getSize() - 1); - - double dist = _distCalc.calcDist(lat0, lon0, lat1, lon1); - seg.setDetourFactor((dist == 0) ? 0 : FormatUtility.roundToDecimals(path.getDistance() / dist, 2)); - } - - String instrText = ""; - double stepDistance, stepDuration; - - for (int ii = 0; ii < nInstructions; ++ii) { - instr = instructions.get(ii); - InstructionAnnotation instrAnnotation = instr.getAnnotation(); - instrType = getInstructionType(ii == 0, instr); - segPoints = instr.getPoints(); - nextSegPoints = (ii + 1 < nInstructions) ? instructions.get(ii + 1).getPoints() : getNextSegPoints(routes, ri + 1, 0); - - String roadName = formatInstructions && !Helper.isEmpty(instr.getName()) ? "" + instr.getName() + "" : instr.getName(); - instrText = ""; - - stepDistance = FormatUtility.roundToDecimals(DistanceUnitUtil.convert(instr.getDistance(), DistanceUnit.Meters, units), unitDecimals); - stepDuration = FormatUtility.roundToDecimals(instr.getTime() / 1000.0, 1); - - RouteStep step = new RouteStep(); - - if (ii == 0) { - if (segPoints.size() == 1) { - if (ii + 1 < nInstructions) { - lat1 = nextSegPoints.getLat(0); - lon1 = nextSegPoints.getLon(0); - } else { - lat1 = segPoints.getLat(ii); - lon1 = segPoints.getLon(ii); - } - } else { - lat1 = segPoints.getLat(ii + 1); - lon1 = segPoints.getLon(ii + 1); - } - - CardinalDirection dir = calcDirection(segPoints.getLat(ii), segPoints.getLon(ii), lat1, lon1); - instrText = instrTranslator.getDepart(dir, roadName); - } else { - if (instr instanceof RoundaboutInstruction) { - RoundaboutInstruction raInstr = (RoundaboutInstruction) instr; - step.setExitNumber(raInstr.getExitNumber()); - instrText = instrTranslator.getRoundabout(raInstr.getExitNumber(), roadName); - } else { - if (isTurnInstruction(instrType)) { - instrText = instrTranslator.getTurn(instrType, roadName); - } else if (isKeepInstruction(instrType)) { - instrText = instrTranslator.getKeep(instrType, roadName); - } else if (instrType == InstructionType.CONTINUE) { - instrText = instrTranslator.getContinue(instrType, roadName); - } else if (instrType == InstructionType.FINISH) { - instrText = instrTranslator.getArrive(getArrivalDirection(routePoints, request.getDestination()), prevInstr.getName()); - } else - instrText = "Oops! Fix me"; - } - } - - - _nameAppendix = null; - - step.setDistance(stepDistance); - step.setDuration(stepDuration); - step.setInstruction(instrText); - step.setName(instr.getName()); - step.setType(instrType.ordinal()); - step.setWayPoints(new int[]{startWayPointIndex, getWayPointEndIndex(startWayPointIndex, instrType, instr)}); - - boolean incMan = request.getIncludeManeuvers(); - boolean isSlightLeftOrRight = instrType.equals(InstructionType.TURN_SLIGHT_RIGHT) || instrType.equals(InstructionType.TURN_SLIGHT_LEFT); - if (incMan || isSlightLeftOrRight) { - RouteStepManeuver man = calcManeuver(instrType, prevSegPoints, segPoints, nextSegPoints); - if (incMan) { - step.setManeuver(man); - } - if (isSlightLeftOrRight) { - // see com.graphhopper.routing.InstructionsFromEdges.getTurn(...) - // is generating the TurnInformation - for what EVER reason this - // is not correct from time to time - so I ADJUST THEM! - if (Math.abs(man.getBearingAfter() - man.getBearingBefore()) < 6) { - step.setInstruction(instrTranslator.getContinue(InstructionType.CONTINUE, roadName)); - step.setType(InstructionType.CONTINUE.ordinal()); - } - } - } - - seg.addStep(step); - - // step.setMessage(message); - // add message and message type - - startWayPointIndex += instr.getPoints().size(); - //step.setMode // walking, cycling, etc. for multimodal routing - - //MARQ24 removed not implemented - //if (instrAnnotation != null && instrAnnotation.getWayType() != 1) // Ferry, Steps as pushing sections - // distanceActual += stepDistance; - - prevInstr = instr; - prevSegPoints = segPoints; - } - - result.addSegment(seg); - - distance += seg.getDistance(); - duration += seg.getDuration(); - } else { - distance += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), FormatUtility.getUnitDecimals(units)); - duration += FormatUtility.roundToDecimals(path.getTime() / 1000.0, 1); - } - } else { - InstructionList instructions = path.getInstructions(); - int nInstructions = instructions.size(); - if (nInstructions > 1) - nInstructions -= 1; - - for (int j = 0; j < nInstructions; ++j) { - Instruction instr = instructions.get(j); - InstructionAnnotation instrAnnotation = instr.getAnnotation(); - - //MARQ24 removed not implemented - //if (instrAnnotation != null && instrAnnotation.getWayType() != 1) // Ferry, Steps as pushing sections - // distanceActual += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(instr.getDistance(), DistanceUnit.Meters, units), unitDecimals); - } - - distance += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), unitDecimals); - duration += FormatUtility.roundToDecimals(path.getTime() / 1000.0, 1); - } - - if (includeElev) { - ascent += path.getAscend(); - descent += path.getDescend(); + result.addPointsToGeometry(path.getPoints(), ri > 0, request.getIncludeElevation()); + result.addWayPointIndex(result.getGeometry().length - 1); } - durationTraffic += path.getRouteWeight(); + result.addSegment(createRouteSegment(path, request, getNextResponseFirstStepPoints(responses, ri))); } - RouteSummary routeSummary = result.getSummary(); - - routeSummary.setDuration(request.getSearchParameters().getConsiderTraffic() ? durationTraffic : duration); - routeSummary.setDistance(FormatUtility.roundToDecimals(distance, unitDecimals)); - //MARQ24 removed not implemented - //routeSummary.setDistanceActual(FormatUtility.roundToDecimals(distanceActual, unitDecimals)); - routeSummary.setAverageSpeed(FormatUtility.roundToDecimals(distance / (units == DistanceUnit.Meters ? 1000 : 1) / (routeSummary.getDuration() / 3600), 1)); - routeSummary.setAscent(FormatUtility.roundToDecimals(ascent, 1)); - routeSummary.setDescent(FormatUtility.roundToDecimals(descent, 1)); - - if (routeWayPoints != null) - result.setWayPointsIndices(routeWayPoints); - - if (summary_pointlist != null) { - if (summary_pointlist.getSize() > 0) { - // The bounding box function of graphhopper returns wrong bboxes. This one should fix it. - BBox summary_bbox = GeomUtility.CalculateBoundingBox(summary_pointlist, bbox); - routeSummary.setBBox(summary_bbox); - } - } else if (bbox != null) - routeSummary.setBBox(bbox); + result.calculateRouteSummary(request); return result; } - private RouteResult[] createRouteResultSet(GHResponse route, RoutingRequest request, List extras) throws Exception { + private RouteResult[] createRouteResultSetFromMultiplePaths(GHResponse response, RoutingRequest request, List extras) throws Exception { - if (route.hasErrors()) + if (response.hasErrors()) throw new InternalServerException(RoutingErrorCodes.UNKNOWN, String.format("Unable to find a route between points %d (%s) and %d (%s)", 0, FormatUtility.formatCoordinate(request.getCoordinates()[0]), 1, FormatUtility.formatCoordinate(request.getCoordinates()[1]))); - InstructionTranslator instrTranslator = InstructionTranslatorsCache.getInstance().getTranslator(request.getLanguage()); - boolean formatInstructions = request.getInstructionsFormat() == RouteInstructionsFormat.HTML; - boolean includeDetourFactor = request.hasAttribute("detourfactor"); - boolean includeElev = request.getIncludeElevation(); - DistanceUnit units = request.getUnits(); - int unitDecimals = FormatUtility.getUnitDecimals(units); + RouteResult[] resultSet = new RouteResult[response.getAll().size()]; - RouteResult[] resultSet = new RouteResult[route.getAll().size()]; - - for (PathWrapper path : route.getAll()) { + for (PathWrapper path : response.getAll()) { RouteResult result = new RouteResult(request.getExtraInfo()); + result.addExtras(request, extras); - double distance = 0.0; - double duration = 0.0; - double ascent = 0.0; - double descent = 0.0; - double durationTraffic = 0.0; - double lon0 = 0, lat0 = 0, lat1 = 0, lon1 = 0; - PointList prevSegPoints = null, segPoints, nextSegPoints; - PointList summary_pointlist = null; - int[] routeWayPoints = null; - + startWayPointIndex = 0; if (request.getIncludeGeometry()) { - routeWayPoints = new int[2]; - routeWayPoints[0] = 0; - } - - if (extras != null) { - // only add the extras we requested unless a "warning" has been generated - for (RouteExtraInfo extra : extras) { - if (RouteExtraInfoFlag.isSet(request.getExtraInfo(), RouteExtraInfoFlag.getFromString(extra.getName()))) { - result.addExtraInfo(extra); - } else { - if (extra.isUsedForWarnings() && extra.getWarningGraphExtension() instanceof WarningGraphExtension) { - WarningGraphExtension warningExtension = extra.getWarningGraphExtension(); - if (warningExtension.generatesWarning(extra)) { - result.addWarning(warningExtension.getWarning()); - result.addExtraInfo(extra); - } - } - } - } + result.addWayPointIndex(0); } - PointList routePoints = path.getPoints(); - if (summary_pointlist == null) { - summary_pointlist = path.getPoints(); - } else { - PointList new_points = path.getPoints(); - summary_pointlist.add(new_points); + result.addPointlist(path.getPoints()); + if (request.getIncludeGeometry()) { + result.addPointsToGeometry(path.getPoints(), false, request.getIncludeElevation()); + result.addWayPointIndex(result.getGeometry().length - 1); } - BBox bbox = new BBox(routePoints.getLon(0), routePoints.getLon(0), routePoints.getLat(0), routePoints.getLat(0)); - bbox = GeomUtility.CalculateBoundingBox(path.getPoints(), bbox); + result.addSegment(createRouteSegment(path, request, null)); + result.calculateRouteSummary(request); - if (request.getIncludeGeometry()) { - result.addPoints(routePoints, false, includeElev); - - routeWayPoints[1] = result.getGeometry().length - 1; + resultSet[response.getAll().indexOf(path)] = result; + } - if (request.getIncludeInstructions()) { - InstructionList instructions = path.getInstructions(); - int startWayPointIndex = routeWayPoints[0]; - int nInstructions = instructions.size(); + return resultSet; + } - Instruction instr, prevInstr = null; - InstructionType instrType = InstructionType.UNKNOWN; - RouteSegment seg = new RouteSegment(path, units); + private PointList getNextResponseFirstStepPoints(List routes, int ri) { + if (ri + 1 >= 0 && ri + 1 < routes.size()) { + GHResponse resp = routes.get(ri + 1); + InstructionList instructions = resp.getBest().getInstructions(); + if (!instructions.isEmpty()) + return instructions.get(0).getPoints(); + } + return null; - if (includeDetourFactor) { - lat0 = routePoints.getLat(0); - lon0 = routePoints.getLon(0); + } - lat1 = routePoints.getLat(routePoints.getSize() - 1); - lon1 = routePoints.getLon(routePoints.getSize() - 1); + private RouteSegment createRouteSegment(PathWrapper path, RoutingRequest request, PointList nextRouteFirstStepPoints) throws Exception { + RouteSegment seg = new RouteSegment(path, request.getUnits()); - double dist = _distCalc.calcDist(lat0, lon0, lat1, lon1); - seg.setDetourFactor((dist == 0) ? 0 : FormatUtility.roundToDecimals(path.getDistance() / dist, 2)); - } + if (request.getIncludeGeometry() && request.getIncludeInstructions()) { + if (request.hasAttribute(RoutingRequest.ATTR_DETOURFACTOR)) { + seg.setDetourFactor(FormatUtility.roundToDecimals(calculateDetourFactor(path), 2)); + } - String instrText = ""; - double stepDistance, stepDuration; - - for (int ii = 0; ii < nInstructions; ++ii) { - instr = instructions.get(ii); - InstructionAnnotation instrAnnotation = instr.getAnnotation(); - instrType = getInstructionType(ii == 0, instr); - segPoints = instr.getPoints(); - nextSegPoints = (ii + 1 < nInstructions) ? instructions.get(ii + 1).getPoints() : null; - - String roadName = formatInstructions && !Helper.isEmpty(instr.getName()) ? "" + instr.getName() + "" : instr.getName(); - instrText = ""; - - stepDistance = FormatUtility.roundToDecimals(DistanceUnitUtil.convert(instr.getDistance(), DistanceUnit.Meters, units), unitDecimals); - stepDuration = FormatUtility.roundToDecimals(instr.getTime() / 1000.0, 1); - - RouteStep step = new RouteStep(); - - if (ii == 0) { - if (segPoints.size() == 1) { - if (ii + 1 < nInstructions) { - lat1 = nextSegPoints.getLat(0); - lon1 = nextSegPoints.getLon(0); - } else { - lat1 = segPoints.getLat(ii); - lon1 = segPoints.getLon(ii); - } - } else { - lat1 = segPoints.getLat(ii + 1); - lon1 = segPoints.getLon(ii + 1); - } - - CardinalDirection dir = calcDirection(segPoints.getLat(ii), segPoints.getLon(ii), lat1, lon1); - instrText = instrTranslator.getDepart(dir, roadName); - } else { - if (instr instanceof RoundaboutInstruction) { - RoundaboutInstruction raInstr = (RoundaboutInstruction) instr; - step.setExitNumber(raInstr.getExitNumber()); - instrText = instrTranslator.getRoundabout(raInstr.getExitNumber(), roadName); - } else { - if (isTurnInstruction(instrType)) { - instrText = instrTranslator.getTurn(instrType, roadName); - } else if (isKeepInstruction(instrType)) { - instrText = instrTranslator.getKeep(instrType, roadName); - } else if (instrType == InstructionType.CONTINUE) { - instrText = instrTranslator.getContinue(instrType, roadName); - } else if (instrType == InstructionType.FINISH) { - instrText = instrTranslator.getArrive(getArrivalDirection(routePoints, request.getDestination()), prevInstr.getName()); - } else - instrText = "Oops! Fix me"; - } - } + InstructionList instructions = path.getInstructions(); + int nInstructions = instructions.size(); + InstructionTranslator instrTranslator = InstructionTranslatorsCache.getInstance().getTranslator(request.getLanguage()); + for (int ii = 0; ii < nInstructions; ++ii) { + RouteStep step = new RouteStep(); - _nameAppendix = null; - - step.setDistance(stepDistance); - step.setDuration(stepDuration); - step.setInstruction(instrText); - step.setName(instr.getName()); - step.setType(instrType.ordinal()); - step.setWayPoints(new int[]{startWayPointIndex, getWayPointEndIndex(startWayPointIndex, instrType, instr)}); - - boolean incMan = request.getIncludeManeuvers(); - boolean isSlightLeftOrRight = instrType.equals(InstructionType.TURN_SLIGHT_RIGHT) || instrType.equals(InstructionType.TURN_SLIGHT_LEFT); - if (incMan || isSlightLeftOrRight) { - RouteStepManeuver man = calcManeuver(instrType, prevSegPoints, segPoints, nextSegPoints); - if (incMan) { - step.setManeuver(man); - } - if (isSlightLeftOrRight) { - // see com.graphhopper.routing.InstructionsFromEdges.getTurn(...) - // is generating the TurnInformation - for what EVER reason this - // is not correct from time to time - so I ADJUST THEM! - if (Math.abs(man.getBearingAfter() - man.getBearingBefore()) < 6) { - step.setInstruction(instrTranslator.getContinue(InstructionType.CONTINUE, roadName)); - step.setType(InstructionType.CONTINUE.ordinal()); - } - } - } + Instruction instr = instructions.get(ii); + InstructionType instrType = getInstructionType(ii == 0, instr); - seg.addStep(step); + PointList currentStepPoints = instr.getPoints(); + PointList nextStepPoints = (ii + 1 < nInstructions) ? instructions.get(ii + 1).getPoints() : nextRouteFirstStepPoints; + PointList prevStepPoints = ii > 0 ? instructions.get(ii - 1).getPoints() : null; - // step.setMessage(message); - // add message and message type + step.setName(instr.getName()); - startWayPointIndex += instr.getPoints().size(); - //step.setMode // walking, cycling, etc. for multimodal routing + double stepDistance = DistanceUnitUtil.convert(instr.getDistance(), DistanceUnit.Meters, request.getUnits()); + step.setDistance(FormatUtility.roundToDecimalsForUnits(stepDistance, request.getUnits())); - //MARQ24 removed not implemented - //if (instrAnnotation != null && instrAnnotation.getWayType() != 1) // Ferry, Steps as pushing sections - // distanceActual += stepDistance; + step.setDuration(FormatUtility.roundToDecimals(instr.getTime() / 1000.0, 1)); - prevInstr = instr; - prevSegPoints = segPoints; + if (request.getIncludeManeuvers() || instrType.isSlightLeftOrRight()) { + RouteStepManeuver maneuver = calcManeuver(instrType, prevStepPoints, currentStepPoints, nextStepPoints); + if (request.getIncludeManeuvers()) { + step.setManeuver(maneuver); } + if (instrType.isSlightLeftOrRight() && maneuver.isContinue()) { + // see com.graphhopper.routing.InstructionsFromEdges.getTurn(...) + // is generating the TurnInformation - for what EVER reason this + // is not correct from time to time - so I ADJUST THEM! + instrType = InstructionType.CONTINUE; + } + } - result.addSegment(seg); - - distance += seg.getDistance(); - duration += seg.getDuration(); + step.setType(instrType.ordinal()); + + String instrText; + String roadName = instr.getName(); + if (request.getInstructionsFormat() == RouteInstructionsFormat.HTML && !Helper.isEmpty(instr.getName()) ) + roadName = "" + instr.getName() + ""; + if (ii == 0) { + double lat; + double lon; + if (currentStepPoints.size() == 1) { + if (nextStepPoints != null) { + lat = nextStepPoints.getLat(0); + lon = nextStepPoints.getLon(0); + } else { + lat = currentStepPoints.getLat(0); + lon = currentStepPoints.getLon(0); + } + } else { + lat = currentStepPoints.getLat(1); + lon = currentStepPoints.getLon(1); + } + instrText = instrTranslator.getDepart(calcDirection(currentStepPoints.getLat(0), currentStepPoints.getLon(0), lat, lon), roadName); } else { - distance += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), FormatUtility.getUnitDecimals(units)); - duration += FormatUtility.roundToDecimals(path.getTime() / 1000.0, 1); + if (instr instanceof RoundaboutInstruction) { + RoundaboutInstruction raInstr = (RoundaboutInstruction) instr; + step.setExitNumber(raInstr.getExitNumber()); + instrText = instrTranslator.getRoundabout(raInstr.getExitNumber(), roadName); + } else { + if (isTurnInstruction(instrType)) { + instrText = instrTranslator.getTurn(instrType, roadName); + } else if (isKeepInstruction(instrType)) { + instrText = instrTranslator.getKeep(instrType, roadName); + } else if (instrType == InstructionType.CONTINUE) { + instrText = instrTranslator.getContinue(instrType, roadName); + } else if (instrType == InstructionType.FINISH) { + String lastInstrName = instructions.get(ii - 1).getName(); + instrText = instrTranslator.getArrive(getArrivalDirection(path.getPoints(), request.getDestination()), lastInstrName); + } else + instrText = "Unknown instruction type!"; + } } - } else { - // TAKB What was that for? -// InstructionList instructions = path.getInstructions(); -// int nInstructions = instructions.size(); -// if (nInstructions > 1) -// nInstructions -= 1; -// -// for (int j = 0; j < nInstructions; ++j) { -// Instruction instr = instructions.get(j); -// InstructionAnnotation instrAnnotation = instr.getAnnotation(); -// -// //MARQ24 removed not implemented -// //if (instrAnnotation != null && instrAnnotation.getWayType() != 1) // Ferry, Steps as pushing sections -// // distanceActual += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(instr.getDistance(), DistanceUnit.Meters, units), unitDecimals); -// } - - distance += FormatUtility.roundToDecimals(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), unitDecimals); - duration += FormatUtility.roundToDecimals(path.getTime() / 1000.0, 1); - } - - if (includeElev) { - ascent += path.getAscend(); - descent += path.getDescend(); - } - - durationTraffic += path.getRouteWeight(); + step.setInstruction(instrText); - RouteSummary routeSummary = result.getSummary(); + step.setWayPoints(new int[]{startWayPointIndex, getEndWayPointIndex(startWayPointIndex, instrType, instr)}); + startWayPointIndex += instr.getPoints().size(); - routeSummary.setDuration(request.getSearchParameters().getConsiderTraffic() ? durationTraffic : duration); - routeSummary.setDistance(FormatUtility.roundToDecimals(distance, unitDecimals)); - //MARQ24 removed not implemented - //routeSummary.setDistanceActual(FormatUtility.roundToDecimals(distanceActual, unitDecimals)); - routeSummary.setAverageSpeed(FormatUtility.roundToDecimals(distance / (units == DistanceUnit.Meters ? 1000 : 1) / (routeSummary.getDuration() / 3600), 1)); - routeSummary.setAscent(FormatUtility.roundToDecimals(ascent, 1)); - routeSummary.setDescent(FormatUtility.roundToDecimals(descent, 1)); - - if (routeWayPoints != null) - result.setWayPointsIndices(routeWayPoints); + seg.addStep(step); + } + } + return seg; + } - if (summary_pointlist != null) { - if (summary_pointlist.getSize() > 0) { - // The bounding box function of graphhopper returns wrong bboxes. This one should fix it. - BBox summary_bbox = GeomUtility.CalculateBoundingBox(summary_pointlist, bbox); - routeSummary.setBBox(summary_bbox); - } - } else if (bbox != null) - routeSummary.setBBox(bbox); + private double calculateDetourFactor(PathWrapper path) { + PointList pathPoints = path.getPoints(); + double lat0 = pathPoints.getLat(0); + double lon0 = pathPoints.getLon(0); + double lat1 = pathPoints.getLat(pathPoints.getSize() - 1); + double lon1 = pathPoints.getLon(pathPoints.getSize() - 1); + double distanceDirect = distCalc.calcDist(lat0, lon0, lat1, lon1); + if (distanceDirect == 0) return 0; + return path.getDistance() / distanceDirect; - resultSet[route.getAll().indexOf(path)] = result; - } - return resultSet; } private ArrivalDirection getArrivalDirection(PointList points, Coordinate destination) { @@ -567,7 +250,7 @@ private ArrivalDirection getArrivalDirection(PointList points, Coordinate destin double lon1 = points.getLon(lastIndex); double lat1 = points.getLat(lastIndex); - double dist = _distCalc.calcDist(lat1, lon1, destination.y, destination.x); + double dist = distCalc.calcDist(lat1, lon1, destination.y, destination.x); if (dist < 1) return ArrivalDirection.StraightAhead; @@ -583,7 +266,7 @@ else if (sign == 1) } } - private int getWayPointEndIndex(int startIndex, InstructionType instrType, Instruction instr) + private int getEndWayPointIndex(int startIndex, InstructionType instrType, Instruction instr) { if (instrType == InstructionType.FINISH) return startIndex; @@ -591,117 +274,64 @@ private int getWayPointEndIndex(int startIndex, InstructionType instrType, Instr return startIndex + instr.getPoints().size(); } - private PointList getNextSegPoints(List routes, int routeIndex, int segIndex) - { - if (routeIndex >= 0 && routeIndex < routes.size()) - { - GHResponse resp = routes.get(routeIndex); - InstructionList instructions = resp.getBest().getInstructions(); - if (segIndex < instructions.size()) - return instructions.get(segIndex).getPoints(); - } - - return null; - } - private RouteStepManeuver calcManeuver(InstructionType instrType, PointList prevSegPoints, PointList segPoints, PointList nextSegPoints) { RouteStepManeuver maneuver = new RouteStepManeuver(); - int bearingBefore = 0; - int bearingAfter = 0; - - if (nextSegPoints != null) - { - if (instrType == InstructionType.DEPART) - { - double lon0 = segPoints.getLon(0); - double lat0 = segPoints.getLat(0); - double lon1, lat1; - maneuver.setLocation(new Coordinate(lon0, lat0)); - - if (segPoints.size() == 1) - { - lon1 = nextSegPoints.getLon(0); - lat1 = nextSegPoints.getLat(0); - } - else - { - lon1 = segPoints.getLon(1); - lat1 = segPoints.getLat(1); - } - - bearingAfter = (int)Math.round(_angleCalc.calcAzimuth(lat0, lon0, lat1, lon1)); - } - else - { - int locIndex = prevSegPoints.size() - 1; - double lon0 = prevSegPoints.getLon(locIndex); - double lat0 = prevSegPoints.getLat(locIndex); - double lon1 = segPoints.getLon(0); - double lat1 = segPoints.getLat(0); - - if (instrType != InstructionType.FINISH) - { - if (segPoints.size() == 1) - { - if (nextSegPoints != null) - { - double lon2 = nextSegPoints.getLon(0); - double lat2 = nextSegPoints.getLat(0); - - bearingAfter = (int)Math.round(_angleCalc.calcAzimuth(lat1, lon1, lat2, lon2)); - } - } - else - { - double lon2 = segPoints.getLon(1); - double lat2 = segPoints.getLat(1); - - bearingAfter = (int)Math.round(_angleCalc.calcAzimuth(lat1, lon1, lat2, lon2)); - } - } - - bearingBefore = (int)Math.round(_angleCalc.calcAzimuth(lat0, lon0, lat1, lon1)); - maneuver.setLocation(new Coordinate(lon1, lat1)); - } + maneuver.setBearingBefore(0); + maneuver.setBearingAfter(0); + if (nextSegPoints == null) { + return maneuver; } - - maneuver.setBearingBefore(bearingBefore); - maneuver.setBearingAfter(bearingAfter); - - return maneuver; - } - - private boolean isValidAppendix(String name) - { - if (name == null) - return false; - - if (_nameAppendix == null) - return StringUtility.containsDigit(name); - else - return _nameAppendix.indexOf(name) == -1 && StringUtility.containsDigit(name); + if (instrType == InstructionType.DEPART) { + double lon0 = segPoints.getLon(0); + double lat0 = segPoints.getLat(0); + maneuver.setLocation(new Coordinate(lon0, lat0)); + double lon1; + double lat1; + if (segPoints.size() == 1) { + lon1 = nextSegPoints.getLon(0); + lat1 = nextSegPoints.getLat(0); + } else { + lon1 = segPoints.getLon(1); + lat1 = segPoints.getLat(1); + } + maneuver.setBearingAfter((int)Math.round(angleCalc.calcAzimuth(lat0, lon0, lat1, lon1))); + } else { + int locIndex = prevSegPoints.size() - 1; + double lon0 = prevSegPoints.getLon(locIndex); + double lat0 = prevSegPoints.getLat(locIndex); + double lon1 = segPoints.getLon(0); + double lat1 = segPoints.getLat(0); + maneuver.setLocation(new Coordinate(lon1, lat1)); + maneuver.setBearingBefore((int)Math.round(angleCalc.calcAzimuth(lat0, lon0, lat1, lon1))); + if (instrType != InstructionType.FINISH) { + double lon2; + double lat2; + if (segPoints.size() == 1) { + lon2 = nextSegPoints.getLon(0); + lat2 = nextSegPoints.getLat(0); + } else { + lon2 = segPoints.getLon(1); + lat2 = segPoints.getLat(1); + } + maneuver.setBearingAfter((int)Math.round(angleCalc.calcAzimuth(lat1, lon1, lat2, lon2))); + } + } + return maneuver; } private boolean isTurnInstruction(InstructionType instrType) { - if (instrType == InstructionType.TURN_LEFT || instrType == InstructionType.TURN_SLIGHT_LEFT + return instrType == InstructionType.TURN_LEFT || instrType == InstructionType.TURN_SLIGHT_LEFT || instrType == InstructionType.TURN_SHARP_LEFT || instrType == InstructionType.TURN_RIGHT - || instrType == InstructionType.TURN_SLIGHT_RIGHT || instrType == InstructionType.TURN_SHARP_RIGHT) - return true; - else - return false; + || instrType == InstructionType.TURN_SLIGHT_RIGHT || instrType == InstructionType.TURN_SHARP_RIGHT; } private boolean isKeepInstruction(InstructionType instrType){ - if(instrType == InstructionType.KEEP_LEFT || instrType == InstructionType.KEEP_RIGHT){ - return true; - }else{ - return false; - } + return instrType == InstructionType.KEEP_LEFT || instrType == InstructionType.KEEP_RIGHT; } - private InstructionType getInstructionType(boolean isDepart, Instruction instr) + private InstructionType getInstructionType(boolean isDepart, Instruction instr) { if (isDepart) { return InstructionType.DEPART; @@ -739,12 +369,12 @@ private InstructionType getInstructionType(boolean isDepart, Instruction instr) private CardinalDirection calcDirection(double lat1, double lon1, double lat2, double lon2 ) { - double orientation = - _angleCalc.calcOrientation(lat1, lon1, lat2, lon2); + double orientation = - angleCalc.calcOrientation(lat1, lon1, lat2, lon2); orientation = Helper.round4(orientation + Math.PI / 2); if (orientation < 0) orientation += 2 * Math.PI; double degree = Math.toDegrees(orientation); - return _directions[(int)Math.floor(((degree+ 22.5) % 360) / 45)]; + return directions[(int)Math.floor(((degree+ 22.5) % 360) / 45)]; } } diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RouteSearchParameters.java b/openrouteservice/src/main/java/heigit/ors/routing/RouteSearchParameters.java index 9651660533..17385c6f73 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RouteSearchParameters.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RouteSearchParameters.java @@ -49,6 +49,11 @@ * It can be called from any class and the values be set according to the needs of the route calculation. */ public class RouteSearchParameters { + + private static final String OPTIONS_KEY_ALTERNATIVE_ROUTES_COUNT = "alternative_routes_count"; + private static final String OPTIONS_KEY_ALTERNATIVE_ROUTES_WEIGHT_FACTOR = "alternative_routes_weight_factor"; + private static final String OPTIONS_KEY_ALTERNATIVE_ROUTES_SHARE_FACTOR = "alternative_routes_share_factor"; + private int _profileType; private int _weightingMethod = WeightingMethod.FASTEST; private Boolean _considerTraffic = false; @@ -65,8 +70,8 @@ public class RouteSearchParameters { private int[] _avoidCountries = null; private BordersExtractor.Avoid _avoidBorders = BordersExtractor.Avoid.NONE; -// TAKB: parameters weight factor and share factor seem to be ignored by the algorithm, further testing required. - private int _alternativeRoutes = -1; +// TAKB: parameters weight factor and share factor seem to be not taken into account properly for all routes beyond the second, needs fixing... + private int _alternativeRoutesCount = -1; private double _alternativeRoutesWeightFactor = 1.4; private double _alternativeRoutesShareFactor = 0.6; @@ -171,12 +176,16 @@ public void setVehicleType(int vehicleType) { this._vehicleType = vehicleType; } - public int getAlternativeRoutes() { - return _alternativeRoutes; + public boolean hasAlternativeRoutes() { + return _alternativeRoutesCount > 1; } - public void setAlternativeRoutes(int _alternativeRoutes) { - this._alternativeRoutes = _alternativeRoutes; + public int getAlternativeRoutesCount() { + return _alternativeRoutesCount; + } + + public void setAlternativeRoutesCount(int _alternativeRoutesCount) { + this._alternativeRoutesCount = _alternativeRoutesCount; } public double getAlternativeRoutesWeightFactor() { @@ -427,24 +436,24 @@ else if (jProfileParams.has("maximum_gradient")) } } - if (json.has("alternative_routes")) { + if (json.has(OPTIONS_KEY_ALTERNATIVE_ROUTES_COUNT)) { try { - _alternativeRoutes = json.getInt("alternative_routes"); + _alternativeRoutesCount = json.getInt(OPTIONS_KEY_ALTERNATIVE_ROUTES_COUNT); } catch (Exception ex) { - throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, "alternative_routes", json.getString("alternative_routes")); + throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, OPTIONS_KEY_ALTERNATIVE_ROUTES_COUNT, json.getString(OPTIONS_KEY_ALTERNATIVE_ROUTES_COUNT)); } - if (json.has("alternative_routes_weight_factor")) { + if (json.has(OPTIONS_KEY_ALTERNATIVE_ROUTES_WEIGHT_FACTOR)) { try { - _alternativeRoutesWeightFactor = json.getDouble("alternative_routes_weight_factor"); + _alternativeRoutesWeightFactor = json.getDouble(OPTIONS_KEY_ALTERNATIVE_ROUTES_WEIGHT_FACTOR); } catch (Exception ex) { - throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, "alternative_routes_weight_factor", json.getString("alternative_routes_weight_factor")); + throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, OPTIONS_KEY_ALTERNATIVE_ROUTES_WEIGHT_FACTOR, json.getString(OPTIONS_KEY_ALTERNATIVE_ROUTES_WEIGHT_FACTOR)); } } - if (json.has("alternative_routes_share_factor")) { + if (json.has(OPTIONS_KEY_ALTERNATIVE_ROUTES_SHARE_FACTOR)) { try { - _alternativeRoutesShareFactor = json.getDouble("alternative_routes_share_factor"); + _alternativeRoutesShareFactor = json.getDouble(OPTIONS_KEY_ALTERNATIVE_ROUTES_SHARE_FACTOR); } catch (Exception ex) { - throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, "alternative_routes_share_factor", json.getString("alternative_routes_share_factor")); + throw new ParameterValueException(RoutingErrorCodes.INVALID_PARAMETER_FORMAT, OPTIONS_KEY_ALTERNATIVE_ROUTES_SHARE_FACTOR, json.getString(OPTIONS_KEY_ALTERNATIVE_ROUTES_SHARE_FACTOR)); } } } @@ -509,4 +518,28 @@ public WayPointBearing[] getBearings() { public void setBearings(WayPointBearing[] bearings) { _bearings = bearings; } + + public boolean isProfileTypeDriving() { + return RoutingProfileType.isDriving(this.getProfileType()); + } + + public boolean isProfileTypeHeavyVehicle() { + return RoutingProfileType.isHeavyVehicle(this.getProfileType()); + } + + public boolean requiresDynamicWeights() { + return hasAvoidAreas() + || hasAvoidFeatures() + || hasAvoidBorders() + || hasAvoidCountries() + || hasAlternativeRoutes() + || getMaximumSpeed() > 0 + || getConsiderTurnRestrictions() + || getWeightingMethod() == WeightingMethod.SHORTEST + || getWeightingMethod() == WeightingMethod.RECOMMENDED + || isProfileTypeHeavyVehicle() && getVehicleType() > 0 + || isProfileTypeDriving() && hasParameters(VehicleParameters.class) + || isProfileTypeDriving() && getConsiderTraffic() + ; + } } diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RouteSegment.java b/openrouteservice/src/main/java/heigit/ors/routing/RouteSegment.java index 5531c349b8..a311c8ca35 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RouteSegment.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RouteSegment.java @@ -26,29 +26,21 @@ public class RouteSegment { private double _distance; private double _duration; + private double _durationTraffic; private double _ascent; private double _descent; private double _detourFactor = 0.0; - private BBox _bbox; private List _steps; public RouteSegment(PathWrapper path, DistanceUnit units) throws Exception { - _distance = FormatUtility.roundToDecimals(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), FormatUtility.getUnitDecimals(units)); - _duration = FormatUtility.roundToDecimals(path.getTime()/1000.0, 1); - _ascent = FormatUtility.roundToDecimals(path.getAscend(), 1); - _descent = FormatUtility.roundToDecimals(path.getDescend() ,1); + _distance = FormatUtility.roundToDecimalsForUnits(DistanceUnitUtil.convert(path.getDistance(), DistanceUnit.Meters, units), units); + _duration = FormatUtility.roundToDecimals(path.getTime()/1000.0, 1); + _durationTraffic += path.getRouteWeight(); + _ascent = path.getAscend(); + _descent = path.getDescend(); - if (_bbox == null) - { - double lat = path.getPoints().getLat(0); - double lon = path.getPoints().getLon(0); - _bbox = new BBox(lon, lon, lat, lat); - } - - path.calcRouteBBox(_bbox); - - _steps = new ArrayList(); + _steps = new ArrayList<>(); } public double getDistance() @@ -61,6 +53,11 @@ public double getDuration() return _duration; } + public double getDurationTraffic() + { + return _durationTraffic; + } + public double getAscent() { return _ascent; @@ -71,9 +68,14 @@ public double getDescent() return _descent; } - public BBox getBBox() + public double getAscentRounded() + { + return FormatUtility.roundToDecimals(_ascent, 1); + } + + public double getDescentRounded() { - return _bbox; + return FormatUtility.roundToDecimals(_descent, 1); } public void addStep(RouteStep step) diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RouteStepManeuver.java b/openrouteservice/src/main/java/heigit/ors/routing/RouteStepManeuver.java index f01336b49d..da03db43c1 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RouteStepManeuver.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RouteStepManeuver.java @@ -46,4 +46,8 @@ public int getBearingAfter() { public void setBearingAfter(int value) { _bearingAfter = value; } + + public boolean isContinue() { + return Math.abs(_bearingAfter - _bearingBefore) < 6; + } } diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfile.java b/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfile.java index 6061462282..afb45b3d07 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfile.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfile.java @@ -34,7 +34,6 @@ import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import heigit.ors.exceptions.InternalServerException; -import heigit.ors.exceptions.PointNotFoundException; import heigit.ors.exceptions.StatusCodeException; import heigit.ors.isochrones.*; import heigit.ors.isochrones.statistics.StatisticsProvider; @@ -55,7 +54,6 @@ import heigit.ors.routing.configuration.RouteProfileConfiguration; import heigit.ors.routing.graphhopper.extensions.*; import heigit.ors.routing.graphhopper.extensions.edgefilters.*; -import heigit.ors.routing.graphhopper.extensions.flagencoders.WheelchairFlagEncoder; import heigit.ors.routing.graphhopper.extensions.storages.GraphStorageUtils; import heigit.ors.routing.parameters.*; import heigit.ors.routing.traffic.RealTrafficDataProvider; @@ -896,7 +894,7 @@ else if (bearings[1] == null) req.setEdgeFilter(searchCntx.getEdgeFilter()); req.setPathProcessor(routeProcCntx.getPathProcessor()); - if (useDynamicWeights(searchParams) || flexibleMode) { + if (searchParams.requiresDynamicWeights() || flexibleMode) { if (mGraphHopper.isCHEnabled()) req.getHints().put("ch.disable", true); if (mGraphHopper.getLMFactoryDecorator().isEnabled()) @@ -920,12 +918,12 @@ else if (bearings[1] == null) if (_astarApproximation != null) req.getHints().put("astarbi.approximation", _astarApproximation); - if (searchParams.getAlternativeRoutes() > 0) { + if (searchParams.getAlternativeRoutesCount() > 0) { req.setAlgorithm("alternative_route"); - req.getHints().put("alternative_route.max_paths", searchParams.getAlternativeRoutes()); + req.getHints().put("alternative_route.max_paths", searchParams.getAlternativeRoutesCount()); req.getHints().put("alternative_route.max_weight_factor", searchParams.getAlternativeRoutesWeightFactor()); req.getHints().put("alternative_route.max_share_factor", searchParams.getAlternativeRoutesShareFactor()); -// TAKB: contraction hierarchies have to be disabled for alternative routes until GH pulls https://github.com/graphhopper/graphhopper/pull/1524 and we update our fork. +// TODO; (TAKB) contraction hierarchies have to be disabled for alternative routes until GH pulls https://github.com/graphhopper/graphhopper/pull/1524 and we update our fork. req.getHints().put("ch.disable", true); } @@ -952,25 +950,6 @@ else if (bearings[1] == null) return resp; } - private boolean useDynamicWeights(RouteSearchParameters searchParams) { - boolean dynamicWeights = - searchParams.hasAvoidAreas() - || searchParams.hasAvoidFeatures() - || searchParams.hasAvoidCountries() - || searchParams.hasAvoidBorders() - || searchParams.getMaximumSpeed() > 0 - ||( RoutingProfileType.isDriving(searchParams.getProfileType()) - &&( searchParams.hasParameters(VehicleParameters.class) - || searchParams.getConsiderTraffic() - ) - ) - ||( searchParams.getWeightingMethod() == WeightingMethod.SHORTEST - || searchParams.getWeightingMethod() == WeightingMethod.RECOMMENDED - ) - || searchParams.getConsiderTurnRestrictions() /*|| RouteExtraInformationFlag.isSet(extraInfo, value) searchParams.getIncludeWaySurfaceInfo()*/; - return dynamicWeights; - } - private static boolean supportWeightingMethod(int profileType) { if (RoutingProfileType.isDriving(profileType) || RoutingProfileType.isCycling(profileType) || RoutingProfileType.isWalking(profileType) || profileType == RoutingProfileType.WHEELCHAIR) { return true; diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfileManager.java b/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfileManager.java index 005139915a..86c76b05bc 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfileManager.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RoutingProfileManager.java @@ -309,7 +309,6 @@ public List computeRoutes(RoutingRequest req, boolean invertFlow, b Coordinate c0 = coords[0]; int nSegments = coords.length - 1; RouteProcessContext routeProcCntx = new RouteProcessContext(pathProcessor); - RouteResultBuilder routeBuilder = new RouteResultBuilder(); EdgeFilter customEdgeFilter = rp.createAccessRestrictionFilter(coords); List resp = new ArrayList(); @@ -330,8 +329,7 @@ public List computeRoutes(RoutingRequest req, boolean invertFlow, b if (!gr.hasErrors()) { resp.clear(); resp.add(gr); - RouteResult route = routeBuilder.createRouteResult(resp, req, (pathProcessor != null && (pathProcessor instanceof ExtraInfoProcessor)) ? ((ExtraInfoProcessor) pathProcessor).getExtras() : null); - route.setLocationIndex(req.getLocationIndex()); + RouteResult route = new RouteResultBuilder().createMergedRouteResultFromBestPaths(resp, req, (pathProcessor != null && (pathProcessor instanceof ExtraInfoProcessor)) ? ((ExtraInfoProcessor) pathProcessor).getExtras() : null); routes.add(route); } else routes.add(null); @@ -369,7 +367,7 @@ public RouteResult[] computeRoute(RoutingRequest req) throws Exception { WayPointBearing[] bearings = (req.getContinueStraight() || searchParams.getBearings() != null) ? new WayPointBearing[2] : null; double[] radiuses = searchParams.getMaximumRadiuses() != null ? new double[2] : null; - if (req.getSearchParameters().getAlternativeRoutes() > 1 && coords.length > 2) { + if (req.getSearchParameters().getAlternativeRoutesCount() > 1 && coords.length > 2) { throw new InternalServerException(RoutingErrorCodes.INVALID_PARAMETER_VALUE, "Alternative routes algorithm does not support more than two way points."); } @@ -463,8 +461,7 @@ private double getHeadingDirection(GHResponse resp) { public RoutingProfile getRouteProfile(RoutingRequest req, boolean oneToMany) throws Exception { RouteSearchParameters searchParams = req.getSearchParameters(); int profileType = searchParams.getProfileType(); - - boolean dynamicWeights = (searchParams.hasAvoidAreas() || searchParams.hasAvoidFeatures() || searchParams.hasAvoidBorders() || searchParams.hasAvoidCountries() || searchParams.getMaximumSpeed() > 0 || (RoutingProfileType.isDriving(profileType) && ((RoutingProfileType.isHeavyVehicle(profileType) && searchParams.getVehicleType() > 0) || searchParams.hasParameters(VehicleParameters.class) || searchParams.getConsiderTraffic())) || (searchParams.getWeightingMethod() == WeightingMethod.SHORTEST || searchParams.getWeightingMethod() == WeightingMethod.RECOMMENDED) || searchParams.getConsiderTurnRestrictions() /*|| RouteExtraInformationFlag.isSet(extraInfo, value) searchParams.getIncludeWaySurfaceInfo()*/); + boolean dynamicWeights = searchParams.requiresDynamicWeights(); RoutingProfile rp = _routeProfiles.getRouteProfile(profileType, !dynamicWeights); diff --git a/openrouteservice/src/main/java/heigit/ors/routing/RoutingRequest.java b/openrouteservice/src/main/java/heigit/ors/routing/RoutingRequest.java index 1dc3519d46..d4336db24b 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/RoutingRequest.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/RoutingRequest.java @@ -20,7 +20,9 @@ public class RoutingRequest extends ServiceRequest { - private Coordinate[] _coordinates; + public static final String ATTR_DETOURFACTOR = "detourfactor"; + + private Coordinate[] _coordinates; private RouteSearchParameters _searchParameters; private DistanceUnit _units = DistanceUnit.Meters; private String _language = "en"; diff --git a/openrouteservice/src/main/java/heigit/ors/routing/instructions/InstructionType.java b/openrouteservice/src/main/java/heigit/ors/routing/instructions/InstructionType.java index 0d5dc8baf0..975ad5563e 100644 --- a/openrouteservice/src/main/java/heigit/ors/routing/instructions/InstructionType.java +++ b/openrouteservice/src/main/java/heigit/ors/routing/instructions/InstructionType.java @@ -29,5 +29,9 @@ public enum InstructionType DEPART, /*11*/ KEEP_LEFT, /*12*/ KEEP_RIGHT, /*13*/ - UNKNOWN /*14*/ + UNKNOWN /*14*/; + + public boolean isSlightLeftOrRight() { + return this == TURN_SLIGHT_RIGHT || this == TURN_SLIGHT_LEFT; + } } diff --git a/openrouteservice/src/main/java/heigit/ors/services/mapmatching/requestprocessors/json/JsonMapMatchingResponseWriter.java b/openrouteservice/src/main/java/heigit/ors/services/mapmatching/requestprocessors/json/JsonMapMatchingResponseWriter.java index 3d2047f201..720c67367e 100644 --- a/openrouteservice/src/main/java/heigit/ors/services/mapmatching/requestprocessors/json/JsonMapMatchingResponseWriter.java +++ b/openrouteservice/src/main/java/heigit/ors/services/mapmatching/requestprocessors/json/JsonMapMatchingResponseWriter.java @@ -173,10 +173,10 @@ public static JSONArray toJsonArray(RoutingRequest request, RouteResult[] routeR jSegment.put("distance", seg.getDistance()); jSegment.put("duration", seg.getDuration()); - if (request.getIncludeElevation() && (seg.getAscent() !=0.0 || seg.getDescent() != 0.0)) + if (request.getIncludeElevation() && (seg.getAscentRounded() !=0.0 || seg.getDescentRounded() != 0.0)) { - jSegment.put("ascent", seg.getAscent()); - jSegment.put("descent", seg.getDescent()); + jSegment.put("ascent", seg.getAscentRounded()); + jSegment.put("descent", seg.getDescentRounded()); } if (attrDetourFactor) diff --git a/openrouteservice/src/main/java/heigit/ors/services/routing/requestprocessors/json/JsonRoutingResponseWriter.java b/openrouteservice/src/main/java/heigit/ors/services/routing/requestprocessors/json/JsonRoutingResponseWriter.java index 9881ead6be..ce52dee012 100644 --- a/openrouteservice/src/main/java/heigit/ors/services/routing/requestprocessors/json/JsonRoutingResponseWriter.java +++ b/openrouteservice/src/main/java/heigit/ors/services/routing/requestprocessors/json/JsonRoutingResponseWriter.java @@ -169,10 +169,10 @@ public static JSONArray toJsonArray(RoutingRequest request, RouteResult[] routeR jSegment.put("distance", seg.getDistance()); jSegment.put("duration", seg.getDuration()); - if (request.getIncludeElevation() && (seg.getAscent() !=0.0 || seg.getDescent() != 0.0)) + if (request.getIncludeElevation() && (seg.getAscentRounded() !=0.0 || seg.getDescentRounded() != 0.0)) { - jSegment.put("ascent", seg.getAscent()); - jSegment.put("descent", seg.getDescent()); + jSegment.put("ascent", seg.getAscentRounded()); + jSegment.put("descent", seg.getDescentRounded()); } if (attrDetourFactor) diff --git a/openrouteservice/src/main/java/heigit/ors/util/FormatUtility.java b/openrouteservice/src/main/java/heigit/ors/util/FormatUtility.java index 2d758ddfa5..bd05e24267 100644 --- a/openrouteservice/src/main/java/heigit/ors/util/FormatUtility.java +++ b/openrouteservice/src/main/java/heigit/ors/util/FormatUtility.java @@ -210,4 +210,9 @@ else if (unit == DistanceUnit.Kilometers || unit == DistanceUnit.Miles) return 1; } + + public static double roundToDecimalsForUnits(double d, DistanceUnit unit) + { + return roundToDecimals(d, getUnitDecimals(unit)); + } } diff --git a/openrouteservice/src/main/java/heigit/ors/util/GeomUtility.java b/openrouteservice/src/main/java/heigit/ors/util/GeomUtility.java index a372643378..f4a5830627 100644 --- a/openrouteservice/src/main/java/heigit/ors/util/GeomUtility.java +++ b/openrouteservice/src/main/java/heigit/ors/util/GeomUtility.java @@ -64,36 +64,33 @@ public static double pointToLineDistance(double ax, double ay, double bx, double * Creates the correct bbox from a Graphhopper pointlist. Instead of using the > or < operators to compare double * values this function uses the Math library which is more accurate and precise and creates correct bboxes even if * the coordinates only differ in some small extend. - * The Fallback bbox is used when the pointlist is empty. - * @param pointList + * @param pointList the points to consider * @return Returns a graphhopper bounding box */ - public static BBox CalculateBoundingBox(PointList pointList, BBox _fallback) { - if (pointList.getSize() <= 0) { - return _fallback; + public static BBox calculateBoundingBox(PointList pointList) { + if (pointList == null || pointList.getSize() <= 0) { + return new BBox(0, 0, 0, 0); } else { - double min_lon = Double.MAX_VALUE; - double max_lon = -Double.MAX_VALUE; - double min_lat = Double.MAX_VALUE; - double max_lat = -Double.MAX_VALUE; - double min_ele = Double.MAX_VALUE; - double max_ele = -Double.MAX_VALUE; + double minLon = Double.MAX_VALUE; + double maxLon = -Double.MAX_VALUE; + double minLat = Double.MAX_VALUE; + double maxLat = -Double.MAX_VALUE; + double minEle = Double.MAX_VALUE; + double maxEle = -Double.MAX_VALUE; for (int i = 0; i < pointList.getSize(); ++i) { - min_lon = Math.min(min_lon, pointList.getLon(i)); - max_lon = Math.max(max_lon, pointList.getLon(i)); - min_lat = Math.min(min_lat, pointList.getLat(i)); - max_lat = Math.max(max_lat, pointList.getLat(i)); + minLon = Math.min(minLon, pointList.getLon(i)); + maxLon = Math.max(maxLon, pointList.getLon(i)); + minLat = Math.min(minLat, pointList.getLat(i)); + maxLat = Math.max(maxLat, pointList.getLat(i)); if (pointList.is3D()) { - min_ele = Math.min(min_ele, pointList.getEle(i)); - max_ele = Math.max(max_ele, pointList.getEle(i)); + minEle = Math.min(minEle, pointList.getEle(i)); + maxEle = Math.max(maxEle, pointList.getEle(i)); } } if (pointList.is3D()) { - BBox summary_bbox = new BBox(min_lon, max_lon, min_lat, max_lat, min_ele, max_ele); - return summary_bbox; + return new BBox(minLon, maxLon, minLat, maxLat, minEle, maxEle); } else { - BBox summary_bbox = new BBox(min_lon, max_lon, min_lat, max_lat); - return summary_bbox; + return new BBox(minLon, maxLon, minLat, maxLat); } } } diff --git a/openrouteservice/src/main/java/heigit/ors/util/mockupUtil/RouteResultMockup.java b/openrouteservice/src/main/java/heigit/ors/util/mockupUtil/RouteResultMockup.java index d23564ca7c..8e8fca69c3 100644 --- a/openrouteservice/src/main/java/heigit/ors/util/mockupUtil/RouteResultMockup.java +++ b/openrouteservice/src/main/java/heigit/ors/util/mockupUtil/RouteResultMockup.java @@ -77,7 +77,7 @@ public static RouteResult[] create(routeResultProfile profile) throws Exception pointList.add(8.6904630144789, 49.384111711027735); pointList.add(8.690476425524274, 49.38459562624832); pointList.add(8.690506107646703, 49.38539990448134); - routeResult.addPoints(pointList, false, false); + routeResult.addPointsToGeometry(pointList, false, false); PathWrapper pathWrapper = new PathWrapper(); pathWrapper.setDistance(0.0); pathWrapper.setInstructions(null); @@ -138,8 +138,8 @@ public static RouteResult[] create(routeResultProfile profile) throws Exception routeSegment.addStep(routeStep3); // Add RouteSegment routeResult.addSegment(routeSegment); - routeResult.setWayPointsIndices(new int[]{0, 2}); - routeResult.setLocationIndex(0); + routeResult.addWayPointIndex(0); + routeResult.addWayPointIndex(2); return new RouteResult[]{routeResult}; } else { diff --git a/openrouteservice/src/test/java/heigit/ors/routing/RouteSearchParametersTest.java b/openrouteservice/src/test/java/heigit/ors/routing/RouteSearchParametersTest.java index 782c559ae4..19f5fc047e 100644 --- a/openrouteservice/src/test/java/heigit/ors/routing/RouteSearchParametersTest.java +++ b/openrouteservice/src/test/java/heigit/ors/routing/RouteSearchParametersTest.java @@ -204,7 +204,7 @@ public void hasParameters() throws Exception { } @Test - public void getProfileParameters() throws Exception { + public void getProfileParameters() { RouteSearchParameters routeSearchParameters = new RouteSearchParameters(); Assert.assertNull(routeSearchParameters.getProfileParameters()); } @@ -253,9 +253,66 @@ public void setBearings() { @Test public void alternativeRoutesParams() throws Exception { RouteSearchParameters routeSearchParameters = new RouteSearchParameters(); - routeSearchParameters.setOptions("{\"alternative_routes\": 2, \"alternative_routes_weight_factor\": 3.3, \"alternative_routes_share_factor\": 4.4}}"); - Assert.assertEquals(2, routeSearchParameters.getAlternativeRoutes()); + routeSearchParameters.setOptions("{\"alternative_routes_count\": 2, \"alternative_routes_weight_factor\": 3.3, \"alternative_routes_share_factor\": 4.4}}"); + Assert.assertEquals(2, routeSearchParameters.getAlternativeRoutesCount()); Assert.assertEquals(3.3, routeSearchParameters.getAlternativeRoutesWeightFactor(), 0.0); Assert.assertEquals(4.4, routeSearchParameters.getAlternativeRoutesShareFactor(), 0.0); } + + @Test + public void requiresDynamicWeights() throws Exception { + RouteSearchParameters routeSearchParameters = new RouteSearchParameters(); + Assert.assertFalse(routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setAvoidAreas(new Polygon[1]); + Assert.assertTrue("avoid areas", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setAvoidFeatureTypes(1); + Assert.assertTrue("avoid features", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setAvoidBorders(BordersExtractor.Avoid.CONTROLLED); + Assert.assertTrue("avoid borders", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setAvoidCountries(new int[1]); + Assert.assertTrue("avoid countries", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setOptions("{\"alternative_routes_count\": 2, \"alternative_routes_weight_factor\": 3.3, \"alternative_routes_share_factor\": 4.4}}"); + Assert.assertTrue("alternative routes", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setMaximumSpeed(2.0); + Assert.assertTrue("maximum speed", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setConsiderTurnRestrictions(true); + Assert.assertTrue("turn restrictions", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setWeightingMethod(WeightingMethod.SHORTEST); + Assert.assertTrue("shortest", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setWeightingMethod(WeightingMethod.RECOMMENDED); + Assert.assertTrue("recommended", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setProfileType(RoutingProfileType.DRIVING_HGV); + routeSearchParameters.setVehicleType(HeavyVehicleAttributes.HGV); + Assert.assertTrue("heavy vehicle", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setProfileType(RoutingProfileType.DRIVING_HGV); + routeSearchParameters.setOptions("{\"profile_params\":{\"weightings\":{\"green\":{\"factor\":0.8}}}}"); + Assert.assertTrue("profile param", routeSearchParameters.requiresDynamicWeights()); + + routeSearchParameters = new RouteSearchParameters(); + routeSearchParameters.setProfileType(RoutingProfileType.DRIVING_CAR); + routeSearchParameters.setConsiderTraffic(true); + Assert.assertTrue("consider traffic", routeSearchParameters.requiresDynamicWeights()); + } } diff --git a/openrouteservice/src/test/java/heigit/ors/util/GeomUtilityTest.java b/openrouteservice/src/test/java/heigit/ors/util/GeomUtilityTest.java index f79b0ef2b7..e01d937937 100644 --- a/openrouteservice/src/test/java/heigit/ors/util/GeomUtilityTest.java +++ b/openrouteservice/src/test/java/heigit/ors/util/GeomUtilityTest.java @@ -32,10 +32,9 @@ public static void setUp() { @Test public void calculateBoundingBox() { - BBox _fallback = new BBox(0, 0, 0, 0); - BBox bbox3D = GeomUtility.CalculateBoundingBox(pointList3D, _fallback); - BBox bbox2D = GeomUtility.CalculateBoundingBox(pointList2D, _fallback); - BBox bbox_fallback = GeomUtility.CalculateBoundingBox(emptyPointList,_fallback); + BBox bbox3D = GeomUtility.calculateBoundingBox(pointList3D); + BBox bbox2D = GeomUtility.calculateBoundingBox(pointList2D); + BBox bbox_fallback = GeomUtility.calculateBoundingBox(emptyPointList); Assert.assertEquals(-35.507813,bbox3D.minLon, 0.000009); Assert.assertEquals(38.408203,bbox3D.maxLon, 0.0000009);