Skip to content

fix: avoid roads reserved to customers #2060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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("\\|");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,38 @@
* @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<RoadAccess> 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);
FlagEncoder encoder = superWeighting.getFlagEncoder();
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) {
Expand Down Expand Up @@ -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;
}
Expand Down
Loading