diff --git a/CHANGELOG.md b/CHANGELOG.md index 50476db745..e60f37281f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,8 +40,9 @@ Releasing is documented in RELEASE.md ### Removed ### Fixed -- fix http pooling for matrix generation requests -- bump deprecated CodeQL and failing Grype scan GitHub actions to their current versions +- fix http pooling for matrix generation requests ([#2059](https://github.com/GIScience/openrouteservice/pull/2059)) +- bump deprecated CodeQL and failing Grype scan GitHub actions to their current versions ([#2061](https://github.com/GIScience/openrouteservice/pull/2061)) +- avoid routing on roads with access reserved to customers ([#2060](https://github.com/GIScience/openrouteservice/pull/2060)) ### Security diff --git a/ors-api/src/test/java/org/heigit/ors/apitests/routing/ResultTest.java b/ors-api/src/test/java/org/heigit/ors/apitests/routing/ResultTest.java index 24f5d9bf2d..ba0d70eefb 100644 --- a/ors-api/src/test/java/org/heigit/ors/apitests/routing/ResultTest.java +++ b/ors-api/src/test/java/org/heigit/ors/apitests/routing/ResultTest.java @@ -4579,6 +4579,47 @@ void testBarriersAccessPermit() { .statusCode(200); } + @Test + void testCustomersAccess() { + JSONArray coord1 = new JSONArray().put(8.682474).put(49.433011); + JSONArray coord2 = new JSONArray().put(8.682742).put(49.433153); + JSONArray coordinates = new JSONArray().put(coord1).put(coord2); + + JSONObject body = new JSONObject() + .put("coordinates", coordinates) + .put("preference", "shortest"); + + given() + .config(JSON_CONFIG_DOUBLE_NUMBERS) + .headers(CommonHeaders.jsonContent) + .pathParam("profile", getParameter("carProfile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(closeTo(35.6, 1))) + .statusCode(200); + + coord2 = new JSONArray().put(8.682718).put(49.433239); + coordinates = new JSONArray().put(coord1).put(coord2); + body.put("coordinates", coordinates); + + given() + .config(JSON_CONFIG_DOUBLE_NUMBERS) + .headers(CommonHeaders.jsonContent) + .pathParam("profile", getParameter("carProfile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(closeTo(60.3, 1))) + .statusCode(200); + } + private JSONArray constructBearings(String coordString) { JSONArray coordinates = new JSONArray(); String[] coordPairs = coordString.split("\\|"); diff --git a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/weighting/LimitedAccessWeighting.java b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/weighting/LimitedAccessWeighting.java index 71b1f65d14..156628b5c2 100644 --- a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/weighting/LimitedAccessWeighting.java +++ b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/weighting/LimitedAccessWeighting.java @@ -27,19 +27,21 @@ * @author Andrzej Oles */ public class LimitedAccessWeighting extends AbstractAdjustedWeighting { - public static double DEFAULT_DESTINATION_FACTOR = 1; - public static double VEHICLE_DESTINATION_FACTOR = 10; - public static double DEFAULT_PRIVATE_FACTOR = 1.2; - public static double VEHICLE_PRIVATE_FACTOR = 10; - - static double MIN_DESTINATION_FACTOR = 1; - static double MAX_DESTINATION_FACTOR = 10; - static double MIN_PRIVATE_FACTOR = 1; - static double MAX_PRIVATE_FACTOR = 10; + public static final double MIN_FACTOR = 1;// ensure that we do not need to change getMinWeight, i.e. road_access_factor >= 1 + public static final double MAX_FACTOR = 10; + public static final double DEFAULT_DESTINATION_FACTOR = 1; + public static final double VEHICLE_DESTINATION_FACTOR = 10; + public static final double DEFAULT_PRIVATE_FACTOR = 1.2; + public static final double VEHICLE_PRIVATE_FACTOR = 10; + public static final double DEFAULT_CUSTOMERS_FACTOR = 1.2; + public static final double VEHICLE_CUSTOMERS_FACTOR = 1.5; private final EnumEncodedValue roadAccessEnc; // this factor puts a penalty on roads with a "destination"-only or private access, see GH#733 and GH#1936 - private final double destinationPenalty, privatePenalty; + private final double destinationPenalty; + private final double privatePenalty; + // this factor puts a penalty on roads with a "customers"-only access, see ORS#1981 + private final double customersPenalty; public LimitedAccessWeighting(Weighting superWeighting, PMap map) { super(superWeighting); @@ -47,12 +49,16 @@ public LimitedAccessWeighting(Weighting superWeighting, PMap map) { if (!encoder.hasEncodedValue(RoadAccess.KEY)) throw new IllegalArgumentException("road_access is not available"); - // ensure that we do not need to change getMinWeight, i.e. road_access_factor >= 1 - double defaultDestinationFactor = encoder.getTransportationMode().isMotorVehicle() ? VEHICLE_DESTINATION_FACTOR : DEFAULT_DESTINATION_FACTOR; - destinationPenalty = checkBounds("road_access_destination_factor", map.getDouble("road_access_destination_factor", defaultDestinationFactor), MIN_DESTINATION_FACTOR, MAX_DESTINATION_FACTOR); - double defaultPrivateFactor = encoder.getTransportationMode().isMotorVehicle() ? VEHICLE_PRIVATE_FACTOR : DEFAULT_PRIVATE_FACTOR; - privatePenalty = checkBounds("road_access_private_factor", map.getDouble("road_access_private_factor", defaultPrivateFactor), MIN_PRIVATE_FACTOR, MAX_PRIVATE_FACTOR); - roadAccessEnc = destinationPenalty > 1 || privatePenalty > 1 ? encoder.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class) : null; + destinationPenalty = getFactorValue(encoder, map, "road_access_destination_factor", DEFAULT_DESTINATION_FACTOR, VEHICLE_DESTINATION_FACTOR); + privatePenalty = getFactorValue(encoder, map, "road_access_private_factor", DEFAULT_PRIVATE_FACTOR, VEHICLE_PRIVATE_FACTOR); + customersPenalty = getFactorValue(encoder, map, "road_access_customers_factor", DEFAULT_CUSTOMERS_FACTOR, VEHICLE_CUSTOMERS_FACTOR); + + roadAccessEnc = destinationPenalty > 1 || privatePenalty > 1 || customersPenalty > 1 ? encoder.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class) : null; + } + + static double getFactorValue(FlagEncoder encoder, PMap map, String key, double defaultFactor, double vehicleFactor) { + double defaultValue = encoder.getTransportationMode().isMotorVehicle() ? vehicleFactor : defaultFactor; + return checkBounds(key, map.getDouble(key, defaultValue), MIN_FACTOR, MAX_FACTOR); } static double checkBounds(String key, double val, double from, double to) { @@ -87,6 +93,8 @@ private double modifyWeight(double weight, EdgeIteratorState edgeState) { weight *= destinationPenalty; else if (access == RoadAccess.PRIVATE) weight *= privatePenalty; + else if (access == RoadAccess.CUSTOMERS) + weight *= customersPenalty; } return weight; }