From 40c140b8c1e544ba5891e657d2ea3195db2ed239 Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Wed, 22 Jan 2025 11:47:23 +0100 Subject: [PATCH 1/7] test: add test for ferry tag handling --- .../flagencoders/CarFlagEncoderTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoderTest.java b/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoderTest.java index e8a25742f2..9f7f638648 100644 --- a/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoderTest.java +++ b/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoderTest.java @@ -41,6 +41,10 @@ Weighting createWeighting(String vehicle, String weighting) { return weightingFactory.createWeighting(profile, new PMap(), false); } + private ReaderWay generateFerryWay() { + way.getTags().put("route", "ferry"); + return way; + } @Test void testDestinationTag() { IntsRef relFlags = em.createRelationFlags(); @@ -67,4 +71,26 @@ void testDestinationTag() { assertEquals(WAY_DISTANCE * LimitedAccessWeighting.VEHICLE_DESTINATION_FACTOR, carShortest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); assertEquals(WAY_DISTANCE * LimitedAccessWeighting.DEFAULT_DESTINATION_FACTOR, bikeShortest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); } + + @Test + void testFerryTag() { + way = generateFerryWay(); + CarFlagEncoder flagEncoder = (CarFlagEncoder) em.getEncoder(FlagEncoderNames.CAR_ORS); + // motor_vehicle = no -> reject + way.getTags().put("motor_vehicle", "no"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + // foot = * -> reject + way.getTags().remove("motor_vehicle"); + way.getTags().put("foot", "no"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + way.getTags().replace("foot", "yes"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + // only ferry flag -> accept + way.getTags().remove("foot"); + assertTrue(flagEncoder.getAccess(way).isFerry()); + } + } From cbad22cb1223525dc398bb555ab73d21e19af55a Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Wed, 22 Jan 2025 11:44:13 +0100 Subject: [PATCH 2/7] fix: allow ways with ferry tag only --- .../extensions/flagencoders/CarFlagEncoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoder.java b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoder.java index 682b583efe..4f3af7a295 100644 --- a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoder.java +++ b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/CarFlagEncoder.java @@ -81,11 +81,14 @@ public EncodingManager.Access getAccess(ReaderWay way) { for (String restrictionValue : restrictionValues) { if (restrictedValues.contains(restrictionValue)) return EncodingManager.Access.CAN_SKIP; - if (intendedValues.contains(restrictionValue) || - // implied default is allowed only if foot and bicycle is not specified: - restrictionValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) + if (intendedValues.contains(restrictionValue)) return EncodingManager.Access.FERRY; } + + // implied default is allowed only if foot and bicycle is not specified: + if (restrictionValues.length == 0 && !way.hasTag("foot") && !way.hasTag("bicycle")) { + return EncodingManager.Access.FERRY; + } } return EncodingManager.Access.CAN_SKIP; } From eb4c9f81e074e40058ff595f0dfdd0117fab363b Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Wed, 22 Jan 2025 16:49:34 +0100 Subject: [PATCH 3/7] test: add HeavyVehicleFlagEncoderTest --- .../HeavyVehicleFlagEncoderTest.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoderTest.java diff --git a/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoderTest.java b/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoderTest.java new file mode 100644 index 0000000000..bcddc565b0 --- /dev/null +++ b/ors-engine/src/test/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoderTest.java @@ -0,0 +1,96 @@ +package org.heigit.ors.routing.graphhopper.extensions.flagencoders; + +import com.graphhopper.config.Profile; +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.WeightingFactory; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.GraphBuilder; +import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.GHUtility; +import com.graphhopper.util.PMap; +import org.heigit.ors.routing.graphhopper.extensions.ORSDefaultFlagEncoderFactory; +import org.heigit.ors.routing.graphhopper.extensions.ORSWeightingFactory; +import org.heigit.ors.routing.graphhopper.extensions.weighting.LimitedAccessWeighting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class HeavyVehicleFlagEncoderTest { + private final EncodingManager em = EncodingManager.create(new ORSDefaultFlagEncoderFactory(), FlagEncoderNames.HEAVYVEHICLE + "," + FlagEncoderNames.BIKE_ORS); + private ReaderWay way; + + static final double WAY_DISTANCE = 1000; + static final double HEAVYVEHICLE_DURATION = 180; + static final double BIKE_DURATION = 300; + + @BeforeEach + void initWay() { + way = new ReaderWay(1); + } + + Weighting createWeighting(String vehicle, String weighting) { + GraphHopperStorage g = new GraphBuilder(em).create(); + WeightingFactory weightingFactory = new ORSWeightingFactory(g, em); + + Profile profile = new Profile(vehicle + "_" + weighting).setVehicle(vehicle).setWeighting(weighting); + + return weightingFactory.createWeighting(profile, new PMap(), false); + } + + private ReaderWay generateFerryWay() { + way.getTags().put("route", "ferry"); + return way; + } + @Test + void testDestinationTag() { + IntsRef relFlags = em.createRelationFlags(); + + Weighting hgvFastest = createWeighting(FlagEncoderNames.HEAVYVEHICLE, "fastest"); + Weighting bikeFastest = createWeighting(FlagEncoderNames.BIKE_ORS, "fastest"); + + way.setTag("highway", "road"); + EncodingManager.AcceptWay acceptWay = new EncodingManager.AcceptWay(); + assertTrue(em.acceptWay(way, acceptWay)); + IntsRef edgeFlags = em.handleWayTags(way, acceptWay, relFlags); + assertEquals(HEAVYVEHICLE_DURATION, hgvFastest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + assertEquals(BIKE_DURATION, bikeFastest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + + way.setTag("motor_vehicle", "destination"); + edgeFlags = em.handleWayTags(way, acceptWay, relFlags); + assertEquals(HEAVYVEHICLE_DURATION * LimitedAccessWeighting.VEHICLE_DESTINATION_FACTOR, hgvFastest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + assertEquals(BIKE_DURATION * LimitedAccessWeighting.DEFAULT_DESTINATION_FACTOR, bikeFastest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + + Weighting carShortest = createWeighting(FlagEncoderNames.HEAVYVEHICLE, "shortest"); + Weighting bikeShortest = createWeighting(FlagEncoderNames.BIKE_ORS, "shortest"); + + edgeFlags = em.handleWayTags(way, acceptWay, relFlags); + assertEquals(WAY_DISTANCE * LimitedAccessWeighting.VEHICLE_DESTINATION_FACTOR, carShortest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + assertEquals(WAY_DISTANCE * LimitedAccessWeighting.DEFAULT_DESTINATION_FACTOR, bikeShortest.calcEdgeWeight(GHUtility.createMockedEdgeIteratorState(WAY_DISTANCE, edgeFlags), false), 0.1); + } + + @Test + void testFerryTag() { + way = generateFerryWay(); + HeavyVehicleFlagEncoder flagEncoder = (HeavyVehicleFlagEncoder) em.getEncoder(FlagEncoderNames.HEAVYVEHICLE); + // motor_vehicle = no -> reject + way.getTags().put("motor_vehicle", "no"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + // foot = * -> reject + way.getTags().remove("motor_vehicle"); + way.getTags().put("foot", "no"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + way.getTags().replace("foot", "yes"); + assertTrue(flagEncoder.getAccess(way).canSkip()); + + // only ferry flag -> accept + way.getTags().remove("foot"); + assertTrue(flagEncoder.getAccess(way).isFerry()); + } + +} \ No newline at end of file From 58da6da92e66638b8efcbb3aa011dfe0044931d5 Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Wed, 22 Jan 2025 16:55:37 +0100 Subject: [PATCH 4/7] fix: allow ways with ferry tag only for hgv --- .../extensions/flagencoders/HeavyVehicleFlagEncoder.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java index 103d59dcea..cfafefe093 100644 --- a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java +++ b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java @@ -162,12 +162,14 @@ public EncodingManager.Access getAccess(ReaderWay way) { for (String restrictionValue : restrictionValues) { if (restrictedValues.contains(restrictionValue)) return EncodingManager.Access.CAN_SKIP; - if (intendedValues.contains(restrictionValue) || - // implied default is allowed only if foot and bicycle is not specified: - restrictionValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) + if (intendedValues.contains(restrictionValue)) return EncodingManager.Access.FERRY; } } + // implied default is allowed only if foot and bicycle is not specified: + if (restrictionValues.length == 0 && !way.hasTag("foot") && !way.hasTag("bicycle")) { + return EncodingManager.Access.FERRY; + } return EncodingManager.Access.CAN_SKIP; } From b5090459ed2fbb70d85b7de3b86631e04dae6e64 Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Wed, 22 Jan 2025 16:56:41 +0100 Subject: [PATCH 5/7] chore: update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d27a7eb8b2..ff1afcc246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ RELEASING: - NPE in error handling ([#1925](https://github.com/GIScience/openrouteservice/pull/1925)) - Add missing 'build' in documentation for profile properties ([#1947](https://github.com/GIScience/openrouteservice/issues//1947)) +- implicit vehicle access handling for ferries ### Security From d96537c92f40e9133bf811d7afbbbbcc0c01b4c1 Mon Sep 17 00:00:00 2001 From: Jakob Schnell Date: Thu, 23 Jan 2025 14:39:17 +0100 Subject: [PATCH 6/7] fix: move check to correct location --- .../extensions/flagencoders/HeavyVehicleFlagEncoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java index cfafefe093..abf96a25ae 100644 --- a/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java +++ b/ors-engine/src/main/java/org/heigit/ors/routing/graphhopper/extensions/flagencoders/HeavyVehicleFlagEncoder.java @@ -165,10 +165,10 @@ public EncodingManager.Access getAccess(ReaderWay way) { if (intendedValues.contains(restrictionValue)) return EncodingManager.Access.FERRY; } - } - // implied default is allowed only if foot and bicycle is not specified: - if (restrictionValues.length == 0 && !way.hasTag("foot") && !way.hasTag("bicycle")) { - return EncodingManager.Access.FERRY; + // implied default is allowed only if foot and bicycle is not specified: + if (restrictionValues.length == 0 && !way.hasTag("foot") && !way.hasTag("bicycle")) { + return EncodingManager.Access.FERRY; + } } return EncodingManager.Access.CAN_SKIP; } From 4e53a67abbc069fc927b952a3e0f838fc0c63a13 Mon Sep 17 00:00:00 2001 From: aoles Date: Thu, 23 Jan 2025 14:50:11 +0100 Subject: [PATCH 7/7] chore: tweak CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff1afcc246..4e93df4d82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,7 @@ RELEASING: - NPE in error handling ([#1925](https://github.com/GIScience/openrouteservice/pull/1925)) - Add missing 'build' in documentation for profile properties ([#1947](https://github.com/GIScience/openrouteservice/issues//1947)) -- implicit vehicle access handling for ferries +- Allow vehicles on ferries without explicit access tags ([#1954](https://github.com/GIScience/openrouteservice/pull/1954)) ### Security