diff --git a/core/src/main/resources/com/graphhopper/custom_models/bike.json b/core/src/main/resources/com/graphhopper/custom_models/bike.json index 875529a77a..22f8ba84dd 100644 --- a/core/src/main/resources/com/graphhopper/custom_models/bike.json +++ b/core/src/main/resources/com/graphhopper/custom_models/bike.json @@ -1,6 +1,6 @@ // to use this custom model you need to set the following option in the config.yml // graph.elevation.provider: srtm # enables elevation -// graph.encoded_values: bike_priority, bike_access, roundabout, bike_average_speed, average_slope +// graph.encoded_values: bike_priority, mtb_rating, bike_access, roundabout, bike_average_speed, average_slope // profiles: // - name: bike // custom_model_files: [bike.json, bike_elevation.json] @@ -8,6 +8,7 @@ { "priority": [ { "if": "true", "multiply_by": "bike_priority" }, + { "if": "mtb_rating > 2", "multiply_by": "0" }, { "if": "!bike_access && (!backward_bike_access || roundabout)", "multiply_by": "0" }, { "else_if": "!bike_access && backward_bike_access", "multiply_by": "0.2" } ], diff --git a/core/src/main/resources/com/graphhopper/custom_models/mtb.json b/core/src/main/resources/com/graphhopper/custom_models/mtb.json index d3b9088d28..d5297e9964 100644 --- a/core/src/main/resources/com/graphhopper/custom_models/mtb.json +++ b/core/src/main/resources/com/graphhopper/custom_models/mtb.json @@ -1,6 +1,6 @@ // to use this custom model you need to set the following option in the config.yml // graph.elevation.provider: srtm # enables elevation -// graph.encoded_values: mtb_priority, mtb_access, roundabout, mtb_average_speed, average_slope +// graph.encoded_values: mtb_priority, mtb_access, roundabout, mtb_average_speed, average_slope, mtb_rating // profiles: // - name: mtb // custom_model_files: [mtb.json, bike_elevation.json] @@ -8,11 +8,14 @@ { "priority": [ { "if": "true", "multiply_by": "mtb_priority" }, + { "if": "mtb_rating > 6", "multiply_by": "0" }, + { "if": "mtb_rating > 3", "multiply_by": "0.5" }, { "if": "!mtb_access && (!backward_mtb_access || roundabout)", "multiply_by": "0" }, { "else_if": "!mtb_access && backward_mtb_access", "multiply_by": "0.2" } ], "speed": [ { "if": "true", "limit_to": "mtb_average_speed" }, + { "if": "mtb_rating > 3", "limit_to": "4" }, { "if": "!mtb_access && backward_mtb_access", "limit_to": "5" } ] } diff --git a/core/src/main/resources/com/graphhopper/custom_models/racingbike.json b/core/src/main/resources/com/graphhopper/custom_models/racingbike.json index 6b32e079d9..fe38f36631 100644 --- a/core/src/main/resources/com/graphhopper/custom_models/racingbike.json +++ b/core/src/main/resources/com/graphhopper/custom_models/racingbike.json @@ -1,6 +1,6 @@ // to use this custom model you need to set the following option in the config.yml // graph.elevation.provider: srtm # enables elevation -// graph.encoded_values: racingbike_priority, racingbike_access, roundabout, racingbike_average_speed, average_slope +// graph.encoded_values: racingbike_priority, racingbike_access, roundabout, racingbike_average_speed, average_slope, mtb_rating // profiles: // - name: racingbike // custom_model_files: [racingbike.json, bike_elevation.json] @@ -8,6 +8,8 @@ { "priority": [ { "if": "true", "multiply_by": "racingbike_priority" }, + { "if": "mtb_rating > 2", "multiply_by": "0" }, + { "if": "mtb_rating == 2", "multiply_by": "0.5" }, { "if": "!racingbike_access && (!backward_racingbike_access || roundabout)", "multiply_by": "0" }, { "else_if": "!racingbike_access && backward_racingbike_access", "multiply_by": "0.2" } ], diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeCustomModelTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeCustomModelTest.java new file mode 100644 index 0000000000..1249145ac5 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeCustomModelTest.java @@ -0,0 +1,162 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.OSMParsers; +import com.graphhopper.routing.util.PriorityCode; +import com.graphhopper.routing.weighting.custom.CustomModelParser; +import com.graphhopper.routing.weighting.custom.CustomWeighting; +import com.graphhopper.storage.BaseGraph; +import com.graphhopper.util.CustomModel; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.GHUtility; +import com.graphhopper.util.PMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class BikeCustomModelTest { + + private EncodingManager em; + private OSMParsers parsers; + + @BeforeEach + public void setup() { + IntEncodedValue bikeRating = MtbRating.create(); + em = new EncodingManager.Builder(). + add(VehicleAccess.create("bike")). + add(VehicleAccess.create("mtb")). + add(VehicleAccess.create("racingbike")). + add(VehicleSpeed.create("bike", 4, 2, false)). + add(VehicleSpeed.create("mtb", 4, 2, false)). + add(VehicleSpeed.create("racingbike", 4, 2, false)). + add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)). + add(VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false)). + add(VehiclePriority.create("racingbike", 4, PriorityCode.getFactor(1), false)). + add(FerrySpeed.create()). + add(RouteNetwork.create(BikeNetwork.KEY)). + add(Roundabout.create()). + add(Smoothness.create()). + add(RoadAccess.create()). + add(bikeRating).build(); + + parsers = new OSMParsers(). + addWayTagParser(new OSMMtbRatingParser(bikeRating)); + + parsers.addWayTagParser(new BikeAccessParser(em, new PMap())); + parsers.addWayTagParser(new MountainBikeAccessParser(em, new PMap())); + parsers.addWayTagParser(new RacingBikeAccessParser(em, new PMap())); + parsers.addWayTagParser(new BikeAverageSpeedParser(em)); + parsers.addWayTagParser(new MountainBikeAverageSpeedParser(em)); + parsers.addWayTagParser(new RacingBikeAverageSpeedParser(em)); + parsers.addWayTagParser(new BikePriorityParser(em)); + parsers.addWayTagParser(new MountainBikePriorityParser(em)); + parsers.addWayTagParser(new RacingBikePriorityParser(em)); + } + + EdgeIteratorState createEdge(ReaderWay way) { + BaseGraph graph = new BaseGraph.Builder(em).create(); + EdgeIteratorState edge = graph.edge(0, 1); + EdgeIntAccess edgeIntAccess = graph.getEdgeAccess(); + parsers.handleWayTags(edge.getEdge(), edgeIntAccess, way, em.createRelationFlags()); + return edge; + } + + @Test + public void testCustomBike() { + CustomModel cm = GHUtility.loadCustomModelFromJar("bike.json"); + ReaderWay way = new ReaderWay(0L); + way.setTag("highway", "path"); + way.setTag("surface", "ground"); + EdgeIteratorState edge = createEdge(way); + CustomWeighting.Parameters p = CustomModelParser.createWeightingParameters(cm, em); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "0"); + edge = createEdge(way); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "1+"); + edge = createEdge(way); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "2-"); + edge = createEdge(way); + assertEquals(0.0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.removeTag("mtb:scale"); + way.setTag("sac_scale", "hiking"); + edge = createEdge(way); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + way.setTag("sac_scale", "mountain_hiking"); + edge = createEdge(way); + assertEquals(0.0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + assertEquals(4.0, p.getEdgeToSpeedMapping().get(edge, false), 0.01); + } + + @Test + public void testCustomMtbBike() { + CustomModel cm = GHUtility.loadCustomModelFromJar("mtb.json"); + ReaderWay way = new ReaderWay(0L); + way.setTag("highway", "path"); + way.setTag("surface", "ground"); + EdgeIteratorState edge = createEdge(way); + CustomWeighting.Parameters p = CustomModelParser.createWeightingParameters(cm, em); + assertEquals(1.2, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + assertEquals(16.0, p.getEdgeToSpeedMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "3"); + edge = createEdge(way); + assertEquals(0.6, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "5"); + edge = createEdge(way); + assertEquals(0.6, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + assertEquals(4.0, p.getEdgeToSpeedMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "6"); + edge = createEdge(way); + assertEquals(0.0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.removeTag("mtb:scale"); + way.setTag("sac_scale", "hiking"); + edge = createEdge(way); + assertEquals(1.2, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + way.setTag("sac_scale", "mountain_hiking"); + edge = createEdge(way); + assertEquals(1.2, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + } + + @Test + public void testCustomRacingBike() { + CustomModel cm = GHUtility.loadCustomModelFromJar("racingbike.json"); + ReaderWay way = new ReaderWay(0L); + way.setTag("highway", "path"); + EdgeIteratorState edge = createEdge(way); + CustomWeighting.Parameters p = CustomModelParser.createWeightingParameters(cm, em); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + assertEquals(8.0, p.getEdgeToSpeedMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "0"); + edge = createEdge(way); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "1"); + edge = createEdge(way); + assertEquals(0.45, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.setTag("mtb:scale", "2"); + edge = createEdge(way); + assertEquals(0.0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + + way.removeTag("mtb:scale"); + way.setTag("sac_scale", "hiking"); + edge = createEdge(way); + assertEquals(0.9, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + way.setTag("sac_scale", "mountain_hiking"); + edge = createEdge(way); + assertEquals(0.0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); + } +} diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/HikeCustomModelTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/HikeCustomModelTest.java index 4742420151..2c085e8530 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/HikeCustomModelTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/HikeCustomModelTest.java @@ -61,12 +61,10 @@ public void testHikePrivate() { way.setTag("motor_vehicle", "private"); edge = createEdge(way); - p = CustomModelParser.createWeightingParameters(cm, em); assertEquals(1.2, p.getEdgeToPriorityMapping().get(edge, false), 0.01); way.setTag("sac_scale", "alpine_hiking"); edge = createEdge(way); - p = CustomModelParser.createWeightingParameters(cm, em); assertEquals(1.2, p.getEdgeToPriorityMapping().get(edge, false), 0.01); assertEquals(1.5, p.getEdgeToSpeedMapping().get(edge, false), 0.01); @@ -74,12 +72,10 @@ public void testHikePrivate() { way.setTag("highway", "track"); way.setTag("access", "private"); edge = createEdge(way); - p = CustomModelParser.createWeightingParameters(cm, em); assertEquals(0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); way.setTag("sac_scale", "alpine_hiking"); edge = createEdge(way); - p = CustomModelParser.createWeightingParameters(cm, em); assertEquals(0, p.getEdgeToPriorityMapping().get(edge, false), 0.01); } }