From a0cddbd8241cae4f3af21bdef109ab5c95e1025a Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 13 Mar 2023 13:13:29 +0100 Subject: [PATCH 001/165] 7.0 release - change readme --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5a42db6ec75..7c5f3567da8 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,17 @@ We even have [good first issues](https://github.com/graphhopper/graphhopper/issu To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read through our documentation and install the GraphHopper Web Service locally. -* 6.x: [documentation](https://github.com/graphhopper/graphhopper/blob/6.x/docs/index.md) - , [web service jar](https://repo1.maven.org/maven2/com/graphhopper/graphhopper-web/6.2/graphhopper-web-6.2.jar) - , [announcement](https://www.graphhopper.com/blog/2022/09/19/graphhopper-routing-engine-6-0-released/) +* 7.x: [documentation](https://github.com/graphhopper/graphhopper/blob/7.x/docs/index.md) + , [web service jar](https://repo1.maven.org/maven2/com/graphhopper/graphhopper-web/7.0/graphhopper-web-7.0.jar) + , [announcement](https://www.graphhopper.com/blog/2023/03/14/graphhopper-routing-engine-7-0-released/) * unstable master: [documentation](https://github.com/graphhopper/graphhopper/blob/master/docs/index.md)
Click to see older releases * See our [changelog file](./CHANGELOG.md) for Java API Changes. +* 6.x: [documentation](https://github.com/graphhopper/graphhopper/blob/6.x/docs/index.md) + , [web service jar](https://repo1.maven.org/maven2/com/graphhopper/graphhopper-web/6.2/graphhopper-web-6.2.jar) + , [announcement](https://www.graphhopper.com/blog/2022/09/19/graphhopper-routing-engine-6-0-released/) * 5.x: [documentation](https://github.com/graphhopper/graphhopper/blob/5.x/docs/index.md) , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar) , [announcement](https://www.graphhopper.com/blog/2022/03/23/graphhopper-routing-engine-5-0-released/) @@ -81,7 +84,7 @@ To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read To install the [GraphHopper Maps](https://graphhopper.com/maps/) UI and the web service locally you [need a JVM](https://adoptium.net) (>= Java 8) and do: ```bash -wget https://repo1.maven.org/maven2/com/graphhopper/graphhopper-web/6.2/graphhopper-web-6.2.jar https://raw.githubusercontent.com/graphhopper/graphhopper/6.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf +wget https://repo1.maven.org/maven2/com/graphhopper/graphhopper-web/7.0/graphhopper-web-7.0.jar https://raw.githubusercontent.com/graphhopper/graphhopper/7.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf java -D"dw.graphhopper.datareader.file=berlin-latest.osm.pbf" -jar graphhopper*.jar server config-example.yml ``` From 0cfe445ba7f5b220fa1da7f7ceabe580be6f6e81 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 13 Mar 2023 13:14:57 +0100 Subject: [PATCH 002/165] use 8.0-SNAPSHOT --- client-hc/pom.xml | 4 ++-- core/pom.xml | 4 ++-- example/pom.xml | 4 ++-- map-matching/pom.xml | 4 ++-- navigation/pom.xml | 4 ++-- pom.xml | 2 +- reader-gtfs/pom.xml | 2 +- tools/pom.xml | 2 +- web-api/pom.xml | 4 ++-- web-bundle/pom.xml | 4 ++-- web/pom.xml | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/client-hc/pom.xml b/client-hc/pom.xml index dd31382f7a2..425832d61e3 100644 --- a/client-hc/pom.xml +++ b/client-hc/pom.xml @@ -22,14 +22,14 @@ 4.0.0 directions-api-client-hc - 7.0-SNAPSHOT + 8.0-SNAPSHOT jar GraphHopper Directions API hand-crafted Java Client. com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index d060a9e3b7b..6d7d227a886 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ graphhopper-core GraphHopper Core - 7.0-SNAPSHOT + 8.0-SNAPSHOT jar GraphHopper is a fast and memory efficient Java road routing engine @@ -14,7 +14,7 @@ com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/example/pom.xml b/example/pom.xml index bc9b9cbe018..50e79f13345 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-example - 7.0-SNAPSHOT + 8.0-SNAPSHOT jar GraphHopper Example com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/map-matching/pom.xml b/map-matching/pom.xml index 2d6bcb0f33c..975e04f6f90 100644 --- a/map-matching/pom.xml +++ b/map-matching/pom.xml @@ -3,14 +3,14 @@ 4.0.0 com.graphhopper graphhopper-map-matching - 7.0-SNAPSHOT + 8.0-SNAPSHOT jar GraphHopper Map Matching com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/navigation/pom.xml b/navigation/pom.xml index a55db2fd6c1..92ff6dd3961 100644 --- a/navigation/pom.xml +++ b/navigation/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-nav - 7.0-SNAPSHOT + 8.0-SNAPSHOT jar GraphHopper Navigation com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 2023a097e27..71571981b93 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.graphhopper graphhopper-parent GraphHopper Parent Project - 7.0-SNAPSHOT + 8.0-SNAPSHOT pom https://www.graphhopper.com 2012 diff --git a/reader-gtfs/pom.xml b/reader-gtfs/pom.xml index a5ede60be48..9c199152d92 100644 --- a/reader-gtfs/pom.xml +++ b/reader-gtfs/pom.xml @@ -10,7 +10,7 @@ com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/tools/pom.xml b/tools/pom.xml index 2aa29aece58..c21c1455d81 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -10,7 +10,7 @@ com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT package diff --git a/web-api/pom.xml b/web-api/pom.xml index 17f8d81aec8..7d55855c268 100644 --- a/web-api/pom.xml +++ b/web-api/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-web-api jar - 7.0-SNAPSHOT + 8.0-SNAPSHOT GraphHopper Web API JSON Representation of the API classes com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml index 7d7c791e127..853496a4c8d 100644 --- a/web-bundle/pom.xml +++ b/web-bundle/pom.xml @@ -5,7 +5,7 @@ 4.0.0 graphhopper-web-bundle jar - 7.0-SNAPSHOT + 8.0-SNAPSHOT 0.0.0-8922383db6f937fddb44acc702f2b45844566575 @@ -15,7 +15,7 @@ com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT diff --git a/web/pom.xml b/web/pom.xml index 62e2c7b2bb8..765dce7b0d4 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-web jar - 7.0-SNAPSHOT + 8.0-SNAPSHOT GraphHopper Web Use the GraphHopper routing engine as a web-service com.graphhopper graphhopper-parent - 7.0-SNAPSHOT + 8.0-SNAPSHOT package From 735de7afa93b5f88dc68f5b55c118a9169611272 Mon Sep 17 00:00:00 2001 From: Andi Date: Tue, 14 Mar 2023 17:55:08 +0100 Subject: [PATCH 003/165] Add path details for the time, distance and weight of the single legs (#2768) --- .../util/details/ConstantDetailsBuilder.java | 48 +++++++++++ .../details/PathDetailsBuilderFactory.java | 10 ++- .../util/details/PathDetailsFromEdges.java | 4 +- .../java/com/graphhopper/util/Parameters.java | 4 + .../resources/RouteResourceClientHCTest.java | 84 +++++++++++++++++++ .../resources/RouteResourceTest.java | 84 +++++++++++++++++++ 6 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/util/details/ConstantDetailsBuilder.java diff --git a/core/src/main/java/com/graphhopper/util/details/ConstantDetailsBuilder.java b/core/src/main/java/com/graphhopper/util/details/ConstantDetailsBuilder.java new file mode 100644 index 00000000000..d308e22acb7 --- /dev/null +++ b/core/src/main/java/com/graphhopper/util/details/ConstantDetailsBuilder.java @@ -0,0 +1,48 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.graphhopper.util.details; + +import com.graphhopper.util.EdgeIteratorState; + +/** + * Simply returns the same value everywhere, useful to represent values that are the same between two (via-)points + */ +public class ConstantDetailsBuilder extends AbstractPathDetailsBuilder { + private final Object value; + private boolean firstEdge = true; + + public ConstantDetailsBuilder(String name, Object value) { + super(name); + this.value = value; + } + + @Override + protected Object getCurrentValue() { + return value; + } + + @Override + public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { + if (firstEdge) { + firstEdge = false; + return true; + } else + return false; + } +} diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index 3719ff12918..6e456a72876 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -17,6 +17,7 @@ */ package com.graphhopper.util.details; +import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.Graph; @@ -33,9 +34,16 @@ */ public class PathDetailsBuilderFactory { - public List createPathDetailsBuilders(List requestedPathDetails, EncodedValueLookup evl, Weighting weighting, Graph graph) { + public List createPathDetailsBuilders(List requestedPathDetails, Path path, EncodedValueLookup evl, Weighting weighting, Graph graph) { List builders = new ArrayList<>(); + if (requestedPathDetails.contains(LEG_TIME)) + builders.add(new ConstantDetailsBuilder(LEG_TIME, path.getTime())); + if (requestedPathDetails.contains(LEG_DISTANCE)) + builders.add(new ConstantDetailsBuilder(LEG_DISTANCE, path.getDistance())); + if (requestedPathDetails.contains(LEG_WEIGHT)) + builders.add(new ConstantDetailsBuilder(LEG_WEIGHT, path.getWeight())); + if (requestedPathDetails.contains(STREET_NAME)) builders.add(new KVStringDetails(STREET_NAME)); if (requestedPathDetails.contains(STREET_REF)) diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java index 3a28ded8205..39da194f606 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java @@ -52,8 +52,6 @@ public PathDetailsFromEdges(List calculators, int previousIn /** * Calculates the PathDetails for a Path. This method will return fast, if there are no calculators. * - * @param path - * @param weighting * @param pathBuilderFactory Generates the relevant PathBuilders * @return List of PathDetails for this Path */ @@ -62,7 +60,7 @@ public static Map> calcDetails(Path path, EncodedValueL int previousIndex, Graph graph) { if (!path.isFound() || requestedPathDetails.isEmpty()) return Collections.emptyMap(); - List pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, evLookup, weighting, graph); + List pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, path, evLookup, weighting, graph); if (pathBuilders.isEmpty()) return Collections.emptyMap(); diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index a4e28ba54e8..1d8e6b6585e 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -205,6 +205,10 @@ public static final class Details { public static final String WEIGHT = "weight"; public static final String DISTANCE = "distance"; public static final String INTERSECTION = "intersection"; + + public static final String LEG_TIME = "leg_time"; + public static final String LEG_DISTANCE = "leg_distance"; + public static final String LEG_WEIGHT = "leg_weight"; } } diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index ff6510ecca0..8fb7e43e511 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -46,6 +46,8 @@ import java.io.File; import java.util.*; +import static com.graphhopper.util.Instruction.FINISH; +import static com.graphhopper.util.Instruction.REACHED_VIA; import static org.junit.jupiter.api.Assertions.*; /** @@ -379,4 +381,86 @@ public void testCustomModel() { assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString()); assertEquals(218_000, rsp.getBest().getTime(), 1000); } + + @ParameterizedTest + @EnumSource(value = TestParam.class) + public void testWaypointIndicesAndLegDetails(TestParam p) { + GraphHopperWeb gh = createGH(p); + List legDetails = Arrays.asList("leg_time", "leg_distance", "leg_weight"); + GHRequest req = new GHRequest(). + addPoint(new GHPoint(42.509141, 1.546063)). + addPoint(new GHPoint(42.507173, 1.531902)). + addPoint(new GHPoint(42.505435, 1.515943)). + addPoint(new GHPoint(42.499062, 1.506067)). + addPoint(new GHPoint(42.498801, 1.505568)). + addPoint(new GHPoint(42.498465, 1.504898)). + addPoint(new GHPoint(42.49833, 1.504619)). + addPoint(new GHPoint(42.498217, 1.504377)). + addPoint(new GHPoint(42.495611, 1.498368)). + setPathDetails(legDetails). + setProfile("bike"); + + GHResponse response = gh.route(req); + ResponsePath path = response.getBest(); + assertEquals(5333, path.getDistance(), 5); + assertEquals(9, path.getWaypoints().size()); + + assertEquals(path.getTime(), path.getPathDetails().get("leg_time").stream().mapToLong(d -> (long) d.getValue()).sum(), 1); + assertEquals(path.getDistance(), path.getPathDetails().get("leg_distance").stream().mapToDouble(d -> (double) d.getValue()).sum(), 1); + assertEquals(path.getRouteWeight(), path.getPathDetails().get("leg_weight").stream().mapToDouble(d -> (double) d.getValue()).sum(), 1); + + List pointListFromInstructions = getPointListFromInstructions(path); + for (String detail : legDetails) { + List pathDetails = path.getPathDetails().get(detail); + + // explicitly check one of the waypoints + assertEquals(42.50539, path.getWaypoints().get(2).lat); + assertEquals(42.50539, path.getPoints().get(pathDetails.get(1).getLast()).getLat()); + assertEquals(42.50539, path.getPoints().get(pathDetails.get(2).getFirst()).getLat()); + // check all the waypoints + assertEquals(path.getWaypoints().get(0), path.getPoints().get(pathDetails.get(0).getFirst())); + for (int i = 1; i < path.getWaypoints().size(); ++i) + assertEquals(path.getWaypoints().get(i), path.getPoints().get(pathDetails.get(i - 1).getLast())); + + List pointListFromLegDetails = getPointListFromLegDetails(path, detail); + assertEquals(8, pointListFromLegDetails.size()); + assertPointListsEquals(pointListFromInstructions, pointListFromLegDetails); + } + } + + private List getPointListFromInstructions(ResponsePath path) { + List legs = new ArrayList<>(); + PointList perLeg = new PointList(); + for (Instruction instruction : path.getInstructions()) { + perLeg.add(instruction.getPoints()); + if (instruction.getSign() == REACHED_VIA || instruction.getSign() == FINISH) { + legs.add(perLeg); + perLeg = new PointList(); + } else { + perLeg.removeLastPoint(); + } + } + return legs; + } + + private List getPointListFromLegDetails(ResponsePath path, String detail) { + List legs = new ArrayList<>(); + List legDetails = path.getPathDetails().get(detail); + for (PathDetail legDetail : legDetails) { + PointList leg = new PointList(legDetail.getLast() - legDetail.getFirst() + 1, path.getPoints().is3D()); + for (int j = legDetail.getFirst(); j <= legDetail.getLast(); j++) + leg.add(path.getPoints(), j); + legs.add(leg); + } + return legs; + } + + private static void assertPointListsEquals(List p, List q) { + assertEquals(p.size(), q.size()); + for (int i = 0; i < q.size(); i++) { + assertEquals(p.get(i).size(), q.get(i).size()); + for (int j = 0; j < q.get(i).size(); j++) + assertEquals(p.get(i).get(j), q.get(i).get(j)); + } + } } diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index eaed06572d2..d364a777b74 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -54,6 +54,8 @@ import static com.graphhopper.application.util.TestUtils.clientTarget; import static com.graphhopper.application.util.TestUtils.clientUrl; +import static com.graphhopper.util.Instruction.FINISH; +import static com.graphhopper.util.Instruction.REACHED_VIA; import static com.graphhopper.util.Parameters.NON_CH.MAX_NON_CH_POINT_DISTANCE; import static org.junit.jupiter.api.Assertions.*; @@ -623,4 +625,86 @@ public void testTooManyHeadings() { JsonNode json = response.readEntity(JsonNode.class); assertEquals("The number of 'heading' parameters must be zero, one or equal to the number of points (1)", json.get("message").asText()); } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void legDetailsAndPointIndices(boolean instructions) { + final long seed = 123L; + Random rnd = new Random(seed); + List legDetails = Arrays.asList("leg_time", "leg_distance", "leg_weight"); + int errors = 0; + for (int numPoints = 2; numPoints < 10; numPoints++) { + String url = "/route?profile=my_car&points_encoded=false&instructions=" + instructions; + for (int i = 0; i < numPoints; i++) { + double lat = 42.493748 + rnd.nextDouble() * (42.565155 - 42.493748); + double lon = 1.487522 + rnd.nextDouble() * (1.557285 - 1.487522); + url += "&point=" + lat + "," + lon; + } + for (String legDetail : legDetails) + url += "&details=" + legDetail; + final Response response = clientTarget(app, url).request().buildGet().invoke(); + JsonNode json = response.readEntity(JsonNode.class); + if (response.getStatus() != 200) { + // sometimes there can be connection-not-found for example, also because we set min_network_size to 0 in this test + errors++; + continue; + } + assertFalse(json.has("message")); + JsonNode path = json.get("paths").get(0); + JsonNode points = path.get("points"); + JsonNode snappedWaypoints = path.get("snapped_waypoints"); + assertEquals(numPoints, snappedWaypoints.get("coordinates").size()); + + assertEquals(path.get("time").asDouble(), sumDetail(path.get("details").get("leg_time")), 1); + assertEquals(path.get("distance").asDouble(), sumDetail(path.get("details").get("leg_distance")), 1); + assertEquals(path.get("weight").asDouble(), sumDetail(path.get("details").get("leg_weight")), 1); + + for (String detail : legDetails) { + JsonNode legDetail = path.get("details").get(detail); + assertEquals(numPoints - 1, legDetail.size()); + assertEquals(snappedWaypoints.get("coordinates").get(0), points.get("coordinates").get(legDetail.get(0).get(0).asInt())); + for (int i = 1; i < numPoints; i++) + // we make sure that the intervals defined by the leg details start/end at the snapped waypoints + assertEquals(snappedWaypoints.get("coordinates").get(i), points.get("coordinates").get(legDetail.get(i - 1).get(1).asInt())); + + if (instructions) { + // we can find the way point indices also from the instructions, so we check if this yields the same + List waypointIndicesFromInstructions = getWaypointIndicesFromInstructions(path.get("instructions")); + List waypointIndicesFromLegDetails = getWaypointIndicesFromLegDetails(legDetail); + assertEquals(waypointIndicesFromInstructions, waypointIndicesFromLegDetails); + } + } + } + if (errors > 3) + fail("too many errors"); + } + + private static List getWaypointIndicesFromInstructions(JsonNode instructions) { + List result = new ArrayList<>(); + result.add(instructions.get(0).get("interval").get(0).asInt()); + for (int i = 0; i < instructions.size(); i++) { + int sign = instructions.get(i).get("sign").asInt(); + if (sign == REACHED_VIA || sign == FINISH) + result.add(instructions.get(i).get("interval").get(1).asInt()); + } + return result; + } + + private static List getWaypointIndicesFromLegDetails(JsonNode detail) { + List result = new ArrayList<>(); + result.add(detail.get(0).get(0).asInt()); + for (int i = 0; i < detail.size(); i++) { + if (i > 0) + assertEquals(detail.get(i - 1).get(1).asInt(), detail.get(i).get(0).asInt()); + result.add(detail.get(i).get(1).asInt()); + } + return result; + } + + private double sumDetail(JsonNode detail) { + double result = 0; + for (int i = 0; i < detail.size(); i++) + result += detail.get(i).get(2).asDouble(); + return result; + } } From d1e00d4086ea854bb8b724101e59b3aa941f52fa Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 15 Mar 2023 09:29:20 +0100 Subject: [PATCH 004/165] A*: set weight of visited path explicitly --- core/src/main/java/com/graphhopper/routing/AStar.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/AStar.java b/core/src/main/java/com/graphhopper/routing/AStar.java index eb38945edd9..deb2e8f0117 100644 --- a/core/src/main/java/com/graphhopper/routing/AStar.java +++ b/core/src/main/java/com/graphhopper/routing/AStar.java @@ -150,7 +150,11 @@ protected Path extractPath() { if (currEdge == null || !finished()) return createEmptyPath(); - return PathExtractor.extractPath(graph, weighting, currEdge); + return PathExtractor.extractPath(graph, weighting, currEdge) + // the path extractor uses currEdge.weight to set the weight, but this is the one that includes the + // A* approximation, not the weight of the visited path! this is still correct, because the approximation + // at the to-node (the end of the route) must be zero. Still it seems clearer to set the weight explicitly. + .setWeight(currEdge.getWeightOfVisitedPath()); } @Override From 345904b6a9674f789ddd9de30bcf849ad4784d21 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Mar 2023 13:52:59 +0100 Subject: [PATCH 005/165] changelog: set release date --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6d8713c07a..9adf524493e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ -### 7.0 [not yet released] +### 8.0 [not yet released] + + +### 7.0 [14 Mar 2023] - remove StringEncodedValue support from custom model due to insufficient usage/testing - handle also node_tags in handleWayTags, when extending AbstractAccessParser call handleNodeTags, #2738 From 33859a06a8e52ba2380da16cf1ea66b077ad5a13 Mon Sep 17 00:00:00 2001 From: otbutz Date: Wed, 15 Mar 2023 13:54:09 +0100 Subject: [PATCH 006/165] Reuse the polygon BBox (#2685) Co-authored-by: Thomas Butz --- core/src/main/java/com/graphhopper/util/shapes/Polygon.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/util/shapes/Polygon.java b/core/src/main/java/com/graphhopper/util/shapes/Polygon.java index 3cd4fdf00d8..e58e1137db7 100644 --- a/core/src/main/java/com/graphhopper/util/shapes/Polygon.java +++ b/core/src/main/java/com/graphhopper/util/shapes/Polygon.java @@ -39,11 +39,13 @@ public class Polygon implements Shape { public final PreparedGeometry prepPolygon; public final boolean rectangle; public final Envelope envelope; + public final BBox bbox; public Polygon(PreparedPolygon prepPolygon) { this.prepPolygon = prepPolygon; this.rectangle = prepPolygon.getGeometry().isRectangle(); this.envelope = prepPolygon.getGeometry().getEnvelopeInternal(); + this.bbox = BBox.fromEnvelope(envelope); } public Polygon(double[] lats, double[] lons) { @@ -61,6 +63,7 @@ public Polygon(double[] lats, double[] lons) { this.prepPolygon = new PreparedPolygon(factory.createPolygon(new PackedCoordinateSequence.Double(coordinates, 2))); this.rectangle = prepPolygon.getGeometry().isRectangle(); this.envelope = prepPolygon.getGeometry().getEnvelopeInternal(); + this.bbox = BBox.fromEnvelope(envelope); } public static Polygon create(org.locationtech.jts.geom.Polygon polygon) { @@ -84,7 +87,7 @@ public boolean contains(double lat, double lon) { @Override public BBox getBounds() { - return new BBox(envelope.getMinX(), envelope.getMaxX(), envelope.getMinY(), envelope.getMaxY()); + return bbox; } public double getMinLat() { From d7817079fb1f6938c043d64f66add63cc5816d80 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 16 Mar 2023 11:31:36 +0100 Subject: [PATCH 007/165] Make use of node tags like 'highway' or 'crossing' (#2705) * Pass all node tags to edge handlers * Remove node tag count (was only used for analysis) * crossing EV (#2706) * add tests; fix traffic_signalS; remove zebra as same as uncontrolled; include proposed tags https://wiki.openstreetmap.org/wiki/Proposed_features/Highway_crossing_cleanup * fix * fix tests * minor fix * minor typo * node tag whitelist; use get not put in removeTag * include node tags handling for road_access and fords (road_environment) * mark only node tags of barrier edge as 'split_node' * avoid stream and collect * minor further perf tune * make barrier edge explicit via tag * simplify handleNodeTags * Remove artificial gh:split_node tag and use long hash set instead * minor rename * use EdgeKVStorage for node tags storage * rename EdgeKVStorage to KVStorage as also used to temporarily store node tags for import * log more infos about node tags; no compact necessary due to KVStorage; limit pointer of KVStorage to positive numbers for now * rename method to handleBarrierEdge * fix taggednodecount method * node tags for the barrier edge should be identical, i.e. use the ref instead of a copy --------- Co-authored-by: Peter --- CHANGELOG.md | 1 + .../java/com/graphhopper/GraphHopper.java | 4 +- .../graphhopper/reader/osm/OSMNodeData.java | 69 ++++++--- .../com/graphhopper/reader/osm/OSMReader.java | 36 +++-- .../graphhopper/reader/osm/SegmentNode.java | 6 +- .../reader/osm/WaySegmentParser.java | 56 ++++--- .../routing/InstructionsFromEdges.java | 2 +- .../com/graphhopper/routing/ev/Crossing.java | 30 ++++ .../ev/DefaultEncodedValueFactory.java | 5 +- .../querygraph/QueryOverlayBuilder.java | 4 +- .../querygraph/VirtualEdgeIterator.java | 6 +- .../querygraph/VirtualEdgeIteratorState.java | 14 +- .../util/parsers/AbstractAccessParser.java | 21 +-- .../util/parsers/BikeCommonAccessParser.java | 13 +- .../routing/util/parsers/CarAccessParser.java | 13 +- .../util/parsers/DefaultTagParserFactory.java | 2 + .../util/parsers/FootAccessParser.java | 12 +- .../util/parsers/OSMCrossingParser.java | 61 ++++++++ .../util/parsers/OSMRoadAccessParser.java | 37 +++-- .../parsers/OSMRoadEnvironmentParser.java | 11 ++ .../{EdgeKVStorage.java => KVStorage.java} | 146 ++++++++++++------ .../com/graphhopper/storage/BaseGraph.java | 14 +- .../java/com/graphhopper/util/Constants.java | 4 +- .../graphhopper/util/EdgeIteratorState.java | 6 +- .../java/com/graphhopper/GraphHopperTest.java | 37 ++++- .../graphhopper/reader/osm/OSMReaderTest.java | 2 +- .../com/graphhopper/routing/PathTest.java | 5 +- .../util/NameSimilarityEdgeFilterTest.java | 8 +- .../util/parsers/FootTagParserTest.java | 13 +- .../util/parsers/OSMCrossingParserTest.java | 88 +++++++++++ ...eKVStorageTest.java => KVStorageTest.java} | 56 +++---- .../storage/AbstractGraphStorageTester.java | 6 +- .../graphhopper/storage/BaseGraphTest.java | 4 +- .../storage/BaseGraphWithTurnCostsTest.java | 4 +- .../graphhopper/util/InstructionListTest.java | 4 +- .../util/PathSimplificationTest.java | 4 +- .../example/LocationIndexExample.java | 4 +- .../gtfs/analysis/PtGraphAsAdjacencyList.java | 6 +- .../java/com/graphhopper/util/Parameters.java | 2 +- .../graphhopper/gpx/GpxConversionsTest.java | 4 +- .../resources/ExtendedJsonResponseTest.java | 5 +- 41 files changed, 567 insertions(+), 258 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/Crossing.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java rename core/src/main/java/com/graphhopper/search/{EdgeKVStorage.java => KVStorage.java} (87%) create mode 100644 core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java rename core/src/test/java/com/graphhopper/search/{EdgeKVStorageTest.java => KVStorageTest.java} (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9adf524493e..0c6b6b3a58a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### 7.0 [14 Mar 2023] +- access node tags via List instead of Map: List> nodeTags = way.getTag("node_tags", emptyList()), see #2705 - remove StringEncodedValue support from custom model due to insufficient usage/testing - handle also node_tags in handleWayTags, when extending AbstractAccessParser call handleNodeTags, #2738 - Format of 'areas' in CustomModel changed to 'FeatureCollection'. The old format is deprecated and will be removed in a later version, #2734 diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index fde4c804c52..a620a0604c9 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -796,7 +796,7 @@ private String getVersionsString() { ",edges:" + Constants.VERSION_EDGE + ",geometry:" + Constants.VERSION_GEOMETRY + ",location_index:" + Constants.VERSION_LOCATION_IDX + - ",string_index:" + Constants.VERSION_EDGEKV_STORAGE + + ",string_index:" + Constants.VERSION_KV_STORAGE + ",nodesCH:" + Constants.VERSION_NODE_CH + ",shortcuts:" + Constants.VERSION_SHORTCUT; } @@ -1176,7 +1176,7 @@ protected void postProcessing(boolean closeEarly) { if (closeEarly) { boolean includesCustomProfiles = profilesByName.values().stream().anyMatch(p -> p instanceof CustomProfile); if (!includesCustomProfiles) - // when there are custom profiles we must not close way geometry or EdgeKVStorage, because + // when there are custom profiles we must not close way geometry or KVStorage, because // they might be needed to evaluate the custom weightings for the following preparations baseGraph.flushAndCloseGeometryAndNameStorage(); } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index b787d78edd5..3c442c01e84 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -18,22 +18,23 @@ package com.graphhopper.reader.osm; +import com.carrotsearch.hppc.LongScatterSet; +import com.carrotsearch.hppc.LongSet; import com.graphhopper.coll.GHLongIntBTree; import com.graphhopper.coll.LongIntMap; import com.graphhopper.reader.ReaderNode; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.Directory; import com.graphhopper.util.PointAccess; import com.graphhopper.util.PointList; import com.graphhopper.util.shapes.GHPoint3D; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; +import java.util.HashMap; import java.util.Map; import java.util.function.DoubleSupplier; import java.util.function.IntUnaryOperator; - -import static java.util.Collections.emptyMap; +import java.util.stream.Collectors; /** * This class stores OSM node data while reading an OSM file in {@link WaySegmentParser}. It is not trivial to do this @@ -67,12 +68,13 @@ class OSMNodeData { private final PillarInfo pillarNodes; private final PointAccess towerNodes; - // this map stores an index for each OSM node we keep the node tags of. a value of -1 means there is no entry - // yet and a value of -2 means there was an entry but it was removed again + // this map stores an index for each OSM node we keep the node tags of. a value of -1 means there is no entry yet. private final LongIntMap nodeTagIndicesByOsmNodeIds; // stores node tags - private final List> nodeTags; + private final KVStorage nodeKVStorage; + // collect all nodes that should be split and a barrier edge should be created between them. + private final LongSet nodesToBeSplit; private int nextTowerId = 0; private int nextPillarId = 0; @@ -80,15 +82,16 @@ class OSMNodeData { private long nextArtificialOSMNodeId = -Long.MAX_VALUE; public OSMNodeData(PointAccess nodeAccess, Directory directory) { - // we use GHLongIntBTree, because it is based on a tree, not an array, so it can store as many entries as there - // are longs. this also makes it memory efficient, because there is no need to pre-allocate memory for empty - // entries. + // We use GHLongIntBTree, because it is based on a tree, not an array, so it can store as many entries as there + // are longs. This also makes it memory efficient, because there is no need to pre-allocate memory for empty + // entries, and it also avoids allocating a new array and copying into it when increasing the size. idsByOsmNodeIds = new GHLongIntBTree(200); towerNodes = nodeAccess; pillarNodes = new PillarInfo(towerNodes.is3D(), directory); nodeTagIndicesByOsmNodeIds = new GHLongIntBTree(200); - nodeTags = new ArrayList<>(); + nodesToBeSplit = new LongScatterSet(); + nodeKVStorage = new KVStorage(directory, false); } public boolean is3D() { @@ -132,11 +135,15 @@ public long getNodeCount() { return idsByOsmNodeIds.getSize(); } + public long getTaggedNodeCount() { + return nodeTagIndicesByOsmNodeIds.getSize(); + } + /** * @return the number of nodes for which we store tags */ - public long getTaggedNodeCount() { - return nodeTags.size(); + public long getNodeTagCapacity() { + return nodeKVStorage.getCapacity(); } /** @@ -187,7 +194,7 @@ SegmentNode addCopyOfNode(SegmentNode node) { if (idsByOsmNodeIds.put(newOsmId, INTERMEDIATE_NODE) != EMPTY_NODE) throw new IllegalStateException("Artificial osm node id already exists: " + newOsmId); int id = addPillarNode(newOsmId, point.getLat(), point.getLon(), point.getEle()); - return new SegmentNode(newOsmId, id); + return new SegmentNode(newOsmId, id, node.tags); } int convertPillarToTowerNode(int id, long osmNodeId) { @@ -241,11 +248,13 @@ public void addCoordinatesToPointList(int id, PointList pointList) { public void setTags(ReaderNode node) { int tagIndex = nodeTagIndicesByOsmNodeIds.get(node.getId()); - if (tagIndex == -2) - throw new IllegalStateException("Cannot add tags after they were removed"); - else if (tagIndex == -1) { - nodeTagIndicesByOsmNodeIds.put(node.getId(), nodeTags.size()); - nodeTags.add(node.getTags()); + if (tagIndex == -1) { + long pointer = nodeKVStorage.add(node.getTags().entrySet().stream().map(m -> new KVStorage.KeyValue(m.getKey(), + m.getValue() instanceof String ? KVStorage.cutString((String) m.getValue()) : m.getValue())). + collect(Collectors.toList())); + if (pointer > Integer.MAX_VALUE) + throw new IllegalStateException("Too many key value pairs are stored in node tags, was " + pointer); + nodeTagIndicesByOsmNodeIds.put(node.getId(), (int) pointer); } else { throw new IllegalStateException("Cannot add tags twice, duplicate node OSM ID: " + node.getId()); } @@ -255,16 +264,12 @@ public Map getTags(long osmNodeId) { int tagIndex = nodeTagIndicesByOsmNodeIds.get(osmNodeId); if (tagIndex < 0) return Collections.emptyMap(); - return nodeTags.get(tagIndex); - } - - public void removeTags(long osmNodeId) { - int prev = nodeTagIndicesByOsmNodeIds.put(osmNodeId, -2); - nodeTags.set(prev, emptyMap()); + return nodeKVStorage.getMap(tagIndex); } public void release() { pillarNodes.clear(); + nodeKVStorage.clear(); } public int towerNodeToId(int towerId) { @@ -282,4 +287,18 @@ public int pillarNodeToId(int pillarId) { public int idToPillarNode(int id) { return id - 3; } + + public boolean setSplitNode(long osmNodeId) { + return nodesToBeSplit.add(osmNodeId); + } + + public void unsetSplitNode(long osmNodeId) { + int removed = nodesToBeSplit.removeAll(osmNodeId); + if (removed == 0) + throw new IllegalStateException("Node " + osmNodeId + " was not a split node"); + } + + public boolean isSplitNode(long osmNodeId) { + return nodesToBeSplit.contains(osmNodeId); + } } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index fcb39a23e04..c974997ffbe 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -39,7 +39,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.RestrictionSetter; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; @@ -57,7 +57,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.*; +import static com.graphhopper.search.KVStorage.KeyValue.*; import static com.graphhopper.util.Helper.nf; import static java.util.Collections.emptyList; @@ -228,7 +228,7 @@ private boolean isFerry(ReaderWay way) { * This method is called during the second pass of {@link WaySegmentParser} and provides an entry point to enrich * the given OSM way with additional tags before it is passed on to the tag parsers. */ - protected void setArtificialWayTags(PointList pointList, ReaderWay way, double distance, Map nodeTags) { + protected void setArtificialWayTags(PointList pointList, ReaderWay way, double distance, List> nodeTags) { way.setTag("node_tags", nodeTags); way.setTag("edge_distance", distance); way.setTag("point_list", pointList); @@ -293,14 +293,16 @@ protected void setArtificialWayTags(PointList pointList, ReaderWay way, double d * @param toIndex a unique integer id for the last node of this segment * @param pointList coordinates of this segment * @param way the OSM way this segment was taken from - * @param nodeTags node tags of this segment if it is an artificial edge, empty otherwise + * @param nodeTags node tags of this segment. there is one map of tags for each point. */ - protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWay way, Map nodeTags) { + protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWay way, List> nodeTags) { // sanity checks if (fromIndex < 0 || toIndex < 0) throw new AssertionError("to or from index is invalid for this edge " + fromIndex + "->" + toIndex + ", points:" + pointList); if (pointList.getDimension() != nodeAccess.getDimension()) throw new AssertionError("Dimension does not match for pointList vs. nodeAccess " + pointList.getDimension() + " <-> " + nodeAccess.getDimension()); + if (pointList.size() != nodeTags.size()) + throw new AssertionError("there should be as many maps of node tags as there are points. node tags: " + nodeTags.size() + ", points: " + pointList.size()); // todo: in principle it should be possible to delay elevation calculation so we do not need to store // elevations during import (saves memory in pillar info during import). also note that we already need to @@ -350,7 +352,7 @@ else if (config.getElevationSmoothing().equals("moving_average")) IntsRef edgeFlags = encodingManager.createEdgeFlags(); osmParsers.handleWayTags(edgeFlags, way, relationFlags); EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags); - List list = way.getTag("key_values", Collections.emptyList()); + List list = way.getTag("key_values", Collections.emptyList()); if (!list.isEmpty()) edge.setKeyValues(list); @@ -394,7 +396,7 @@ else if (Math.abs(edgeDistance - geometryDistance) > tolerance) */ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier coordinateSupplier) { // storing the road name does not yet depend on the flagEncoder so manage it directly - List list = new ArrayList<>(); + List list = new ArrayList<>(); if (config.isParseWayNames()) { // http://wiki.openstreetmap.org/wiki/Key:name String name = ""; @@ -403,28 +405,28 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier if (name.isEmpty()) name = fixWayName(way.getTag("name")); if (!name.isEmpty()) - list.add(new EdgeKVStorage.KeyValue(STREET_NAME, name)); + list.add(new KVStorage.KeyValue(STREET_NAME, name)); // http://wiki.openstreetmap.org/wiki/Key:ref String refName = fixWayName(way.getTag("ref")); if (!refName.isEmpty()) - list.add(new EdgeKVStorage.KeyValue(STREET_REF, refName)); + list.add(new KVStorage.KeyValue(STREET_REF, refName)); if (way.hasTag("destination:ref")) { - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref")))); + list.add(new KVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref")))); } else { if (way.hasTag("destination:ref:forward")) - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:forward")), true, false)); + list.add(new KVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:forward")), true, false)); if (way.hasTag("destination:ref:backward")) - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:backward")), false, true)); + list.add(new KVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:backward")), false, true)); } if (way.hasTag("destination")) { - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination")))); + list.add(new KVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination")))); } else { if (way.hasTag("destination:forward")) - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:forward")), true, false)); + list.add(new KVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:forward")), true, false)); if (way.hasTag("destination:backward")) - list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:backward")), false, true)); + list.add(new KVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:backward")), false, true)); } } way.setTag("key_values", list); @@ -478,8 +480,8 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier static String fixWayName(String str) { if (str == null) return ""; - // the EdgeKVStorage does not accept too long strings -> Helper.cutStringForKV - return EdgeKVStorage.cutString(WAY_NAME_PATTERN.matcher(str).replaceAll(", ")); + // the KVStorage does not accept too long strings -> Helper.cutStringForKV + return KVStorage.cutString(WAY_NAME_PATTERN.matcher(str).replaceAll(", ")); } /** diff --git a/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java b/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java index a80bff0901c..cbd2b8b6288 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java +++ b/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java @@ -18,12 +18,16 @@ package com.graphhopper.reader.osm; +import java.util.Map; + class SegmentNode { long osmNodeId; int id; + Map tags; - public SegmentNode(long osmNodeId, int id) { + public SegmentNode(long osmNodeId, int id, Map tags) { this.osmNodeId = osmNodeId; this.id = id; + this.tags = tags; } } diff --git a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java index 89dba982027..52593f6401d 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java +++ b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java @@ -38,17 +38,13 @@ import java.io.File; import java.io.IOException; import java.text.ParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; import java.util.function.LongToIntFunction; import java.util.function.Predicate; import static com.graphhopper.reader.osm.OSMNodeData.*; import static com.graphhopper.util.Helper.nf; -import static java.util.Collections.emptyMap; /** * This class parses a given OSM file and splits OSM ways into 'segments' at all intersections (or 'junctions'). @@ -68,6 +64,7 @@ */ public class WaySegmentParser { private static final Logger LOGGER = LoggerFactory.getLogger(WaySegmentParser.class); + private static final Set INCLUDE_IF_NODE_TAGS = new HashSet<>(Arrays.asList("barrier", "highway", "railway", "crossing", "ford")); private final ElevationProvider eleProvider; private final Predicate wayFilter; @@ -224,14 +221,26 @@ public void handleNode(ReaderNode node) { acceptedNodes++; - // we keep node tags for barrier nodes + // remember which nodes we want to split if (splitNodeFilter.test(node)) { if (nodeType == JUNCTION_NODE) { LOGGER.debug("OSM node {} at {},{} is a barrier node at a junction. The barrier will be ignored", node.getId(), Helper.round(node.getLat(), 7), Helper.round(node.getLon(), 7)); ignoredSplitNodes++; } else + nodeData.setSplitNode(node.getId()); + } + + // store node tags if at least one important tag is included and make this available for the edge handler + for (Map.Entry e : node.getTags().entrySet()) { + if (INCLUDE_IF_NODE_TAGS.contains(e.getKey())) { + node.removeTag("created_by"); + node.removeTag("source"); + node.removeTag("note"); + node.removeTag("fixme"); nodeData.setTags(node); + break; + } } } @@ -251,7 +260,7 @@ public void handleWay(ReaderWay way) { return; List segment = new ArrayList<>(way.getNodes().size()); for (LongCursor node : way.getNodes()) - segment.add(new SegmentNode(node.value, nodeData.getId(node.value))); + segment.add(new SegmentNode(node.value, nodeData.getId(node.value), nodeData.getTags(node.value))); wayPreprocessor.preprocessWay(way, osmNodeId -> nodeData.getCoordinates(nodeData.getId(osmNodeId))); splitWayAtJunctionsAndEmptySections(segment, way); } @@ -304,9 +313,11 @@ private void splitSegmentAtSplitNodes(List parentSegment, ReaderWay List segment = new ArrayList<>(); for (int i = 0; i < parentSegment.size(); i++) { SegmentNode node = parentSegment.get(i); - Map nodeTags = nodeData.getTags(node.osmNodeId); - // so far we only consider node tags of split nodes, so if there are node tags we split the node - if (!nodeTags.isEmpty()) { + if (nodeData.isSplitNode(node.osmNodeId)) { + // do not split this node again. for example a barrier can be connecting two ways (appear in both + // ways) and we only want to add a barrier edge once (but we want to add one). + nodeData.unsetSplitNode(node.osmNodeId); + // this node is a barrier. we will copy it and add an extra edge SegmentNode barrierFrom = node; SegmentNode barrierTo = nodeData.addCopyOfNode(node); @@ -318,28 +329,30 @@ private void splitSegmentAtSplitNodes(List parentSegment, ReaderWay } if (!segment.isEmpty()) { segment.add(barrierFrom); - handleSegment(segment, way, emptyMap()); + handleSegment(segment, way); segment = new ArrayList<>(); } + + // mark barrier edge + way.setTag("gh:barrier_edge", true); segment.add(barrierFrom); segment.add(barrierTo); - handleSegment(segment, way, nodeTags); + handleSegment(segment, way); + way.removeTag("gh:barrier_edge"); + segment = new ArrayList<>(); segment.add(barrierTo); - - // ignore this barrier node from now. for example a barrier can be connecting two ways (appear in both - // ways) and we only want to add a barrier edge once (but we want to add one). - nodeData.removeTags(node.osmNodeId); } else { segment.add(node); } } if (segment.size() > 1) - handleSegment(segment, way, emptyMap()); + handleSegment(segment, way); } - void handleSegment(List segment, ReaderWay way, Map nodeTags) { + void handleSegment(List segment, ReaderWay way) { final PointList pointList = new PointList(segment.size(), nodeData.is3D()); + final List> nodeTags = new ArrayList<>(segment.size()); int from = -1; int to = -1; for (int i = 0; i < segment.size(); i++) { @@ -359,6 +372,7 @@ else if (i == segment.size() - 1) else if (isTowerNode(id)) throw new IllegalStateException("Tower nodes should only appear at the end of segments, way: " + way.getId()); nodeData.addCoordinatesToPointList(id, pointList); + nodeTags.add(node.tags); } if (from < 0 || to < 0) throw new IllegalStateException("The first and last nodes of a segment must be tower nodes, way: " + way.getId()); @@ -377,8 +391,8 @@ public void handleRelation(ReaderRelation relation) { @Override public void onFinish() { - LOGGER.info("pass2 - finished, processed ways: {}, way nodes: {}, with tags: {}, ignored barriers at junctions: {}", - nf(wayCounter), nf(acceptedNodes), nf(nodeData.getTaggedNodeCount()), nf(ignoredSplitNodes)); + LOGGER.info("pass2 - finished, processed ways: {}, way nodes: {}, nodes with tags: {}, node tag capacity: {}, ignored barriers at junctions: {}", + nf(wayCounter), nf(acceptedNodes), nf(nodeData.getTaggedNodeCount()), nf(nodeData.getNodeTagCapacity()), nf(ignoredSplitNodes)); } public int getInternalNodeIdOfOSMNode(long nodeOsmId) { @@ -547,7 +561,7 @@ default void onFinish() { } public interface EdgeHandler { - void handleEdge(int from, int to, PointList pointList, ReaderWay way, Map nodeTags); + void handleEdge(int from, int to, PointList pointList, ReaderWay way, List> nodeTags); } public interface RelationProcessor { diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java index a25b8fae436..29db65622f2 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java @@ -24,7 +24,7 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.*; +import static com.graphhopper.search.KVStorage.KeyValue.*; /** * This class calculates instructions from the edges in a Path. diff --git a/core/src/main/java/com/graphhopper/routing/ev/Crossing.java b/core/src/main/java/com/graphhopper/routing/ev/Crossing.java new file mode 100644 index 00000000000..e5ddba670a5 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/Crossing.java @@ -0,0 +1,30 @@ +package com.graphhopper.routing.ev; + +import com.graphhopper.util.Helper; + +public enum Crossing { + MISSING, // no information + RAILWAY_BARRIER, // railway crossing with barrier + RAILWAY, // railway crossing with road + TRAFFIC_SIGNALS, // with light signals + UNCONTROLLED, // with crosswalk, without traffic lights + MARKED, // with crosswalk, with or without traffic lights + UNMARKED, // without markings or traffic lights + NO; // crossing is impossible or illegal + public static final String KEY = "crossing"; + + @Override + public String toString() { + return Helper.toLowerCase(name()); + } + + public static Crossing find(String name) { + if (name == null) + return MISSING; + try { + return Crossing.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return MISSING; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index 6ae0d3ec999..214a7f84929 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -87,7 +87,10 @@ public EncodedValue create(String name, PMap properties) { return AverageSlope.create(); } else if (Curvature.KEY.equals(name)) { return Curvature.create(); - } else + } else if (Crossing.KEY.equals(name)) { + return new EnumEncodedValue<>(Crossing.KEY, Crossing.class); + } else { throw new IllegalArgumentException("DefaultEncodedValueFactory cannot find EncodedValue " + name); + } } } diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java index e05b58ef467..557c09ca5ae 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java @@ -20,7 +20,7 @@ import com.carrotsearch.hppc.predicates.IntObjectPredicate; import com.graphhopper.coll.GHIntObjectHashMap; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.Snap; @@ -233,7 +233,7 @@ private void createEdges(int origEdgeKey, int origRevEdgeKey, boolean reverse = closestEdge.get(EdgeIteratorState.REVERSE_STATE); // edges between base and snapped point - List keyValues = closestEdge.getKeyValues(); + List keyValues = closestEdge.getKeyValues(); VirtualEdgeIteratorState baseEdge = new VirtualEdgeIteratorState(origEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, false), prevNodeId, nodeId, baseDistance, closestEdge.getFlags(), keyValues, basePoints, reverse); VirtualEdgeIteratorState baseReverseEdge = new VirtualEdgeIteratorState(origRevEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, true), diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java index c47272890b9..9541130fdeb 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java @@ -19,7 +19,7 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.EdgeIteratorState; @@ -262,12 +262,12 @@ public String getName() { } @Override - public List getKeyValues() { + public List getKeyValues() { return getCurrentEdge().getKeyValues(); } @Override - public EdgeIteratorState setKeyValues(List list) { + public EdgeIteratorState setKeyValues(List list) { return getCurrentEdge().setKeyValues(list); } diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index 0cac2260041..6ceccf72a42 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -18,7 +18,7 @@ package com.graphhopper.routing.querygraph; import com.graphhopper.routing.ev.*; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; @@ -41,14 +41,14 @@ public class VirtualEdgeIteratorState implements EdgeIteratorState { private final int originalEdgeKey; private double distance; private IntsRef edgeFlags; - private List keyValues; + private List keyValues; // true if edge should be avoided as start/stop private boolean unfavored; private EdgeIteratorState reverseEdge; private final boolean reverse; public VirtualEdgeIteratorState(int originalEdgeKey, int edgeKey, int baseNode, int adjNode, double distance, - IntsRef edgeFlags, List keyValues, PointList pointList, boolean reverse) { + IntsRef edgeFlags, List keyValues, PointList pointList, boolean reverse) { this.originalEdgeKey = originalEdgeKey; this.edgeKey = edgeKey; this.baseNode = baseNode; @@ -310,25 +310,25 @@ public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd @Override public String getName() { - String name = (String) getValue(EdgeKVStorage.KeyValue.STREET_NAME); + String name = (String) getValue(KVStorage.KeyValue.STREET_NAME); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } @Override - public EdgeIteratorState setKeyValues(List list) { + public EdgeIteratorState setKeyValues(List list) { this.keyValues = list; return this; } @Override - public List getKeyValues() { + public List getKeyValues() { return keyValues; } @Override public Object getValue(String key) { - for (EdgeKVStorage.KeyValue keyValue : keyValues) { + for (KVStorage.KeyValue keyValue : keyValues) { if (keyValue.key.equals(key)) return keyValue.value; } return null; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java index c8be7f9860f..cea8a580c14 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java @@ -75,19 +75,14 @@ public ConditionalTagInspector getConditionalTagInspector() { return conditionalTagInspector; } - /** - * Updates the given edge flags based on node tags - */ - protected void handleNodeTags(IntsRef edgeFlags, Map nodeTags) { - if (!nodeTags.isEmpty()) { - // for now we just create a dummy reader node, because our encoders do not make use of the coordinates anyway - ReaderNode readerNode = new ReaderNode(0, 0, 0, nodeTags); - // block access for barriers - if (isBarrier(readerNode)) { - BooleanEncodedValue accessEnc = getAccessEnc(); - accessEnc.setBool(false, edgeFlags, false); - accessEnc.setBool(true, edgeFlags, false); - } + protected void handleBarrierEdge(IntsRef edgeFlags, Map nodeTags) { + // for now we just create a dummy reader node, because our encoders do not make use of the coordinates anyway + ReaderNode readerNode = new ReaderNode(0, 0, 0, nodeTags); + // block access for barriers + if (isBarrier(readerNode)) { + BooleanEncodedValue accessEnc = getAccessEnc(); + accessEnc.setBool(false, edgeFlags, false); + accessEnc.setBool(true, edgeFlags, false); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 896ac4b8bd7..7b9f50ffc86 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -6,12 +6,7 @@ import com.graphhopper.routing.util.WayAccess; import com.graphhopper.storage.IntsRef; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static java.util.Collections.emptyMap; +import java.util.*; public abstract class BikeCommonAccessParser extends AbstractAccessParser implements TagParser { @@ -133,8 +128,10 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { handleAccess(edgeFlags, way); } - Map nodeTags = way.getTag("node_tags", emptyMap()); - handleNodeTags(edgeFlags, nodeTags); + if (way.hasTag("gh:barrier_edge")) { + List> nodeTags = way.getTag("node_tags", Collections.emptyList()); + handleBarrierEdge(edgeFlags, nodeTags.get(0)); + } } protected void handleAccess(IntsRef edgeFlags, ReaderWay way) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index 3874be1c9ff..4e130044d59 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -27,12 +27,7 @@ import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static java.util.Collections.emptyMap; +import java.util.*; public class CarAccessParser extends AbstractAccessParser implements TagParser { @@ -158,8 +153,10 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { accessEnc.setBool(true, edgeFlags, true); } - Map nodeTags = way.getTag("node_tags", emptyMap()); - handleNodeTags(edgeFlags, nodeTags); + if (way.hasTag("gh:barrier_edge")) { + List> nodeTags = way.getTag("node_tags", Collections.emptyList()); + handleBarrierEdge(edgeFlags, nodeTags.get(0)); + } } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java index bf78ce995a4..f7c19fa1cd0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java @@ -77,6 +77,8 @@ else if (name.equals(Footway.KEY)) return new OSMFootwayParser(lookup.getEnumEncodedValue(Footway.KEY, Footway.class)); else if (name.equals(Country.KEY)) return new CountryParser(lookup.getEnumEncodedValue(Country.KEY, Country.class)); + else if (name.equals(Crossing.KEY)) + return new OSMCrossingParser(lookup.getEnumEncodedValue(Crossing.KEY, Crossing.class)); return null; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java index eeb29001f63..6df60feb8a0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java @@ -27,14 +27,10 @@ import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.graphhopper.routing.ev.RouteNetwork.*; import static com.graphhopper.routing.util.PriorityCode.UNCHANGED; -import static java.util.Collections.emptyMap; public class FootAccessParser extends AbstractAccessParser implements TagParser { @@ -184,7 +180,9 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { accessEnc.setBool(true, edgeFlags, true); } - Map nodeTags = way.getTag("node_tags", emptyMap()); - handleNodeTags(edgeFlags, nodeTags); + if (way.hasTag("gh:barrier_edge")) { + List> nodeTags = way.getTag("node_tags", Collections.emptyList()); + handleBarrierEdge(edgeFlags, nodeTags.get(0)); + } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java new file mode 100644 index 00000000000..1afa11207fd --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java @@ -0,0 +1,61 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Crossing; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.Helper; + +import java.util.List; +import java.util.Map; + +/** + * Parses the node information regarding crossing=* and railway=* + */ +public class OSMCrossingParser implements TagParser { + protected final EnumEncodedValue crossingEnc; + + public OSMCrossingParser(EnumEncodedValue crossingEnc) { + this.crossingEnc = crossingEnc; + } + + @Override + public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + List> nodeTags = readerWay.getTag("node_tags", null); + if (nodeTags == null) + return; + + for (int i = 0; i < nodeTags.size(); i++) { + Map tags = nodeTags.get(i); + if ("crossing".equals(tags.get("railway")) || "level_crossing".equals(tags.get("railway"))) { + String barrierVal = (String) tags.get("crossing:barrier"); + crossingEnc.setEnum(false, edgeFlags, (Helper.isEmpty(barrierVal) || "no".equals(barrierVal)) ? Crossing.RAILWAY : Crossing.RAILWAY_BARRIER); + return; + } + + String crossingSignals = (String) tags.get("crossing:signals"); + if ("yes".equals(crossingSignals)) { + crossingEnc.setEnum(false, edgeFlags, Crossing.TRAFFIC_SIGNALS); + return; + } + + String crossingMarkings = (String) tags.get("crossing:markings"); + if ("yes".equals(crossingMarkings)) { + crossingEnc.setEnum(false, edgeFlags, Crossing.MARKED); + return; + } + + String crossingValue = (String) tags.get("crossing"); + // some crossing values like "no" do not require highway=crossing and sometimes no crossing value exists although highway=crossing + if (Helper.isEmpty(crossingValue) && ("no".equals(crossingSignals) || "no".equals(crossingMarkings) + || "crossing".equals(tags.get("highway")) || "crossing".equals(tags.get("footway")) || "crossing".equals(tags.get("cycleway")))) { + crossingEnc.setEnum(false, edgeFlags, Crossing.UNMARKED); + // next node could have more specific Crossing value + continue; + } + Crossing crossing = Crossing.find(crossingValue); + if (crossing != Crossing.MISSING) + crossingEnc.setEnum(false, edgeFlags, crossing); + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java index b290671de85..f7b5207d505 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java @@ -25,7 +25,9 @@ import com.graphhopper.storage.IntsRef; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; import static com.graphhopper.routing.ev.RoadAccess.YES; @@ -41,18 +43,17 @@ public OSMRoadAccessParser(EnumEncodedValue roadAccessEnc, List accessValue.ordinal()) { - accessValue = tmpAccessValue; - } - } + + List> nodeTags = readerWay.getTag("node_tags", Collections.emptyList()); + // a barrier edge has the restriction in both nodes and the tags are the same + if (readerWay.hasTag("gh:barrier_edge")) + for (String restriction : restrictions) { + Object value = nodeTags.get(0).get(restriction); + if (value != null) accessValue = getRoadAccess((String) value, accessValue); } + + for (String restriction : restrictions) { + accessValue = getRoadAccess(readerWay.getTag(restriction), accessValue); } CountryRule countryRule = readerWay.getTag("country_rule", null); @@ -62,6 +63,20 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati roadAccessEnc.setEnum(false, edgeFlags, accessValue); } + private RoadAccess getRoadAccess(String tagValue, RoadAccess accessValue) { + RoadAccess tmpAccessValue; + if (tagValue != null) { + String[] complex = tagValue.split(";"); + for (String simple : complex) { + tmpAccessValue = RoadAccess.find(simple); + if (tmpAccessValue != null && tmpAccessValue.ordinal() > accessValue.ordinal()) { + accessValue = tmpAccessValue; + } + } + } + return accessValue; + } + public static List toOSMRestrictions(TransportationMode mode) { switch (mode) { case FOOT: diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java index d6fa9cd0186..c4c2513b705 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java @@ -22,6 +22,10 @@ import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.storage.IntsRef; +import java.util.Collections; +import java.util.List; +import java.util.Map; + import static com.graphhopper.routing.ev.RoadEnvironment.*; public class OSMRoadEnvironmentParser implements TagParser { @@ -34,6 +38,13 @@ public OSMRoadEnvironmentParser(EnumEncodedValue roadEnvEnc) { @Override public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + List> nodeTags = readerWay.getTag("node_tags", Collections.emptyList()); + // a barrier edge has the restriction in both nodes and the tags are the same + if (readerWay.hasTag("gh:barrier_edge") && nodeTags.get(0).containsKey("ford")) { + roadEnvEnc.setEnum(false, edgeFlags, FORD); + return; + } + RoadEnvironment roadEnvironment = OTHER; if ((readerWay.hasTag("route", "ferry") && !readerWay.hasTag("ferry", "no")) || // TODO shuttle_train is sometimes also used in relations, e.g. https://www.openstreetmap.org/relation/1932780 diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/KVStorage.java similarity index 87% rename from core/src/main/java/com/graphhopper/search/EdgeKVStorage.java rename to core/src/main/java/com/graphhopper/search/KVStorage.java index d6338f6d880..3e7a4060105 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/KVStorage.java @@ -32,7 +32,7 @@ * * @author Peter Karich */ -public class EdgeKVStorage { +public class KVStorage { private static final long EMPTY_POINTER = 0, START_POINTER = 1; // Store the key index in 2 bytes. Use first 2 bits for marking fwd+bwd existence. @@ -40,6 +40,7 @@ public class EdgeKVStorage { // Store string value as byte array and store the length into 1 byte private static final int MAX_LENGTH = (1 << 8) - 1; + private final Directory dir; // It stores the mapping of "key to index" in the keys DataAccess. E.g. if your first key is "some" then we will // store the mapping "1->some" there (the 0th index is skipped on purpose). As this map is 'small' the keys // DataAccess is only used for long term storage, i.e. only in loadExisting and flush. For add and getAll we use @@ -85,12 +86,18 @@ public class EdgeKVStorage { /** * Specify a larger cacheSize to reduce disk usage. Note that this increases the memory usage of this object. */ - public EdgeKVStorage(Directory dir) { - keys = dir.create("edgekv_keys", 10 * 1024); - vals = dir.create("edgekv_vals"); + public KVStorage(Directory dir, boolean edge) { + this.dir = dir; + if (edge) { + this.keys = dir.create("edgekv_keys", 10 * 1024); + this.vals = dir.create("edgekv_vals"); + } else { + this.keys = dir.create("nodekv_keys", 10 * 1024); + this.vals = dir.create("nodekv_vals"); + } } - public EdgeKVStorage create(long initBytes) { + public KVStorage create(long initBytes) { keys.create(initBytes); vals.create(initBytes); // add special empty case to have a reliable duplicate detection via negative keyIndex @@ -104,8 +111,8 @@ public boolean loadExisting() { if (vals.loadExisting()) { if (!keys.loadExisting()) throw new IllegalStateException("Loaded values but cannot load keys"); bytePointer = bitUtil.combineIntsToLong(vals.getHeader(0), vals.getHeader(4)); - GHUtility.checkDAVersion(vals.getName(), Constants.VERSION_EDGEKV_STORAGE, vals.getHeader(8)); - GHUtility.checkDAVersion(keys.getName(), Constants.VERSION_EDGEKV_STORAGE, keys.getHeader(0)); + GHUtility.checkDAVersion(vals.getName(), Constants.VERSION_KV_STORAGE, vals.getHeader(8)); + GHUtility.checkDAVersion(keys.getName(), Constants.VERSION_KV_STORAGE, keys.getHeader(0)); // load keys into memory int count = keys.getShort(0); @@ -137,37 +144,9 @@ Collection getKeys() { return indexToKey; } - /** - * This method writes the specified entryMap (key-value pairs) into the storage. Please note that null keys or null - * values are rejected. The Class of a value can be only: byte[], String, int, long, float or double - * (or more precisely, their wrapper equivalent). For all other types an exception is thrown. The first call of add - * assigns a Class to every key in the Map and future calls of add will throw an exception if this Class differs. - * - * @return entryPointer with which you can later fetch the entryMap via the get or getAll method - */ - public long add(final List entries) { - if (entries == null) throw new IllegalArgumentException("specified List must not be null"); - if (entries.isEmpty()) return EMPTY_POINTER; - else if (entries.size() > 200) - throw new IllegalArgumentException("Cannot store more than 200 entries per entry"); - - // This is a very important "compression" mechanism because one OSM way is split into multiple edges and so we - // can often re-use the serialized key-value pairs of the previous edge. - if (isEquals(entries, lastEntries)) return lastEntryPointer; - - // If the Class of a value is unknown it should already fail here, before we modify internal data. (see #2597#discussion_r896469840) - for (KeyValue kv : entries) - if (keyToIndex.get(kv.key) != null) - getBytesForValue(indexToClass.get(keyToIndex.get(kv.key)), kv.value); - - lastEntries = entries; - lastEntryPointer = bytePointer; - // while adding there could be exceptions and we need to avoid that the bytePointer is modified - long currentPointer = bytePointer; - - vals.ensureCapacity(currentPointer + 1); - vals.setByte(currentPointer, (byte) entries.size()); - currentPointer += 1; + private long setKVList(long currentPointer, final List entries) { + if (currentPointer == EMPTY_POINTER) return currentPointer; + currentPointer += 1; // skip stored count for (KeyValue entry : entries) { String key = entry.key; if (key == null) throw new IllegalArgumentException("key cannot be null"); @@ -215,9 +194,39 @@ else if (entries.size() > 200) vals.setBytes(currentPointer, valueBytes, valueBytes.length); currentPointer += valueBytes.length; } - bytePointer = currentPointer; + return currentPointer; + } + + /** + * This method writes the specified entryMap (key-value pairs) into the storage. Please note that null keys or null + * values are rejected. The Class of a value can be only: byte[], String, int, long, float or double + * (or more precisely, their wrapper equivalent). For all other types an exception is thrown. The first call of add + * assigns a Class to every key in the Map and future calls of add will throw an exception if this Class differs. + * + * @return entryPointer with which you can later fetch the entryMap via the get or getAll method + */ + public long add(final List entries) { + if (entries == null) throw new IllegalArgumentException("specified List must not be null"); + if (entries.isEmpty()) return EMPTY_POINTER; + else if (entries.size() > 200) + throw new IllegalArgumentException("Cannot store more than 200 entries per entry"); + + // This is a very important "compression" mechanism because one OSM way is split into multiple edges and so we + // can often re-use the serialized key-value pairs of the previous edge. + if (isEquals(entries, lastEntries)) return lastEntryPointer; + + // If the Class of a value is unknown it should already fail here, before we modify internal data. (see #2597#discussion_r896469840) + for (KeyValue kv : entries) + if (keyToIndex.get(kv.key) != null) + getBytesForValue(indexToClass.get(keyToIndex.get(kv.key)), kv.value); + + lastEntries = entries; + lastEntryPointer = bytePointer; + vals.ensureCapacity(bytePointer + 1); + vals.setByte(bytePointer, (byte) entries.size()); + bytePointer = setKVList(bytePointer, entries); if (bytePointer < 0) - throw new IllegalStateException("Negative bytePointer in EdgeKVStorage"); + throw new IllegalStateException("Negative bytePointer in KVStorage"); return lastEntryPointer; } @@ -235,16 +244,16 @@ private boolean isEquals(List entries, List lastEntries) { return false; } - public List getAll(final long entryPointer) { + public List getAll(final long entryPointer) { if (entryPointer < 0) - throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); + throw new IllegalStateException("Pointer to access KVStorage cannot be negative:" + entryPointer); if (entryPointer == EMPTY_POINTER) return Collections.emptyList(); int keyCount = vals.getByte(entryPointer) & 0xFF; if (keyCount == 0) return Collections.emptyList(); - List list = new ArrayList<>(keyCount); + List list = new ArrayList<>(keyCount); long tmpPointer = entryPointer + 1; AtomicInteger sizeOfObject = new AtomicInteger(); for (int i = 0; i < keyCount; i++) { @@ -263,6 +272,36 @@ public List getAll(final long entryPointer) { return list; } + /** + * Please note that this method ignores potentially different tags for forward and backward direction. To avoid this + * use {@link #getAll(long)} instead. + */ + public Map getMap(final long entryPointer) { + if (entryPointer < 0) + throw new IllegalStateException("Pointer to access KVStorage cannot be negative:" + entryPointer); + + if (entryPointer == EMPTY_POINTER) return Collections.emptyMap(); + + int keyCount = vals.getByte(entryPointer) & 0xFF; + if (keyCount == 0) return Collections.emptyMap(); + + HashMap map = new HashMap<>(keyCount); + long tmpPointer = entryPointer + 1; + AtomicInteger sizeOfObject = new AtomicInteger(); + for (int i = 0; i < keyCount; i++) { + int currentKeyIndexRaw = vals.getShort(tmpPointer); + int currentKeyIndex = currentKeyIndexRaw >>> 2; + tmpPointer += 2; + + Object object = deserializeObj(sizeOfObject, tmpPointer, indexToClass.get(currentKeyIndex)); + tmpPointer += sizeOfObject.get(); + String key = indexToKey.get(currentKeyIndex); + map.put(key, object); + } + + return map; + } + private boolean hasDynLength(Class clazz) { return clazz.equals(String.class) || clazz.equals(byte[].class); } @@ -353,7 +392,7 @@ private Object deserializeObj(AtomicInteger sizeOfObject, long pointer, Class public Object get(final long entryPointer, String key, boolean reverse) { if (entryPointer < 0) - throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); + throw new IllegalStateException("Pointer to access KVStorage cannot be negative:" + entryPointer); if (entryPointer == EMPTY_POINTER) return null; @@ -407,15 +446,20 @@ public void flush() { keys.setBytes(keyBytePointer, clazzBytes, 1); keyBytePointer += 1; } - keys.setHeader(0, Constants.VERSION_EDGEKV_STORAGE); + keys.setHeader(0, Constants.VERSION_KV_STORAGE); keys.flush(); vals.setHeader(0, bitUtil.getIntLow(bytePointer)); vals.setHeader(4, bitUtil.getIntHigh(bytePointer)); - vals.setHeader(8, Constants.VERSION_EDGEKV_STORAGE); + vals.setHeader(8, Constants.VERSION_KV_STORAGE); vals.flush(); } + public void clear() { + dir.remove(keys.getName()); + dir.remove(vals.getName()); + } + public void close() { keys.close(); vals.close(); @@ -446,6 +490,14 @@ public KeyValue(String key, Object value) { this.bwd = true; } + public Object getValue() { + return value; + } + + public String getKey() { + return key; + } + public KeyValue(String key, Object value, boolean fwd, boolean bwd) { this.key = key; this.value = value; @@ -481,7 +533,7 @@ public String toString() { } /** - * This method limits the specified String value to the length currently accepted for values in the EdgeKVStorage. + * This method limits the specified String value to the length currently accepted for values in the KVStorage. */ public static String cutString(String value) { byte[] bytes = value.getBytes(Helper.UTF_CS); diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index fc54bf7c754..741c3de6290 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -22,7 +22,7 @@ import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; @@ -46,7 +46,7 @@ public class BaseGraph implements Graph, Closeable { final static long MAX_UNSIGNED_INT = 0xFFFF_FFFFL; final BaseGraphNodesAndEdges store; final NodeAccess nodeAccess; - final EdgeKVStorage edgeKVStorage; + final KVStorage edgeKVStorage; // can be null if turn costs are not supported final TurnCostStorage turnCostStorage; final BitUtil bitUtil; @@ -62,7 +62,7 @@ public BaseGraph(Directory dir, int intsForFlags, boolean withElevation, boolean this.dir = dir; this.bitUtil = BitUtil.LITTLE; this.wayGeometry = dir.create("geometry", segmentSize); - this.edgeKVStorage = new EdgeKVStorage(dir); + this.edgeKVStorage = new KVStorage(dir, true); this.store = new BaseGraphNodesAndEdges(dir, intsForFlags, withElevation, withTurnCosts, segmentSize); this.nodeAccess = new GHNodeAccess(store); this.segmentSize = segmentSize; @@ -184,7 +184,7 @@ public String toDetailsString() { } /** - * Flush and free resources that are not needed for post-processing (way geometries and EdgeKVStorage). + * Flush and free resources that are not needed for post-processing (way geometries and KVStorage for edges). */ public void flushAndCloseGeometryAndNameStorage() { setWayGeometryHeader(); @@ -952,7 +952,7 @@ public int getReverseEdgeKey() { } @Override - public EdgeIteratorState setKeyValues(List entries) { + public EdgeIteratorState setKeyValues(List entries) { long pointer = baseGraph.edgeKVStorage.add(entries); if (pointer > MAX_UNSIGNED_INT) throw new IllegalStateException("Too many key value pairs are stored, currently limited to " + MAX_UNSIGNED_INT + " was " + pointer); @@ -961,7 +961,7 @@ public EdgeIteratorState setKeyValues(List entries) { } @Override - public List getKeyValues() { + public List getKeyValues() { long kvEntryRef = Helper.toUnsignedLong(store.getKeyValuesRef(edgePointer)); return baseGraph.edgeKVStorage.getAll(kvEntryRef); } @@ -974,7 +974,7 @@ public Object getValue(String key) { @Override public String getName() { - String name = (String) getValue(EdgeKVStorage.KeyValue.STREET_NAME); + String name = (String) getValue(KVStorage.KeyValue.STREET_NAME); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 94322f9585c..f881a1f9f8d 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -74,7 +74,7 @@ public class Constants { public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; public static final int VERSION_LOCATION_IDX = 5; - public static final int VERSION_EDGEKV_STORAGE = 2; + public static final int VERSION_KV_STORAGE = 2; /** * The version without the snapshot string */ @@ -147,7 +147,7 @@ public class Constants { public static String getVersions() { return VERSION_NODE + "," + VERSION_EDGE + "," + VERSION_GEOMETRY + "," + VERSION_LOCATION_IDX - + "," + VERSION_EDGEKV_STORAGE + "," + VERSION_SHORTCUT; + + "," + VERSION_KV_STORAGE + "," + VERSION_SHORTCUT; } public static String getMajorVersion() { diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index c53b56a38b6..14adce29b9f 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -18,7 +18,7 @@ package com.graphhopper.util; import com.graphhopper.routing.ev.*; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; @@ -208,14 +208,14 @@ public boolean isStoreTwoDirections() { * But it might be slow and more inefficient on retrieval. Call this setKeyValues method only once per * EdgeIteratorState as it allocates new space everytime this method is called. */ - EdgeIteratorState setKeyValues(List map); + EdgeIteratorState setKeyValues(List map); /** * This method returns KeyValue pairs for both directions in contrast to {@link #getValue(String)}. * * @see #setKeyValues(List) */ - List getKeyValues(); + List getKeyValues(); /** * This method returns the *first* value for the specified key and only if stored for the direction of this diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 0e8090fe9fa..6a8870334d8 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -36,7 +36,7 @@ import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.routing.weighting.custom.CustomProfile; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.storage.index.Snap; @@ -2268,7 +2268,7 @@ public void simplifyWithInstructionsAndPathDetails() { .addPoint(new GHPoint(50.016895, 11.4923)) .addPoint(new GHPoint(50.003464, 11.49157)) .setProfile(profile) - .setPathDetails(Arrays.asList(EdgeKVStorage.KeyValue.STREET_REF, "max_speed")); + .setPathDetails(Arrays.asList(KVStorage.KeyValue.STREET_REF, "max_speed")); req.putHint("elevation", true); GHResponse rsp = hopper.route(req); @@ -2310,7 +2310,7 @@ public void simplifyWithInstructionsAndPathDetails() { assertDetail(speeds.get(7), "null [38, 40]"); // check street names - List streetNames = path.getPathDetails().get(EdgeKVStorage.KeyValue.STREET_REF); + List streetNames = path.getPathDetails().get(KVStorage.KeyValue.STREET_REF); assertDetail(streetNames.get(0), "KU 11 [0, 4]"); assertDetail(streetNames.get(1), "B 85 [4, 16]"); assertDetail(streetNames.get(2), "B 85 [16, 32]"); @@ -2321,7 +2321,7 @@ public void simplifyWithInstructionsAndPathDetails() { } private void assertInstruction(Instruction instruction, String expectedRef, String expectedInterval, int expectedLength, int expectedPoints) { - assertEquals(expectedRef, instruction.getExtraInfoJSON().get(EdgeKVStorage.KeyValue.STREET_REF)); + assertEquals(expectedRef, instruction.getExtraInfoJSON().get(KVStorage.KeyValue.STREET_REF)); assertEquals(expectedInterval, ((ShallowImmutablePointList) instruction.getPoints()).getIntervalString()); assertEquals(expectedLength, instruction.getLength()); assertEquals(expectedPoints, instruction.getPoints().size()); @@ -2495,10 +2495,11 @@ public void testBarriers() { GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile("../map-matching/files/leipzig_germany.osm.pbf"). + setVehiclesString("car|block_private=false"). setProfiles( - new Profile("car").setVehicle("car").setWeighting("fastest"), - new Profile("bike").setVehicle("bike").setWeighting("fastest"), - new Profile("foot").setVehicle("foot").setWeighting("fastest") + new CustomProfile("car").setCustomModel(new CustomModel()).setVehicle("car"), + new CustomProfile("bike").setCustomModel(new CustomModel()).setVehicle("bike"), + new CustomProfile("foot").setCustomModel(new CustomModel()).setVehicle("foot") ). setMinNetworkSize(0); hopper.importOrLoad(); @@ -2560,6 +2561,28 @@ public void testBarriers() { bikeRsp = hopper.route(new GHRequest(51.355455, 12.40202, 51.355318, 12.401741).setProfile("bike")); assertEquals(24, bikeRsp.getBest().getDistance(), 1); } + + { + // node tag "ford" should be recognized in road_environment + GHResponse footRsp = hopper.route(new GHRequest(51.290141, 12.365849, 51.290996, 12.366155).setProfile("foot")); + assertEquals(105, footRsp.getBest().getDistance(), 1); + + footRsp = hopper.route(new GHRequest(51.290141, 12.365849, 51.290996, 12.366155). + setCustomModel(new CustomModel().addToPriority(Statement.If("road_environment == FORD", Statement.Op.MULTIPLY, "0"))).setProfile("foot")); + assertEquals(330, footRsp.getBest().getDistance(), 1); + } + + { + // private access restriction as node tag + GHResponse rsp = hopper.route(new GHRequest(51.327411, 12.429598, 51.32723, 12.429979).setProfile("car")); + assertEquals(39, rsp.getBest().getDistance(), 1); + + rsp = hopper.route(new GHRequest(51.327411, 12.429598, 51.32723, 12.429979). + setCustomModel(new CustomModel().addToPriority(Statement.If("road_access == PRIVATE", Statement.Op.MULTIPLY, "0"))). + setProfile("car")); + assertFalse(rsp.hasErrors()); + assertEquals(20, rsp.getBest().getDistance(), 1); + } } @Test diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 76fe4f9c256..1d2ca29477e 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -949,7 +949,7 @@ public void testCountries() throws IOException { ReaderWay way = new ReaderWay(0L); PointList list = new PointList(); list.add(49.214906, -2.156067); - reader.setArtificialWayTags(list, way, 10, new HashMap<>()); + reader.setArtificialWayTags(list, way, 10, Collections.singletonList(new HashMap<>())); assertEquals("JEY", way.getTag("country", null).toString()); } diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index af9a9c36249..1afde7dd194 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -23,7 +23,6 @@ import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.NodeAccess; @@ -35,8 +34,8 @@ import java.util.*; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static com.graphhopper.storage.AbstractGraphStorageTester.assertPList; import static com.graphhopper.util.Parameters.Details.*; import static org.junit.jupiter.api.Assertions.*; diff --git a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java index 15a49cf5f0f..290fd95fc9e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java @@ -20,7 +20,7 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValueImpl; import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.util.EdgeIteratorState; @@ -28,8 +28,8 @@ import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.Test; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** @@ -310,7 +310,7 @@ private EdgeIteratorState createTestEdgeIterator(String name) { EdgeIteratorState edge = new BaseGraph.Builder(1).create().edge(0, 0) .setWayGeometry(pointList); if (name != null) - edge.setKeyValues(EdgeKVStorage.KeyValue.createKV(EdgeKVStorage.KeyValue.STREET_NAME, name)); + edge.setKeyValues(KVStorage.KeyValue.createKV(KVStorage.KeyValue.STREET_NAME, name)); return edge; } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java index 62e47414091..d53073a6d48 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java @@ -30,9 +30,7 @@ import org.junit.jupiter.api.Test; import java.text.DateFormat; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; +import java.util.*; import static com.graphhopper.routing.util.parsers.FootAverageSpeedParser.MEAN_SPEED; import static com.graphhopper.routing.util.parsers.FootAverageSpeedParser.SLOW_SPEED; @@ -411,11 +409,12 @@ public void testReadBarrierNodesFromWay() { IntsRef intsRef = encodingManager.createEdgeFlags(); ReaderWay way = new ReaderWay(1); way.setTag("highway", "secondary"); + way.setTag("gh:barrier_edge", true); - ReaderNode node = new ReaderNode(1, -1, -1); - node.setTag("barrier", "gate"); - node.setTag("access", "no"); - way.setTag("node_tags", node.getTags()); + Map tags = new HashMap<>(); + tags.put("barrier", "gate"); + tags.put("access", "no"); + way.setTag("node_tags", Collections.singletonList(tags)); accessParser.handleWayTags(intsRef, way); assertFalse(footAccessEnc.getBool(false, intsRef)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java new file mode 100644 index 00000000000..9ff168984ae --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java @@ -0,0 +1,88 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Crossing; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OSMCrossingParserTest { + + private EncodingManager em; + private OSMCrossingParser parser; + private EnumEncodedValue crossingEV; + + @BeforeEach + public void setup() { + crossingEV = new EnumEncodedValue<>(Crossing.KEY, Crossing.class); + em = new EncodingManager.Builder().add(crossingEV).build(); + parser = new OSMCrossingParser(crossingEV); + } + + @Test + public void testRailway() { + IntsRef edgeFlags = em.createEdgeFlags(); + parser.handleWayTags(edgeFlags, + createReader(new PMap().putObject("railway", "level_crossing").toMap()), null); + assertEquals(Crossing.RAILWAY, crossingEV.getEnum(false, edgeFlags)); + } + + @Test + public void testSignals() { + IntsRef edgeFlags = em.createEdgeFlags(); + parser.handleWayTags(edgeFlags, + createReader(new PMap().putObject("crossing", "traffic_signals").toMap()), null); + assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing:signals", "yes").toMap()), null); + assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing:signals", "no").toMap()), null); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + } + + @Test + public void testMarked() { + IntsRef edgeFlags = em.createEdgeFlags(); + parser.handleWayTags(edgeFlags, createReader(new HashMap<>()), null); + assertEquals(Crossing.MISSING, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("highway", "crossing").toMap()), null); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing", "marked").toMap()), null); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing:markings", "yes").toMap()), null); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing:markings", "no").toMap()), null); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + + parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + createReader(new PMap().putObject("crossing:signals", "no").putObject("crossing:markings", "yes").toMap()), null); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + } + + ReaderWay createReader(Map map) { + ReaderWay way = new ReaderWay(1); + way.setTag("node_tags", Collections.singletonList(map)); + return way; + } + +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/KVStorageTest.java similarity index 90% rename from core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java rename to core/src/test/java/com/graphhopper/search/KVStorageTest.java index ed526933368..938ffce14c6 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/KVStorageTest.java @@ -1,7 +1,7 @@ package com.graphhopper.search; import com.carrotsearch.hppc.LongArrayList; -import com.graphhopper.search.EdgeKVStorage.KeyValue; +import com.graphhopper.search.KVStorage.KeyValue; import com.graphhopper.storage.RAMDirectory; import com.graphhopper.util.Helper; import org.junit.jupiter.api.RepeatedTest; @@ -10,18 +10,18 @@ import java.io.File; import java.util.*; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; -import static com.graphhopper.search.EdgeKVStorage.MAX_UNIQUE_KEYS; -import static com.graphhopper.search.EdgeKVStorage.cutString; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.MAX_UNIQUE_KEYS; +import static com.graphhopper.search.KVStorage.cutString; import static com.graphhopper.util.Helper.UTF_CS; import static org.junit.jupiter.api.Assertions.*; -public class EdgeKVStorageTest { +public class KVStorageTest { private final static String location = "./target/edge-kv-storage"; - private EdgeKVStorage create() { - return new EdgeKVStorage(new RAMDirectory()).create(1000); + private KVStorage create() { + return new KVStorage(new RAMDirectory(), true).create(1000); } List createList(Object... keyValues) { @@ -36,7 +36,7 @@ List createList(Object... keyValues) { @Test public void putSame() { - EdgeKVStorage index = create(); + KVStorage index = create(); long aPointer = index.add(createList("a", "same name", "b", "same name")); assertNull(index.get(aPointer, "", false)); @@ -51,7 +51,7 @@ public void putSame() { @Test public void putAB() { - EdgeKVStorage index = create(); + KVStorage index = create(); long aPointer = index.add(createList("a", "a name", "b", "b name")); assertNull(index.get(aPointer, "", false)); @@ -61,7 +61,7 @@ public void putAB() { @Test public void getForwardBackward() { - EdgeKVStorage index = create(); + KVStorage index = create(); List list = new ArrayList<>(); list.add(new KeyValue("keyA", "FORWARD", true, false)); list.add(new KeyValue("keyB", "BACKWARD", false, true)); @@ -84,7 +84,7 @@ public void getForwardBackward() { @Test public void putEmpty() { - EdgeKVStorage index = create(); + KVStorage index = create(); assertEquals(1, index.add(createList("", ""))); // cannot store null (in its first version we accepted null once it was clear which type the value has, but this is inconsequential) assertThrows(IllegalArgumentException.class, () -> assertEquals(5, index.add(createList("", null)))); @@ -98,7 +98,7 @@ public void putEmpty() { @Test public void putMany() { - EdgeKVStorage index = create(); + KVStorage index = create(); long aPointer = 0, tmpPointer = 0; for (int i = 0; i < 10000; i++) { @@ -117,7 +117,7 @@ public void putMany() { @Test public void putManyKeys() { - EdgeKVStorage index = create(); + KVStorage index = create(); // one key is already stored => empty key for (int i = 1; i < MAX_UNIQUE_KEYS; i++) { index.add(createList("a" + i, "a name")); @@ -131,7 +131,7 @@ public void putManyKeys() { @Test public void testNoErrorOnLargeStringValue() { - EdgeKVStorage index = create(); + KVStorage index = create(); String str = ""; for (int i = 0; i < 127; i++) { str += "ß"; @@ -143,7 +143,7 @@ public void testNoErrorOnLargeStringValue() { @Test public void testTooLongStringValueError() { - EdgeKVStorage index = create(); + KVStorage index = create(); assertThrows(IllegalArgumentException.class, () -> index.add(createList("", "Бухарестская улица (http://ru.wikipedia.org/wiki" + "/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"))); @@ -157,7 +157,7 @@ public void testTooLongStringValueError() { @Test public void testNoErrorOnLargestByteArray() { - EdgeKVStorage index = create(); + KVStorage index = create(); byte[] bytes = new byte[255]; byte[] copy = new byte[255]; for (int i = 0; i < bytes.length; i++) { @@ -175,7 +175,7 @@ public void testNoErrorOnLargestByteArray() { @Test public void testIntLongDoubleFloat() { - EdgeKVStorage index = create(); + KVStorage index = create(); long intres = index.add(createKV("intres", 4)); long doubleres = index.add(createKV("doubleres", 4d)); long floatres = index.add(createKV("floatres", 4f)); @@ -193,7 +193,7 @@ public void testIntLongDoubleFloat() { @Test public void testIntLongDoubleFloat2() { - EdgeKVStorage index = create(); + KVStorage index = create(); List list = new ArrayList<>(); list.add(new KeyValue("int", 4)); list.add(new KeyValue("long", 4L)); @@ -217,12 +217,12 @@ public void testIntLongDoubleFloat2() { public void testFlush() { Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()); + KVStorage index = new KVStorage(new RAMDirectory(location, true).create(), true); long pointer = index.add(createList("", "test")); index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true)); + index = new KVStorage(new RAMDirectory(location, true), true); assertTrue(index.loadExisting()); assertEquals("test", index.get(pointer, "", false)); // make sure bytePointer is correctly set after loadExisting @@ -237,7 +237,7 @@ public void testFlush() { public void testLoadKeys() { Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()).create(1000); + KVStorage index = new KVStorage(new RAMDirectory(location, true).create(), true).create(1000); long pointerA = index.add(createList("c", "test value")); assertEquals(2, index.getKeys().size()); long pointerB = index.add(createList("a", "value", "b", "another value")); @@ -246,7 +246,7 @@ public void testLoadKeys() { index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true)); + index = new KVStorage(new RAMDirectory(location, true), true); assertTrue(index.loadExisting()); assertEquals("[, c, a, b]", index.getKeys().toString()); assertEquals("test value", index.get(pointerA, "c", false)); @@ -263,7 +263,7 @@ public void testLoadKeys() { @Test public void testEmptyKey() { - EdgeKVStorage index = create(); + KVStorage index = create(); long pointerA = index.add(createList("", "test value")); long pointerB = index.add(createList("a", "value", "b", "another value")); @@ -276,7 +276,7 @@ public void testEmptyKey() { @Test public void testSameByteArray() { - EdgeKVStorage index = create(); + KVStorage index = create(); long pointerA = index.add(createList("mykey", new byte[]{1, 2, 3, 4})); long pointerB = index.add(createList("mykey", new byte[]{1, 2, 3, 4})); @@ -290,7 +290,7 @@ public void testSameByteArray() { @Test public void testUnknownValueClass() { - EdgeKVStorage index = create(); + KVStorage index = create(); IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> index.add(createList("mykey", new Object()))); assertTrue(ex.getMessage().contains("The Class of a value was Object, currently supported"), ex.getMessage()); } @@ -299,7 +299,7 @@ public void testUnknownValueClass() { public void testRandom() { final long seed = new Random().nextLong(); try { - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()).create(1000); + KVStorage index = new KVStorage(new RAMDirectory(location, true).create(), true).create(1000); Random random = new Random(seed); List keys = createRandomStringList(random, "_key", 100); List values = createRandomList(random, 500); @@ -328,7 +328,7 @@ public void testRandom() { index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true).create()); + index = new KVStorage(new RAMDirectory(location, true).create(), true); assertTrue(index.loadExisting()); for (int i = 0; i < size; i++) { List list = index.getAll(pointers.get(i)); @@ -340,7 +340,7 @@ public void testRandom() { } index.close(); } catch (Throwable t) { - throw new RuntimeException("EdgeKVStorageTest.testRandom seed:" + seed, t); + throw new RuntimeException("KVStorageTest.testRandom seed:" + seed, t); } } diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index acad6621059..d7736765d51 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -32,8 +32,8 @@ import java.io.File; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** @@ -652,7 +652,7 @@ public void testGetAllEdges() { } @Test - public void testEdgeKVStorage() { + public void testKVStorage() { graph = createGHStorage(); EdgeIteratorState iter1 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); iter1.setKeyValues(createKV(STREET_NAME, "named street1")); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 35e2e58ee49..6c49fe793b6 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -19,7 +19,7 @@ import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.search.EdgeKVStorage.KeyValue; +import com.graphhopper.search.KVStorage.KeyValue; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import org.junit.jupiter.api.Test; @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE; import static com.graphhopper.util.FetchMode.*; import static org.junit.jupiter.api.Assertions.*; diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index d138fa8c38c..addeff1bf63 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -20,14 +20,14 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.search.EdgeKVStorage.KeyValue; +import com.graphhopper.search.KVStorage.KeyValue; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.Helper; import org.junit.jupiter.api.Test; import java.util.Random; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index cfb06e32bca..f7ace539773 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -42,8 +42,8 @@ import java.util.List; import java.util.Locale; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 92985cf5541..9fc29d71c91 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -37,8 +37,8 @@ import java.util.*; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static com.graphhopper.util.Parameters.Details.AVERAGE_SPEED; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java index dfd91b58e2b..7880ca92e9a 100644 --- a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java +++ b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java @@ -3,7 +3,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.LocationIndexTree; @@ -35,7 +35,7 @@ public static void graphhopperLocationIndex(String relDir) { public static void lowLevelLocationIndex() { // If you don't use the GraphHopper class you have to use the low level API: BaseGraph graph = new BaseGraph.Builder(1).create(); - graph.edge(0, 1).setKeyValues(EdgeKVStorage.KeyValue.createKV("name", "test edge")); + graph.edge(0, 1).setKeyValues(KVStorage.KeyValue.createKV("name", "test edge")); graph.getNodeAccess().setNode(0, 12, 42); graph.getNodeAccess().setNode(1, 12.01, 42.01); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java index 8a59c834e0c..b9670f3bf5c 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java @@ -5,7 +5,7 @@ import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.*; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; @@ -304,12 +304,12 @@ public String getName() { } @Override - public EdgeIteratorState setKeyValues(List list) { + public EdgeIteratorState setKeyValues(List list) { throw new RuntimeException(); } @Override - public List getKeyValues() { + public List getKeyValues() { throw new RuntimeException(); } diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index 1d8e6b6585e..e7d946e40bd 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -192,7 +192,7 @@ public static final class Details { public static final String PATH_DETAILS = "details"; - // these details are directly accessing the EdgeKVStorage and the names have to be identical + // these details are directly accessing the KVStorage for edges and the names have to be identical public static final String STREET_NAME = "street_name"; public static final String STREET_REF = "street_ref"; public static final String STREET_DESTINATION = "street_destination"; diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 41c342264ba..ad34a7df20f 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -46,8 +46,8 @@ import java.util.List; import java.util.Locale; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; -import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; +import static com.graphhopper.search.KVStorage.KeyValue.STREET_NAME; +import static com.graphhopper.search.KVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; public class GpxConversionsTest { diff --git a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java index 91123aa815c..5607313bff3 100644 --- a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java @@ -25,7 +25,7 @@ import com.graphhopper.matching.State; import com.graphhopper.resources.MapMatchingResource; import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; -import com.graphhopper.search.EdgeKVStorage; +import com.graphhopper.search.KVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.Snap; import com.graphhopper.util.EdgeIteratorState; @@ -35,7 +35,6 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -89,7 +88,7 @@ private EdgeIteratorState getEdgeIterator() { pointList.add(-3.4445, -38.9990); pointList.add(-3.5550, -38.7990); return new VirtualEdgeIteratorState(0, 0, 0, 1, 10, new IntsRef(1), - EdgeKVStorage.KeyValue.createKV(EdgeKVStorage.KeyValue.STREET_NAME, "test of iterator"), pointList, false); + KVStorage.KeyValue.createKV(KVStorage.KeyValue.STREET_NAME, "test of iterator"), pointList, false); } } From dea59e8ec2eaa460264352cf969d841f09266d10 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 17 Mar 2023 13:09:40 +0100 Subject: [PATCH 008/165] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c6b6b3a58a..fddf96a14a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ### 8.0 [not yet released] - +- renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 ### 7.0 [14 Mar 2023] From ce29ab2773558ad0fe2ee793008e06d746ce82e8 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Sun, 19 Mar 2023 12:04:11 -0700 Subject: [PATCH 009/165] pt: remove hardcoded use of FastestWeighting to avoid problems with foot-priority-0 links --- .../com/graphhopper/gtfs/GraphHopperGtfs.java | 7 ++++-- .../java/com/graphhopper/gtfs/GtfsReader.java | 22 +++++-------------- .../gtfs/PtRouterFreeWalkImpl.java | 21 +++++------------- .../com/graphhopper/gtfs/PtRouterImpl.java | 15 +++---------- .../com/graphhopper/gtfs/RealtimeFeed.java | 6 ++--- .../http/RealtimeFeedLoadingCache.java | 2 +- 6 files changed, 21 insertions(+), 52 deletions(-) diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java index b12d54da2b9..05023b60fd8 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java @@ -21,7 +21,9 @@ import com.conveyal.gtfs.model.Transfer; import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperConfig; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; +import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.index.InMemConstructionIndex; import com.graphhopper.storage.index.IndexStructureInfo; @@ -86,8 +88,9 @@ protected void importPublicTransit() { getGtfsStorage().getGtfsFeeds().forEach((id, gtfsFeed) -> { Transfers transfers = new Transfers(gtfsFeed); allTransfers.put(id, transfers); - GtfsReader gtfsReader = new GtfsReader(id, getBaseGraph(), getEncodingManager(), ptGraph, ptGraph, getGtfsStorage(), getLocationIndex(), transfers, indexBuilder); - gtfsReader.connectStopsToStreetNetwork(); + GtfsReader gtfsReader = new GtfsReader(id, ptGraph, ptGraph, getGtfsStorage(), getLocationIndex(), transfers, indexBuilder); + Weighting weighting = createWeighting(getProfile("foot"), new PMap()); + gtfsReader.connectStopsToStreetNetwork(new DefaultSnapFilter(weighting, getEncodingManager().getBooleanEncodedValue(Subnetwork.key("foot")))); LOGGER.info("Building transit graph for feed {}", gtfsFeed.feedId); gtfsReader.buildPtNetwork(); allReaders.put(id, gtfsReader); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java index 5b3e934b548..95d18400a83 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java @@ -22,12 +22,7 @@ import com.conveyal.gtfs.model.*; import com.google.common.collect.HashMultimap; import com.google.transit.realtime.GtfsRealtime; -import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.weighting.FastestWeighting; -import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.InMemConstructionIndex; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -76,9 +71,7 @@ static class TripWithStopTimes { private static final Logger LOGGER = LoggerFactory.getLogger(GtfsReader.class); - private final BaseGraph baseGraph; - private final EncodingManager encodingManager; - private final LocationIndex walkNetworkIndex; + private final LocationIndex streetNetworkIndex; private final GtfsStorage gtfsStorage; private final Transfers transfers; @@ -87,12 +80,10 @@ static class TripWithStopTimes { private final Map>> departureTimelinesByStop = new HashMap<>(); private final Map>> arrivalTimelinesByStop = new HashMap<>(); - GtfsReader(String id, BaseGraph baseGraph, EncodingManager encodingManager, PtGraph ptGraph, PtGraphOut out, GtfsStorage gtfsStorage, LocationIndex walkNetworkIndex, Transfers transfers, InMemConstructionIndex indexBuilder) { + GtfsReader(String id, PtGraph ptGraph, PtGraphOut out, GtfsStorage gtfsStorage, LocationIndex streetNetworkIndex, Transfers transfers, InMemConstructionIndex indexBuilder) { this.id = id; - this.baseGraph = baseGraph; - this.encodingManager = encodingManager; this.gtfsStorage = gtfsStorage; - this.walkNetworkIndex = walkNetworkIndex; + this.streetNetworkIndex = streetNetworkIndex; this.feed = this.gtfsStorage.getGtfsFeeds().get(id); this.transfers = transfers; this.startDate = feed.getStartDate(); @@ -102,13 +93,10 @@ static class TripWithStopTimes { this.indexBuilder = indexBuilder; } - void connectStopsToStreetNetwork() { - BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key("foot")); - DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key("foot")); - final EdgeFilter filter = new DefaultSnapFilter(new FastestWeighting(accessEnc, speedEnc), encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); + void connectStopsToStreetNetwork(EdgeFilter filter) { for (Stop stop : feed.stops.values()) { if (stop.location_type == 0) { // Only stops. Not interested in parent stations for now. - Snap locationSnap = walkNetworkIndex.findClosest(stop.stop_lat, stop.stop_lon, filter); + Snap locationSnap = streetNetworkIndex.findClosest(stop.stop_lat, stop.stop_lon, filter); int stopNode; if (locationSnap.isValid()) { stopNode = gtfsStorage.getStreetToPt().getOrDefault(locationSnap.getClosestNode(), -1); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java index 8ca431599e3..a0452862d4b 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java @@ -27,13 +27,10 @@ import com.graphhopper.routing.DefaultWeightingFactory; import com.graphhopper.routing.WeightingFactory; import com.graphhopper.routing.ev.Subnetwork; -import com.graphhopper.routing.ev.VehicleAccess; -import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; @@ -66,10 +63,8 @@ public final class PtRouterFreeWalkImpl implements PtRouter { public PtRouterFreeWalkImpl(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { this.config = config; this.weightingFactory = new DefaultWeightingFactory(baseGraph.getBaseGraph(), encodingManager); - this.accessEgressWeighting = new FastestWeighting( - encodingManager.getBooleanEncodedValue(VehicleAccess.key("foot")), - encodingManager.getDecimalEncodedValue(VehicleSpeed.key("foot")) - ); + Profile accessEgressProfile = config.getProfiles().stream().filter(p -> p.getName().equals("foot")).findFirst().get(); + this.accessEgressWeighting = weightingFactory.createWeighting(accessEgressProfile, new PMap(), false); this.translationMap = translationMap; this.baseGraph = baseGraph; this.encodingManager = encodingManager; @@ -110,7 +105,7 @@ public Factory(GraphHopperConfig config, TranslationMap translationMap, BaseGrap public PtRouter createWith(GtfsRealtime.FeedMessage realtimeFeed) { Map realtimeFeeds = new HashMap<>(); realtimeFeeds.put("gtfs_0", realtimeFeed); - return new PtRouterFreeWalkImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); + return new PtRouterFreeWalkImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); } public PtRouter createWithoutRealtimeFeed() { @@ -171,16 +166,10 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting( - encodingManager.getBooleanEncodedValue(VehicleAccess.key(accessProfile.getVehicle())), - encodingManager.getDecimalEncodedValue(VehicleSpeed.key(accessProfile.getVehicle())) - ), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting( - encodingManager.getBooleanEncodedValue(VehicleAccess.key(egressProfile.getVehicle())), - encodingManager.getDecimalEncodedValue(VehicleSpeed.key(egressProfile.getVehicle())) - ), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java index be9c6094b74..9f0313881d9 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java @@ -27,13 +27,10 @@ import com.graphhopper.routing.DefaultWeightingFactory; import com.graphhopper.routing.WeightingFactory; import com.graphhopper.routing.ev.Subnetwork; -import com.graphhopper.routing.ev.VehicleAccess; -import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; @@ -107,7 +104,7 @@ public Factory(GraphHopperConfig config, TranslationMap translationMap, BaseGrap public PtRouter createWith(GtfsRealtime.FeedMessage realtimeFeed) { Map realtimeFeeds = new HashMap<>(); realtimeFeeds.put("gtfs_0", realtimeFeed); - return new PtRouterImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); + return new PtRouterImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); } public PtRouter createWithoutRealtimeFeed() { @@ -168,16 +165,10 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting( - encodingManager.getBooleanEncodedValue(VehicleAccess.key(accessProfile.getVehicle())), - encodingManager.getDecimalEncodedValue(VehicleSpeed.key(accessProfile.getVehicle())) - ), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting( - encodingManager.getBooleanEncodedValue(VehicleAccess.key(egressProfile.getVehicle())), - encodingManager.getDecimalEncodedValue(VehicleSpeed.key(egressProfile.getVehicle())) - ), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java index 4b5f6e9d995..43162c92696 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java @@ -26,8 +26,6 @@ import com.conveyal.gtfs.model.StopTime; import com.conveyal.gtfs.model.Trip; import com.google.transit.realtime.GtfsRealtime; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.BaseGraph; import org.mapdb.Fun; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,7 +66,7 @@ public static RealtimeFeed empty() { return new RealtimeFeed(Collections.emptyMap(), new IntHashSet(), new IntLongHashMap(), new IntLongHashMap(), Collections.emptyList()); } - public static RealtimeFeed fromProtobuf(BaseGraph baseGraph, EncodingManager encodingManager, GtfsStorage staticGtfs, Map transfers, Map feedMessages) { + public static RealtimeFeed fromProtobuf(GtfsStorage staticGtfs, Map transfers, Map feedMessages) { final IntHashSet blockedEdges = new IntHashSet(); final IntLongHashMap delaysForBoardEdges = new IntLongHashMap(); final IntLongHashMap delaysForAlightEdges = new IntLongHashMap(); @@ -95,7 +93,7 @@ public int createNode() { GTFSFeed feed = staticGtfs.getGtfsFeeds().get(feedKey); ZoneId timezone = ZoneId.of(feed.agency.values().stream().findFirst().get().agency_timezone); PtGraph ptGraphNodesAndEdges = staticGtfs.getPtGraph(); - final GtfsReader gtfsReader = new GtfsReader(feedKey, baseGraph, encodingManager, ptGraphNodesAndEdges, overlayGraph, staticGtfs, null, transfers.get(feedKey), null); + final GtfsReader gtfsReader = new GtfsReader(feedKey, ptGraphNodesAndEdges, overlayGraph, staticGtfs, null, transfers.get(feedKey), null); Instant timestamp = Instant.ofEpochSecond(feedMessage.getHeader().getTimestamp()); LocalDate dateToChange = timestamp.atZone(timezone).toLocalDate(); //FIXME BitSet validOnDay = new BitSet(); diff --git a/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java b/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java index d6f2f3e3620..e563dc135f1 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java +++ b/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java @@ -118,7 +118,7 @@ private RealtimeFeed fetchFeedsAndCreateGraph() { throw new RuntimeException(e); } } - return RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, feedMessageMap); + return RealtimeFeed.fromProtobuf(gtfsStorage, this.transfers, feedMessageMap); } } From 0a89987c3b3b7499a97846fc3dc4f4a0a1560c50 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 21 Mar 2023 17:47:03 +0100 Subject: [PATCH 010/165] New "backward_xy" variable notation in custom models (#2760) * initial backward_car_access impl * test+fix when used in CustomModel --- .../weighting/custom/CustomModelParser.java | 35 ++++++++++++------- .../ConditionalExpressionVisitorTest.java | 12 +++---- .../custom/CustomModelParserTest.java | 16 +++++++++ 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index b7538d53ca7..ae308da14e7 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -41,6 +41,7 @@ public class CustomModelParser { private static final AtomicLong longVal = new AtomicLong(1); static final String IN_AREA_PREFIX = "in_"; + static final String BACKWARD_PREFIX = "backward_"; private static final boolean JANINO_DEBUG = Boolean.getBoolean(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_ENABLE); private static final String SCRIPT_FILE_DIR = System.getProperty(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_DIR, "./src/main/java/com/graphhopper/routing/weighting/custom"); @@ -211,21 +212,27 @@ private static List createGetPriorityStatements(Set return priorityStatements; } - static boolean isValidVariableName(String name) { - return name.startsWith(IN_AREA_PREFIX); - } - /** * For the methods getSpeed and getPriority we declare variables that contain the encoded value of the current edge * or if an area contains the current edge. */ - private static String getVariableDeclaration(EncodedValueLookup lookup, String arg) { + private static String getVariableDeclaration(EncodedValueLookup lookup, final String arg) { if (lookup.hasEncodedValue(arg)) { EncodedValue enc = lookup.getEncodedValue(arg, EncodedValue.class); return getReturnType(enc) + " " + arg + " = reverse ? " + "edge.getReverse((" + getInterface(enc) + ") this." + arg + "_enc) : " + "edge.get((" + getInterface(enc) + ") this." + arg + "_enc);\n"; - } else if (isValidVariableName(arg)) { + } else if (arg.startsWith(BACKWARD_PREFIX)) { + final String argSubstr = arg.substring(BACKWARD_PREFIX.length()); + if (lookup.hasEncodedValue(argSubstr)) { + EncodedValue enc = lookup.getEncodedValue(argSubstr, EncodedValue.class); + return getReturnType(enc) + " " + arg + " = reverse ? " + + "edge.get((" + getInterface(enc) + ") this." + argSubstr + "_enc) : " + + "edge.getReverse((" + getInterface(enc) + ") this." + argSubstr + "_enc);\n"; + } else { + throw new IllegalArgumentException("Not supported for backward: " + argSubstr); + } + } else if (arg.startsWith(IN_AREA_PREFIX)) { return ""; } else { throw new IllegalArgumentException("Not supported " + arg); @@ -270,13 +277,16 @@ private static String createClassTemplate(long counter, final StringBuilder initSourceCode = new StringBuilder("this.avg_speed_enc = avgSpeedEnc;\n"); initSourceCode.append("this.priority_enc = priorityEnc;\n"); - Set set = new HashSet<>(priorityVariables); - set.addAll(speedVariables); + Set set = new HashSet<>(); + for (String prioVar : priorityVariables) + set.add(prioVar.startsWith(BACKWARD_PREFIX) ? prioVar.substring(BACKWARD_PREFIX.length()) : prioVar); + for (String speedVar : speedVariables) + set.add(speedVar.startsWith(BACKWARD_PREFIX) ? speedVar.substring(BACKWARD_PREFIX.length()) : speedVar); + for (String arg : set) { if (lookup.hasEncodedValue(arg)) { EncodedValue enc = lookup.getEncodedValue(arg, EncodedValue.class); classSourceCode.append("protected " + getInterface(enc) + " " + arg + "_enc;\n"); - initSourceCode.append("if (lookup.hasEncodedValue(\"" + arg + "\")) "); initSourceCode.append("this." + arg + "_enc = (" + getInterface(enc) + ") lookup.getEncodedValue(\"" + arg + "\", EncodedValue.class);\n"); } else if (arg.startsWith(IN_AREA_PREFIX)) { @@ -306,7 +316,7 @@ private static String createClassTemplate(long counter, initSourceCode.append("JsonFeature feature_" + id + " = (JsonFeature) areas.get(\"" + id + "\");\n"); initSourceCode.append("this." + arg + " = new Polygon(new PreparedPolygon((Polygonal) feature_" + id + ".getGeometry()));\n"); } else { - if (!isValidVariableName(arg)) + if (!arg.startsWith(IN_AREA_PREFIX)) throw new IllegalArgumentException("Variable not supported: " + arg); } } @@ -354,9 +364,10 @@ private static String createClassTemplate(long counter, */ private static List verifyExpressions(StringBuilder expressions, String info, Set createObjects, List list, EncodedValueLookup lookup) throws Exception { - // allow variables, all encoded values, constants + // allow variables, all encoded values, constants and special variables like in_xyarea or backward_car_access NameValidator nameInConditionValidator = name -> lookup.hasEncodedValue(name) - || name.toUpperCase(Locale.ROOT).equals(name) || isValidVariableName(name); + || name.toUpperCase(Locale.ROOT).equals(name) || name.startsWith(IN_AREA_PREFIX) + || name.startsWith(BACKWARD_PREFIX) && lookup.hasEncodedValue(name.substring(BACKWARD_PREFIX.length())); parseExpressions(expressions, nameInConditionValidator, info, createObjects, list); return new Parser(new org.codehaus.janino.Scanner(info, new StringReader(expressions.toString()))). diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java index 78474cd8d35..a37e95c12d8 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.weighting.custom; -import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.StringEncodedValue; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.IntsRef; @@ -11,7 +10,6 @@ import java.util.Arrays; import static com.graphhopper.routing.weighting.custom.ConditionalExpressionVisitor.parse; -import static com.graphhopper.routing.weighting.custom.CustomModelParser.isValidVariableName; import static org.junit.jupiter.api.Assertions.*; public class ConditionalExpressionVisitorTest { @@ -55,8 +53,7 @@ public void protectUsFromStuff() { @Test public void testConvertExpression() { - NameValidator validVariable = s -> isValidVariableName(s) - || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); + NameValidator validVariable = s -> Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); ParseResult result = parse("toll == NO", validVariable); assertTrue(result.ok); @@ -77,8 +74,7 @@ public void testConvertExpression() { @Test public void isValidAndSimpleCondition() { - NameValidator validVariable = s -> isValidVariableName(s) - || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll") || s.equals("my_speed"); + NameValidator validVariable = s -> Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll") || s.equals("my_speed") || s.equals("backward_my_speed"); ParseResult result = parse("in_something", validVariable); assertTrue(result.ok); @@ -117,6 +113,10 @@ public void isValidAndSimpleCondition() { result = parse("(toll == NO || road_class == PRIMARY) && toll == NO", validVariable); assertTrue(result.ok); assertEquals("[toll, road_class]", result.guessedVariables.toString()); + + result = parse("backward_my_speed", validVariable); + assertTrue(result.ok); + assertEquals("[backward_my_speed]", result.guessedVariables.toString()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index 6b291a10454..f018a483bcf 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -284,4 +284,20 @@ public void parseConditionWithError() { Arrays.asList(If("edge.fetchWayGeometry().size() > 2", MULTIPLY, "0")))); assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"edge.fetchWayGeometry().size() > 2\": size is an illegal method"), ret.getMessage()); } + + @Test + void testBackwardFunction() { + CustomModel customModel = new CustomModel(); + customModel.addToPriority(If("backward_car_access != car_access", MULTIPLY, "0.5")); + CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, + avgSpeedEnc, maxSpeed, null).getEdgeToPriorityMapping(); + + BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); + EdgeIteratorState edge1 = graph.edge(0, 1).setDistance(100).set(accessEnc, true, false); + EdgeIteratorState edge2 = graph.edge(1, 2).setDistance(100).set(accessEnc, true, true); + + assertEquals(0.5, priorityMapping.get(edge1, false), 1.e-6); + assertEquals(1.0, priorityMapping.get(edge2, false), 1.e-6); + } + } \ No newline at end of file From 229e4b0de3830223164d218207d374f34478a922 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 22 Mar 2023 16:22:44 +0100 Subject: [PATCH 011/165] new test regarding the addition order of (bike) VehicleTagParser and selected other TagParser --- .../java/com/graphhopper/GraphHopperTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 6a8870334d8..f261cb5d507 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -2099,6 +2099,33 @@ public void testOneWaySubnetwork_issue1807() { assertEquals(658, rsp.getBest().getDistance(), 1); } + @Test + public void testTagParserProcessingOrder() { + // it does not matter when the OSMBikeNetworkTagParser is added (before or even after BikeCommonPriorityParser) + // as it is a different type but it is important that OSMSmoothnessParser is added before smoothnessEnc is used + // in BikeCommonAverageSpeedParser + GraphHopper hopper = new GraphHopper(). + setGraphHopperLocation(GH_LOCATION). + setOSMFile(BAYREUTH). + setMinNetworkSize(0). + setProfiles(new CustomProfile("bike").setCustomModel(new CustomModel()).setVehicle("bike")); + + hopper.importOrLoad(); + GHRequest req = new GHRequest(new GHPoint(49.98021, 11.50730), new GHPoint(49.98026, 11.50795)); + req.setProfile("bike"); + GHResponse rsp = hopper.route(req); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); + // due to smoothness=bad => 7 seconds longer + assertEquals(21, rsp.getBest().getTime() / 1000.0, 1); + + req = new GHRequest(new GHPoint(50.015067, 11.502093), new GHPoint(50.014694, 11.499748)); + req.setProfile("bike"); + rsp = hopper.route(req); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); + // due to bike network (relation 2247905) a lower route weight => otherwise 29.0 + assertEquals(23.2, rsp.getBest().getRouteWeight(), .1); + } + @Test public void testEdgeCount() { GraphHopper hopper = new GraphHopper(). From 74a3ea52fbfd87f3b0b7b1b0fb0ee94b05f71104 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 23 Mar 2023 09:49:25 +0100 Subject: [PATCH 012/165] New signature for encoded values and tag parsers (#2740) --- .../java/com/graphhopper/GraphHopper.java | 2 +- .../com/graphhopper/reader/osm/OSMReader.java | 13 +- .../routing/ev/ArrayEdgeIntAccess.java | 45 +++ .../routing/ev/BooleanEncodedValue.java | 6 +- .../routing/ev/DecimalEncodedValue.java | 6 +- .../routing/ev/DecimalEncodedValueImpl.java | 13 +- .../graphhopper/routing/ev/EdgeIntAccess.java | 31 ++ .../routing/ev/EnumEncodedValue.java | 9 +- .../routing/ev/IntEncodedValue.java | 6 +- .../routing/ev/IntEncodedValueImpl.java | 21 +- .../routing/ev/IntsRefEdgeIntAccess.java | 39 ++ .../routing/ev/SimpleBooleanEncodedValue.java | 9 +- .../routing/ev/StringEncodedValue.java | 11 +- .../querygraph/VirtualEdgeIteratorState.java | 63 ++-- .../routing/util/CurvatureCalculator.java | 7 +- .../graphhopper/routing/util/OSMParsers.java | 7 +- .../routing/util/SlopeCalculator.java | 13 +- .../util/parsers/AbstractAccessParser.java | 13 +- .../parsers/AbstractAverageSpeedParser.java | 13 +- .../util/parsers/BikeCommonAccessParser.java | 22 +- .../parsers/BikeCommonAverageSpeedParser.java | 14 +- .../parsers/BikeCommonPriorityParser.java | 9 +- .../routing/util/parsers/CarAccessParser.java | 24 +- .../util/parsers/CarAverageSpeedParser.java | 12 +- .../routing/util/parsers/CountryParser.java | 5 +- .../util/parsers/FootAccessParser.java | 16 +- .../util/parsers/FootAverageSpeedParser.java | 21 +- .../util/parsers/FootPriorityParser.java | 8 +- .../util/parsers/MotorcycleAccessParser.java | 22 +- .../parsers/MotorcycleAverageSpeedParser.java | 12 +- .../parsers/MotorcyclePriorityParser.java | 5 +- .../util/parsers/OSMBikeNetworkTagParser.java | 16 +- .../util/parsers/OSMCrossingParser.java | 13 +- .../util/parsers/OSMFootNetworkTagParser.java | 16 +- .../util/parsers/OSMFootwayParser.java | 5 +- .../util/parsers/OSMGetOffBikeParser.java | 5 +- .../routing/util/parsers/OSMHazmatParser.java | 5 +- .../util/parsers/OSMHazmatTunnelParser.java | 9 +- .../util/parsers/OSMHazmatWaterParser.java | 7 +- .../routing/util/parsers/OSMHgvParser.java | 5 +- .../util/parsers/OSMHikeRatingParser.java | 5 +- .../util/parsers/OSMHorseRatingParser.java | 5 +- .../routing/util/parsers/OSMLanesParser.java | 5 +- .../util/parsers/OSMMaxAxleLoadParser.java | 5 +- .../util/parsers/OSMMaxHeightParser.java | 5 +- .../util/parsers/OSMMaxLengthParser.java | 5 +- .../util/parsers/OSMMaxSpeedParser.java | 7 +- .../util/parsers/OSMMaxWeightParser.java | 5 +- .../util/parsers/OSMMaxWidthParser.java | 5 +- .../util/parsers/OSMMtbRatingParser.java | 5 +- .../util/parsers/OSMRoadAccessParser.java | 5 +- .../util/parsers/OSMRoadClassLinkParser.java | 5 +- .../util/parsers/OSMRoadClassParser.java | 5 +- .../parsers/OSMRoadEnvironmentParser.java | 7 +- .../util/parsers/OSMRoundaboutParser.java | 5 +- .../util/parsers/OSMSmoothnessParser.java | 5 +- .../util/parsers/OSMSurfaceParser.java | 5 +- .../routing/util/parsers/OSMTollParser.java | 7 +- .../util/parsers/OSMTrackTypeParser.java | 5 +- .../routing/util/parsers/OSMWayIDParser.java | 5 +- .../util/parsers/RoadsAccessParser.java | 7 +- .../util/parsers/RoadsAverageSpeedParser.java | 7 +- .../routing/util/parsers/TagParser.java | 3 +- .../util/parsers/WheelchairAccessParser.java | 8 +- .../parsers/WheelchairAverageSpeedParser.java | 20 +- .../parsers/WheelchairPriorityParser.java | 6 +- .../parsers/helpers/OSMValueExtractor.java | 10 +- .../com/graphhopper/storage/BaseGraph.java | 107 +++--- .../storage/BaseGraphNodesAndEdges.java | 12 +- .../graphhopper/storage/TurnCostStorage.java | 11 +- .../graphhopper/util/EdgeIteratorState.java | 4 +- .../java/com/graphhopper/GraphHopperTest.java | 3 +- .../graphhopper/reader/osm/OSMReaderTest.java | 28 +- ...fficChangeWithNodeOrderingReusingTest.java | 2 +- .../routing/ev/BooleanEncodedValueTest.java | 23 +- .../ev/DecimalEncodedValueImplTest.java | 131 +++---- .../routing/ev/DecimalEncodedValueTest.java | 21 +- .../routing/ev/EnumEncodedValueTest.java | 11 +- .../routing/ev/IntEncodedValueImplTest.java | 81 +++-- .../graphhopper/routing/ev/MaxWeightTest.java | 14 +- .../routing/ev/StringEncodedValueTest.java | 43 ++- .../routing/util/CurvatureCalculatorTest.java | 21 +- .../routing/util/SlopeCalculatorTest.java | 44 +-- .../parsers/AbstractBikeTagParserTester.java | 66 ++-- .../util/parsers/BikeTagParserTest.java | 192 +++++----- .../util/parsers/CarTagParserTest.java | 333 +++++++++--------- .../util/parsers/FootTagParserTest.java | 158 +++++---- .../util/parsers/MotorcycleTagParserTest.java | 35 +- .../util/parsers/OSMCrossingParserTest.java | 57 ++- .../util/parsers/OSMGetOffBikeParserTest.java | 11 +- .../util/parsers/OSMHazmatParserTest.java | 36 +- .../parsers/OSMHazmatTunnelParserTest.java | 130 +++---- .../parsers/OSMHazmatWaterParserTest.java | 30 +- .../util/parsers/OSMLanesParserTest.java | 18 +- .../parsers/OSMMaxAxleLoadParserTest.java | 43 +-- .../util/parsers/OSMMaxSpeedParserTest.java | 17 +- .../util/parsers/OSMMaxWeightParserTest.java | 17 +- .../util/parsers/OSMMtbRatingParserTest.java | 11 +- .../util/parsers/OSMRoadAccessParserTest.java | 25 +- .../util/parsers/OSMRoadClassParserTest.java | 43 +-- .../parsers/OSMRoadEnvironmentParserTest.java | 11 +- .../util/parsers/OSMSmoothnessParserTest.java | 15 +- .../util/parsers/OSMSurfaceParserTest.java | 19 +- .../util/parsers/OSMTollParserTest.java | 41 ++- .../util/parsers/OSMTrackTypeParserTest.java | 49 +-- .../util/parsers/RacingBikeTagParserTest.java | 15 +- .../util/parsers/RoadsTagParserTest.java | 10 +- .../routing/util/parsers/TagParsingTest.java | 37 +- .../util/parsers/WheelchairTagParserTest.java | 85 +++-- .../ConditionalExpressionVisitorTest.java | 4 +- 110 files changed, 1495 insertions(+), 1314 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/ArrayEdgeIntAccess.java create mode 100644 core/src/main/java/com/graphhopper/routing/ev/EdgeIntAccess.java create mode 100644 core/src/main/java/com/graphhopper/routing/ev/IntsRefEdgeIntAccess.java diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index a620a0604c9..7c0f3a3895c 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -920,7 +920,7 @@ protected void importOSM() { } logger.info("start creating graph from " + osmFile); - OSMReader reader = new OSMReader(baseGraph.getBaseGraph(), encodingManager, osmParsers, osmReaderConfig).setFile(_getOSMFile()). + OSMReader reader = new OSMReader(baseGraph.getBaseGraph(), osmParsers, osmReaderConfig).setFile(_getOSMFile()). setAreaIndex(areaIndex). setElevationProvider(eleProvider). setCountryRuleFactory(countryRuleFactory); diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index c974997ffbe..d69fe61ca09 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -32,9 +32,9 @@ import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.routing.OSMReaderConfig; import com.graphhopper.routing.ev.Country; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.AreaIndex; import com.graphhopper.routing.util.CustomArea; -import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.OSMParsers; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; @@ -77,9 +77,9 @@ public class OSMReader { private final OSMReaderConfig config; private final BaseGraph baseGraph; + private final EdgeIntAccess edgeIntAccess; private final NodeAccess nodeAccess; private final TurnCostStorage turnCostStorage; - private final EncodingManager encodingManager; private final OSMParsers osmParsers; private final DistanceCalc distCalc = DistanceCalcEarth.DIST_EARTH; private final RestrictionSetter restrictionSetter; @@ -97,9 +97,9 @@ public class OSMReader { private WayToEdgesMap restrictedWaysToEdgesMap = new WayToEdgesMap(); private List restrictionRelations = new ArrayList<>(); - public OSMReader(BaseGraph baseGraph, EncodingManager encodingManager, OSMParsers osmParsers, OSMReaderConfig config) { + public OSMReader(BaseGraph baseGraph, OSMParsers osmParsers, OSMReaderConfig config) { this.baseGraph = baseGraph; - this.encodingManager = encodingManager; + this.edgeIntAccess = baseGraph.createIntAccess(); this.config = config; this.nodeAccess = baseGraph.getNodeAccess(); this.osmParsers = osmParsers; @@ -349,9 +349,8 @@ else if (config.getElevationSmoothing().equals("moving_average")) setArtificialWayTags(pointList, way, distance, nodeTags); IntsRef relationFlags = getRelFlagsMap(way.getId()); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, way, relationFlags); - EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags); + EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance); + osmParsers.handleWayTags(edge.getEdge(), edgeIntAccess, way, relationFlags); List list = way.getTag("key_values", Collections.emptyList()); if (!list.isEmpty()) edge.setKeyValues(list); diff --git a/core/src/main/java/com/graphhopper/routing/ev/ArrayEdgeIntAccess.java b/core/src/main/java/com/graphhopper/routing/ev/ArrayEdgeIntAccess.java new file mode 100644 index 00000000000..6de724fd94b --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/ArrayEdgeIntAccess.java @@ -0,0 +1,45 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.graphhopper.routing.ev; + +import com.carrotsearch.hppc.IntArrayList; + +public class ArrayEdgeIntAccess implements EdgeIntAccess { + private final int intsPerEdge; + private final IntArrayList arr = new IntArrayList(); + + public ArrayEdgeIntAccess(int intsPerEdge) { + this.intsPerEdge = intsPerEdge; + } + + @Override + public int getInt(int edgeId, int index) { + int arrIndex = edgeId * intsPerEdge + index; + return arrIndex >= arr.size() ? 0 : arr.get(arrIndex); + } + + @Override + public void setInt(int edgeId, int index, int value) { + int arrIndex = edgeId * intsPerEdge + index; + if (arrIndex >= arr.size()) + arr.resize(arrIndex + 1); + arr.set(arrIndex, value); + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/ev/BooleanEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/BooleanEncodedValue.java index b1636aaf6d1..24f7e888c35 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/BooleanEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/BooleanEncodedValue.java @@ -1,12 +1,10 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; - /** * This interface defines access to an edge property of type boolean. The default value is false. */ public interface BooleanEncodedValue extends EncodedValue { - void setBool(boolean reverse, IntsRef ref, boolean value); + void setBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, boolean value); - boolean getBool(boolean reverse, IntsRef ref); + boolean getBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java index ffa890274c6..87d8367965c 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java @@ -1,7 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; - /** * This class defines how and where to store an unsigned decimal value. It is important to note that: * 1. the range of the number is highly limited (unlike the Java 32bit float or 64bit double values) @@ -17,9 +15,9 @@ public interface DecimalEncodedValue extends EncodedValue { * * @see #getMaxStorableDecimal() */ - void setDecimal(boolean reverse, IntsRef ref, double value); + void setDecimal(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, double value); - double getDecimal(boolean reverse, IntsRef ref); + double getDecimal(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess); /** * The maximum double value this EncodedValue accepts for setDecimal without throwing an exception. diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index 161c1e9213d..ee9b5b3aa31 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.storage.IntsRef; /** * This class holds a signed decimal value and stores it as an integer value via a conversion factor and a certain @@ -80,15 +79,15 @@ public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, d } @Override - public void setDecimal(boolean reverse, IntsRef ref, double value) { + public void setDecimal(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, double value) { if (!isInitialized()) throw new IllegalStateException("Call init before using EncodedValue " + getName()); if (useMaximumAsInfinity) { if (Double.isInfinite(value)) { - super.setInt(reverse, ref, maxStorableValue); + super.setInt(reverse, edgeId, edgeIntAccess, maxStorableValue); return; } else if (value >= maxStorableValue * factor) { // equality is important as maxStorableValue is reserved for infinity - super.uncheckedSet(reverse, ref, maxStorableValue - 1); + super.uncheckedSet(reverse, edgeId, edgeIntAccess, maxStorableValue - 1); return; } } else if (Double.isInfinite(value)) @@ -103,12 +102,12 @@ public void setDecimal(boolean reverse, IntsRef ref, double value) { if (value < minStorableValue) throw new IllegalArgumentException(getName() + " value too small for encoding " + value + ", minValue:" + minStorableValue + ", factor: " + factor); - super.uncheckedSet(reverse, ref, (int) Math.round(value)); + super.uncheckedSet(reverse, edgeId, edgeIntAccess, (int) Math.round(value)); } @Override - public double getDecimal(boolean reverse, IntsRef ref) { - int value = getInt(reverse, ref); + public double getDecimal(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { + int value = getInt(reverse, edgeId, edgeIntAccess); if (useMaximumAsInfinity && value == maxStorableValue) return Double.POSITIVE_INFINITY; return value * factor; diff --git a/core/src/main/java/com/graphhopper/routing/ev/EdgeIntAccess.java b/core/src/main/java/com/graphhopper/routing/ev/EdgeIntAccess.java new file mode 100644 index 00000000000..3bae8da4b80 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/EdgeIntAccess.java @@ -0,0 +1,31 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.graphhopper.routing.ev; + +public interface EdgeIntAccess { + /** + * Gets the int value at the given index for the given edgeId + */ + int getInt(int edgeId, int index); + + /** + * Sets the int value at the given index for the given edgeId + */ + void setInt(int edgeId, int index, int value); +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java index 9716a59edd0..b1097acc1a2 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.storage.IntsRef; /** * This class allows to store distinct values via an enum. I.e. it stores just the indices @@ -66,13 +65,13 @@ public E[] getValues() { return arr; } - public final void setEnum(boolean reverse, IntsRef ref, E value) { + public final void setEnum(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, E value) { int intValue = value.ordinal(); - super.setInt(reverse, ref, intValue); + super.setInt(reverse, edgeId, edgeIntAccess, intValue); } - public final E getEnum(boolean reverse, IntsRef ref) { - int value = super.getInt(reverse, ref); + public final E getEnum(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { + int value = super.getInt(reverse, edgeId, edgeIntAccess); return arr[value]; } diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java index 1157aec1338..c6a0875d796 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java @@ -1,7 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; - /** * This class defines how and where to store an unsigned integer. It is important to note that: 1. the range of the * integer is highly limited (unlike the Java 32bit integer values) so that the storable part of it fits into the @@ -14,12 +12,12 @@ public interface IntEncodedValue extends EncodedValue { /** * This method restores the integer value from the specified 'flags' taken from the storage. */ - int getInt(boolean reverse, IntsRef ref); + int getInt(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess); /** * This method stores the specified integer value in the specified IntsRef. */ - void setInt(boolean reverse, IntsRef ref, int value); + void setInt(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, int value); /** * The maximum int value this EncodedValue accepts for setInt without throwing an exception. diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 390a1a5bfd9..d2111737b47 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.storage.IntsRef; import javax.lang.model.SourceVersion; @@ -150,9 +149,9 @@ boolean isInitialized() { } @Override - public final void setInt(boolean reverse, IntsRef ref, int value) { + public final void setInt(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, int value) { checkValue(value); - uncheckedSet(reverse, ref, value); + uncheckedSet(reverse, edgeId, edgeIntAccess, value); } private void checkValue(int value) { @@ -164,7 +163,7 @@ private void checkValue(int value) { throw new IllegalArgumentException(name + " value too small for encoding " + value + ", minValue:" + minStorableValue); } - final void uncheckedSet(boolean reverse, IntsRef ref, int value) { + final void uncheckedSet(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, int value) { if (negateReverseDirection) { if (reverse) { reverse = false; @@ -177,26 +176,26 @@ final void uncheckedSet(boolean reverse, IntsRef ref, int value) { value -= minStorableValue; if (reverse) { - int flags = ref.ints[bwdDataIndex + ref.offset]; + int flags = edgeIntAccess.getInt(edgeId, bwdDataIndex); // clear value bits flags &= ~bwdMask; - ref.ints[bwdDataIndex + ref.offset] = flags | (value << bwdShift); + edgeIntAccess.setInt(edgeId, bwdDataIndex, flags | (value << bwdShift)); } else { - int flags = ref.ints[fwdDataIndex + ref.offset]; + int flags = edgeIntAccess.getInt(edgeId, fwdDataIndex); flags &= ~fwdMask; - ref.ints[fwdDataIndex + ref.offset] = flags | (value << fwdShift); + edgeIntAccess.setInt(edgeId, fwdDataIndex, flags | (value << fwdShift)); } } @Override - public final int getInt(boolean reverse, IntsRef ref) { + public final int getInt(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { int flags; // if we do not store both directions ignore reverse == true for convenient reading if (storeTwoDirections && reverse) { - flags = ref.ints[bwdDataIndex + ref.offset]; + flags = edgeIntAccess.getInt(edgeId, bwdDataIndex); return minStorableValue + ((flags & bwdMask) >>> bwdShift); } else { - flags = ref.ints[fwdDataIndex + ref.offset]; + flags = edgeIntAccess.getInt(edgeId, fwdDataIndex); if (negateReverseDirection && reverse) return -(minStorableValue + ((flags & fwdMask) >>> fwdShift)); return minStorableValue + ((flags & fwdMask) >>> fwdShift); diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntsRefEdgeIntAccess.java b/core/src/main/java/com/graphhopper/routing/ev/IntsRefEdgeIntAccess.java new file mode 100644 index 00000000000..1b964092fc5 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/IntsRefEdgeIntAccess.java @@ -0,0 +1,39 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.graphhopper.routing.ev; + +import com.graphhopper.storage.IntsRef; + +public class IntsRefEdgeIntAccess implements EdgeIntAccess { + private final IntsRef intsRef; + + public IntsRefEdgeIntAccess(IntsRef intsRef) { + this.intsRef = intsRef; + } + + @Override + public int getInt(int edgeId, int index) { + return intsRef.ints[index]; + } + + @Override + public void setInt(int edgeId, int index, int value) { + intsRef.ints[index] = value; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java index f82ee30757f..eec079cdcab 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.storage.IntsRef; /** * This class implements a simple boolean storage via an UnsignedIntEncodedValue with 1 bit. @@ -54,12 +53,12 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { } @Override - public final void setBool(boolean reverse, IntsRef ref, boolean value) { - setInt(reverse, ref, value ? 1 : 0); + public final void setBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, boolean value) { + setInt(reverse, edgeId, edgeIntAccess, value ? 1 : 0); } @Override - public final boolean getBool(boolean reverse, IntsRef ref) { - return getInt(reverse, ref) == 1; + public final boolean getBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { + return getInt(reverse, edgeId, edgeIntAccess) == 1; } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java index a4c9aa3bfc2..cf687207c17 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.storage.IntsRef; import java.util.*; @@ -74,9 +73,9 @@ public StringEncodedValue(String name, int bits, List values, boolean st this.indexMap = indexMap; } - public final void setString(boolean reverse, IntsRef ref, String value) { + public final void setString(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, String value) { if (value == null) { - super.setInt(reverse, ref, 0); + super.setInt(reverse, edgeId, edgeIntAccess, 0); return; } int index = indexMap.getOrDefault(value, 0); @@ -88,11 +87,11 @@ public final void setString(boolean reverse, IntsRef ref, String value) { index = values.size(); indexMap.put(value, index); } - super.setInt(reverse, ref, index); + super.setInt(reverse, edgeId, edgeIntAccess, index); } - public final String getString(boolean reverse, IntsRef ref) { - int value = super.getInt(reverse, ref); + public final String getString(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { + int value = super.getInt(reverse, edgeId, edgeIntAccess); if (value == 0) { return null; } diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index 6ceccf72a42..2aabb20c8d1 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -41,6 +41,7 @@ public class VirtualEdgeIteratorState implements EdgeIteratorState { private final int originalEdgeKey; private double distance; private IntsRef edgeFlags; + private EdgeIntAccess edgeIntAccess; private List keyValues; // true if edge should be avoided as start/stop private boolean unfavored; @@ -55,6 +56,7 @@ public VirtualEdgeIteratorState(int originalEdgeKey, int edgeKey, int baseNode, this.adjNode = adjNode; this.distance = distance; this.edgeFlags = edgeFlags; + this.edgeIntAccess = new IntsRefEdgeIntAccess(edgeFlags); this.keyValues = keyValues; this.pointList = pointList; this.reverse = reverse; @@ -145,6 +147,7 @@ public IntsRef getFlags() { @Override public EdgeIteratorState setFlags(IntsRef flags) { this.edgeFlags = flags; + this.edgeIntAccess = new IntsRefEdgeIntAccess(flags); return this; } @@ -153,12 +156,12 @@ public boolean get(BooleanEncodedValue property) { if (property == EdgeIteratorState.UNFAVORED_EDGE) return unfavored; - return property.getBool(reverse, edgeFlags); + return property.getBool(reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState set(BooleanEncodedValue property, boolean value) { - property.setBool(reverse, edgeFlags, value); + property.setBool(reverse, -1, edgeIntAccess, value); return this; } @@ -166,12 +169,12 @@ public EdgeIteratorState set(BooleanEncodedValue property, boolean value) { public boolean getReverse(BooleanEncodedValue property) { if (property == EdgeIteratorState.UNFAVORED_EDGE) return unfavored; - return property.getBool(!reverse, edgeFlags); + return property.getBool(!reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState setReverse(BooleanEncodedValue property, boolean value) { - property.setBool(!reverse, edgeFlags, value); + property.setBool(!reverse, -1, edgeIntAccess, value); return this; } @@ -179,30 +182,30 @@ public EdgeIteratorState setReverse(BooleanEncodedValue property, boolean value) public EdgeIteratorState set(BooleanEncodedValue property, boolean fwd, boolean bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setBool(reverse, edgeFlags, fwd); - property.setBool(!reverse, edgeFlags, bwd); + property.setBool(reverse, -1, edgeIntAccess, fwd); + property.setBool(!reverse, -1, edgeIntAccess, bwd); return this; } @Override public int get(IntEncodedValue property) { - return property.getInt(reverse, edgeFlags); + return property.getInt(reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState set(IntEncodedValue property, int value) { - property.setInt(reverse, edgeFlags, value); + property.setInt(reverse, -1, edgeIntAccess, value); return this; } @Override public int getReverse(IntEncodedValue property) { - return property.getInt(!reverse, edgeFlags); + return property.getInt(!reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState setReverse(IntEncodedValue property, int value) { - property.setInt(!reverse, edgeFlags, value); + property.setInt(!reverse, -1, edgeIntAccess, value); return this; } @@ -210,30 +213,30 @@ public EdgeIteratorState setReverse(IntEncodedValue property, int value) { public EdgeIteratorState set(IntEncodedValue property, int fwd, int bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setInt(reverse, edgeFlags, fwd); - property.setInt(!reverse, edgeFlags, bwd); + property.setInt(reverse, -1, edgeIntAccess, fwd); + property.setInt(!reverse, -1, edgeIntAccess, bwd); return this; } @Override public double get(DecimalEncodedValue property) { - return property.getDecimal(reverse, edgeFlags); + return property.getDecimal(reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState set(DecimalEncodedValue property, double value) { - property.setDecimal(reverse, edgeFlags, value); + property.setDecimal(reverse, -1, edgeIntAccess, value); return this; } @Override public double getReverse(DecimalEncodedValue property) { - return property.getDecimal(!reverse, edgeFlags); + return property.getDecimal(!reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState setReverse(DecimalEncodedValue property, double value) { - property.setDecimal(!reverse, edgeFlags, value); + property.setDecimal(!reverse, -1, edgeIntAccess, value); return this; } @@ -241,30 +244,30 @@ public EdgeIteratorState setReverse(DecimalEncodedValue property, double value) public EdgeIteratorState set(DecimalEncodedValue property, double fwd, double bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setDecimal(reverse, edgeFlags, fwd); - property.setDecimal(!reverse, edgeFlags, bwd); + property.setDecimal(reverse, -1, edgeIntAccess, fwd); + property.setDecimal(!reverse, -1, edgeIntAccess, bwd); return this; } @Override public > T get(EnumEncodedValue property) { - return property.getEnum(reverse, edgeFlags); + return property.getEnum(reverse, -1, edgeIntAccess); } @Override public > EdgeIteratorState set(EnumEncodedValue property, T value) { - property.setEnum(reverse, edgeFlags, value); + property.setEnum(reverse, -1, edgeIntAccess, value); return this; } @Override public > T getReverse(EnumEncodedValue property) { - return property.getEnum(!reverse, edgeFlags); + return property.getEnum(!reverse, -1, edgeIntAccess); } @Override public > EdgeIteratorState setReverse(EnumEncodedValue property, T value) { - property.setEnum(!reverse, edgeFlags, value); + property.setEnum(!reverse, -1, edgeIntAccess, value); return this; } @@ -272,30 +275,30 @@ public > EdgeIteratorState setReverse(EnumEncodedValue prop public > EdgeIteratorState set(EnumEncodedValue property, T fwd, T bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setEnum(reverse, edgeFlags, fwd); - property.setEnum(!reverse, edgeFlags, bwd); + property.setEnum(reverse, -1, edgeIntAccess, fwd); + property.setEnum(!reverse, -1, edgeIntAccess, bwd); return this; } @Override public String get(StringEncodedValue property) { - return property.getString(reverse, edgeFlags); + return property.getString(reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState set(StringEncodedValue property, String value) { - property.setString(reverse, edgeFlags, value); + property.setString(reverse, -1, edgeIntAccess, value); return this; } @Override public String getReverse(StringEncodedValue property) { - return property.getString(!reverse, edgeFlags); + return property.getString(!reverse, -1, edgeIntAccess); } @Override public EdgeIteratorState setReverse(StringEncodedValue property, String value) { - property.setString(!reverse, edgeFlags, value); + property.setString(!reverse, -1, edgeIntAccess, value); return this; } @@ -303,8 +306,8 @@ public EdgeIteratorState setReverse(StringEncodedValue property, String value) { public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setString(reverse, edgeFlags, fwd); - property.setString(!reverse, edgeFlags, bwd); + property.setString(reverse, -1, edgeIntAccess, fwd); + property.setString(!reverse, -1, edgeIntAccess, bwd); return this; } diff --git a/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java b/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java index 769f2e4a9fc..fdc864641d8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; @@ -16,7 +17,7 @@ public CurvatureCalculator(DecimalEncodedValue curvatureEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { PointList pointList = way.getTag("point_list", null); Double edgeDistance = way.getTag("edge_distance", null); if (pointList != null && edgeDistance != null && !pointList.isEmpty()) { @@ -24,10 +25,10 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag pointList.getLat(pointList.size() - 1), pointList.getLon(pointList.size() - 1)); // For now keep the formula simple. Maybe later use quadratic value as it might improve the "resolution" double curvature = beeline / edgeDistance; - curvatureEnc.setDecimal(false, edgeFlags, Math.max(curvatureEnc.getMinStorableDecimal(), Math.min(curvatureEnc.getMaxStorableDecimal(), + curvatureEnc.setDecimal(false, edgeId, edgeIntAccess, Math.max(curvatureEnc.getMinStorableDecimal(), Math.min(curvatureEnc.getMaxStorableDecimal(), curvature))); } else { - curvatureEnc.setDecimal(false, edgeFlags, 1.0); + curvatureEnc.setDecimal(false, edgeId, edgeIntAccess, 1.0); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 3ce359ac215..dd50f2cb0c4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -22,6 +22,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.RestrictionTagParser; import com.graphhopper.routing.ev.EncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.RelationTagParser; import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.storage.IntsRef; @@ -93,11 +94,11 @@ public IntsRef handleRelationTags(ReaderRelation relation, IntsRef relFlags) { return relFlags; } - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { for (RelationTagParser relParser : relationTagParsers) - relParser.handleWayTags(edgeFlags, way, relationFlags); + relParser.handleWayTags(edgeId, edgeIntAccess, way, relationFlags); for (TagParser parser : wayTagParsers) - parser.handleWayTags(edgeFlags, way, relationFlags); + parser.handleWayTags(edgeId, edgeIntAccess, way, relationFlags); } public IntsRef createRelationFlags() { diff --git a/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java index 9a73dab655c..d6e2b6ea37c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; @@ -19,11 +20,11 @@ public SlopeCalculator(DecimalEncodedValue max, DecimalEncodedValue averageEnc) } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { PointList pointList = way.getTag("point_list", null); if (pointList != null) { if (pointList.isEmpty() || !pointList.is3D()) { - averageSlopeEnc.setDecimal(false, edgeFlags, 0); + averageSlopeEnc.setDecimal(false, edgeId, edgeIntAccess, 0); return; } // Calculate 2d distance, although pointList might be 3D. @@ -31,7 +32,7 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag double distance2D = DistanceCalcEarth.calcDistance(pointList, false); if (distance2D < MIN_LENGTH) { // default is minimum of average_slope is negative so we have to explicitly set it to 0 - averageSlopeEnc.setDecimal(false, edgeFlags, 0); + averageSlopeEnc.setDecimal(false, edgeId, edgeIntAccess, 0); return; } @@ -40,9 +41,9 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag throw new IllegalArgumentException("average_slope was NaN for OSM way ID " + way.getId()); if (towerNodeSlope >= 0) - averageSlopeEnc.setDecimal(false, edgeFlags, Math.min(towerNodeSlope, averageSlopeEnc.getMaxStorableDecimal())); + averageSlopeEnc.setDecimal(false, edgeId, edgeIntAccess, Math.min(towerNodeSlope, averageSlopeEnc.getMaxStorableDecimal())); else - averageSlopeEnc.setDecimal(true, edgeFlags, Math.min(Math.abs(towerNodeSlope), averageSlopeEnc.getMaxStorableDecimal())); + averageSlopeEnc.setDecimal(true, edgeId, edgeIntAccess, Math.min(Math.abs(towerNodeSlope), averageSlopeEnc.getMaxStorableDecimal())); // max_slope is more error-prone as the shorter distances increase the fluctuation // so apply some more filtering (here we use the average elevation delta of the previous two points) @@ -71,7 +72,7 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag // TODO Use two independent values for both directions to store if it is a gain or loss and not just the absolute change. // TODO To save space then it would be nice to have an encoded value that can store two different values which are swapped when the reverse direction is used - maxSlopeEnc.setDecimal(false, edgeFlags, Math.min(maxSlope, maxSlopeEnc.getMaxStorableDecimal())); + maxSlopeEnc.setDecimal(false, edgeId, edgeIntAccess, Math.min(maxSlope, maxSlopeEnc.getMaxStorableDecimal())); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java index cea8a580c14..bd876cd2fee 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java @@ -6,6 +6,7 @@ import com.graphhopper.reader.osm.conditional.ConditionalTagInspector; import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.storage.IntsRef; @@ -75,23 +76,23 @@ public ConditionalTagInspector getConditionalTagInspector() { return conditionalTagInspector; } - protected void handleBarrierEdge(IntsRef edgeFlags, Map nodeTags) { + protected void handleBarrierEdge(int edgeId, EdgeIntAccess edgeIntAccess, Map nodeTags) { // for now we just create a dummy reader node, because our encoders do not make use of the coordinates anyway ReaderNode readerNode = new ReaderNode(0, 0, 0, nodeTags); // block access for barriers if (isBarrier(readerNode)) { BooleanEncodedValue accessEnc = getAccessEnc(); - accessEnc.setBool(false, edgeFlags, false); - accessEnc.setBool(true, edgeFlags, false); + accessEnc.setBool(false, edgeId, edgeIntAccess, false); + accessEnc.setBool(true, edgeId, edgeIntAccess, false); } } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - handleWayTags(edgeFlags, way); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + handleWayTags(edgeId, edgeIntAccess, way); } - public abstract void handleWayTags(IntsRef edgeFlags, ReaderWay way); + public abstract void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way); /** * @return true if the given OSM node blocks access for this vehicle, false otherwise diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAverageSpeedParser.java index 63e15586ef5..b9b9ce74c52 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAverageSpeedParser.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.FerrySpeedCalculator; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -53,14 +54,14 @@ public final DecimalEncodedValue getAverageSpeedEnc() { return avgSpeedEnc; } - protected void setSpeed(boolean reverse, IntsRef edgeFlags, double speed) { + protected void setSpeed(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, double speed) { // special case when speed is non-zero but would be "rounded down" to 0 due to the low precision of the EncodedValue if (speed > 0.1 && speed < avgSpeedEnc.getSmallestNonZeroValue()) speed = avgSpeedEnc.getSmallestNonZeroValue(); if (speed < avgSpeedEnc.getSmallestNonZeroValue()) { - avgSpeedEnc.setDecimal(reverse, edgeFlags, 0); + avgSpeedEnc.setDecimal(reverse, edgeId, edgeIntAccess, 0); } else { - avgSpeedEnc.setDecimal(reverse, edgeFlags, Math.min(speed, getMaxSpeed())); + avgSpeedEnc.setDecimal(reverse, edgeId, edgeIntAccess, Math.min(speed, getMaxSpeed())); } } @@ -69,11 +70,11 @@ public final String getName() { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - handleWayTags(edgeFlags, way); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + handleWayTags(edgeId, edgeIntAccess, way); } - public abstract void handleWayTags(IntsRef edgeFlags, ReaderWay way); + public abstract void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way); @Override public String toString() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 7b9f50ffc86..5b6fc1c0606 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -2,9 +2,9 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import java.util.*; @@ -116,25 +116,25 @@ boolean isSacScaleAllowed(String sacScale) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { WayAccess access = getAccess(way); if (access.canSkip()) return; if (access.isFerry()) { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } else { - handleAccess(edgeFlags, way); + handleAccess(edgeId, edgeIntAccess, way); } if (way.hasTag("gh:barrier_edge")) { List> nodeTags = way.getTag("node_tags", Collections.emptyList()); - handleBarrierEdge(edgeFlags, nodeTags.get(0)); + handleBarrierEdge(edgeId, edgeIntAccess, nodeTags.get(0)); } } - protected void handleAccess(IntsRef edgeFlags, ReaderWay way) { + protected void handleAccess(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { // handle oneways. The value -1 means it is a oneway but for reverse direction of stored geometry. // The tagging oneway:bicycle=no or cycleway:right:oneway=no or cycleway:left:oneway=no lifts the generic oneway restriction of the way for bike boolean isOneway = way.hasTag("oneway", oneways) && !way.hasTag("oneway", "-1") && !way.hasTag("bicycle:backward", intendedValues) @@ -147,7 +147,7 @@ protected void handleAccess(IntsRef edgeFlags, ReaderWay way) { || way.hasTag("bicycle:forward", restrictedValues) || way.hasTag("bicycle:backward", restrictedValues); - if ((isOneway || roundaboutEnc.getBool(false, edgeFlags)) + if ((isOneway || roundaboutEnc.getBool(false, edgeId, edgeIntAccess)) && !way.hasTag("oneway:bicycle", "no") && !way.hasTag("cycleway", oppositeLanes) && !way.hasTag("cycleway:left", oppositeLanes) @@ -160,11 +160,11 @@ protected void handleAccess(IntsRef edgeFlags, ReaderWay way) { || way.hasTag("cycleway:right:oneway", "-1") || way.hasTag("vehicle:forward", restrictedValues) || way.hasTag("bicycle:forward", restrictedValues); - accessEnc.setBool(isBackward, edgeFlags, true); + accessEnc.setBool(isBackward, edgeId, edgeIntAccess, true); } else { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java index b1dea92243e..9fb0985372b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java @@ -3,8 +3,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.Smoothness; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import java.util.HashMap; @@ -136,27 +136,27 @@ public double applyMaxSpeed(ReaderWay way, double speed, boolean bwd) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { if (way.hasTag("route", ferries)) { double ferrySpeed = ferrySpeedCalc.getSpeed(way); - avgSpeedEnc.setDecimal(false, edgeFlags, ferrySpeed); + avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, ferrySpeed); if (avgSpeedEnc.isStoreTwoDirections()) - avgSpeedEnc.setDecimal(true, edgeFlags, ferrySpeed); + avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, ferrySpeed); } if (!way.hasTag("railway", "platform") && !way.hasTag("man_made", "pier")) return; } double speed = getSpeed(way); - Smoothness smoothness = smoothnessEnc.getEnum(false, edgeFlags); + Smoothness smoothness = smoothnessEnc.getEnum(false, edgeId, edgeIntAccess); speed = Math.max(MIN_SPEED, smoothnessFactor.get(smoothness) * speed); double speedFwd = applyMaxSpeed(way, speed, false); - avgSpeedEnc.setDecimal(false, edgeFlags, speedFwd); + avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, speedFwd); if (avgSpeedEnc.isStoreTwoDirections()) { speed = applyMaxSpeed(way, speed, true); - avgSpeedEnc.setDecimal(true, edgeFlags, speed); + avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, speed); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index eb91762d1e9..0ba95fdfac7 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RouteNetwork; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.storage.IntsRef; @@ -77,9 +78,9 @@ protected BikeCommonPriorityParser(DecimalEncodedValue priorityEnc, DecimalEncod } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { String highwayValue = way.getTag("highway"); - Integer priorityFromRelation = routeMap.get(bikeRouteEnc.getEnum(false, edgeFlags)); + Integer priorityFromRelation = routeMap.get(bikeRouteEnc.getEnum(false, edgeId, edgeIntAccess)); if (highwayValue == null) { if (way.hasTag("route", ferries)) { priorityFromRelation = SLIGHT_AVOID.getValue(); @@ -88,8 +89,8 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag } } - double maxSpeed = Math.max(avgSpeedEnc.getDecimal(false, edgeFlags), avgSpeedEnc.getDecimal(true, edgeFlags)); - priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way, maxSpeed, priorityFromRelation))); + double maxSpeed = Math.max(avgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), avgSpeedEnc.getDecimal(true, edgeId, edgeIntAccess)); + priorityEnc.setDecimal(false, edgeId, edgeIntAccess, PriorityCode.getValue(handlePriority(way, maxSpeed, priorityFromRelation))); } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index 4e130044d59..6acf137d0e9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -18,13 +18,9 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.Roundabout; -import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import java.util.*; @@ -131,31 +127,31 @@ public WayAccess getAccess(ReaderWay way) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { WayAccess access = getAccess(way); if (access.canSkip()) return; if (!access.isFerry()) { - boolean isRoundabout = roundaboutEnc.getBool(false, edgeFlags); + boolean isRoundabout = roundaboutEnc.getBool(false, edgeId, edgeIntAccess); if (isOneway(way) || isRoundabout) { if (isForwardOneway(way)) - accessEnc.setBool(false, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); if (isBackwardOneway(way)) - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } else { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } } else { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } if (way.hasTag("gh:barrier_edge")) { List> nodeTags = way.getTag("node_tags", Collections.emptyList()); - handleBarrierEdge(edgeFlags, nodeTags.get(0)); + handleBarrierEdge(edgeId, edgeIntAccess, nodeTags.get(0)); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAverageSpeedParser.java index cda428503f2..1527cb4ad93 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAverageSpeedParser.java @@ -20,8 +20,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleSpeed; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; @@ -120,14 +120,14 @@ protected double getSpeed(ReaderWay way) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { if (way.hasTag("route", ferries)) { double ferrySpeed = ferrySpeedCalc.getSpeed(way); - setSpeed(false, edgeFlags, ferrySpeed); + setSpeed(false, edgeId, edgeIntAccess, ferrySpeed); if (avgSpeedEnc.isStoreTwoDirections()) - setSpeed(true, edgeFlags, ferrySpeed); + setSpeed(true, edgeId, edgeIntAccess, ferrySpeed); } return; } @@ -136,8 +136,8 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { double speed = getSpeed(way); speed = applyBadSurfaceSpeed(way, speed); - setSpeed(false, edgeFlags, applyMaxSpeed(way, speed, false)); - setSpeed(true, edgeFlags, applyMaxSpeed(way, speed, true)); + setSpeed(false, edgeId, edgeIntAccess, applyMaxSpeed(way, speed, false)); + setSpeed(true, edgeId, edgeIntAccess, applyMaxSpeed(way, speed, true)); } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CountryParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CountryParser.java index 1022ee3c076..e9aa6b955cd 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CountryParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CountryParser.java @@ -20,6 +20,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.Country; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; public class CountryParser implements TagParser { @@ -30,8 +31,8 @@ public CountryParser(EnumEncodedValue countryEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { Country country = way.getTag("country", Country.MISSING); - countryEnc.setEnum(false, edgeFlags, country); + countryEnc.setEnum(false, edgeId, edgeIntAccess, country); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java index 6df60feb8a0..e2a4d4553d5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java @@ -18,13 +18,9 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.RouteNetwork; -import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import java.util.*; @@ -165,7 +161,7 @@ public WayAccess getAccess(ReaderWay way) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { WayAccess access = getAccess(way); if (access.canSkip()) return; @@ -174,15 +170,15 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { || way.hasTag("oneway", oneways) && way.hasTag("highway", "steps") // outdated mapping style ) { boolean reverse = way.hasTag("oneway:foot", "-1") || way.hasTag("foot:backward", "yes") || way.hasTag("foot:forward", "no"); - accessEnc.setBool(reverse, edgeFlags, true); + accessEnc.setBool(reverse, edgeId, edgeIntAccess, true); } else { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } if (way.hasTag("gh:barrier_edge")) { List> nodeTags = way.getTag("node_tags", Collections.emptyList()); - handleBarrierEdge(edgeFlags, nodeTags.get(0)); + handleBarrierEdge(edgeId, edgeIntAccess, nodeTags.get(0)); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAverageSpeedParser.java index 1cbe05bace3..e235dbadcc0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAverageSpeedParser.java @@ -1,18 +1,13 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.RouteNetwork; -import com.graphhopper.routing.ev.VehicleSpeed; -import com.graphhopper.storage.IntsRef; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import java.util.*; import static com.graphhopper.routing.ev.RouteNetwork.*; import static com.graphhopper.routing.util.PriorityCode.*; -import static com.graphhopper.routing.util.parsers.AbstractAccessParser.INTENDED; public class FootAverageSpeedParser extends AbstractAverageSpeedParser implements TagParser { static final int SLOW_SPEED = 2; @@ -77,12 +72,12 @@ protected FootAverageSpeedParser(DecimalEncodedValue speedEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { if (way.hasTag("route", ferries)) { double ferrySpeed = ferrySpeedCalc.getSpeed(way); - setSpeed(edgeFlags, true, true, ferrySpeed); + setSpeed(edgeId, edgeIntAccess, true, true, ferrySpeed); } if (!way.hasTag("railway", "platform") && !way.hasTag("man_made", "pier")) return; @@ -90,18 +85,18 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { String sacScale = way.getTag("sac_scale"); if (sacScale != null) { - setSpeed(edgeFlags, true, true, "hiking".equals(sacScale) ? MEAN_SPEED : SLOW_SPEED); + setSpeed(edgeId, edgeIntAccess, true, true, "hiking".equals(sacScale) ? MEAN_SPEED : SLOW_SPEED); } else { - setSpeed(edgeFlags, true, true, way.hasTag("highway", "steps") ? MEAN_SPEED - 2 : MEAN_SPEED); + setSpeed(edgeId, edgeIntAccess, true, true, way.hasTag("highway", "steps") ? MEAN_SPEED - 2 : MEAN_SPEED); } } - void setSpeed(IntsRef edgeFlags, boolean fwd, boolean bwd, double speed) { + void setSpeed(int edgeId, EdgeIntAccess edgeIntAccess, boolean fwd, boolean bwd, double speed) { if (speed > getMaxSpeed()) speed = getMaxSpeed(); if (fwd) - avgSpeedEnc.setDecimal(false, edgeFlags, speed); + avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, speed); if (bwd && avgSpeedEnc.isStoreTwoDirections()) - avgSpeedEnc.setDecimal(true, edgeFlags, speed); + avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, speed); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootPriorityParser.java index f5e931a18f0..e6f8764d6d8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootPriorityParser.java @@ -72,14 +72,14 @@ protected FootPriorityParser(DecimalEncodedValue priorityEnc, EnumEncodedValue bikeRouteEnc, Enco @Override public void handleRelationTags(IntsRef relFlags, ReaderRelation relation) { - RouteNetwork oldBikeNetwork = transformerRouteRelEnc.getEnum(false, relFlags); + IntsRefEdgeIntAccess relIntAccess = new IntsRefEdgeIntAccess(relFlags); + RouteNetwork oldBikeNetwork = transformerRouteRelEnc.getEnum(false, -1, relIntAccess); if (relation.hasTag("route", "bicycle")) { String tag = Helper.toLowerCase(relation.getTag("network", "")); RouteNetwork newBikeNetwork = RouteNetwork.LOCAL; @@ -53,15 +52,16 @@ public void handleRelationTags(IntsRef relFlags, ReaderRelation relation) { newBikeNetwork = RouteNetwork.INTERNATIONAL; } if (oldBikeNetwork == RouteNetwork.MISSING || oldBikeNetwork.ordinal() > newBikeNetwork.ordinal()) - transformerRouteRelEnc.setEnum(false, relFlags, newBikeNetwork); + transformerRouteRelEnc.setEnum(false, -1, relIntAccess, newBikeNetwork); } } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { // just copy value into different bit range - RouteNetwork routeNetwork = transformerRouteRelEnc.getEnum(false, relationFlags); - bikeRouteEnc.setEnum(false, edgeFlags, routeNetwork); + IntsRefEdgeIntAccess relIntAccess = new IntsRefEdgeIntAccess(relationFlags); + RouteNetwork routeNetwork = transformerRouteRelEnc.getEnum(false, -1, relIntAccess); + bikeRouteEnc.setEnum(false, edgeId, edgeIntAccess, routeNetwork); } public EnumEncodedValue getTransformerRouteRelEnc() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java index 1afa11207fd..5f463714b17 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMCrossingParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.Crossing; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; @@ -20,7 +21,7 @@ public OSMCrossingParser(EnumEncodedValue crossingEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { List> nodeTags = readerWay.getTag("node_tags", null); if (nodeTags == null) return; @@ -29,19 +30,19 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati Map tags = nodeTags.get(i); if ("crossing".equals(tags.get("railway")) || "level_crossing".equals(tags.get("railway"))) { String barrierVal = (String) tags.get("crossing:barrier"); - crossingEnc.setEnum(false, edgeFlags, (Helper.isEmpty(barrierVal) || "no".equals(barrierVal)) ? Crossing.RAILWAY : Crossing.RAILWAY_BARRIER); + crossingEnc.setEnum(false, edgeId, edgeIntAccess, (Helper.isEmpty(barrierVal) || "no".equals(barrierVal)) ? Crossing.RAILWAY : Crossing.RAILWAY_BARRIER); return; } String crossingSignals = (String) tags.get("crossing:signals"); if ("yes".equals(crossingSignals)) { - crossingEnc.setEnum(false, edgeFlags, Crossing.TRAFFIC_SIGNALS); + crossingEnc.setEnum(false, edgeId, edgeIntAccess, Crossing.TRAFFIC_SIGNALS); return; } String crossingMarkings = (String) tags.get("crossing:markings"); if ("yes".equals(crossingMarkings)) { - crossingEnc.setEnum(false, edgeFlags, Crossing.MARKED); + crossingEnc.setEnum(false, edgeId, edgeIntAccess, Crossing.MARKED); return; } @@ -49,13 +50,13 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati // some crossing values like "no" do not require highway=crossing and sometimes no crossing value exists although highway=crossing if (Helper.isEmpty(crossingValue) && ("no".equals(crossingSignals) || "no".equals(crossingMarkings) || "crossing".equals(tags.get("highway")) || "crossing".equals(tags.get("footway")) || "crossing".equals(tags.get("cycleway")))) { - crossingEnc.setEnum(false, edgeFlags, Crossing.UNMARKED); + crossingEnc.setEnum(false, edgeId, edgeIntAccess, Crossing.UNMARKED); // next node could have more specific Crossing value continue; } Crossing crossing = Crossing.find(crossingValue); if (crossing != Crossing.MISSING) - crossingEnc.setEnum(false, edgeFlags, crossing); + crossingEnc.setEnum(false, edgeId, edgeIntAccess, crossing); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootNetworkTagParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootNetworkTagParser.java index 7f496f6b0f1..878d7db0769 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootNetworkTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootNetworkTagParser.java @@ -19,9 +19,7 @@ import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RouteNetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; @@ -39,7 +37,8 @@ public OSMFootNetworkTagParser(EnumEncodedValue footRouteEnc, Enco @Override public void handleRelationTags(IntsRef relFlags, ReaderRelation relation) { - RouteNetwork oldFootNetwork = transformerRouteRelEnc.getEnum(false, relFlags); + IntsRefEdgeIntAccess relIntAccess = new IntsRefEdgeIntAccess(relFlags); + RouteNetwork oldFootNetwork = transformerRouteRelEnc.getEnum(false, -1, relIntAccess); if (relation.hasTag("route", "hiking") || relation.hasTag("route", "foot")) { String tag = Helper.toLowerCase(relation.getTag("network", "")); RouteNetwork newFootNetwork = RouteNetwork.LOCAL; @@ -53,14 +52,15 @@ public void handleRelationTags(IntsRef relFlags, ReaderRelation relation) { newFootNetwork = RouteNetwork.INTERNATIONAL; } if (oldFootNetwork == RouteNetwork.MISSING || oldFootNetwork.ordinal() > newFootNetwork.ordinal()) - transformerRouteRelEnc.setEnum(false, relFlags, newFootNetwork); + transformerRouteRelEnc.setEnum(false, -1, relIntAccess, newFootNetwork); } } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { // just copy value into different bit range - RouteNetwork footNetwork = transformerRouteRelEnc.getEnum(false, relationFlags); - footRouteEnc.setEnum(false, edgeFlags, footNetwork); + IntsRefEdgeIntAccess relIntAccess = new IntsRefEdgeIntAccess(relationFlags); + RouteNetwork footNetwork = transformerRouteRelEnc.getEnum(false, -1, relIntAccess); + footRouteEnc.setEnum(false, edgeId, edgeIntAccess, footNetwork); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootwayParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootwayParser.java index 31d150659f5..a4a51f99ca9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootwayParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMFootwayParser.java @@ -21,6 +21,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.Footway; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; /** @@ -34,8 +35,8 @@ public OSMFootwayParser(EnumEncodedValue footwayEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { String footway = way.getTag("footway"); - footwayEnc.setEnum(false, edgeFlags, Footway.find(footway)); + footwayEnc.setEnum(false, edgeId, edgeIntAccess, Footway.find(footway)); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java index c6efe55dc56..2ef299c4491 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; import java.util.Arrays; @@ -27,11 +28,11 @@ public OSMGetOffBikeParser(BooleanEncodedValue getOffBikeEnc, List pushB } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { String highway = way.getTag("highway"); if (!way.hasTag("bicycle", accepted) && (pushBikeHighwayTags.contains(highway) || way.hasTag("railway", "platform")) || "steps".equals(highway) || way.hasTag("bicycle", "dismount")) { - offBikeEnc.setBool(false, edgeFlags, true); + offBikeEnc.setBool(false, edgeId, edgeIntAccess, true); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatParser.java index cd14bb9869a..d7c6000480f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.Hazmat; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; public class OSMHazmatParser implements TagParser { @@ -14,8 +15,8 @@ public OSMHazmatParser(EnumEncodedValue hazEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { if (readerWay.hasTag("hazmat", "no")) - hazEnc.setEnum(false, edgeFlags, Hazmat.NO); + hazEnc.setEnum(false, edgeId, edgeIntAccess, Hazmat.NO); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParser.java index 2c68906ac6f..bc20e6d331f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.HazmatTunnel; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; public class OSMHazmatTunnelParser implements TagParser { @@ -24,18 +25,18 @@ public OSMHazmatTunnelParser(EnumEncodedValue hazTunnelEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { if (readerWay.hasTag("hazmat:adr_tunnel_cat", TUNNEL_CATEGORY_NAMES)) { HazmatTunnel code = HazmatTunnel.valueOf(readerWay.getTag("hazmat:adr_tunnel_cat")); - hazTunnelEnc.setEnum(false, edgeFlags, code); + hazTunnelEnc.setEnum(false, edgeId, edgeIntAccess, code); } else if (readerWay.hasTag("hazmat:tunnel_cat", TUNNEL_CATEGORY_NAMES)) { HazmatTunnel code = HazmatTunnel.valueOf(readerWay.getTag("hazmat:tunnel_cat")); - hazTunnelEnc.setEnum(false, edgeFlags, code); + hazTunnelEnc.setEnum(false, edgeId, edgeIntAccess, code); } else if (readerWay.hasTag("tunnel", "yes")) { HazmatTunnel[] codes = HazmatTunnel.values(); for (int i = codes.length - 1; i >= 0; i--) { if (readerWay.hasTag("hazmat:" + codes[i].name(), "no")) { - hazTunnelEnc.setEnum(false, edgeFlags, codes[i]); + hazTunnelEnc.setEnum(false, edgeId, edgeIntAccess, codes[i]); break; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParser.java index 64597857654..7c1cc986a1c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.HazmatWater; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; @@ -15,11 +16,11 @@ public OSMHazmatWaterParser(EnumEncodedValue hazWaterEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { if (readerWay.hasTag("hazmat:water", "no")) { - hazWaterEnc.setEnum(false, edgeFlags, HazmatWater.NO); + hazWaterEnc.setEnum(false, edgeId, edgeIntAccess, HazmatWater.NO); } else if (readerWay.hasTag("hazmat:water", "permissive")) { - hazWaterEnc.setEnum(false, edgeFlags, HazmatWater.PERMISSIVE); + hazWaterEnc.setEnum(false, edgeId, edgeIntAccess, HazmatWater.PERMISSIVE); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java index 58bc601ea5d..03918c5cb31 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.Hgv; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; public class OSMHgvParser implements TagParser { @@ -13,7 +14,7 @@ public OSMHgvParser(EnumEncodedValue hgvEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - hgvEnc.setEnum(false, edgeFlags, Hgv.find(way.getTag("hgv"))); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + hgvEnc.setEnum(false, edgeId, edgeIntAccess, Hgv.find(way.getTag("hgv"))); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHikeRatingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHikeRatingParser.java index 22f264e46dd..8e99957d6c9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHikeRatingParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHikeRatingParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.IntEncodedValue; import com.graphhopper.storage.IntsRef; @@ -35,7 +36,7 @@ public OSMHikeRatingParser(IntEncodedValue sacScaleEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String scale = readerWay.getTag("sac_scale"); int rating = 0; if (scale != null) { @@ -47,6 +48,6 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati else if (scale.equals("difficult_alpine_hiking")) rating = 6; } if (rating != 0) - sacScaleEnc.setInt(false, edgeFlags, rating); + sacScaleEnc.setInt(false, edgeId, edgeIntAccess, rating); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHorseRatingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHorseRatingParser.java index 18a75e76dd7..ab701c3fba9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHorseRatingParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHorseRatingParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.IntEncodedValue; import com.graphhopper.storage.IntsRef; @@ -35,7 +36,7 @@ public OSMHorseRatingParser(IntEncodedValue horseScale) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String scale = readerWay.getTag("horse_scale"); int rating = 0; if (scale != null) { @@ -47,6 +48,6 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati else if (scale.equals("impossible")) rating = 6; } if (rating != 0) - horseScale.setInt(false, edgeFlags, rating); + horseScale.setInt(false, edgeId, edgeIntAccess, rating); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMLanesParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMLanesParser.java index f85e3d4c0e6..946cf6b0811 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMLanesParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMLanesParser.java @@ -19,6 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.IntEncodedValue; import com.graphhopper.storage.IntsRef; @@ -33,7 +34,7 @@ public OSMLanesParser(IntEncodedValue lanesEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { int laneCount = 1; if (way.hasTag("lanes")) { String noLanes = way.getTag("lanes"); @@ -53,6 +54,6 @@ else if (noLanesInt > 6) } } } - lanesEnc.setInt(false, edgeFlags, laneCount); + lanesEnc.setInt(false, edgeId, edgeIntAccess, laneCount); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParser.java index f5011a5862a..d849d5f09ac 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -33,7 +34,7 @@ public OSMMaxAxleLoadParser(DecimalEncodedValue maxAxleLoadEncoder) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - OSMValueExtractor.extractTons(edgeFlags, way, maxAxleLoadEncoder, Collections.singletonList("maxaxleload")); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + OSMValueExtractor.extractTons(edgeId, edgeIntAccess, way, maxAxleLoadEncoder, Collections.singletonList("maxaxleload")); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxHeightParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxHeightParser.java index 01e2aa9e82a..27615d6366f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxHeightParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxHeightParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -34,8 +35,8 @@ public OSMMaxHeightParser(DecimalEncodedValue heightEncoder) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { List heightTags = Arrays.asList("maxheight", "maxheight:physical"/*, the OSM tag "height" is not used for the height of a road, so omit it here! */); - OSMValueExtractor.extractMeter(edgeFlags, way, heightEncoder, heightTags); + OSMValueExtractor.extractMeter(edgeId, edgeIntAccess, way, heightEncoder, heightTags); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxLengthParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxLengthParser.java index f8dedbd290a..ce3e8c2c9c8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxLengthParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxLengthParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -33,7 +34,7 @@ public OSMMaxLengthParser(DecimalEncodedValue lengthEncoder) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - OSMValueExtractor.extractMeter(edgeFlags, way, lengthEncoder, Collections.singletonList("maxlength")); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + OSMValueExtractor.extractMeter(edgeId, edgeIntAccess, way, lengthEncoder, Collections.singletonList("maxlength")); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParser.java index d0c75cd37de..29151f33f8e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.MaxSpeed; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; @@ -39,7 +40,7 @@ public OSMMaxSpeedParser(DecimalEncodedValue carMaxSpeedEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { double maxSpeed = OSMValueExtractor.stringToKmh(way.getTag("maxspeed")); CountryRule countryRule = way.getTag("country_rule", null); @@ -61,11 +62,11 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlag if (!isValidSpeed(fwdSpeed)) fwdSpeed = UNSET_SPEED; - carMaxSpeedEnc.setDecimal(false, edgeFlags, fwdSpeed); + carMaxSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, fwdSpeed); if (!isValidSpeed(bwdSpeed)) bwdSpeed = UNSET_SPEED; - carMaxSpeedEnc.setDecimal(true, edgeFlags, bwdSpeed); + carMaxSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, bwdSpeed); } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java index 7992db57741..7b397b3263a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -34,9 +35,9 @@ public OSMMaxWeightParser(DecimalEncodedValue weightEncoder) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { // do not include OSM tag "height" here as it has completely different meaning (height of peak) List weightTags = Arrays.asList("maxweight", "maxgcweight"); - OSMValueExtractor.extractTons(edgeFlags, way, weightEncoder, weightTags); + OSMValueExtractor.extractTons(edgeId, edgeIntAccess, way, weightEncoder, weightTags); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWidthParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWidthParser.java index f96feb6aaf4..b3f65145308 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWidthParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWidthParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; @@ -34,8 +35,8 @@ public OSMMaxWidthParser(DecimalEncodedValue widthEncoder) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { List widthTags = Arrays.asList("maxwidth", "maxwidth:physical", "width"); - OSMValueExtractor.extractMeter(edgeFlags, way, widthEncoder, widthTags); + OSMValueExtractor.extractMeter(edgeId, edgeIntAccess, way, widthEncoder, widthTags); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java index 1ff17e6ff67..ec425dbe1b5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.IntEncodedValue; import com.graphhopper.storage.IntsRef; @@ -36,7 +37,7 @@ public OSMMtbRatingParser(IntEncodedValue mtbRatingEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String scale = readerWay.getTag("mtb:scale"); int rating = 0; if (scale != null) { @@ -49,6 +50,6 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati } } if (rating > 0 && rating < 8) - mtbRatingEnc.setInt(false, edgeFlags, rating); + mtbRatingEnc.setInt(false, edgeId, edgeIntAccess, rating); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java index f7b5207d505..2534c747c10 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; @@ -41,7 +42,7 @@ public OSMRoadAccessParser(EnumEncodedValue roadAccessEnc, List> nodeTags = readerWay.getTag("node_tags", Collections.emptyList()); @@ -60,7 +61,7 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati if (countryRule != null) accessValue = countryRule.getAccess(readerWay, TransportationMode.CAR, accessValue); - roadAccessEnc.setEnum(false, edgeFlags, accessValue); + roadAccessEnc.setEnum(false, edgeId, edgeIntAccess, accessValue); } private RoadAccess getRoadAccess(String tagValue, RoadAccess accessValue) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassLinkParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassLinkParser.java index 6dc42c17464..a38727f3e8e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassLinkParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassLinkParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; @@ -30,9 +31,9 @@ public OSMRoadClassLinkParser(BooleanEncodedValue linkEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String highwayTag = readerWay.getTag("highway"); if (!Helper.isEmpty(highwayTag) && highwayTag.endsWith("_link")) - linkEnc.setBool(false, edgeFlags, true); + linkEnc.setBool(false, edgeId, edgeIntAccess, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassParser.java index eb932fd14f6..a46c3a96372 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadClassParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RoadClass; import com.graphhopper.storage.IntsRef; @@ -33,7 +34,7 @@ public OSMRoadClassParser(EnumEncodedValue roadClassEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String roadClassTag = readerWay.getTag("highway"); if (roadClassTag == null) return; @@ -42,6 +43,6 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati roadClass = RoadClass.find(roadClassTag.substring(0, roadClassTag.length() - 5)); if (roadClass != OTHER) - roadClassEnc.setEnum(false, edgeFlags, roadClass); + roadClassEnc.setEnum(false, edgeId, edgeIntAccess, roadClass); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java index c4c2513b705..9ba52ce172d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.storage.IntsRef; @@ -37,11 +38,11 @@ public OSMRoadEnvironmentParser(EnumEncodedValue roadEnvEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { List> nodeTags = readerWay.getTag("node_tags", Collections.emptyList()); // a barrier edge has the restriction in both nodes and the tags are the same if (readerWay.hasTag("gh:barrier_edge") && nodeTags.get(0).containsKey("ford")) { - roadEnvEnc.setEnum(false, edgeFlags, FORD); + roadEnvEnc.setEnum(false, edgeId, edgeIntAccess, FORD); return; } @@ -60,6 +61,6 @@ else if (readerWay.hasTag("highway")) roadEnvironment = ROAD; if (roadEnvironment != OTHER) - roadEnvEnc.setEnum(false, edgeFlags, roadEnvironment); + roadEnvEnc.setEnum(false, edgeId, edgeIntAccess, roadEnvironment); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoundaboutParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoundaboutParser.java index 8bb0b09f4bf..cad15014986 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoundaboutParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoundaboutParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; public class OSMRoundaboutParser implements TagParser { @@ -30,9 +31,9 @@ public OSMRoundaboutParser(BooleanEncodedValue roundaboutEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { boolean isRoundabout = way.hasTag("junction", "roundabout") || way.hasTag("junction", "circular"); if (isRoundabout) - roundaboutEnc.setBool(false, edgeFlags, true); + roundaboutEnc.setBool(false, edgeId, edgeIntAccess, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParser.java index ccbe036bb56..f9435793ed2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.Smoothness; import com.graphhopper.storage.IntsRef; @@ -33,12 +34,12 @@ public OSMSmoothnessParser(EnumEncodedValue smoothnessEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String smoothnessTag = readerWay.getTag("smoothness"); Smoothness smoothness = Smoothness.find(smoothnessTag); if (smoothness == MISSING) return; - smoothnessEnc.setEnum(false, edgeFlags, smoothness); + smoothnessEnc.setEnum(false, edgeId, edgeIntAccess, smoothness); } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java index 2ffe2e38067..808070af301 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.Surface; import com.graphhopper.storage.IntsRef; @@ -33,7 +34,7 @@ public OSMSurfaceParser(EnumEncodedValue surfaceEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String surfaceTag = readerWay.getTag("surface"); Surface surface = Surface.find(surfaceTag); if (surface == MISSING) @@ -48,6 +49,6 @@ else if (surfaceTag.equals("wood")) else if (surfaceTag.equals("earth")) surface = DIRT; - surfaceEnc.setEnum(false, edgeFlags, surface); + surfaceEnc.setEnum(false, edgeId, edgeIntAccess, surface); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java index f6ce187dae7..20782dcef7c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.Toll; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.storage.IntsRef; @@ -37,7 +38,7 @@ public OSMTollParser(EnumEncodedValue tollEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { Toll toll; if (readerWay.hasTag("toll", "yes")) { toll = Toll.ALL; @@ -52,7 +53,7 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relati CountryRule countryRule = readerWay.getTag("country_rule", null); if (countryRule != null) toll = countryRule.getToll(readerWay, toll); - - tollEnc.setEnum(false, edgeFlags, toll); + + tollEnc.setEnum(false, edgeId, edgeIntAccess, toll); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParser.java index b492ef7ba36..b0581898448 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParser.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.TrackType; import com.graphhopper.storage.IntsRef; @@ -33,11 +34,11 @@ public OSMTrackTypeParser(EnumEncodedValue trackTypeEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { String trackTypeTag = readerWay.getTag("tracktype"); TrackType trackType = TrackType.find(trackTypeTag); if (trackType != MISSING) - trackTypeEnc.setEnum(false, edgeFlags, trackType); + trackTypeEnc.setEnum(false, edgeId, edgeIntAccess, trackType); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMWayIDParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMWayIDParser.java index 4aac9669bbf..2dd7ea1b5f4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMWayIDParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMWayIDParser.java @@ -19,6 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.IntEncodedValue; import com.graphhopper.storage.IntsRef; @@ -30,12 +31,12 @@ public OSMWayIDParser(IntEncodedValue osmWayIdEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { if (way.getId() > osmWayIdEnc.getMaxStorableInt()) throw new IllegalArgumentException("Cannot store OSM way ID: " + way.getId() + " as it is too large (> " + osmWayIdEnc.getMaxStorableInt() + "). You can disable " + osmWayIdEnc.getName() + " if you do not " + "need to store the OSM way IDs"); int wayId = Math.toIntExact(way.getId()); - osmWayIdEnc.setInt(false, edgeFlags, wayId); + osmWayIdEnc.setInt(false, edgeId, edgeIntAccess, wayId); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java index 2c8165e5056..17be2eef811 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleAccess; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; @@ -19,9 +20,9 @@ public RoadsAccessParser(BooleanEncodedValue accessEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - accessEnc.setBool(true, edgeFlags, true); - accessEnc.setBool(false, edgeFlags, true); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + accessEnc.setBool(true, edgeId, edgeIntAccess, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAverageSpeedParser.java index 7f51d1d25ea..2486b0e52be 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAverageSpeedParser.java @@ -3,6 +3,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; @@ -22,10 +23,10 @@ public RoadsAverageSpeedParser(DecimalEncodedValue avgSpeedEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { // let's make it high and let it be reduced in the custom model - avgSpeedEnc.setDecimal(false, edgeFlags, maxPossibleSpeed); + avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, maxPossibleSpeed); if (avgSpeedEnc.isStoreTwoDirections()) - avgSpeedEnc.setDecimal(true, edgeFlags, maxPossibleSpeed); + avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, maxPossibleSpeed); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/TagParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/TagParser.java index 0ba905ae853..56ae88d9811 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/TagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/TagParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; /** @@ -26,5 +27,5 @@ */ public interface TagParser { - void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags); + void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags); } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java index 5316007e845..83fa8e039d3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java @@ -3,9 +3,9 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleAccess; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import java.util.HashSet; @@ -132,12 +132,12 @@ public WayAccess getAccess(ReaderWay way) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { WayAccess access = getAccess(way); if (access.canSkip()) return; - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAverageSpeedParser.java index 2e3548c79c5..456ad593b15 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAverageSpeedParser.java @@ -3,8 +3,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleSpeed; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import com.graphhopper.util.PointList; @@ -37,19 +37,19 @@ protected WheelchairAverageSpeedParser(DecimalEncodedValue speedEnc) { } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { if (way.hasTag("route", ferries)) { double ferrySpeed = ferrySpeedCalc.getSpeed(way); - setSpeed(edgeFlags, true, true, ferrySpeed); + setSpeed(edgeId, edgeIntAccess, true, true, ferrySpeed); } if (!way.hasTag("railway", "platform") && !way.hasTag("man_made", "pier")) return; } - setSpeed(edgeFlags, true, true, MEAN_SPEED); - applyWayTags(way, edgeFlags); + setSpeed(edgeId, edgeIntAccess, true, true, MEAN_SPEED); + applyWayTags(way, edgeId, edgeIntAccess); } /** @@ -57,7 +57,7 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way) { * and maxInclinePercent will reduce speed to SLOW_SPEED. In-/declines above maxInclinePercent will result in zero * speed. */ - public void applyWayTags(ReaderWay way, IntsRef edgeFlags) { + public void applyWayTags(ReaderWay way, int edgeId, EdgeIntAccess edgeIntAccess) { PointList pl = way.getTag("point_list", null); if (pl == null) throw new IllegalArgumentException("The artificial point_list tag is missing"); @@ -86,8 +86,8 @@ public void applyWayTags(ReaderWay way, IntsRef edgeFlags) { // it can be problematic to exclude roads due to potential bad elevation data (e.g.delta for narrow nodes could be too high) // so exclude only when we are certain if (fullDist2D > 50) { - setSpeed(edgeFlags, true, false, 0); - setSpeed(edgeFlags, true, true, 0); + setSpeed(edgeId, edgeIntAccess, true, false, 0); + setSpeed(edgeId, edgeIntAccess, true, true, 0); return; } @@ -95,7 +95,7 @@ public void applyWayTags(ReaderWay way, IntsRef edgeFlags) { bwdSpeed = SLOW_SPEED; } - if (fwdSpeed > 0) setSpeed(edgeFlags, true, false, fwdSpeed); - if (bwdSpeed > 0) setSpeed(edgeFlags, false, true, bwdSpeed); + if (fwdSpeed > 0) setSpeed(edgeId, edgeIntAccess, true, false, fwdSpeed); + if (bwdSpeed > 0) setSpeed(edgeId, edgeIntAccess, false, true, bwdSpeed); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairPriorityParser.java index 6f25072c84b..a632b91fc2d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairPriorityParser.java @@ -33,9 +33,9 @@ protected WheelchairPriorityParser(DecimalEncodedValue priorityEnc, EnumEncodedV } @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - Integer priorityFromRelation = routeMap.get(footRouteEnc.getEnum(false, edgeFlags)); - priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way, priorityFromRelation))); + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + Integer priorityFromRelation = routeMap.get(footRouteEnc.getEnum(false, edgeId, edgeIntAccess)); + priorityWayEncoder.setDecimal(false, edgeId, edgeIntAccess, PriorityCode.getValue(handlePriority(way, priorityFromRelation))); } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java index ac8ae968108..be0e2da0ad0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java @@ -2,8 +2,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.MaxSpeed; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; import com.graphhopper.util.Helper; import org.slf4j.Logger; @@ -29,13 +29,13 @@ private OSMValueExtractor() { // utility class } - public static void extractTons(IntsRef edgeFlags, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { + public static void extractTons(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { final String rawValue = way.getFirstPriorityTag(keys); double value = stringToTons(rawValue); if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; - valueEncoder.setDecimal(false, edgeFlags, value); + valueEncoder.setDecimal(false, edgeId, edgeIntAccess, value); // too many // if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) // logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); @@ -68,13 +68,13 @@ public static double stringToTons(String value) { } } - public static void extractMeter(IntsRef edgeFlags, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { + public static void extractMeter(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { final String rawValue = way.getFirstPriorityTag(keys); double value = stringToMeter(rawValue); if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; - valueEncoder.setDecimal(false, edgeFlags, value); + valueEncoder.setDecimal(false, edgeId, edgeIntAccess, value); // too many // if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) // logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 741c3de6290..0b5d796d78f 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -363,6 +363,22 @@ private void setWayGeometry_(PointList pillarNodes, long edgePointer, boolean re } } + public EdgeIntAccess createIntAccess() { + return new EdgeIntAccess() { + @Override + public int getInt(int edgeId, int index) { + long edgePointer = store.toEdgePointer(edgeId); + return store.getFlagInt(edgePointer, index); + } + + @Override + public void setInt(int edgeId, int index, int value) { + long edgePointer = store.toEdgePointer(edgeId); + store.setFlagInt(edgePointer, index, value); + } + }; + } + private void setWayGeometryAtGeoRef(PointList pillarNodes, long edgePointer, boolean reverse, long geoRef) { int len = pillarNodes.size(); int dim = nodeAccess.getDimension(); @@ -584,7 +600,6 @@ void goToNext() { boolean baseNodeIsNodeA = baseNode == nodeA; adjNode = baseNodeIsNodeA ? store.getNodeB(edgePointer) : nodeA; reverse = !baseNodeIsNodeA; - refreshFlags = true; // position to next edge nextEdgeId = baseNodeIsNodeA ? store.getLinkA(edgePointer) : store.getLinkB(edgePointer); @@ -621,7 +636,6 @@ public boolean next() { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - refreshFlags = true; reverse = false; return true; } @@ -655,13 +669,12 @@ static class EdgeIteratorStateImpl implements EdgeIteratorState { int adjNode; // we need reverse if detach is called boolean reverse = false; - boolean refreshFlags; int edgeId = -1; - private final IntsRef edgeFlags; + private final EdgeIntAccess edgeIntAccess; public EdgeIteratorStateImpl(BaseGraph baseGraph) { this.baseGraph = baseGraph; - this.edgeFlags = new IntsRef(baseGraph.store.getIntsForFlags()); + edgeIntAccess = baseGraph.createIntAccess(); store = baseGraph.store; } @@ -675,7 +688,6 @@ final boolean init(int edgeId, int expectedAdjNode) { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - refreshFlags = true; if (expectedAdjNode == adjNode || expectedAdjNode == Integer.MIN_VALUE) { reverse = false; @@ -700,7 +712,6 @@ final void init(int edgeKey) { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - refreshFlags = true; if (edgeKey % 2 == 0 || baseNode == adjNode) { reverse = false; @@ -735,10 +746,8 @@ public EdgeIteratorState setDistance(double dist) { @Override public IntsRef getFlags() { - if (refreshFlags) { - store.readFlags(edgePointer, edgeFlags); - refreshFlags = false; - } + IntsRef edgeFlags = new IntsRef(store.getIntsForFlags()); + store.readFlags(edgePointer, edgeFlags); return edgeFlags; } @@ -746,31 +755,28 @@ public IntsRef getFlags() { public final EdgeIteratorState setFlags(IntsRef edgeFlags) { assert edgeId < store.getEdges() : "must be edge but was shortcut: " + edgeId + " >= " + store.getEdges() + ". Use setFlagsAndWeight"; store.writeFlags(edgePointer, edgeFlags); - System.arraycopy(edgeFlags.ints, 0, this.edgeFlags.ints, 0, edgeFlags.ints.length); return this; } @Override public boolean get(BooleanEncodedValue property) { - return property.getBool(reverse, getFlags()); + return property.getBool(reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState set(BooleanEncodedValue property, boolean value) { - property.setBool(reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setBool(reverse, edgeId, edgeIntAccess, value); return this; } @Override public boolean getReverse(BooleanEncodedValue property) { - return property.getBool(!reverse, getFlags()); + return property.getBool(!reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState setReverse(BooleanEncodedValue property, boolean value) { - property.setBool(!reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setBool(!reverse, edgeId, edgeIntAccess, value); return this; } @@ -778,33 +784,30 @@ public EdgeIteratorState setReverse(BooleanEncodedValue property, boolean value) public EdgeIteratorState set(BooleanEncodedValue property, boolean fwd, boolean bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setBool(reverse, getFlags(), fwd); - property.setBool(!reverse, getFlags(), bwd); - store.writeFlags(edgePointer, getFlags()); + property.setBool(reverse, edgeId, edgeIntAccess, fwd); + property.setBool(!reverse, edgeId, edgeIntAccess, bwd); return this; } @Override public int get(IntEncodedValue property) { - return property.getInt(reverse, getFlags()); + return property.getInt(reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState set(IntEncodedValue property, int value) { - property.setInt(reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setInt(reverse, edgeId, edgeIntAccess, value); return this; } @Override public int getReverse(IntEncodedValue property) { - return property.getInt(!reverse, getFlags()); + return property.getInt(!reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState setReverse(IntEncodedValue property, int value) { - property.setInt(!reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setInt(!reverse, edgeId, edgeIntAccess, value); return this; } @@ -812,33 +815,30 @@ public EdgeIteratorState setReverse(IntEncodedValue property, int value) { public EdgeIteratorState set(IntEncodedValue property, int fwd, int bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setInt(reverse, getFlags(), fwd); - property.setInt(!reverse, getFlags(), bwd); - store.writeFlags(edgePointer, getFlags()); + property.setInt(reverse, edgeId, edgeIntAccess, fwd); + property.setInt(!reverse, edgeId, edgeIntAccess, bwd); return this; } @Override public double get(DecimalEncodedValue property) { - return property.getDecimal(reverse, getFlags()); + return property.getDecimal(reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState set(DecimalEncodedValue property, double value) { - property.setDecimal(reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setDecimal(reverse, edgeId, edgeIntAccess, value); return this; } @Override public double getReverse(DecimalEncodedValue property) { - return property.getDecimal(!reverse, getFlags()); + return property.getDecimal(!reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState setReverse(DecimalEncodedValue property, double value) { - property.setDecimal(!reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setDecimal(!reverse, edgeId, edgeIntAccess, value); return this; } @@ -846,33 +846,30 @@ public EdgeIteratorState setReverse(DecimalEncodedValue property, double value) public EdgeIteratorState set(DecimalEncodedValue property, double fwd, double bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setDecimal(reverse, getFlags(), fwd); - property.setDecimal(!reverse, getFlags(), bwd); - store.writeFlags(edgePointer, getFlags()); + property.setDecimal(reverse, edgeId, edgeIntAccess, fwd); + property.setDecimal(!reverse, edgeId, edgeIntAccess, bwd); return this; } @Override public > T get(EnumEncodedValue property) { - return property.getEnum(reverse, getFlags()); + return property.getEnum(reverse, edgeId, edgeIntAccess); } @Override public > EdgeIteratorState set(EnumEncodedValue property, T value) { - property.setEnum(reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setEnum(reverse, edgeId, edgeIntAccess, value); return this; } @Override public > T getReverse(EnumEncodedValue property) { - return property.getEnum(!reverse, getFlags()); + return property.getEnum(!reverse, edgeId, edgeIntAccess); } @Override public > EdgeIteratorState setReverse(EnumEncodedValue property, T value) { - property.setEnum(!reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setEnum(!reverse, edgeId, edgeIntAccess, value); return this; } @@ -880,33 +877,30 @@ public > EdgeIteratorState setReverse(EnumEncodedValue prop public > EdgeIteratorState set(EnumEncodedValue property, T fwd, T bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setEnum(reverse, getFlags(), fwd); - property.setEnum(!reverse, getFlags(), bwd); - store.writeFlags(edgePointer, getFlags()); + property.setEnum(reverse, edgeId, edgeIntAccess, fwd); + property.setEnum(!reverse, edgeId, edgeIntAccess, bwd); return this; } @Override public String get(StringEncodedValue property) { - return property.getString(reverse, getFlags()); + return property.getString(reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState set(StringEncodedValue property, String value) { - property.setString(reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setString(reverse, edgeId, edgeIntAccess, value); return this; } @Override public String getReverse(StringEncodedValue property) { - return property.getString(!reverse, getFlags()); + return property.getString(!reverse, edgeId, edgeIntAccess); } @Override public EdgeIteratorState setReverse(StringEncodedValue property, String value) { - property.setString(!reverse, getFlags(), value); - store.writeFlags(edgePointer, getFlags()); + property.setString(!reverse, edgeId, edgeIntAccess, value); return this; } @@ -914,9 +908,8 @@ public EdgeIteratorState setReverse(StringEncodedValue property, String value) { public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd) { if (!property.isStoreTwoDirections()) throw new IllegalArgumentException("EncodedValue " + property.getName() + " supports only one direction"); - property.setString(reverse, getFlags(), fwd); - property.setString(!reverse, getFlags(), bwd); - store.writeFlags(edgePointer, getFlags()); + property.setString(reverse, edgeId, edgeIntAccess, fwd); + property.setString(!reverse, edgeId, edgeIntAccess, bwd); return this; } diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java b/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java index a84bf523bbd..22100ff69d1 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java @@ -243,13 +243,21 @@ public long toEdgePointer(int edge) { public void readFlags(long edgePointer, IntsRef edgeFlags) { int size = edgeFlags.ints.length; for (int i = 0; i < size; ++i) - edgeFlags.ints[i] = edges.getInt(edgePointer + E_FLAGS + i * 4); + edgeFlags.ints[i] = getFlagInt(edgePointer, i); } public void writeFlags(long edgePointer, IntsRef edgeFlags) { int size = edgeFlags.ints.length; for (int i = 0; i < size; ++i) - edges.setInt(edgePointer + E_FLAGS + i * 4, edgeFlags.ints[i]); + setFlagInt(edgePointer, i, edgeFlags.ints[i]); + } + + public int getFlagInt(long edgePointer, int index) { + return edges.getInt(edgePointer + E_FLAGS + index * 4); + } + + public void setFlagInt(long edgePointer, int index, int value) { + edges.setInt(edgePointer + E_FLAGS + index * 4, value); } public void setNodeA(long edgePointer, int nodeA) { diff --git a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java index b041b9e3d8f..bf1c987d985 100644 --- a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java +++ b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java @@ -18,6 +18,8 @@ package com.graphhopper.storage; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.IntsRefEdgeIntAccess; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.util.EdgeIterator; @@ -92,7 +94,8 @@ public boolean loadExisting() { */ public void set(DecimalEncodedValue turnCostEnc, int fromEdge, int viaNode, int toEdge, double cost) { IntsRef tcFlags = TurnCost.createFlags(); - turnCostEnc.setDecimal(false, tcFlags, cost); + IntsRefEdgeIntAccess intAccess = new IntsRefEdgeIntAccess(tcFlags); + turnCostEnc.setDecimal(false, -1, intAccess, cost); merge(tcFlags, fromEdge, viaNode, toEdge); } @@ -156,7 +159,8 @@ private void merge(IntsRef tcFlags, int fromEdge, int viaNode, int toEdge) { */ public double get(DecimalEncodedValue turnCostEnc, int fromEdge, int viaNode, int toEdge) { IntsRef flags = readFlags(fromEdge, viaNode, toEdge); - return turnCostEnc.getDecimal(false, flags); + IntsRefEdgeIntAccess intAccess = new IntsRefEdgeIntAccess(flags); + return turnCostEnc.getDecimal(false, -1, intAccess); } /** @@ -240,6 +244,7 @@ private class Itr implements Iterator { private int viaNode = -1; private int turnCostIndex = -1; private final IntsRef intsRef = TurnCost.createFlags(); + private final EdgeIntAccess edgeIntAccess = new IntsRefEdgeIntAccess(intsRef); private long turnCostPtr() { return (long) turnCostIndex * BYTES_PER_ENTRY; @@ -263,7 +268,7 @@ public int getToEdge() { @Override public double getCost(DecimalEncodedValue encodedValue) { intsRef.ints[0] = turnCosts.getInt(turnCostPtr() + TC_FLAGS); - return encodedValue.getDecimal(false, intsRef); + return encodedValue.getDecimal(false, -1, edgeIntAccess); } @Override diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index 14adce29b9f..44ca68898a3 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -56,12 +56,12 @@ public String getName() { } @Override - public boolean getBool(boolean reverse, IntsRef ref) { + public boolean getBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess) { return reverse; } @Override - public void setBool(boolean reverse, IntsRef ref, boolean value) { + public void setBool(boolean reverse, int edgeId, EdgeIntAccess edgeIntAccess, boolean value) { throw new IllegalStateException("reverse state cannot be modified"); } diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index f261cb5d507..7e205b3abcf 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -25,6 +25,7 @@ import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.reader.dem.SkadiProvider; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.AllEdgesIterator; @@ -1135,7 +1136,7 @@ public TagParser create(EncodedValueLookup lookup, String name, PMap properties) if (name.equals("road_environment")) parser = new OSMRoadEnvironmentParser(lookup.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class)) { @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) { + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay readerWay, IntsRef relationFlags) { // do not change RoadEnvironment to avoid triggering tunnel interpolation } }; diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 1d2ca29477e..ca9ff5d7398 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -496,22 +496,24 @@ public void testRelation() { osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); - IntsRef edgeFlags = manager.createRelationFlags(); - osmParsers.handleRelationTags(osmRel, edgeFlags); - assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, edgeFlags)); + IntsRef relFlags = manager.createRelationFlags(); + IntsRefEdgeIntAccess intAccess = new IntsRefEdgeIntAccess(relFlags); + int edgeId = 0; + osmParsers.handleRelationTags(osmRel, relFlags); + assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, edgeId, intAccess)); // unchanged network - IntsRef before = IntsRef.deepCopyOf(edgeFlags); - osmParsers.handleRelationTags(osmRel, edgeFlags); - assertEquals(before, edgeFlags); - assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, before)); - assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, edgeFlags)); + IntsRef before = IntsRef.deepCopyOf(relFlags); + osmParsers.handleRelationTags(osmRel, relFlags); + assertEquals(before, relFlags); + assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, edgeId, intAccess)); + assertEquals(RouteNetwork.LOCAL, transformEnc.getEnum(false, edgeId, intAccess)); // overwrite network osmRel.setTag("network", "ncn"); - osmParsers.handleRelationTags(osmRel, edgeFlags); - assertEquals(RouteNetwork.NATIONAL, transformEnc.getEnum(false, edgeFlags)); - assertNotEquals(before, edgeFlags); + osmParsers.handleRelationTags(osmRel, relFlags); + assertEquals(RouteNetwork.NATIONAL, transformEnc.getEnum(false, edgeId, intAccess)); + assertNotEquals(before, relFlags); } @Test @@ -931,7 +933,7 @@ public void testCountries() throws IOException { OSMParsers osmParsers = new OSMParsers(); osmParsers.addWayTagParser(new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); BaseGraph graph = new BaseGraph.Builder(em).create(); - OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig()); + OSMReader reader = new OSMReader(graph, osmParsers, new OSMReaderConfig()); reader.setCountryRuleFactory(new CountryRuleFactory()); reader.setAreaIndex(createCountryIndex()); // there are two edges, both with highway=track, one in Berlin, one in Paris @@ -964,7 +966,7 @@ public void testCurvedWayAlongBorder() throws IOException { OSMParsers osmParsers = new OSMParsers() .addWayTagParser(new CountryParser(countryEnc)); BaseGraph graph = new BaseGraph.Builder(em).create(); - OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig()); + OSMReader reader = new OSMReader(graph, osmParsers, new OSMReaderConfig()); reader.setCountryRuleFactory(new CountryRuleFactory()); reader.setAreaIndex(createCountryIndex()); reader.setFile(new File(getClass().getResource("test-osm12.xml").getFile())); diff --git a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java index b5b9f47ab24..f327f52475d 100644 --- a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java +++ b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java @@ -95,7 +95,7 @@ public void testPerformanceForRandomTrafficChange(Fixture f) throws IOException LOGGER.info("Running performance test, max deviation percentage: " + f.maxDeviationPercentage); // read osm - OSMReader reader = new OSMReader(f.graph, f.em, f.osmParsers, new OSMReaderConfig()); + OSMReader reader = new OSMReader(f.graph, f.osmParsers, new OSMReaderConfig()); reader.setFile(new File(OSM_FILE)); reader.readGraph(); f.graph.freeze(); diff --git a/core/src/test/java/com/graphhopper/routing/ev/BooleanEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/BooleanEncodedValueTest.java index 784ca09ea46..54247797256 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/BooleanEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/BooleanEncodedValueTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -16,11 +15,12 @@ public void testBit() { BooleanEncodedValue bool = new SimpleBooleanEncodedValue("access", false); bool.init(config); - IntsRef ref = new IntsRef(1); - bool.setBool(false, ref, false); - assertFalse(bool.getBool(false, ref)); - bool.setBool(false, ref, true); - assertTrue(bool.getBool(false, ref)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + bool.setBool(false, edgeId, edgeIntAccess, false); + assertFalse(bool.getBool(false, edgeId, edgeIntAccess)); + bool.setBool(false, edgeId, edgeIntAccess, true); + assertTrue(bool.getBool(false, edgeId, edgeIntAccess)); } @Test @@ -28,11 +28,12 @@ public void testBitDirected() { EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); BooleanEncodedValue bool = new SimpleBooleanEncodedValue("access", true); bool.init(config); - IntsRef ref = new IntsRef(1); - bool.setBool(false, ref, false); - bool.setBool(true, ref, true); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + bool.setBool(false, edgeId, edgeIntAccess, false); + bool.setBool(true, edgeId, edgeIntAccess, true); - assertFalse(bool.getBool(false, ref)); - assertTrue(bool.getBool(true, ref)); + assertFalse(bool.getBool(false, edgeId, edgeIntAccess)); + assertTrue(bool.getBool(true, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 2e65dc92ee3..3fdb38cf5aa 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import java.util.Random; @@ -14,33 +13,35 @@ public void getDecimal() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 1, false); testEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); - assertEquals(0, testEnc.getDecimal(false, intsRef), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + assertEquals(0, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - testEnc.setDecimal(false, intsRef, 7); - assertEquals(7, testEnc.getDecimal(false, intsRef), .1); + testEnc.setDecimal(false, edgeId, edgeIntAccess, 7); + assertEquals(7, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test public void setMaxToInfinity() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 0, 1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); - assertEquals(0, testEnc.getDecimal(false, intsRef), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + assertEquals(0, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); assertTrue(Double.isInfinite(testEnc.getMaxOrMaxStorableDecimal())); assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); assertTrue(Double.isInfinite(testEnc.getNextStorableValue(7))); assertEquals(6, testEnc.getNextStorableValue(6)); - testEnc.setDecimal(false, intsRef, 5); - assertEquals(5, testEnc.getDecimal(false, intsRef), .1); + testEnc.setDecimal(false, edgeId, edgeIntAccess, 5); + assertEquals(5, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); assertEquals(5, testEnc.getMaxOrMaxStorableDecimal()); assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); - testEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); - assertEquals(Double.POSITIVE_INFINITY, testEnc.getDecimal(false, intsRef), .1); + testEnc.setDecimal(false, edgeId, edgeIntAccess, Double.POSITIVE_INFINITY); + assertEquals(Double.POSITIVE_INFINITY, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); assertTrue(Double.isInfinite(testEnc.getMaxOrMaxStorableDecimal())); assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); } @@ -49,13 +50,14 @@ public void setMaxToInfinity() { public void testNegative() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; // a bit ugly: the default is the minimum not 0 - assertEquals(-6, testEnc.getDecimal(false, intsRef), .1); + assertEquals(-6, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - testEnc.setDecimal(false, intsRef, -5.5); - assertEquals(-5.5, testEnc.getDecimal(false, intsRef), .1); - assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); + testEnc.setDecimal(false, edgeId, edgeIntAccess, -5.5); + assertEquals(-5.5, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(-5.5, testEnc.getDecimal(true, edgeId, edgeIntAccess), .1); Exception e = assertThrows(IllegalArgumentException.class, () -> { new DecimalEncodedValueImpl("test", 3, -6, 0.11, false, false, true); @@ -67,50 +69,53 @@ public void testNegative() { public void testInfinityWithMinValue() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); - testEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); - assertEquals(Double.POSITIVE_INFINITY, testEnc.getDecimal(false, intsRef), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + testEnc.setDecimal(false, edgeId, edgeIntAccess, Double.POSITIVE_INFINITY); + assertEquals(Double.POSITIVE_INFINITY, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test public void testNegateReverse() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 4, 0, 0.5, true, false, false); testEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); - testEnc.setDecimal(false, intsRef, 5.5); - assertEquals(5.5, testEnc.getDecimal(false, intsRef), .1); - assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + testEnc.setDecimal(false, edgeId, edgeIntAccess, 5.5); + assertEquals(5.5, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(-5.5, testEnc.getDecimal(true, edgeId, edgeIntAccess), .1); - testEnc.setDecimal(false, intsRef, -5.5); - assertEquals(-5.5, testEnc.getDecimal(false, intsRef), .1); - assertEquals(5.5, testEnc.getDecimal(true, intsRef), .1); + testEnc.setDecimal(false, edgeId, edgeIntAccess, -5.5); + assertEquals(-5.5, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(5.5, testEnc.getDecimal(true, edgeId, edgeIntAccess), .1); EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); new DecimalEncodedValueImpl("tmp1", 5, 1, false).init(config); testEnc = new DecimalEncodedValueImpl("tmp2", 5, 0, 1, true, false, false); testEnc.init(config); - intsRef = new IntsRef(1); - testEnc.setDecimal(true, intsRef, 2.6); - assertEquals(-3, testEnc.getDecimal(false, intsRef), .1); - assertEquals(3, testEnc.getDecimal(true, intsRef), .1); - - testEnc.setDecimal(true, intsRef, -2.6); - assertEquals(3, testEnc.getDecimal(false, intsRef), .1); - assertEquals(-3, testEnc.getDecimal(true, intsRef), .1); + edgeIntAccess = new ArrayEdgeIntAccess(1); + testEnc.setDecimal(true, edgeId, edgeIntAccess, 2.6); + assertEquals(-3, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(3, testEnc.getDecimal(true, edgeId, edgeIntAccess), .1); + + testEnc.setDecimal(true, edgeId, edgeIntAccess, -2.6); + assertEquals(3, testEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(-3, testEnc.getDecimal(true, edgeId, edgeIntAccess), .1); } @Test public void testNextStorableValue() { DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 3, false); enc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; // some values can be stored... - enc.setDecimal(false, intsRef, 3); - assertEquals(3, enc.getDecimal(false, intsRef)); + enc.setDecimal(false, edgeId, edgeIntAccess, 3); + assertEquals(3, enc.getDecimal(false, edgeId, edgeIntAccess)); // ... and some cannot: - enc.setDecimal(false, intsRef, 5); - assertEquals(6, enc.getDecimal(false, intsRef)); + enc.setDecimal(false, edgeId, edgeIntAccess, 5); + assertEquals(6, enc.getDecimal(false, edgeId, edgeIntAccess)); // getNextStorableValue tells us the next highest value we can store without such modification between set/get assertEquals(0, enc.getNextStorableValue(0)); @@ -132,8 +137,8 @@ public void testNextStorableValue() { double value = rnd.nextDouble() * 45; double nextStorable = enc.getNextStorableValue(value); assertTrue(nextStorable >= value, "next storable value should be larger than the value"); - enc.setDecimal(false, intsRef, nextStorable); - assertEquals(nextStorable, enc.getDecimal(false, intsRef), "next storable value should be returned without modification"); + enc.setDecimal(false, edgeId, edgeIntAccess, nextStorable); + assertEquals(nextStorable, enc.getDecimal(false, edgeId, edgeIntAccess), "next storable value should be returned without modification"); } } @@ -154,11 +159,12 @@ public void smallestNonZeroValue() { private void assertSmallestNonZeroValue(DecimalEncodedValueImpl enc, double expected) { enc.init(new EncodedValue.InitializerConfig()); assertEquals(expected, enc.getSmallestNonZeroValue()); - IntsRef intsRef = new IntsRef(1); - enc.setDecimal(false, intsRef, enc.getSmallestNonZeroValue()); - assertEquals(expected, enc.getDecimal(false, intsRef)); - enc.setDecimal(false, intsRef, enc.getSmallestNonZeroValue() / 2 - 0.01); - assertEquals(0, enc.getDecimal(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + enc.setDecimal(false, edgeId, edgeIntAccess, enc.getSmallestNonZeroValue()); + assertEquals(expected, enc.getDecimal(false, edgeId, edgeIntAccess)); + enc.setDecimal(false, edgeId, edgeIntAccess, enc.getSmallestNonZeroValue() / 2 - 0.01); + assertEquals(0, enc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -171,12 +177,13 @@ public void testNextStorableValue_maxInfinity() { assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(42.1)); assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(45)); assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(45.1)); - IntsRef intsRef = new IntsRef(1); - enc.setDecimal(false, intsRef, 45); - assertEquals(42, enc.getDecimal(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + enc.setDecimal(false, edgeId, edgeIntAccess, 45); + assertEquals(42, enc.getDecimal(false, edgeId, edgeIntAccess)); - enc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); - assertEquals(Double.POSITIVE_INFINITY, enc.getDecimal(false, intsRef)); + enc.setDecimal(false, edgeId, edgeIntAccess, Double.POSITIVE_INFINITY); + assertEquals(Double.POSITIVE_INFINITY, enc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -184,16 +191,17 @@ public void lowestUpperBound_with_negateReverseDirection() { DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, true, false, false); enc.init(new EncodedValue.InitializerConfig()); assertEquals(15 * 3, enc.getMaxOrMaxStorableDecimal()); - IntsRef ints = new IntsRef(1); - enc.setDecimal(false, ints, 3); - assertEquals(3, enc.getDecimal(false, ints)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + enc.setDecimal(false, edgeId, edgeIntAccess, 3); + assertEquals(3, enc.getDecimal(false, edgeId, edgeIntAccess)); assertEquals(3, enc.getMaxOrMaxStorableDecimal()); - enc.setDecimal(true, ints, -6); - assertEquals(6, enc.getDecimal(false, ints)); + enc.setDecimal(true, edgeId, edgeIntAccess, -6); + assertEquals(6, enc.getDecimal(false, edgeId, edgeIntAccess)); assertEquals(6, enc.getMaxOrMaxStorableDecimal()); // note that the maximum is never lowered, even when we lower the value for the 'same' edge flags - enc.setDecimal(false, ints, 0); - assertEquals(0, enc.getDecimal(false, ints)); + enc.setDecimal(false, edgeId, edgeIntAccess, 0); + assertEquals(0, enc.getDecimal(false, edgeId, edgeIntAccess)); assertEquals(6, enc.getMaxOrMaxStorableDecimal()); } @@ -203,8 +211,9 @@ public void minStorableBug() { enc.init(new EncodedValue.InitializerConfig()); assertEquals(3.2, enc.getMaxStorableDecimal()); - IntsRef flags = new IntsRef(1); - enc.setDecimal(true, flags, 1.6); - assertEquals(1.6, enc.getDecimal(true, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + enc.setDecimal(true, edgeId, edgeIntAccess, 1.6); + assertEquals(1.6, enc.getDecimal(true, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java index 7445b2c1cc5..e079585f465 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java @@ -1,7 +1,6 @@ package com.graphhopper.routing.ev; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,24 +12,28 @@ public class DecimalEncodedValueTest { public void testInit() { DecimalEncodedValue prop = new DecimalEncodedValueImpl("test", 10, 2, false); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(1); - prop.setDecimal(false, ref, 10d); - assertEquals(10d, prop.getDecimal(false, ref), 0.1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + prop.setDecimal(false, edgeId, edgeIntAccess, 10d); + assertEquals(10d, prop.getDecimal(false, edgeId, edgeIntAccess), 0.1); } @Test public void testMaxValue() { DecimalEncodedValue ev = new DecimalEncodedValueImpl("test1", 8, 0.5, false); - EncodingManager em = EncodingManager.start().add(ev).build(); - IntsRef flags = em.createEdgeFlags(); - ev.setDecimal(false, flags, 100d); - assertEquals(100, ev.getDecimal(false, flags), 1e-1); + EncodingManager.start().add(ev).build(); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + ev.setDecimal(false, edgeId, edgeIntAccess, 100d); + assertEquals(100, ev.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test public void testNegativeBounds() { DecimalEncodedValue prop = new DecimalEncodedValueImpl("test", 10, 5, false); prop.init(new EncodedValue.InitializerConfig()); - assertThrows(Exception.class, () -> prop.setDecimal(false, new IntsRef(1), -1)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + assertThrows(Exception.class, () -> prop.setDecimal(false, edgeId, edgeIntAccess, -1)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java index 32d03bb64d0..97eb66b79ba 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -15,13 +14,13 @@ public void testInit() { assertEquals(5, prop.bits); assertEquals(0, init.dataIndex); assertEquals(0, init.shift); - IntsRef ref = new IntsRef(1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); // default if empty - ref.ints[0] = 0; - assertEquals(RoadClass.OTHER, prop.getEnum(false, ref)); + intAccess.setInt(0, 0, 0); + assertEquals(RoadClass.OTHER, prop.getEnum(false, 0, intAccess)); - prop.setEnum(false, ref, RoadClass.SECONDARY); - assertEquals(RoadClass.SECONDARY, prop.getEnum(false, ref)); + prop.setEnum(false, 0, intAccess, RoadClass.SECONDARY); + assertEquals(RoadClass.SECONDARY, prop.getEnum(false, 0, intAccess)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/ev/IntEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/IntEncodedValueImplTest.java index d65c2599a42..bec8f00dc37 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/IntEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/IntEncodedValueImplTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -15,7 +14,7 @@ public void testInvalidReverseAccess() { IntEncodedValue prop = new IntEncodedValueImpl("test", 10, false); prop.init(new EncodedValue.InitializerConfig()); try { - prop.setInt(true, new IntsRef(1), -1); + prop.setInt(true, 0, createIntAccess(1), -1); fail(); } catch (Exception ex) { } @@ -25,42 +24,42 @@ public void testInvalidReverseAccess() { public void testDirectedValue() { IntEncodedValue prop = new IntEncodedValueImpl("test", 10, true); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(1); - prop.setInt(false, ref, 10); - prop.setInt(true, ref, 20); - assertEquals(10, prop.getInt(false, ref)); - assertEquals(20, prop.getInt(true, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(1); + prop.setInt(false, 0, edgeIntAccess, 10); + prop.setInt(true, 0, edgeIntAccess, 20); + assertEquals(10, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(20, prop.getInt(true, 0, edgeIntAccess)); } @Test public void multiIntsUsage() { IntEncodedValue prop = new IntEncodedValueImpl("test", 31, true); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(2); - prop.setInt(false, ref, 10); - prop.setInt(true, ref, 20); - assertEquals(10, prop.getInt(false, ref)); - assertEquals(20, prop.getInt(true, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(2); + prop.setInt(false, 0, edgeIntAccess, 10); + prop.setInt(true, 0, edgeIntAccess, 20); + assertEquals(10, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(20, prop.getInt(true, 0, edgeIntAccess)); } @Test public void padding() { IntEncodedValue prop = new IntEncodedValueImpl("test", 30, true); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(2); - prop.setInt(false, ref, 10); - prop.setInt(true, ref, 20); - assertEquals(10, prop.getInt(false, ref)); - assertEquals(20, prop.getInt(true, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(2); + prop.setInt(false, 0, edgeIntAccess, 10); + prop.setInt(true, 0, edgeIntAccess, 20); + assertEquals(10, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(20, prop.getInt(true, 0, edgeIntAccess)); } @Test public void maxValue() { IntEncodedValue prop = new IntEncodedValueImpl("test", 31, false); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(2); - prop.setInt(false, ref, (1 << 31) - 1); - assertEquals(2_147_483_647L, prop.getInt(false, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(2); + prop.setInt(false, 0, edgeIntAccess, (1 << 31) - 1); + assertEquals(2_147_483_647L, prop.getInt(false, 0, edgeIntAccess)); } @Test @@ -69,15 +68,15 @@ public void testSignedInt() { EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); prop.init(config); - IntsRef ref = new IntsRef(1); + EdgeIntAccess edgeIntAccess = createIntAccess(1); Exception exception = assertThrows(IllegalArgumentException.class, () -> { - prop.setInt(false, ref, Integer.MAX_VALUE); + prop.setInt(false, 0, edgeIntAccess, Integer.MAX_VALUE); }); assertTrue(exception.getMessage().contains("test value too large for encoding"), exception.getMessage()); - prop.setInt(false, ref, -5); - assertEquals(-5, prop.getInt(false, ref)); - assertEquals(-5, prop.getInt(false, ref)); + prop.setInt(false, 0, edgeIntAccess, -5); + assertEquals(-5, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(-5, prop.getInt(false, 0, edgeIntAccess)); } @Test @@ -86,12 +85,12 @@ public void testSignedInt2() { EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); prop.init(config); - IntsRef ref = new IntsRef(1); - prop.setInt(false, ref, Integer.MAX_VALUE); - assertEquals(Integer.MAX_VALUE, prop.getInt(false, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(1); + prop.setInt(false, 0, edgeIntAccess, Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, prop.getInt(false, 0, edgeIntAccess)); Exception exception = assertThrows(IllegalArgumentException.class, () -> { - prop.setInt(false, ref, -5); + prop.setInt(false, 0, edgeIntAccess, -5); }); assertTrue(exception.getMessage().contains("test value too small for encoding"), exception.getMessage()); } @@ -102,18 +101,18 @@ public void testNegateReverseDirection() { EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); prop.init(config); - IntsRef ref = new IntsRef(1); - prop.setInt(false, ref, 5); - assertEquals(5, prop.getInt(false, ref)); - assertEquals(-5, prop.getInt(true, ref)); + EdgeIntAccess edgeIntAccess = createIntAccess(1); + prop.setInt(false, 0, edgeIntAccess, 5); + assertEquals(5, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(-5, prop.getInt(true, 0, edgeIntAccess)); - prop.setInt(true, ref, 2); - assertEquals(-2, prop.getInt(false, ref)); - assertEquals(2, prop.getInt(true, ref)); + prop.setInt(true, 0, edgeIntAccess, 2); + assertEquals(-2, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(2, prop.getInt(true, 0, edgeIntAccess)); - prop.setInt(false, ref, -3); - assertEquals(-3, prop.getInt(false, ref)); - assertEquals(3, prop.getInt(true, ref)); + prop.setInt(false, 0, edgeIntAccess, -3); + assertEquals(-3, prop.getInt(false, 0, edgeIntAccess)); + assertEquals(3, prop.getInt(true, 0, edgeIntAccess)); } @Test @@ -132,4 +131,8 @@ public void testEncodedValueName() { assertFalse(isValidEncodedValue(str), str); } } + + private static ArrayEdgeIntAccess createIntAccess(int ints) { + return new ArrayEdgeIntAccess(ints); + } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/MaxWeightTest.java b/core/src/test/java/com/graphhopper/routing/ev/MaxWeightTest.java index 652d65030fe..d5245b0c0fd 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/MaxWeightTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/MaxWeightTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,12 +10,13 @@ public class MaxWeightTest { public void testSetAndGet() { DecimalEncodedValue mappedDecimalEnc = MaxWeight.create(); mappedDecimalEnc.init(new EncodedValue.InitializerConfig()); - IntsRef intsRef = new IntsRef(1); - mappedDecimalEnc.setDecimal(false, intsRef, 20); - assertEquals(20, mappedDecimalEnc.getDecimal(false, intsRef), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + mappedDecimalEnc.setDecimal(false, edgeId, edgeIntAccess, 20); + assertEquals(20, mappedDecimalEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - intsRef = new IntsRef(1); - mappedDecimalEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); - assertEquals(Double.POSITIVE_INFINITY, mappedDecimalEnc.getDecimal(false, intsRef), .1); + edgeIntAccess = new ArrayEdgeIntAccess(1); + mappedDecimalEnc.setDecimal(false, edgeId, edgeIntAccess, Double.POSITIVE_INFINITY); + assertEquals(Double.POSITIVE_INFINITY, mappedDecimalEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/StringEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/StringEncodedValueTest.java index 82b0f8082d0..6b411317211 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/StringEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/StringEncodedValueTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.ev; -import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -58,8 +57,8 @@ public void testNull() { StringEncodedValue prop = new StringEncodedValue("country", 3); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(1); - prop.setString(false, ref, null); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + prop.setString(false, 0, edgeIntAccess, null); assertEquals(0, prop.getValues().size()); } @@ -80,24 +79,24 @@ public void testLookup() { StringEncodedValue prop = new StringEncodedValue("country", 3); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(1); - assertEquals(null, prop.getString(false, ref)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + assertEquals(null, prop.getString(false, 0, edgeIntAccess)); assertEquals(0, prop.getValues().size()); - prop.setString(false, ref, "aut"); - assertEquals("aut", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "aut"); + assertEquals("aut", prop.getString(false, 0, edgeIntAccess)); assertEquals(1, prop.getValues().size()); - prop.setString(false, ref, "deu"); - assertEquals("deu", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "deu"); + assertEquals("deu", prop.getString(false, 0, edgeIntAccess)); assertEquals(2, prop.getValues().size()); - prop.setString(false, ref, "che"); - assertEquals("che", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "che"); + assertEquals("che", prop.getString(false, 0, edgeIntAccess)); assertEquals(3, prop.getValues().size()); - prop.setString(false, ref, "deu"); - assertEquals("deu", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "deu"); + assertEquals("deu", prop.getString(false, 0, edgeIntAccess)); assertEquals(3, prop.getValues().size()); } @@ -106,20 +105,20 @@ public void testStoreTooManyEntries() { StringEncodedValue prop = new StringEncodedValue("country", 3); prop.init(new EncodedValue.InitializerConfig()); - IntsRef ref = new IntsRef(1); - assertEquals(null, prop.getString(false, ref)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + assertEquals(null, prop.getString(false, 0, edgeIntAccess)); - prop.setString(false, ref, "aut"); - assertEquals("aut", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "aut"); + assertEquals("aut", prop.getString(false, 0, edgeIntAccess)); - prop.setString(false, ref, "deu"); - assertEquals("deu", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "deu"); + assertEquals("deu", prop.getString(false, 0, edgeIntAccess)); - prop.setString(false, ref, "che"); - assertEquals("che", prop.getString(false, ref)); + prop.setString(false, 0, edgeIntAccess, "che"); + assertEquals("che", prop.getString(false, 0, edgeIntAccess)); try { - prop.setString(false, ref, "xyz"); + prop.setString(false, 0, edgeIntAccess, "xyz"); fail("The encoded value should only allow a limited number of values"); } catch (IllegalStateException e) { assertTrue(e.getMessage().startsWith("Maximum number of values reached for")); diff --git a/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java index 58c98672d74..3405025ac6d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java @@ -1,12 +1,8 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.ArrayEdgeIntAccess; import com.graphhopper.routing.ev.Curvature; -import com.graphhopper.storage.BaseGraph; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.storage.NodeAccess; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.Helper; import com.graphhopper.util.PointList; import org.junit.jupiter.api.Test; @@ -19,13 +15,14 @@ class CurvatureCalculatorTest { @Test public void testCurvature() { CurvatureCalculator calculator = new CurvatureCalculator(em.getDecimalEncodedValue(Curvature.KEY)); - IntsRef ints = em.createEdgeFlags(); - calculator.handleWayTags(ints, getStraightWay(), null); - double valueStraight = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, ints); - - ints = em.createEdgeFlags(); - calculator.handleWayTags(ints, getCurvyWay(), null); - double valueCurvy = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, ints); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + calculator.handleWayTags(edgeId, intAccess, getStraightWay(), null); + double valueStraight = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, edgeId, intAccess); + + intAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + calculator.handleWayTags(edgeId, intAccess, getCurvyWay(), null); + double valueCurvy = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, edgeId, intAccess); assertTrue(valueCurvy < valueStraight, "The bendiness of the straight road is smaller than the one of the curvy road"); } diff --git a/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java index dd035d00717..0a66a3b2811 100644 --- a/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.AverageSlope; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.MaxSlope; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PointList; import org.junit.jupiter.api.Test; @@ -18,7 +16,8 @@ void simpleElevation() { DecimalEncodedValue maxEnc = MaxSlope.create(); new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); - IntsRef edgeRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay way = new ReaderWay(1L); PointList pointList = new PointList(5, true); pointList.add(51.0, 12.001, 0); @@ -26,13 +25,13 @@ void simpleElevation() { pointList.add(51.0, 12.003, 4); // ~140m pointList.add(51.0, 12.004, 2); // ~210m way.setTag("point_list", pointList); - creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + creator.handleWayTags(edgeId, edgeIntAccess, way, IntsRef.EMPTY); - assertEquals(Math.round(2.0 / 210 * 100), averageEnc.getDecimal(false, edgeRef), 1e-3); - assertEquals(-Math.round(2.0 / 210 * 100), averageEnc.getDecimal(true, edgeRef), 1e-3); + assertEquals(Math.round(2.0 / 210 * 100), averageEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-3); + assertEquals(-Math.round(2.0 / 210 * 100), averageEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-3); - assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(false, edgeRef), 1e-3); - assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(true, edgeRef), 1e-3); + assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-3); + assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-3); } @Test @@ -42,7 +41,8 @@ public void testAveragingOfMaxSlope() { DecimalEncodedValue maxEnc = MaxSlope.create(); new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); - IntsRef edgeRef = new IntsRef(1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay way = new ReaderWay(1L); PointList pointList = new PointList(5, true); pointList.add(51.0, 12.0010, 10); @@ -51,10 +51,10 @@ public void testAveragingOfMaxSlope() { pointList.add(51.0, 12.0054, 0); // 140m pointList.add(51.0, 12.0070, 7); // 112m way.setTag("point_list", pointList); - creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + creator.handleWayTags(edgeId, intAccess, way, IntsRef.EMPTY); - assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(false, edgeRef), 1e-3); - assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(true, edgeRef), 1e-3); + assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(false, edgeId, intAccess), 1e-3); + assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(true, edgeId, intAccess), 1e-3); } @Test @@ -65,19 +65,21 @@ public void test2() { pointList.add(47.7283135, 11.9991135, 1178.0); ReaderWay way = new ReaderWay(1); way.setTag("point_list", pointList); - IntsRef edgeRef = new IntsRef(1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; DecimalEncodedValue averageEnc = AverageSlope.create(); DecimalEncodedValue maxEnc = MaxSlope.create(); new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); - creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); - assertEquals(31, maxEnc.getDecimal(false, edgeRef), 1e-3); - assertEquals(31, averageEnc.getDecimal(false, edgeRef), 1e-3); + creator.handleWayTags(edgeId, intAccess, way, IntsRef.EMPTY); + assertEquals(31, maxEnc.getDecimal(false, edgeId, intAccess), 1e-3); + assertEquals(31, averageEnc.getDecimal(false, edgeId, intAccess), 1e-3); } @Test public void test2D() { - IntsRef edgeRef = new IntsRef(1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; PointList pointList = new PointList(5, false); pointList.add(47.7283135, 11.9991135); ReaderWay way = new ReaderWay(1); @@ -87,8 +89,8 @@ public void test2D() { new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); - creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); - assertEquals(0, maxEnc.getDecimal(false, edgeRef), 1e-3); - assertEquals(0, averageEnc.getDecimal(false, edgeRef), 1e-3); + creator.handleWayTags(edgeId, intAccess, way, IntsRef.EMPTY); + assertEquals(0, maxEnc.getDecimal(false, edgeId, intAccess), 1e-3); + assertEquals(0, averageEnc.getDecimal(false, edgeId, intAccess), 1e-3); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index dfcde5129ba..2e0be12b13d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -73,9 +73,10 @@ public void setUp() { protected void assertPriority(int expectedPrio, ReaderWay way) { IntsRef relFlags = osmParsers.handleRelationTags(new ReaderRelation(0), osmParsers.createRelationFlags()); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, way, relFlags); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeFlags), 0.01); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); + assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); } protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way) { @@ -84,18 +85,20 @@ protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, Re protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way, ReaderRelation rel) { IntsRef relFlags = osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags()); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, way, relFlags); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeFlags), 0.01); - assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(false, edgeFlags), 0.1); - assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(true, edgeFlags), 0.1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); + assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); + assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(false, edgeId, intAccess), 0.1); + assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(true, edgeId, intAccess), 0.1); } protected double getSpeedFromFlags(ReaderWay way) { IntsRef relFlags = osmParsers.createRelationFlags(); - IntsRef flags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(flags, way, relFlags); - return avgSpeedEnc.getDecimal(false, flags); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); + return avgSpeedEnc.getDecimal(false, edgeId, intAccess); } @Test @@ -259,10 +262,11 @@ public void testRelation() { // two relation tags => we currently cannot store a list, so pick the lower ordinal 'regional' // Example https://www.openstreetmap.org/way/213492914 => two hike 84544, 2768803 and two bike relations 3162932, 5254650 IntsRef relFlags = osmParsers.handleRelationTags(rel2, osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags())); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, way, relFlags); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); EnumEncodedValue enc = encodingManager.getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class); - assertEquals(RouteNetwork.REGIONAL, enc.getEnum(false, edgeFlags)); + assertEquals(RouteNetwork.REGIONAL, enc.getEnum(false, edgeId, intAccess)); } @Test @@ -288,30 +292,31 @@ public void testTramStations() { way = new ReaderWay(1); way.setTag("railway", "platform"); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way, null); - speedParser.handleWayTags(edgeFlags, way, null); - assertEquals(4.0, avgSpeedEnc.getDecimal(false, edgeFlags)); - assertTrue(accessEnc.getBool(false, edgeFlags)); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, intAccess, way, null); + speedParser.handleWayTags(edgeId, intAccess, way, null); + assertEquals(4.0, avgSpeedEnc.getDecimal(false, edgeId, intAccess)); + assertTrue(accessEnc.getBool(false, edgeId, intAccess)); way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("railway", "platform"); - accessParser.handleWayTags(edgeFlags = encodingManager.createEdgeFlags(), way, null); - assertTrue(accessEnc.getBool(false, edgeFlags)); + accessParser.handleWayTags(edgeId, intAccess, way, null); + assertTrue(accessEnc.getBool(false, edgeId, intAccess)); - speedParser.handleWayTags(edgeFlags, way, null); - assertEquals(4, avgSpeedEnc.getDecimal(false, edgeFlags)); + speedParser.handleWayTags(edgeId, intAccess, way, null); + assertEquals(4, avgSpeedEnc.getDecimal(false, edgeId, intAccess)); way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("railway", "platform"); way.setTag("bicycle", "no"); - edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way); - assertEquals(0.0, avgSpeedEnc.getDecimal(false, edgeFlags)); - assertFalse(accessEnc.getBool(false, edgeFlags)); + intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, intAccess, way); + assertEquals(0.0, avgSpeedEnc.getDecimal(false, edgeId, intAccess)); + assertFalse(accessEnc.getBool(false, edgeId, intAccess)); } @Test @@ -385,9 +390,10 @@ public void testHandleWayTagsCallsHandlePriority() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "cycleway"); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - priorityParser.handleWayTags(edgeFlags, osmWay, null); - assertEquals(PriorityCode.getValue(VERY_NICE.getValue()), priorityEnc.getDecimal(false, edgeFlags), 1e-3); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + priorityParser.handleWayTags(edgeId, intAccess, osmWay, null); + assertEquals(PriorityCode.getValue(VERY_NICE.getValue()), priorityEnc.getDecimal(false, edgeId, intAccess), 1e-3); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 1f58807f020..662e8eae6f2 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -20,9 +20,7 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BikeNetwork; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.RouteNetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.VehicleEncodedValues; @@ -372,163 +370,164 @@ public void testWayAcceptance() { public void testOneway() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "tertiary"); - IntsRef flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.setTag("oneway", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertFalse(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway:bicycle", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertFalse(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("oneway:bicycle", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("oneway:bicycle", "-1"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("cycleway:right:oneway", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("cycleway:right:oneway", "-1"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("vehicle:forward", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("bicycle:forward", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("vehicle:backward", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertFalse(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("motor_vehicle:backward", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("bicycle:backward", "no"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertFalse(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.setTag("bicycle:backward", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "residential"); way.setTag("oneway", "yes"); way.setTag("bicycle:backward", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "residential"); way.setTag("oneway", "-1"); way.setTag("bicycle:forward", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("bicycle:forward", "use_sidepath"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("bicycle:forward", "use_sidepath"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("oneway", "yes"); way.setTag("cycleway", "opposite"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "residential"); way.setTag("oneway", "yes"); way.setTag("cycleway:left", "opposite_lane"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, flags)); - assertTrue(accessParser.getAccessEnc().getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); } @Test @@ -610,28 +609,29 @@ public void testCalcPriority() { osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "icn"); IntsRef relFlags = osmParsers.handleRelationTags(osmRel, osmParsers.createRelationFlags()); - IntsRef flags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(flags, osmWay, relFlags); - assertEquals(RouteNetwork.INTERNATIONAL, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); - assertEquals(PriorityCode.getValue(BEST.getValue()), priorityEnc.getDecimal(false, flags), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, edgeIntAccess, osmWay, relFlags); + assertEquals(RouteNetwork.INTERNATIONAL, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, edgeId, edgeIntAccess)); + assertEquals(PriorityCode.getValue(BEST.getValue()), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), .1); // for some highways the priority is UNCHANGED osmRel = new ReaderRelation(1); osmWay = new ReaderWay(1); osmWay.setTag("highway", "track"); - flags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(flags, osmWay, osmParsers.createRelationFlags()); - assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); - assertEquals(PriorityCode.getValue(UNCHANGED.getValue()), priorityEnc.getDecimal(false, flags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + osmParsers.handleWayTags(edgeId, edgeIntAccess, osmWay, osmParsers.createRelationFlags()); + assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, edgeId, edgeIntAccess)); + assertEquals(PriorityCode.getValue(UNCHANGED.getValue()), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), .1); // unknown highway tags will be excluded but priority will be unchanged osmWay = new ReaderWay(1); osmWay.setTag("highway", "whatever"); - flags = encodingManager.createEdgeFlags(); - osmParsers.handleWayTags(flags, osmWay, osmParsers.createRelationFlags()); - assertFalse(accessParser.getAccessEnc().getBool(false, flags)); - assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); - assertEquals(PriorityCode.getValue(UNCHANGED.getValue()), priorityEnc.getDecimal(false, flags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + osmParsers.handleWayTags(edgeId, edgeIntAccess, osmWay, osmParsers.createRelationFlags()); + assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, edgeId, edgeIntAccess)); + assertEquals(PriorityCode.getValue(UNCHANGED.getValue()), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java index d1206437d4f..67db4c51f10 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java @@ -24,7 +24,6 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -200,49 +199,50 @@ public void testFordAccess() { public void testOneway() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); - IntsRef flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertTrue(accessEnc.getBool(false, flags)); - assertTrue(accessEnc.getBool(true, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.setTag("oneway", "yes"); - flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertTrue(accessEnc.getBool(false, flags)); - assertFalse(accessEnc.getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); - flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertTrue(accessEnc.getBool(false, flags)); - assertTrue(accessEnc.getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("vehicle:forward", "no"); - flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertFalse(accessEnc.getBool(false, flags)); - assertTrue(accessEnc.getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("vehicle:backward", "no"); - flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertTrue(accessEnc.getBool(false, flags)); - assertFalse(accessEnc.getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.clearTags(); // This is no one way way.setTag("highway", "tertiary"); way.setTag("vehicle:backward", "designated"); - flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertTrue(accessEnc.getBool(false, flags)); - assertTrue(accessEnc.getBool(true, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); way.clearTags(); } @@ -251,41 +251,45 @@ public void shouldBlockPrivate() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("access", "private"); - IntsRef flags = em.createEdgeFlags(); - parser.handleWayTags(flags, way); - assertFalse(accessEnc.getBool(false, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); final CarAccessParser parser = createParser(em, new PMap("block_private=false")); - parser.handleWayTags(flags = em.createEdgeFlags(), way); - assertTrue(parser.getAccessEnc().getBool(false, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); way.setTag("highway", "primary"); way.setTag("motor_vehicle", "permit"); // currently handled like "private", see #2712 - parser.handleWayTags(flags = em.createEdgeFlags(), way); - assertTrue(parser.getAccessEnc().getBool(false, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); } @Test public void testSetAccess() { - IntsRef edgeFlags = em.createEdgeFlags(); - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); - assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); - - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, false); - assertTrue(accessEnc.getBool(false, edgeFlags)); - assertFalse(accessEnc.getBool(true, edgeFlags)); - - accessEnc.setBool(false, edgeFlags, false); - accessEnc.setBool(true, edgeFlags, true); - assertFalse(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); - - accessEnc.setBool(false, edgeFlags, false); - accessEnc.setBool(true, edgeFlags, false); - assertFalse(accessEnc.getBool(true, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); + + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, false); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(accessEnc.getBool(true, edgeId, edgeIntAccess)); + + accessEnc.setBool(false, edgeId, edgeIntAccess, false); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); + assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); + + accessEnc.setBool(false, edgeId, edgeIntAccess, false); + accessEnc.setBool(true, edgeId, edgeIntAccess, false); + assertFalse(accessEnc.getBool(true, edgeId, edgeIntAccess)); } @Test @@ -293,47 +297,48 @@ public void testMaxSpeed() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "trunk"); way.setTag("maxspeed", "500"); - IntsRef edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(140, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(140, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:backward", "10"); way.setTag("maxspeed:forward", "20"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(20, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); - assertEquals(10, avSpeedEnc.getDecimal(true, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(20, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); + assertEquals(10, avSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:forward", "20"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(20, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(20, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:backward", "20"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(65, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); - assertEquals(20, avSpeedEnc.getDecimal(true, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(65, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); + assertEquals(20, avSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-1); way = new ReaderWay(1); way.setTag("highway", "motorway"); way.setTag("maxspeed", "none"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(135, avSpeedEnc.getDecimal(false, edgeFlags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(135, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); way = new ReaderWay(1); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "70 mph"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(100, avSpeedEnc.getDecimal(true, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(100, avSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-1); } @Test @@ -342,62 +347,63 @@ public void testSpeed() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "trunk"); way.setTag("maxspeed", "110"); - IntsRef edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(100, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(100, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "residential"); way.setTag("surface", "cobblestone"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(30, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(30, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "track"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(15, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(15, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "track"); way.setTag("tracktype", "grade1"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(20, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(20, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "secondary"); way.setTag("surface", "compacted"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); - assertEquals(30, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + assertEquals(30, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "secondary"); way.setTag("motorroad", "yes"); // motorroad should not influence speed. only access for non-motor vehicles - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); - assertEquals(60, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + assertEquals(60, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "motorway"); way.setTag("motorroad", "yes"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(100, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(100, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "motorway_link"); way.setTag("motorroad", "yes"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(70, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(70, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); try { - avSpeedEnc.setDecimal(false, em.createEdgeFlags(), -1); + avSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, -1); assertTrue(false); } catch (IllegalArgumentException ex) { } @@ -405,59 +411,62 @@ public void testSpeed() { @Test public void testSetSpeed() { - IntsRef edgeFlags = em.createEdgeFlags(); - avSpeedEnc.setDecimal(false, edgeFlags, 10); - assertEquals(10, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + avSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); + assertEquals(10, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test public void testSetSpeed0_issue367_issue1234() { - IntsRef edgeFlags = em.createEdgeFlags(); - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); - speedParser.setSpeed(false, edgeFlags, 30); - speedParser.setSpeed(true, edgeFlags, 40); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); + speedParser.setSpeed(false, edgeId, edgeIntAccess, 30); + speedParser.setSpeed(true, edgeId, edgeIntAccess, 40); // round down only for very low speed values - speedParser.setSpeed(false, edgeFlags, 0.09); - assertEquals(0, avSpeedEnc.getDecimal(false, edgeFlags), .1); + speedParser.setSpeed(false, edgeId, edgeIntAccess, 0.09); + assertEquals(0, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); // this is independent from the speed - assertTrue(accessEnc.getBool(false, edgeFlags)); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); // and does not affect the reverse direction: - assertEquals(40, avSpeedEnc.getDecimal(true, edgeFlags), .1); - assertTrue(accessEnc.getBool(true, edgeFlags)); + assertEquals(40, avSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), .1); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); // for low speed values (and low precision of the EncodedValue) it can happen that the speed is increased: - speedParser.setSpeed(false, edgeFlags, 1); - assertEquals(avSpeedEnc.getSmallestNonZeroValue(), avSpeedEnc.getDecimal(false, edgeFlags), .1); + speedParser.setSpeed(false, edgeId, edgeIntAccess, 1); + assertEquals(avSpeedEnc.getSmallestNonZeroValue(), avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - assertTrue(accessEnc.getBool(true, edgeFlags)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); } @Test public void testRoundabout() { - IntsRef edgeFlags = em.createEdgeFlags(); - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); - roundaboutEnc.setBool(false, edgeFlags, true); - assertTrue(roundaboutEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); - - roundaboutEnc.setBool(false, edgeFlags, false); - assertFalse(roundaboutEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + accessEnc.setBool(false, edgeId, edgeIntAccess, true); + accessEnc.setBool(true, edgeId, edgeIntAccess, true); + roundaboutEnc.setBool(false, edgeId, edgeIntAccess, true); + assertTrue(roundaboutEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); + + roundaboutEnc.setBool(false, edgeId, edgeIntAccess, false); + assertFalse(roundaboutEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway"); - edgeFlags = em.createEdgeFlags(); - parser.handleWayTags(edgeFlags, way); - assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); - assertFalse(roundaboutEnc.getBool(false, edgeFlags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(accessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(accessEnc.getBool(true, edgeId, edgeIntAccess)); + assertFalse(roundaboutEnc.getBool(false, edgeId, edgeIntAccess)); } @Test @@ -502,10 +511,11 @@ public void testFerry() { way.setTag("duration:seconds", 35L * 60); // accept assertTrue(parser.getAccess(way).isFerry()); - IntsRef edgeFlags = em.createEdgeFlags(); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; // calculate speed from tags: speed_from_duration * 1.4 (+ rounded using the speed factor) - speedParser.handleWayTags(edgeFlags, way); - assertEquals(60, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags)); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(60, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess)); //Test for very short and slow 0.5km/h still realistic ferry way = new ReaderWay(1); @@ -518,13 +528,13 @@ public void testFerry() { // accept assertTrue(parser.getAccess(way).isFerry()); // We can't store 0.5km/h, but we expect the lowest possible speed (5km/h) - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags)); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess)); - edgeFlags = em.createEdgeFlags(); - avSpeedEnc.setDecimal(false, edgeFlags, 2.5); - assertEquals(5, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + avSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 2.5); + assertEquals(5, avSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); //Test for missing duration way = new ReaderWay(1); @@ -533,9 +543,9 @@ public void testFerry() { way.setTag("edge_distance", 100.0); // accept assertTrue(parser.getAccess(way).isFerry()); - speedParser.handleWayTags(edgeFlags, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); // We use the unknown speed - assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags)); + assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("route", "ferry"); @@ -625,21 +635,22 @@ public void testMaxValue() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "60 mph"); - IntsRef edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); // double speed = AbstractFlagEncoder.parseSpeed("60 mph"); // => 96.56 * 0.9 => 86.9 - assertEquals(86.9, smallFactorSpeedEnc.getDecimal(false, edgeFlags), 1e-1); - assertEquals(86.9, smallFactorSpeedEnc.getDecimal(true, edgeFlags), 1e-1); + assertEquals(86.9, smallFactorSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); + assertEquals(86.9, smallFactorSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), 1e-1); // test that maxPossibleValue is not exceeded way = new ReaderWay(2); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "70 mph"); - edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(101.5, smallFactorSpeedEnc.getDecimal(false, edgeFlags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(101.5, smallFactorSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test @@ -665,14 +676,15 @@ public void testCombination() { bikeParser.init(new DateRangeParser()); assertEquals(WayAccess.CAN_SKIP, parser.getAccess(way)); assertNotEquals(WayAccess.CAN_SKIP, bikeParser.getAccess(way)); - IntsRef edgeFlags = em.createEdgeFlags(); - parser.handleWayTags(edgeFlags, way); - bikeParser.handleWayTags(edgeFlags, way); - assertFalse(accessEnc.getBool(true, edgeFlags)); - assertFalse(accessEnc.getBool(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way); + bikeParser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(accessEnc.getBool(true, edgeId, edgeIntAccess)); + assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); BooleanEncodedValue bikeAccessEnc = bikeParser.getAccessEnc(); - assertTrue(bikeAccessEnc.getBool(true, edgeFlags)); - assertTrue(bikeAccessEnc.getBool(false, edgeFlags)); + assertTrue(bikeAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertTrue(bikeAccessEnc.getBool(false, edgeId, edgeIntAccess)); } @Test @@ -690,9 +702,10 @@ public void testIssue_1256() { way.setTag("edge_distance", 257.0); // default is 5km/h minimum speed for car - IntsRef edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(5, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess), .1); // for a smaller speed factor the minimum speed is also smaller DecimalEncodedValueImpl lowFactorSpeedEnc = new DecimalEncodedValueImpl(VehicleSpeed.key("car"), 10, 1, false); @@ -701,9 +714,9 @@ public void testIssue_1256() { .add(lowFactorSpeedEnc) .addTurnCostEncodedValue(TurnCost.create(TurnCost.key("car"), 1)) .build(); - edgeFlags = lowFactorEm.createEdgeFlags(); - new CarAverageSpeedParser(lowFactorEm, new PMap()).handleWayTags(edgeFlags, way); - assertEquals(1, lowFactorSpeedEnc.getDecimal(false, edgeFlags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(lowFactorEm.getIntsForFlags()); + new CarAverageSpeedParser(lowFactorEm, new PMap()).handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(1, lowFactorSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @ParameterizedTest diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java index d53073a6d48..0add0b45c81 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java @@ -25,7 +25,6 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.storage.BaseGraph; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.*; import org.junit.jupiter.api.Test; @@ -62,25 +61,27 @@ public FootTagParserTest() { @Test public void testGetSpeed() { - IntsRef fl = encodingManager.createEdgeFlags(); - footAccessEnc.setBool(false, fl, true); - footAccessEnc.setBool(true, fl, true); - footAvgSpeedEnc.setDecimal(false, fl, 10); - assertEquals(10, footAvgSpeedEnc.getDecimal(false, fl), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + footAccessEnc.setBool(false, edgeId, edgeIntAccess, true); + footAccessEnc.setBool(true, edgeId, edgeIntAccess, true); + footAvgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); + assertEquals(10, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test public void testSteps() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "service"); - IntsRef flags = encodingManager.createEdgeFlags(); - speedParser.handleWayTags(flags, way); - assertEquals(MEAN_SPEED, footAvgSpeedEnc.getDecimal(false, flags), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(MEAN_SPEED, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.setTag("highway", "steps"); - flags = encodingManager.createEdgeFlags(); - speedParser.handleWayTags(encodingManager.createEdgeFlags(), way); - assertTrue(MEAN_SPEED > footAvgSpeedEnc.getDecimal(false, flags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(MEAN_SPEED > footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -98,11 +99,12 @@ public void testCombined() { assertTrue(edge.get(carAccessEnc)); assertFalse(edge.getReverse(carAccessEnc)); - IntsRef raw = encodingManager.createEdgeFlags(); - footAvgSpeedEnc.setDecimal(false, raw, 10); - footAccessEnc.setBool(false, raw, true); - footAccessEnc.setBool(true, raw, true); - assertEquals(0, carAvSpeedEnc.getDecimal(false, raw), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + footAvgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); + footAccessEnc.setBool(false, edgeId, edgeIntAccess, true); + footAccessEnc.setBool(true, edgeId, edgeIntAccess, true); + assertEquals(0, carAvSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test @@ -242,40 +244,42 @@ public void testAccess() { public void testRailPlatformIssue366() { ReaderWay way = new ReaderWay(1); way.setTag("railway", "platform"); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way); - speedParser.handleWayTags(edgeFlags, way); - assertTrue(footAccessEnc.getBool(false, edgeFlags)); - assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); way.clearTags(); way.setTag("highway", "track"); way.setTag("railway", "platform"); - edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way); - speedParser.handleWayTags(edgeFlags, way); - assertTrue(footAccessEnc.getBool(false, edgeFlags)); - assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeFlags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); way.clearTags(); // only tram, no highway => no access way.setTag("railway", "tram"); - edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way); - speedParser.handleWayTags(edgeFlags, way); - assertFalse(footAccessEnc.getBool(false, edgeFlags)); - assertEquals(0, footAvgSpeedEnc.getDecimal(false, edgeFlags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertEquals(0, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test public void testPier() { ReaderWay way = new ReaderWay(1); way.setTag("man_made", "pier"); - IntsRef flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way); - speedParser.handleWayTags(flags, way); - assertTrue(footAccessEnc.getBool(false, flags)); - assertEquals(5, footAvgSpeedEnc.getDecimal(false, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -283,17 +287,19 @@ public void testOneway() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "path"); way.setTag("foot:forward", "yes"); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way, null); - assertTrue(footAccessEnc.getBool(false, edgeFlags)); - assertFalse(footAccessEnc.getBool(true, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); way.clearTags(); way.setTag("highway", "path"); way.setTag("foot:backward", "yes"); - accessParser.handleWayTags(edgeFlags = encodingManager.createEdgeFlags(), way); - assertFalse(footAccessEnc.getBool(false, edgeFlags)); - assertTrue(footAccessEnc.getBool(true, edgeFlags)); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); } @Test @@ -304,37 +310,39 @@ public void testFerrySpeed() { way.setTag("edge_distance", 30000.0); way.setTag("speed_from_duration", 30 / 0.5); // the speed is truncated to maxspeed (=15) - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way); - assertEquals(15, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(15, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess)); } @Test public void testMixSpeedAndSafe() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway"); - IntsRef flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way); - assertFalse(footAccessEnc.getBool(false, flags)); - assertFalse(footAccessEnc.getBool(true, flags)); - assertEquals(0, footAvgSpeedEnc.getDecimal(false, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertEquals(0, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); way.setTag("sidewalk", "yes"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way); - speedParser.handleWayTags(flags, way); - assertTrue(footAccessEnc.getBool(false, flags)); - assertTrue(footAccessEnc.getBool(true, flags)); - assertEquals(5, footAvgSpeedEnc.getDecimal(false, flags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.clearTags(); way.setTag("highway", "track"); - flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way); - speedParser.handleWayTags(flags, way); - assertTrue(footAccessEnc.getBool(false, flags)); - assertTrue(footAccessEnc.getBool(true, flags)); - assertEquals(5, footAvgSpeedEnc.getDecimal(false, flags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertEquals(5, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test @@ -393,20 +401,22 @@ public void testSlowHiking() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("sac_scale", "hiking"); - IntsRef flags = encodingManager.createEdgeFlags(); - speedParser.handleWayTags(flags, way); - assertEquals(MEAN_SPEED, footAvgSpeedEnc.getDecimal(false, flags), 1e-1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(MEAN_SPEED, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); way.setTag("highway", "track"); way.setTag("sac_scale", "mountain_hiking"); - flags = encodingManager.createEdgeFlags(); - speedParser.handleWayTags(flags, way); - assertEquals(SLOW_SPEED, footAvgSpeedEnc.getDecimal(false, flags), 1e-1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + speedParser.handleWayTags(edgeId, edgeIntAccess, way); + assertEquals(SLOW_SPEED, footAvgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), 1e-1); } @Test public void testReadBarrierNodesFromWay() { - IntsRef intsRef = encodingManager.createEdgeFlags(); + int edgeId = 0; + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); ReaderWay way = new ReaderWay(1); way.setTag("highway", "secondary"); way.setTag("gh:barrier_edge", true); @@ -415,10 +425,10 @@ public void testReadBarrierNodesFromWay() { tags.put("barrier", "gate"); tags.put("access", "no"); way.setTag("node_tags", Collections.singletonList(tags)); - accessParser.handleWayTags(intsRef, way); + accessParser.handleWayTags(edgeId, edgeIntAccess, way); - assertFalse(footAccessEnc.getBool(false, intsRef)); - assertFalse(footAccessEnc.getBool(true, intsRef)); + assertFalse(footAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(footAccessEnc.getBool(true, edgeId, edgeIntAccess)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java index 5d7d7c9d086..0d996ae95ed 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java @@ -23,7 +23,6 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -143,30 +142,32 @@ public void testHandleWayTags() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "service"); assertTrue(parser.getAccess(way).isWay()); - IntsRef edgeFlags = em.createEdgeFlags(); - speedParser.handleWayTags(edgeFlags, way, null); - assertEquals(20, speedParser.avgSpeedEnc.getDecimal(false, edgeFlags), .1); - assertEquals(20, speedParser.avgSpeedEnc.getDecimal(true, edgeFlags), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + speedParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertEquals(20, speedParser.avgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(20, speedParser.avgSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), .1); } @Test public void testSetSpeed0_issue367() { - IntsRef edgeFlags = em.createEdgeFlags(); - motorcycleAccessEnc.setBool(false, edgeFlags, true); - motorcycleAccessEnc.setBool(true, edgeFlags, true); - speedParser.getAverageSpeedEnc().setDecimal(false, edgeFlags, 10); - speedParser.getAverageSpeedEnc().setDecimal(true, edgeFlags, 10); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + motorcycleAccessEnc.setBool(false, edgeId, edgeIntAccess, true); + motorcycleAccessEnc.setBool(true, edgeId, edgeIntAccess, true); + speedParser.getAverageSpeedEnc().setDecimal(false, edgeId, edgeIntAccess, 10); + speedParser.getAverageSpeedEnc().setDecimal(true, edgeId, edgeIntAccess, 10); - assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); - assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(true, edgeFlags), .1); + assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(true, edgeId, edgeIntAccess), .1); - speedParser.setSpeed(false, edgeFlags, 0); - assertEquals(0, speedParser.avgSpeedEnc.getDecimal(false, edgeFlags), .1); - assertEquals(10, speedParser.avgSpeedEnc.getDecimal(true, edgeFlags), .1); + speedParser.setSpeed(false, edgeId, edgeIntAccess, 0); + assertEquals(0, speedParser.avgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); + assertEquals(10, speedParser.avgSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), .1); // speed and access are independent - assertTrue(motorcycleAccessEnc.getBool(false, edgeFlags)); - assertTrue(motorcycleAccessEnc.getBool(true, edgeFlags)); + assertTrue(motorcycleAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(motorcycleAccessEnc.getBool(true, edgeId, edgeIntAccess)); } @ParameterizedTest diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java index 9ff168984ae..3875dea5eb1 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMCrossingParserTest.java @@ -1,10 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.Crossing; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.IntsRef; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,66 +14,68 @@ class OSMCrossingParserTest { - private EncodingManager em; private OSMCrossingParser parser; private EnumEncodedValue crossingEV; @BeforeEach public void setup() { crossingEV = new EnumEncodedValue<>(Crossing.KEY, Crossing.class); - em = new EncodingManager.Builder().add(crossingEV).build(); + crossingEV.init(new EncodedValue.InitializerConfig()); parser = new OSMCrossingParser(crossingEV); } @Test public void testRailway() { - IntsRef edgeFlags = em.createEdgeFlags(); - parser.handleWayTags(edgeFlags, + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, createReader(new PMap().putObject("railway", "level_crossing").toMap()), null); - assertEquals(Crossing.RAILWAY, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.RAILWAY, crossingEV.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testSignals() { - IntsRef edgeFlags = em.createEdgeFlags(); - parser.handleWayTags(edgeFlags, + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, createReader(new PMap().putObject("crossing", "traffic_signals").toMap()), null); - assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing:signals", "yes").toMap()), null); - assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.TRAFFIC_SIGNALS, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing:signals", "no").toMap()), null); - assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testMarked() { - IntsRef edgeFlags = em.createEdgeFlags(); - parser.handleWayTags(edgeFlags, createReader(new HashMap<>()), null); - assertEquals(Crossing.MISSING, crossingEV.getEnum(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, createReader(new HashMap<>()), null); + assertEquals(Crossing.MISSING, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("highway", "crossing").toMap()), null); - assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing", "marked").toMap()), null); - assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing:markings", "yes").toMap()), null); - assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing:markings", "no").toMap()), null); - assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.UNMARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); - parser.handleWayTags(edgeFlags = em.createEdgeFlags(), + parser.handleWayTags(edgeId, edgeIntAccess = new ArrayEdgeIntAccess(1), createReader(new PMap().putObject("crossing:signals", "no").putObject("crossing:markings", "yes").toMap()), null); - assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeFlags)); + assertEquals(Crossing.MARKED, crossingEV.getEnum(false, edgeId, edgeIntAccess)); } ReaderWay createReader(Map map) { diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java index b55aec28e89..08eb6a18f1a 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.GetOffBike; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; @@ -99,9 +97,10 @@ public void testHandleCommonWayTags() { } private boolean isGetOffBike(ReaderWay way) { - IntsRef edgeFlags = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; IntsRef relationFlags = new IntsRef(1); - parser.handleWayTags(edgeFlags, way, relationFlags); - return offBikeEnc.getBool(false, edgeFlags); + parser.handleWayTags(edgeId, edgeIntAccess, way, relationFlags); + return offBikeEnc.getBool(false, edgeId, edgeIntAccess); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java index bf2030e70d4..320934ca229 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.Hazmat; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,32 +23,34 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("hazmat", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Hazmat.NO, hazEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hazmat.NO, hazEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("hazmat", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hazmat.YES, hazEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("hazmat", "designated"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hazmat.YES, hazEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("hazmat", "designated"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hazmat.YES, hazEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testNoNPE() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hazmat.YES, hazEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java index 36de3d5f769..94ceb2f8f5a 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.HazmatTunnel; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,111 +23,114 @@ public void setUp() { @Test public void testADRTunnelCat() { - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("hazmat:adr_tunnel_cat", "A"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:adr_tunnel_cat", "B"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:adr_tunnel_cat", "C"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:adr_tunnel_cat", "D"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:adr_tunnel_cat", "E"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testTunnelCat() { - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("hazmat:tunnel_cat", "A"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:tunnel_cat", "B"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:tunnel_cat", "C"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:tunnel_cat", "D"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("hazmat:tunnel_cat", "E"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testHazmatSubtags() { - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:A", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:B", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.B, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:C", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:D", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.D, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:E", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testOrder() { - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:A", "no"); @@ -137,41 +138,44 @@ public void testOrder() { readerWay.setTag("hazmat:C", "no"); readerWay.setTag("hazmat:D", "no"); readerWay.setTag("hazmat:E", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, intsRef)); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:A", "no"); readerWay.setTag("hazmat:B", "no"); readerWay.setTag("hazmat:C", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.C, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay = new ReaderWay(1); readerWay.setTag("tunnel", "yes"); readerWay.setTag("hazmat:B", "no"); readerWay.setTag("hazmat:E", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.E, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testIgnoreNonTunnelSubtags() { - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("hazmat:B", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, intsRef)); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testNoNPE() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatTunnel.A, hazTunnelEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java index 90d4cbf98cb..e3182ae2411 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.HazmatWater; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,27 +24,29 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("hazmat:water", "no"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatWater.NO, hazWaterEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatWater.NO, hazWaterEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("hazmat:water", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("hazmat:water", "permissive"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatWater.PERMISSIVE, hazWaterEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatWater.PERMISSIVE, hazWaterEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testNoNPE() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMLanesParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMLanesParserTest.java index 859001c21af..b0a5dc28790 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMLanesParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMLanesParserTest.java @@ -19,9 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.IntEncodedValue; -import com.graphhopper.routing.ev.Lanes; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -42,18 +40,20 @@ void setup() { @Test void basic() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("lanes", "4"); - parser.handleWayTags(intsRef, readerWay, relFlags); - Assertions.assertEquals(4, lanesEnc.getInt(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + Assertions.assertEquals(4, lanesEnc.getInt(false, edgeId, edgeIntAccess)); } @Test void notTagged() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - Assertions.assertEquals(1, lanesEnc.getInt(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + Assertions.assertEquals(1, lanesEnc.getInt(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java index 4bff4038e10..135d669403d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.MaxAxleLoad; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,42 +24,45 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("maxaxleload", "11.5"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(11.5, malEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(11.5, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); // if value is beyond the maximum then do not use infinity instead fallback to more restrictive maximum - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("maxaxleload", "80"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(63.0, malEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(63.0, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); } @Test public void testRounding() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("maxaxleload", "4.8"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(5.0, malEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(5.0, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("maxaxleload", "3.6"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(3.5, malEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(3.5, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("maxaxleload", "2.4"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(2.5, malEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(2.5, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); } @Test public void testNoLimit() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Double.POSITIVE_INFINITY, malEnc.getDecimal(false, intsRef), .01); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Double.POSITIVE_INFINITY, malEnc.getDecimal(false, edgeId, edgeIntAccess), .01); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParserTest.java index 638241f145d..c04d9fcad43 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParserTest.java @@ -18,9 +18,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.MaxSpeed; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.storage.IntsRef; @@ -44,15 +42,16 @@ public double getMaxSpeed(ReaderWay readerWay, TransportationMode transportation return 5; } }); - IntsRef edgeFlags = new IntsRef(1); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(5, maxSpeedEnc.getDecimal(false, edgeFlags), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(5, maxSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); // without a country_rule we get the default value - edgeFlags = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); way.removeTag("country_rule"); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(MaxSpeed.UNSET_SPEED, maxSpeedEnc.getDecimal(false, edgeFlags), .1); + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(MaxSpeed.UNSET_SPEED, maxSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java index 1d3d29ad0a5..62a0313dadf 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.MaxWeight; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,16 +24,17 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("highway", "primary"); readerWay.setTag("maxweight", "5"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(5.0, mwEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(5.0, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); // if value is beyond the maximum then do not use infinity instead fallback to more restrictive maximum - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("maxweight", "50"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(25.4, mwEnc.getDecimal(false, intsRef), .01); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(25.4, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParserTest.java index 28d7f2049f8..a09d5ea87db 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParserTest.java @@ -19,9 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.IntEncodedValue; -import com.graphhopper.routing.ev.MtbRating; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; @@ -59,12 +57,13 @@ private void checkRating(int expectedRating, String scaleString) { IntEncodedValue ev = MtbRating.create(); ev.init(new EncodedValue.InitializerConfig()); OSMMtbRatingParser parser = new OSMMtbRatingParser(ev); - IntsRef edgeFlags = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay way = new ReaderWay(0); if (scaleString != null) way.setTag("mtb:scale", scaleString); - parser.handleWayTags(edgeFlags, way, new IntsRef(2)); - assertEquals(expectedRating, ev.getInt(false, edgeFlags), "unexpected rating for mtb:scale=" + scaleString); + parser.handleWayTags(edgeId, edgeIntAccess, way, new IntsRef(2)); + assertEquals(expectedRating, ev.getInt(false, edgeId, edgeIntAccess), "unexpected rating for mtb:scale=" + scaleString); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java index 1d790b649fc..e9fa5f05642 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java @@ -19,9 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadAccess; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.storage.IntsRef; @@ -46,23 +44,24 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati return RoadAccess.DESTINATION; } }); - IntsRef edgeFlags = new IntsRef(1); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(RoadAccess.DESTINATION, roadAccessEnc.getEnum(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(RoadAccess.DESTINATION, roadAccessEnc.getEnum(false, edgeId, edgeIntAccess)); // if there is no country rule we get the default value - edgeFlags = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); way.removeTag("country_rule"); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(RoadAccess.YES, roadAccessEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(RoadAccess.YES, roadAccessEnc.getEnum(false, edgeId, edgeIntAccess)); way.setTag("motor_vehicle", "agricultural;forestry"); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeId, edgeIntAccess)); way.setTag("motor_vehicle", "forestry;agricultural"); - parser.handleWayTags(edgeFlags, way, relFlags); - assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, edgeIntAccess, way, relFlags); + assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeId, edgeIntAccess)); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java index e106d3c98c0..9925b0f3ccc 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,42 +24,45 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef edgeFlags = new IntsRef(1); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("highway", "primary"); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.PRIMARY, rcEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, intAccess, readerWay, relFlags); + assertEquals(RoadClass.PRIMARY, rcEnc.getEnum(false, edgeId, intAccess)); - edgeFlags = new IntsRef(1); + intAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "unknownstuff"); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, intAccess, readerWay, relFlags); + assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeId, intAccess)); - edgeFlags = new IntsRef(1); + intAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "motorway_link"); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.MOTORWAY, rcEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, intAccess, readerWay, relFlags); + assertEquals(RoadClass.MOTORWAY, rcEnc.getEnum(false, edgeId, intAccess)); readerWay = new ReaderWay(1); readerWay.setTag("highway", "cycleway"); - edgeFlags = new IntsRef(1); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.CYCLEWAY, rcEnc.getEnum(false, edgeFlags)); + intAccess = new ArrayEdgeIntAccess(1); + parser.handleWayTags(edgeId, intAccess, readerWay, relFlags); + assertEquals(RoadClass.CYCLEWAY, rcEnc.getEnum(false, edgeId, intAccess)); } @Test public void testIgnore() { ReaderWay readerWay = new ReaderWay(1); - IntsRef edgeFlags = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("route", "ferry"); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeFlags)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testNoNPE() { ReaderWay readerWay = new ReaderWay(1); - IntsRef edgeFlags = new IntsRef(1); - parser.handleWayTags(edgeFlags, readerWay, relFlags); - assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeFlags)); + ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, intAccess, readerWay, relFlags); + assertEquals(RoadClass.OTHER, rcEnc.getEnum(false, edgeId, intAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java index 3e751df22af..ffe6931d334 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java @@ -19,9 +19,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadEnvironment; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; @@ -34,11 +32,12 @@ void ferry() { EnumEncodedValue roadEnvironmentEnc = new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class); roadEnvironmentEnc.init(new EncodedValue.InitializerConfig()); OSMRoadEnvironmentParser parser = new OSMRoadEnvironmentParser(roadEnvironmentEnc); - IntsRef edgeFlags = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; ReaderWay way = new ReaderWay(0); way.setTag("route", "shuttle_train"); - parser.handleWayTags(edgeFlags, way, new IntsRef(2)); - RoadEnvironment roadEnvironment = roadEnvironmentEnc.getEnum(false, edgeFlags); + parser.handleWayTags(edgeId, edgeIntAccess, way, new IntsRef(2)); + RoadEnvironment roadEnvironment = roadEnvironmentEnc.getEnum(false, edgeId, edgeIntAccess); assertEquals(RoadEnvironment.FERRY, roadEnvironment); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java index 5ce54f37cf7..f62a227bccf 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.Smoothness; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,14 +25,15 @@ public void testSimpleTags() { IntsRef relFlags = new IntsRef(2); ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("highway", "primary"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Smoothness.MISSING, smoothnessEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Smoothness.MISSING, smoothnessEnc.getEnum(false, edgeId, edgeIntAccess)); readerWay.setTag("smoothness", "bad"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Smoothness.BAD, smoothnessEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Smoothness.BAD, smoothnessEnc.getEnum(false, edgeId, edgeIntAccess)); assertTrue(Smoothness.BAD.ordinal() < Smoothness.VERY_BAD.ordinal()); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java index fb5a0e4e114..adf9120f03f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.Surface; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,18 +24,19 @@ public void setUp() { public void testSimpleTags() { IntsRef relFlags = new IntsRef(2); ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("highway", "primary"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Surface.MISSING, surfaceEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.MISSING, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); readerWay.setTag("surface", "cobblestone"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); assertTrue(Surface.COBBLESTONE.ordinal() > Surface.ASPHALT.ordinal()); readerWay.setTag("surface", "earth"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Surface.DIRT, surfaceEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.DIRT, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java index caaf60c4e43..60c0f823753 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,42 +23,43 @@ public void setUp() { public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); IntsRef relFlags = new IntsRef(2); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("highway", "primary"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.MISSING, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.MISSING, tollEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "primary"); readerWay.setTag("toll:hgv", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.HGV, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.HGV, tollEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "primary"); readerWay.setTag("toll:N2", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.HGV, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.HGV, tollEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "primary"); readerWay.setTag("toll:N3", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.HGV, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.HGV, tollEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "primary"); readerWay.setTag("toll", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.ALL, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.ALL, tollEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("highway", "primary"); readerWay.setTag("toll", "yes"); readerWay.setTag("toll:hgv", "yes"); readerWay.setTag("toll:N2", "yes"); readerWay.setTag("toll:N3", "yes"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(Toll.ALL, tollEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Toll.ALL, tollEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java index 101222380e5..ade65799624 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java @@ -1,9 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.TrackType; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,46 +24,49 @@ public void setUp() { @Test public void testSimpleTags() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("tracktype", "grade1"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.GRADE1, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.GRADE1, ttEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("tracktype", "grade2"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.GRADE2, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.GRADE2, ttEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("tracktype", "grade3"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.GRADE3, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.GRADE3, ttEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("tracktype", "grade4"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.GRADE4, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.GRADE4, ttEnc.getEnum(false, edgeId, edgeIntAccess)); - intsRef = new IntsRef(1); + edgeIntAccess = new ArrayEdgeIntAccess(1); readerWay.setTag("tracktype", "grade5"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.GRADE5, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.GRADE5, ttEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testUnkownValue() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; readerWay.setTag("tracktype", "unknownstuff"); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.MISSING, ttEnc.getEnum(false, intsRef)); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.MISSING, ttEnc.getEnum(false, edgeId, edgeIntAccess)); } @Test public void testNoNPE() { ReaderWay readerWay = new ReaderWay(1); - IntsRef intsRef = new IntsRef(1); - parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(TrackType.MISSING, ttEnc.getEnum(false, intsRef)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(TrackType.MISSING, ttEnc.getEnum(false, edgeId, edgeIntAccess)); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index bf0e44af1bf..6f3f38beb94 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -24,7 +24,6 @@ import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.VehicleEncodedValues; import com.graphhopper.routing.util.VehicleTagParsers; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -100,8 +99,9 @@ public void testSacScale() { @Test public void testGetSpeed() { - IntsRef intsRef = encodingManager.createEdgeFlags(); - avgSpeedEnc.setDecimal(false, intsRef, 10); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); ReaderWay way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("tracktype", "grade3"); @@ -274,10 +274,11 @@ public void testPriority_avoidanceOfHighMaxSpeed() { private void assertPriorityAndSpeed(EncodingManager encodingManager, DecimalEncodedValue priorityEnc, DecimalEncodedValue speedEnc, List parsers, int expectedPrio, double expectedSpeed, ReaderWay way) { - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - for (TagParser p : parsers) p.handleWayTags(edgeFlags, way, null); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeFlags), 0.01); - assertEquals(expectedSpeed, speedEnc.getDecimal(false, edgeFlags), 0.1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + for (TagParser p : parsers) p.handleWayTags(edgeId, edgeIntAccess, way, null); + assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), 0.01); + assertEquals(expectedSpeed, speedEnc.getDecimal(false, edgeId, edgeIntAccess), 0.1); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RoadsTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RoadsTagParserTest.java index 079a1486a8a..bb68170c981 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RoadsTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RoadsTagParserTest.java @@ -1,10 +1,11 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.ArrayEdgeIntAccess; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.VehicleEncodedValues; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -22,9 +23,10 @@ public RoadsTagParserTest() { @Test public void testSpeed() { ReaderWay way = new ReaderWay(1); - IntsRef flags = encodingManager.createEdgeFlags(); - parser.handleWayTags(flags, way, null); - assertTrue(encodingManager.getDecimalEncodedValue(VehicleSpeed.key("roads")).getDecimal(false, flags) > 200); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(encodingManager.getDecimalEncodedValue(VehicleSpeed.key("roads")).getDecimal(false, edgeId, edgeIntAccess) > 200); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java index cf3e2c3f909..8b4f56989d3 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java @@ -58,10 +58,10 @@ public void testCombineRelations() { BikePriorityParser bike1Parser = new BikePriorityParser(em, new PMap("name=bike1")); BikePriorityParser bike2Parser = new BikePriorityParser(em, new PMap("name=bike2")) { @Override - public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relTags) { + public void handleWayTags(int edgeId, EdgeIntAccess intAccess, ReaderWay way, IntsRef relTags) { // accept less relations - if (bikeRouteEnc.getEnum(false, edgeFlags) != RouteNetwork.MISSING) - priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getFactor(2)); + if (bikeRouteEnc.getEnum(false, edgeId, intAccess) != RouteNetwork.MISSING) + priorityEnc.setDecimal(false, edgeId, intAccess, PriorityCode.getFactor(2)); } }; OSMParsers osmParsers = new OSMParsers() @@ -75,10 +75,11 @@ public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relTags) { osmRel.setTag("network", "lcn"); IntsRef relFlags = osmParsers.createRelationFlags(); relFlags = osmParsers.handleRelationTags(osmRel, relFlags); - IntsRef edgeFlags = em.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); - assertEquals(RouteNetwork.LOCAL, bikeNetworkEnc.getEnum(false, edgeFlags)); - assertTrue(bike1PriorityEnc.getDecimal(false, edgeFlags) > bike2PriorityEnc.getDecimal(false, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, edgeIntAccess, osmWay, relFlags); + assertEquals(RouteNetwork.LOCAL, bikeNetworkEnc.getEnum(false, edgeId, edgeIntAccess)); + assertTrue(bike1PriorityEnc.getDecimal(false, edgeId, edgeIntAccess) > bike2PriorityEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -115,11 +116,12 @@ public void testMixBikeTypesAndRelationCombination() { osmRel.setTag("network", "rcn"); IntsRef relFlags = osmParsers.createRelationFlags(); relFlags = osmParsers.handleRelationTags(osmRel, relFlags); - IntsRef edgeFlags = em.createEdgeFlags(); - osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + osmParsers.handleWayTags(edgeId, edgeIntAccess, osmWay, relFlags); // bike: uninfluenced speed for grade but via network => NICE // mtb: uninfluenced speed only PREFER - assertTrue(bikePriorityEnc.getDecimal(false, edgeFlags) > mtbPriorityEnc.getDecimal(false, edgeFlags)); + assertTrue(bikePriorityEnc.getDecimal(false, edgeId, edgeIntAccess) > mtbPriorityEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test @@ -154,26 +156,27 @@ public void testSharedEncodedValues() { if (tagParser instanceof AbstractAccessParser) ((AbstractAccessParser) tagParser).init(new DateRangeParser()); - final IntsRef edgeFlags = manager.createEdgeFlags(); + final ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(manager.getIntsForFlags()); + int edgeId = 0; IntsRef relFlags = manager.createRelationFlags(); ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("junction", "roundabout"); - tagParsers.forEach(p -> p.handleWayTags(edgeFlags, way, relFlags)); + tagParsers.forEach(p -> p.handleWayTags(edgeId, intAccess, way, relFlags)); - assertTrue(roundaboutEnc.getBool(false, edgeFlags)); + assertTrue(roundaboutEnc.getBool(false, edgeId, intAccess)); for (BooleanEncodedValue accessEnc : accessEncs) - assertTrue(accessEnc.getBool(false, edgeFlags)); + assertTrue(accessEnc.getBool(false, edgeId, intAccess)); final IntsRef edgeFlags2 = manager.createEdgeFlags(); way.clearTags(); way.setTag("highway", "tertiary"); way.setTag("junction", "circular"); - tagParsers.forEach(p -> p.handleWayTags(edgeFlags2, way, relFlags)); + tagParsers.forEach(p -> p.handleWayTags(edgeId, intAccess, way, relFlags)); - assertTrue(roundaboutEnc.getBool(false, edgeFlags2)); + assertTrue(roundaboutEnc.getBool(false, edgeId, intAccess)); for (BooleanEncodedValue accessEnc : accessEncs) - assertTrue(accessEnc.getBool(false, edgeFlags2)); + assertTrue(accessEnc.getBool(false, edgeId, intAccess)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java index 6b6063dabd8..b9ceeeb0a31 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java @@ -25,7 +25,6 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.storage.BaseGraph; -import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; import com.graphhopper.util.*; import org.junit.jupiter.api.Test; @@ -63,9 +62,9 @@ public WheelchairTagParserTest() { accessParser.init(new DateRangeParser()); speedParser = new WheelchairAverageSpeedParser(encodingManager, new PMap()) { @Override - public void applyWayTags(ReaderWay way, IntsRef edgeFlags) { + public void applyWayTags(ReaderWay way, int edgeId, EdgeIntAccess edgeIntAccess) { if (way.hasTag("point_list") && way.hasTag("edge_distance")) - super.applyWayTags(way, edgeFlags); + super.applyWayTags(way, edgeId, edgeIntAccess); } }; prioParser = new WheelchairPriorityParser(encodingManager, new PMap()); @@ -73,11 +72,12 @@ public void applyWayTags(ReaderWay way, IntsRef edgeFlags) { @Test public void testGetSpeed() { - IntsRef fl = encodingManager.createEdgeFlags(); - wheelchairAccessEnc.setBool(false, fl, true); - wheelchairAccessEnc.setBool(true, fl, true); - wheelchairAvSpeedEnc.setDecimal(false, fl, 10); - assertEquals(10, wheelchairAvSpeedEnc.getDecimal(false, fl), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + wheelchairAccessEnc.setBool(false, edgeId, edgeIntAccess, true); + wheelchairAccessEnc.setBool(true, edgeId, edgeIntAccess, true); + wheelchairAvSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); + assertEquals(10, wheelchairAvSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test @@ -95,11 +95,12 @@ public void testCombined() { assertTrue(edge.get(carAccessEnc)); assertFalse(edge.getReverse(carAccessEnc)); - IntsRef raw = encodingManager.createEdgeFlags(); - wheelchairAvSpeedEnc.setDecimal(false, raw, 10); - wheelchairAccessEnc.setBool(false, raw, true); - wheelchairAccessEnc.setBool(true, raw, true); - assertEquals(0, carAvSpeedEnc.getDecimal(false, raw), .1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + wheelchairAvSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, 10); + wheelchairAccessEnc.setBool(false, edgeId, edgeIntAccess, true); + wheelchairAccessEnc.setBool(true, edgeId, edgeIntAccess, true); + assertEquals(0, carAvSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); } @Test @@ -305,37 +306,39 @@ public void testAccess() { public void testPier() { ReaderWay way = new ReaderWay(1); way.setTag("man_made", "pier"); - IntsRef flags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(flags, way, null); - speedParser.handleWayTags(flags, way, null); - assertTrue(wheelchairAccessEnc.getBool(false, flags)); - assertTrue(wheelchairAccessEnc.getBool(true, flags)); - assertEquals(5, wheelchairAvSpeedEnc.getDecimal(false, flags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + speedParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(wheelchairAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(wheelchairAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertEquals(5, wheelchairAvSpeedEnc.getDecimal(false, edgeId, edgeIntAccess)); } @Test public void testMixSpeedAndSafe() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway"); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way, null); - assertFalse(wheelchairAccessEnc.getBool(false, edgeFlags)); - assertFalse(wheelchairAccessEnc.getBool(true, edgeFlags)); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + int edgeId = 0; + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(wheelchairAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(wheelchairAccessEnc.getBool(true, edgeId, edgeIntAccess)); way.setTag("sidewalk", "yes"); - edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way, null); - speedParser.handleWayTags(edgeFlags, way, null); - assertTrue(wheelchairAccessEnc.getBool(false, edgeFlags)); - assertTrue(wheelchairAccessEnc.getBool(true, edgeFlags)); - assertEquals(5, wheelchairAvSpeedEnc.getDecimal(false, edgeFlags), .1); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + speedParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertTrue(wheelchairAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(wheelchairAccessEnc.getBool(true, edgeId, edgeIntAccess)); + assertEquals(5, wheelchairAvSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); way.clearTags(); way.setTag("highway", "track"); - edgeFlags = encodingManager.createEdgeFlags(); - accessParser.handleWayTags(edgeFlags, way, null); - assertFalse(wheelchairAccessEnc.getBool(false, edgeFlags)); - assertFalse(wheelchairAccessEnc.getBool(true, edgeFlags)); + edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); + assertFalse(wheelchairAccessEnc.getBool(false, edgeId, edgeIntAccess)); + assertFalse(wheelchairAccessEnc.getBool(true, edgeId, edgeIntAccess)); } @Test @@ -555,21 +558,19 @@ public void testApplyWayTags() { ReaderWay way1 = new ReaderWay(1); way1.setTag("point_list", edge01.fetchWayGeometry(FetchMode.ALL)); way1.setTag("edge_distance", edge01.getDistance()); - IntsRef flags = edge01.getFlags(); - speedParser.applyWayTags(way1, flags); - edge01.setFlags(flags); + EdgeIntAccess edgeIntAccess = graph.createIntAccess(); + speedParser.applyWayTags(way1, edge01.getEdge(), edgeIntAccess); assertTrue(edge01.get(wheelchairAccessEnc)); assertTrue(edge01.getReverse(wheelchairAccessEnc)); + assertEquals(2, edge01.get(wheelchairAvSpeedEnc), 0); assertEquals(2, edge01.get(speedParser.getAverageSpeedEnc()), 0); assertEquals(5, edge01.getReverse(speedParser.getAverageSpeedEnc()), 0); ReaderWay way2 = new ReaderWay(2); way2.setTag("point_list", edge23.fetchWayGeometry(FetchMode.ALL)); way2.setTag("edge_distance", edge23.getDistance()); - flags = edge23.getFlags(); - speedParser.applyWayTags(way2, flags); - edge23.setFlags(flags); + speedParser.applyWayTags(way2, edge23.getEdge(), edgeIntAccess); assertTrue(edge23.get(wheelchairAccessEnc)); assertTrue(edge23.getReverse(wheelchairAccessEnc)); @@ -581,10 +582,8 @@ public void testApplyWayTags() { ReaderWay way3 = new ReaderWay(3); way3.setTag("point_list", edge45.fetchWayGeometry(FetchMode.ALL)); way3.setTag("edge_distance", edge45.getDistance()); - flags = edge45.getFlags(); - speedParser.handleWayTags(flags, way3, null); - speedParser.applyWayTags(way3, flags); - edge45.setFlags(flags); + speedParser.handleWayTags(edge45.getEdge(), edgeIntAccess, way3, null); + speedParser.applyWayTags(way3, edge45.getEdge(), edgeIntAccess); assertEquals(0, edge45.get(wheelchairAvSpeedEnc), 0.1); assertEquals(0, edge45.getReverse(wheelchairAvSpeedEnc), 0.1); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java index a37e95c12d8..4d2b23ef30c 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java @@ -1,8 +1,8 @@ package com.graphhopper.routing.weighting.custom; +import com.graphhopper.routing.ev.ArrayEdgeIntAccess; import com.graphhopper.routing.ev.StringEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,7 +18,7 @@ public class ConditionalExpressionVisitorTest { public void before() { StringEncodedValue sev = new StringEncodedValue("country", 10); new EncodingManager.Builder().add(sev).build(); - sev.setString(false, new IntsRef(1), "DEU"); + sev.setString(false, 0, new ArrayEdgeIntAccess(1), "DEU"); } @Test From 38cc8d8741c989f9c0842eca1287225e9b779298 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 19 Jan 2023 18:50:57 +0100 Subject: [PATCH 013/165] Add static creators for enum encoded values --- .../ev/DefaultEncodedValueFactory.java | 30 +++++++++---------- .../com/graphhopper/routing/ev/Footway.java | 4 +++ .../com/graphhopper/routing/ev/Hazmat.java | 4 +++ .../graphhopper/routing/ev/HazmatTunnel.java | 26 ++++++++++++---- .../graphhopper/routing/ev/HazmatWater.java | 4 +++ .../java/com/graphhopper/routing/ev/Hgv.java | 4 +++ .../graphhopper/routing/ev/RoadAccess.java | 4 +++ .../com/graphhopper/routing/ev/RoadClass.java | 4 +++ .../graphhopper/routing/ev/RoadClassLink.java | 4 +++ .../routing/ev/RoadEnvironment.java | 4 +++ .../graphhopper/routing/ev/RouteNetwork.java | 4 +++ .../graphhopper/routing/ev/Smoothness.java | 4 +++ .../com/graphhopper/routing/ev/Surface.java | 4 +++ .../java/com/graphhopper/routing/ev/Toll.java | 4 +++ .../com/graphhopper/routing/ev/TrackType.java | 4 +++ .../graphhopper/reader/osm/OSMReaderTest.java | 2 +- .../routing/ev/EnumEncodedValueTest.java | 2 +- .../routing/util/EncodingManagerTest.java | 7 +++-- .../util/parsers/CarTagParserTest.java | 4 +-- .../util/parsers/FootTagParserTest.java | 4 +-- .../util/parsers/OSMHazmatParserTest.java | 2 +- .../parsers/OSMHazmatTunnelParserTest.java | 2 +- .../parsers/OSMHazmatWaterParserTest.java | 2 +- .../util/parsers/OSMRoadAccessParserTest.java | 2 +- .../util/parsers/OSMRoadClassParserTest.java | 2 +- .../parsers/OSMRoadEnvironmentParserTest.java | 2 +- .../util/parsers/OSMSmoothnessParserTest.java | 2 +- .../util/parsers/OSMSurfaceParserTest.java | 2 +- .../util/parsers/OSMTollParserTest.java | 2 +- .../util/parsers/OSMTrackTypeParserTest.java | 2 +- .../util/parsers/RacingBikeTagParserTest.java | 4 +-- .../routing/util/parsers/TagParsingTest.java | 14 ++++----- .../util/parsers/WheelchairTagParserTest.java | 2 +- .../custom/CustomModelParserTest.java | 2 +- .../weighting/custom/CustomWeightingTest.java | 6 ++-- 35 files changed, 122 insertions(+), 53 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index 214a7f84929..dec908b6b35 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -28,13 +28,13 @@ public EncodedValue create(String name, PMap properties) { } else if (GetOffBike.KEY.equals(name)) { return GetOffBike.create(); } else if (RoadClass.KEY.equals(name)) { - return new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class); + return RoadClass.create(); } else if (RoadClassLink.KEY.equals(name)) { - return new SimpleBooleanEncodedValue(RoadClassLink.KEY); + return RoadClassLink.create(); } else if (RoadEnvironment.KEY.equals(name)) { - return new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class); + return RoadEnvironment.create(); } else if (RoadAccess.KEY.equals(name)) { - return new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class); + return RoadAccess.create(); } else if (MaxSpeed.KEY.equals(name)) { return MaxSpeed.create(); } else if (MaxWeight.KEY.equals(name)) { @@ -48,27 +48,27 @@ public EncodedValue create(String name, PMap properties) { } else if (MaxLength.KEY.equals(name)) { return MaxLength.create(); } else if (Hgv.KEY.equals(name)) { - return new EnumEncodedValue<>(Hgv.KEY, Hgv.class); + return Hgv.create(); } else if (Surface.KEY.equals(name)) { - return new EnumEncodedValue<>(Surface.KEY, Surface.class); + return Surface.create(); } else if (Smoothness.KEY.equals(name)) { - return new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class); + return Smoothness.create(); } else if (Toll.KEY.equals(name)) { - return new EnumEncodedValue<>(Toll.KEY, Toll.class); + return Toll.create(); } else if (TrackType.KEY.equals(name)) { - return new EnumEncodedValue<>(TrackType.KEY, TrackType.class); + return TrackType.create(); } else if (BikeNetwork.KEY.equals(name) || FootNetwork.KEY.equals(name)) { - return new EnumEncodedValue<>(name, RouteNetwork.class); + return RouteNetwork.create(name); } else if (Hazmat.KEY.equals(name)) { - return new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class); + return Hazmat.create(); } else if (HazmatTunnel.KEY.equals(name)) { - return new EnumEncodedValue<>(HazmatTunnel.KEY, HazmatTunnel.class); + return HazmatTunnel.create(); } else if (HazmatWater.KEY.equals(name)) { - return new EnumEncodedValue<>(HazmatWater.KEY, HazmatWater.class); + return HazmatWater.create(); } else if (Lanes.KEY.equals(name)) { return Lanes.create(); } else if (Footway.KEY.equals(name)) { - return new EnumEncodedValue<>(Footway.KEY, Footway.class); + return Footway.create(); } else if (OSMWayID.KEY.equals(name)) { return OSMWayID.create(); } else if (MtbRating.KEY.equals(name)) { @@ -80,7 +80,7 @@ public EncodedValue create(String name, PMap properties) { } else if (Country.KEY.equals(name)) { return Country.create(); } else if (name.endsWith(Subnetwork.key(""))) { - return new SimpleBooleanEncodedValue(name); + return Subnetwork.create(name); } else if (MaxSlope.KEY.equals(name)) { return MaxSlope.create(); } else if (AverageSlope.KEY.equals(name)) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Footway.java b/core/src/main/java/com/graphhopper/routing/ev/Footway.java index 49765e14a3a..bddfb017721 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Footway.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Footway.java @@ -24,6 +24,10 @@ public enum Footway { public static final String KEY = "footway"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Footway.class); + } + private final String name; Footway(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java b/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java index 0bf56e29758..9fef11dfb66 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java @@ -9,6 +9,10 @@ public enum Hazmat { public static final String KEY = "hazmat"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Hazmat.class); + } + private final String name; Hazmat(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java b/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java index 2422be9379a..202e5e25746 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java +++ b/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java @@ -3,23 +3,37 @@ /** * Defines the degree of restriction for the transport of hazardous goods through tunnels.
* If not tagged it will be {@link #A} - * + * * @see Hazmat Tunnel restrictions */ public enum HazmatTunnel { - /** driving with any dangerous goods allowed */ + /** + * driving with any dangerous goods allowed + */ A("A"), - /** no goods with very large explosion range */ + /** + * no goods with very large explosion range + */ B("B"), - /** no goods with large explosion or poisoning range */ + /** + * no goods with large explosion or poisoning range + */ C("C"), - /** no goods which threaten a large explosion, poisoning or fire */ + /** + * no goods which threaten a large explosion, poisoning or fire + */ D("D"), - /** forbids all dangerous goods except: UN 2919,3291, 3331, 3359, 3373 */ + /** + * forbids all dangerous goods except: UN 2919,3291, 3331, 3359, 3373 + */ E("E"); public static final String KEY = "hazmat_tunnel"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, HazmatTunnel.class); + } + private final String name; HazmatTunnel(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java b/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java index d128147147c..d91cf98d915 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java +++ b/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java @@ -9,6 +9,10 @@ public enum HazmatWater { public static final String KEY = "hazmat_water"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, HazmatWater.class); + } + private final String name; HazmatWater(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Hgv.java b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java index 7adcd3a31d2..7284f6acb33 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Hgv.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java @@ -30,6 +30,10 @@ public enum Hgv { public static final String KEY = "hgv"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(Hgv.KEY, Hgv.class); + } + private final String name; Hgv(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java b/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java index 32593f78df8..ebcaf71a4a8 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java @@ -31,6 +31,10 @@ public enum RoadAccess { public static final String KEY = "road_access"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class); + } + private final String name; RoadAccess(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java b/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java index 827b0ceaf45..88f56c9b5f9 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java @@ -32,6 +32,10 @@ public enum RoadClass { public static final String KEY = "road_class"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class); + } + private final String name; RoadClass(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadClassLink.java b/core/src/main/java/com/graphhopper/routing/ev/RoadClassLink.java index 0ae5be8d1d6..17acde4a7bd 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadClassLink.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadClassLink.java @@ -19,4 +19,8 @@ public class RoadClassLink { public static final String KEY = "road_class_link"; + + public static BooleanEncodedValue create() { + return new SimpleBooleanEncodedValue(KEY); + } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java b/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java index a743414bdda..6c60eff74b2 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java @@ -29,6 +29,10 @@ public enum RoadEnvironment { public static final String KEY = "road_environment"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class); + } + private final String name; RoadEnvironment(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java b/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java index 9c2a7fd6331..2fc739e9c86 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java @@ -32,6 +32,10 @@ public static String key(String prefix) { return prefix + "_network"; } + public static EnumEncodedValue create(String name) { + return new EnumEncodedValue<>(name, RouteNetwork.class); + } + private final String name; RouteNetwork(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java index 7ca39c05df5..29e41106503 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java @@ -32,6 +32,10 @@ public enum Smoothness { public static final String KEY = "smoothness"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Smoothness.class); + } + private final String name; Smoothness(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Surface.java b/core/src/main/java/com/graphhopper/routing/ev/Surface.java index 2252aa998f1..a76be0c4b03 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Surface.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Surface.java @@ -34,6 +34,10 @@ public enum Surface { public static final String KEY = "surface"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Surface.class); + } + private final String name; Surface(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Toll.java b/core/src/main/java/com/graphhopper/routing/ev/Toll.java index a01bc548063..4a4eff5c6ad 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Toll.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Toll.java @@ -26,6 +26,10 @@ public enum Toll { public static final String KEY = "toll"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Toll.class); + } + private final String name; Toll(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/TrackType.java b/core/src/main/java/com/graphhopper/routing/ev/TrackType.java index 1fb61cff2ae..bc178222923 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/TrackType.java +++ b/core/src/main/java/com/graphhopper/routing/ev/TrackType.java @@ -32,6 +32,10 @@ public enum TrackType { public static final String KEY = "track_type"; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, TrackType.class); + } + private final String name; TrackType(String name) { diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index ca9ff5d7398..8b979c543af 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -958,7 +958,7 @@ public void testCountries() throws IOException { @Test public void testCurvedWayAlongBorder() throws IOException { // see https://discuss.graphhopper.com/t/country-of-way-is-wrong-on-road-near-border-with-curvature/6908/2 - EnumEncodedValue countryEnc = new EnumEncodedValue<>(Country.KEY, Country.class); + EnumEncodedValue countryEnc = Country.create(); EncodingManager em = EncodingManager.start() .add(VehicleEncodedValues.car(new PMap())) .add(countryEnc) diff --git a/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java index 97eb66b79ba..00ef4adf083 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EnumEncodedValueTest.java @@ -8,7 +8,7 @@ public class EnumEncodedValueTest { @Test public void testInit() { - EnumEncodedValue prop = new EnumEncodedValue<>("road_class", RoadClass.class); + EnumEncodedValue prop = RoadClass.create(); EncodedValue.InitializerConfig init = new EncodedValue.InitializerConfig(); assertEquals(5, prop.init(init)); assertEquals(5, prop.bits); diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index 13f5c8106ae..2ecac791e91 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -17,7 +17,10 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.RoadAccess; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.util.parsers.BikeAccessParser; import com.graphhopper.routing.util.parsers.CarAccessParser; import com.graphhopper.routing.util.parsers.FootAccessParser; @@ -71,7 +74,7 @@ public void testGetVehicles() { .add(VehicleAccess.create("bike")).add(VehicleSpeed.create("bike", 4, 2, true)) .add(VehicleSpeed.create("roads", 5, 5, false)) .add(VehicleAccess.create("hike")).add(new DecimalEncodedValueImpl("whatever_hike_average_speed_2022", 5, 5, true)) - .add(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)) + .add(RoadAccess.create()) .build(); // only for bike+hike there is access+'speed' assertEquals(Arrays.asList("bike", "hike"), em.getVehicles()); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java index 67db4c51f10..c2dbb4da03e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java @@ -55,8 +55,8 @@ private EncodingManager createEncodingManager(String carName) { .add(VehicleAccess.create("bike")) .add(VehicleSpeed.create("bike", 4, 2, false)) .add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)) - .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) - .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .add(RouteNetwork.create(BikeNetwork.KEY)) + .add(Smoothness.create()) .build(); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java index 0add0b45c81..83dd1769706 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java @@ -47,8 +47,8 @@ public class FootTagParserTest { private final BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); private final DecimalEncodedValue carAvSpeedEnc = VehicleSpeed.create("car", 5, 5, false); private final EncodingManager encodingManager = EncodingManager.start() - .add(footAccessEnc).add(footAvgSpeedEnc).add(footPriorityEnc).add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) - .add(bikeAccessEnc).add(bikeAvgSpeedEnc).add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(footAccessEnc).add(footAvgSpeedEnc).add(footPriorityEnc).add(RouteNetwork.create(FootNetwork.KEY)) + .add(bikeAccessEnc).add(bikeAvgSpeedEnc).add(RouteNetwork.create(BikeNetwork.KEY)) .add(carAccessEnc).add(carAvSpeedEnc) .build(); private final FootAccessParser accessParser = new FootAccessParser(encodingManager, new PMap()); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java index 320934ca229..93ced81a480 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatParserTest.java @@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class OSMHazmatParserTest { - private final EnumEncodedValue hazEnc = new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class); + private final EnumEncodedValue hazEnc = Hazmat.create(); private OSMHazmatParser parser; private IntsRef relFlags; diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java index 94ceb2f8f5a..8f31f06c7ed 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatTunnelParserTest.java @@ -15,7 +15,7 @@ public class OSMHazmatTunnelParserTest { @BeforeEach public void setUp() { - hazTunnelEnc = new EnumEncodedValue<>(HazmatTunnel.KEY, HazmatTunnel.class); + hazTunnelEnc = HazmatTunnel.create(); hazTunnelEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMHazmatTunnelParser(hazTunnelEnc); relFlags = new IntsRef(2); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java index e3182ae2411..18d4fef9c2a 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHazmatWaterParserTest.java @@ -15,7 +15,7 @@ public class OSMHazmatWaterParserTest { @BeforeEach public void setUp() { - hazWaterEnc = new EnumEncodedValue<>(HazmatWater.KEY, HazmatWater.class); + hazWaterEnc = HazmatWater.create(); hazWaterEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMHazmatWaterParser(hazWaterEnc); relFlags = new IntsRef(2); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java index e9fa5f05642..74aead04caf 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java @@ -31,7 +31,7 @@ class OSMRoadAccessParserTest { @Test void countryRule() { - EnumEncodedValue roadAccessEnc = new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class); + EnumEncodedValue roadAccessEnc = RoadAccess.create(); roadAccessEnc.init(new EncodedValue.InitializerConfig()); OSMRoadAccessParser parser = new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java index 9925b0f3ccc..db5ead2d4fc 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadClassParserTest.java @@ -15,7 +15,7 @@ public class OSMRoadClassParserTest { @BeforeEach public void setUp() { - rcEnc = new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class); + rcEnc = RoadClass.create(); rcEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMRoadClassParser(rcEnc); relFlags = new IntsRef(2); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java index ffe6931d334..0bc294af446 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadEnvironmentParserTest.java @@ -29,7 +29,7 @@ class OSMRoadEnvironmentParserTest { @Test void ferry() { - EnumEncodedValue roadEnvironmentEnc = new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class); + EnumEncodedValue roadEnvironmentEnc = RoadEnvironment.create(); roadEnvironmentEnc.init(new EncodedValue.InitializerConfig()); OSMRoadEnvironmentParser parser = new OSMRoadEnvironmentParser(roadEnvironmentEnc); EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java index f62a227bccf..c0b5e3ead0e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSmoothnessParserTest.java @@ -15,7 +15,7 @@ public class OSMSmoothnessParserTest { @BeforeEach public void setUp() { - smoothnessEnc = new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class); + smoothnessEnc = Smoothness.create(); smoothnessEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMSmoothnessParser(smoothnessEnc); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java index adf9120f03f..4765dc0bf6c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java @@ -15,7 +15,7 @@ public class OSMSurfaceParserTest { @BeforeEach public void setUp() { - surfaceEnc = new EnumEncodedValue<>(Surface.KEY, Surface.class); + surfaceEnc = Surface.create(); surfaceEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMSurfaceParser(surfaceEnc); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java index 60c0f823753..e5bb19b0189 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTollParserTest.java @@ -14,7 +14,7 @@ public class OSMTollParserTest { @BeforeEach public void setUp() { - tollEnc = new EnumEncodedValue<>(Toll.KEY, Toll.class); + tollEnc = Toll.create(); tollEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMTollParser(tollEnc); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java index ade65799624..6ea1e973a56 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTrackTypeParserTest.java @@ -15,7 +15,7 @@ public class OSMTrackTypeParserTest { @BeforeEach public void setUp() { - ttEnc = new EnumEncodedValue<>(TrackType.KEY, TrackType.class); + ttEnc = TrackType.create(); ttEnc.init(new EncodedValue.InitializerConfig()); parser = new OSMTrackTypeParser(ttEnc); relFlags = new IntsRef(2); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index 6f3f38beb94..fc7f8ea2679 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -218,8 +218,8 @@ public void testPriority_avoidanceOfHighMaxSpeed() { DecimalEncodedValue priorityEnc = VehiclePriority.create("racingbike", 4, PriorityCode.getValue(1), false); EncodingManager encodingManager = EncodingManager.start() .add(accessEnc).add(speedEnc).add(priorityEnc) - .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) - .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .add(RouteNetwork.create(BikeNetwork.KEY)) + .add(Smoothness.create()) .build(); List parsers = Arrays.asList( new RacingBikeAverageSpeedParser(encodingManager, new PMap()), diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java index 8b4f56989d3..2e44a7dfd3c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java @@ -48,12 +48,12 @@ public void testCombineRelations() { BooleanEncodedValue bike2AccessEnc = VehicleAccess.create("bike2"); DecimalEncodedValue bike2SpeedEnc = VehicleSpeed.create("bike2", 4, 2, false); DecimalEncodedValue bike2PriorityEnc = VehiclePriority.create("bike2", 4, PriorityCode.getFactor(1), false); - EnumEncodedValue bikeNetworkEnc = new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class); + EnumEncodedValue bikeNetworkEnc = RouteNetwork.create(BikeNetwork.KEY); EncodingManager em = EncodingManager.start() .add(bike1AccessEnc).add(bike1SpeedEnc).add(bike1PriorityEnc) .add(bike2AccessEnc).add(bike2SpeedEnc).add(bike2PriorityEnc) .add(bikeNetworkEnc) - .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .add(Smoothness.create()) .build(); BikePriorityParser bike1Parser = new BikePriorityParser(em, new PMap("name=bike1")); BikePriorityParser bike2Parser = new BikePriorityParser(em, new PMap("name=bike2")) { @@ -96,12 +96,12 @@ public void testMixBikeTypesAndRelationCombination() { BooleanEncodedValue mtbAccessEnc = VehicleAccess.create("mtb"); DecimalEncodedValue mtbSpeedEnc = VehicleSpeed.create("mtb", 4, 2, false); DecimalEncodedValue mtbPriorityEnc = VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false); - EnumEncodedValue bikeNetworkEnc = new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class); + EnumEncodedValue bikeNetworkEnc = RouteNetwork.create(BikeNetwork.KEY); EncodingManager em = EncodingManager.start() .add(bikeAccessEnc).add(bikeSpeedEnc).add(bikePriorityEnc) .add(mtbAccessEnc).add(mtbSpeedEnc).add(mtbPriorityEnc) .add(bikeNetworkEnc) - .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .add(Smoothness.create()) .build(); BikePriorityParser bikeTagParser = new BikePriorityParser(em, new PMap()); MountainBikePriorityParser mtbTagParser = new MountainBikePriorityParser(em, new PMap()); @@ -138,9 +138,9 @@ public void testSharedEncodedValues() { .add(bikeAccessEnc).add(VehicleSpeed.create("bike", 4, 2, false)).add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)) .add(motorcycleAccessEnc).add(VehicleSpeed.create("motorcycle", 5, 5, true)).add(VehiclePriority.create("motorcycle", 4, PriorityCode.getFactor(1), false)).add(new DecimalEncodedValueImpl("motorcycle_curvature", 5, 5, true)) .add(mtbAccessEnc).add(VehicleSpeed.create("mtb", 4, 2, false)).add(VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false)) - .add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) - .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) - .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .add(RouteNetwork.create(FootNetwork.KEY)) + .add(RouteNetwork.create(BikeNetwork.KEY)) + .add(Smoothness.create()) .build(); BooleanEncodedValue roundaboutEnc = manager.getBooleanEncodedValue(Roundabout.KEY); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java index b9ceeeb0a31..7ed814a5dc5 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java @@ -55,7 +55,7 @@ public WheelchairTagParserTest() { carAccessEnc = VehicleAccess.create("car"); carAvSpeedEnc = VehicleSpeed.create("car", 5, 5, false); encodingManager = EncodingManager.start() - .add(wheelchairAccessEnc).add(wheelchairAvSpeedEnc).add(wheelchairPriorityEnc).add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) + .add(wheelchairAccessEnc).add(wheelchairAvSpeedEnc).add(wheelchairPriorityEnc).add(RouteNetwork.create(FootNetwork.KEY)) .add(carAccessEnc).add(carAvSpeedEnc) .build(); accessParser = new WheelchairAccessParser(encodingManager, new PMap()); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index f018a483bcf..1ee9433db5d 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -56,7 +56,7 @@ void setup() { avgSpeedEnc = VehicleSpeed.create("car", 5, 5, false); countryEnc = new StringEncodedValue("country", 10); encodingManager = new EncodingManager.Builder().add(accessEnc).add(avgSpeedEnc) - .add(countryEnc).add(MaxSpeed.create()).add(new EnumEncodedValue<>(Surface.KEY, Surface.class)).build(); + .add(countryEnc).add(MaxSpeed.create()).add(Surface.create()).build(); graph = new BaseGraph.Builder(encodingManager).create(); roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); maxSpeed = 140; diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 0c725a4c740..5d3a1cbeab6 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -37,9 +37,9 @@ public void setup() { accessEnc = VehicleAccess.create("car"); avSpeedEnc = VehicleSpeed.create("car", 5, 5, true); encodingManager = new EncodingManager.Builder().add(accessEnc).add(avSpeedEnc) - .add(new EnumEncodedValue<>(Toll.KEY, Toll.class)) - .add(new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class)) - .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(Toll.create()) + .add(Hazmat.create()) + .add(RouteNetwork.create(BikeNetwork.KEY)) .build(); maxSpeedEnc = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); roadClassEnc = encodingManager.getEnumEncodedValue(KEY, RoadClass.class); From d0cb557fa291db3f415afbfbde36372178c3add4 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 23 Mar 2023 13:09:31 +0100 Subject: [PATCH 014/165] Rename createIntAccess -> createEdgeIntAccess --- core/src/main/java/com/graphhopper/reader/osm/OSMReader.java | 2 +- core/src/main/java/com/graphhopper/storage/BaseGraph.java | 4 ++-- .../routing/util/parsers/WheelchairTagParserTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index d69fe61ca09..5ca65dd7b46 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -99,7 +99,7 @@ public class OSMReader { public OSMReader(BaseGraph baseGraph, OSMParsers osmParsers, OSMReaderConfig config) { this.baseGraph = baseGraph; - this.edgeIntAccess = baseGraph.createIntAccess(); + this.edgeIntAccess = baseGraph.createEdgeIntAccess(); this.config = config; this.nodeAccess = baseGraph.getNodeAccess(); this.osmParsers = osmParsers; diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 0b5d796d78f..26984d1d8e1 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -363,7 +363,7 @@ private void setWayGeometry_(PointList pillarNodes, long edgePointer, boolean re } } - public EdgeIntAccess createIntAccess() { + public EdgeIntAccess createEdgeIntAccess() { return new EdgeIntAccess() { @Override public int getInt(int edgeId, int index) { @@ -674,7 +674,7 @@ static class EdgeIteratorStateImpl implements EdgeIteratorState { public EdgeIteratorStateImpl(BaseGraph baseGraph) { this.baseGraph = baseGraph; - edgeIntAccess = baseGraph.createIntAccess(); + edgeIntAccess = baseGraph.createEdgeIntAccess(); store = baseGraph.store; } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java index 7ed814a5dc5..60a3d77d88f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java @@ -558,7 +558,7 @@ public void testApplyWayTags() { ReaderWay way1 = new ReaderWay(1); way1.setTag("point_list", edge01.fetchWayGeometry(FetchMode.ALL)); way1.setTag("edge_distance", edge01.getDistance()); - EdgeIntAccess edgeIntAccess = graph.createIntAccess(); + EdgeIntAccess edgeIntAccess = graph.createEdgeIntAccess(); speedParser.applyWayTags(way1, edge01.getEdge(), edgeIntAccess); assertTrue(edge01.get(wheelchairAccessEnc)); From 56c7941d01ef78a05720335e7986712660046239 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 24 Mar 2023 14:10:38 +0100 Subject: [PATCH 015/165] bike profile should allow reverse oneway roads and set walking speed (#2774) * bike: allow reverse oneways; mark them as 'get off bike' and slow down to 4km/h * fix speed issue * fix test * create bike_oneway that is always true, except for the reverse direction of a oneway road * fix tests * minor cleanup * initial backward_car_access impl * test+fix when used in CustomModel * use modified bike profile * include custom_models/bike.json in integration test * for bike test reverse access of oneways; use jackson allow comments feature * revert changes to jackson parsing with comment * include bike_priority in bike.json * make custom models simpler via setting bike speed and priority unconditionally at the beginning * add get_off_bike parser after bike_access * comment * fixed typo * re-add test * imports * minor revert to master for 2 files --- CHANGELOG.md | 2 + .../java/com/graphhopper/GraphHopper.java | 5 +- .../graphhopper/routing/ev/GetOffBike.java | 2 +- .../util/parsers/BikeCommonAccessParser.java | 28 ++- .../parsers/BikeCommonAverageSpeedParser.java | 15 +- .../util/parsers/OSMGetOffBikeParser.java | 36 ++-- .../java/com/graphhopper/GraphHopperTest.java | 42 ++--- .../routing/RoutingAlgorithmWithOSMTest.java | 52 +++--- .../ev/EncodedValueSerializerTest.java | 4 +- .../parsers/AbstractBikeTagParserTester.java | 116 +++++++++++++ .../util/parsers/BikeTagParserTest.java | 164 ------------------ .../util/parsers/OSMGetOffBikeParserTest.java | 38 +++- custom_models/bike.json | 17 +- .../resources/RouteResourceClientHCTest.java | 7 +- .../RouteResourceCustomModelTest.java | 24 ++- .../RouteResourceProfileSelectionTest.java | 6 +- 16 files changed, 286 insertions(+), 272 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fddf96a14a5..0dfb15cdada 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ### 8.0 [not yet released] + - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 +- bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 ### 7.0 [14 Mar 2023] diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 7c0f3a3895c..bb62f2fcdfb 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -669,8 +669,6 @@ protected OSMParsers buildOSMParsers(Map vehiclesByName, List new OSMBikeNetworkTagParser(encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)); - if (encodingManager.hasEncodedValue(GetOffBike.KEY) && added.add(GetOffBike.KEY)) - osmParsers.addWayTagParser(new OSMGetOffBikeParser(encodingManager.getBooleanEncodedValue(GetOffBike.KEY))); if (encodingManager.hasEncodedValue(Smoothness.KEY) && added.add(Smoothness.KEY)) osmParsers.addWayTagParser(new OSMSmoothnessParser(encodingManager.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))); } else if (tagParser instanceof FootAccessParser) { @@ -690,6 +688,9 @@ protected OSMParsers buildOSMParsers(Map vehiclesByName, List { if (tagParser == null) return; osmParsers.addWayTagParser(tagParser); + + if (tagParser instanceof BikeCommonAccessParser && encodingManager.hasEncodedValue(GetOffBike.KEY) && added.add(GetOffBike.KEY)) + osmParsers.addWayTagParser(new OSMGetOffBikeParser(encodingManager.getBooleanEncodedValue(GetOffBike.KEY), ((BikeCommonAccessParser) tagParser).getAccessEnc())); }); }); return osmParsers; diff --git a/core/src/main/java/com/graphhopper/routing/ev/GetOffBike.java b/core/src/main/java/com/graphhopper/routing/ev/GetOffBike.java index ae29ef92354..457964e0af7 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/GetOffBike.java +++ b/core/src/main/java/com/graphhopper/routing/ev/GetOffBike.java @@ -4,6 +4,6 @@ public class GetOffBike { public static final String KEY = "get_off_bike"; public static BooleanEncodedValue create() { - return new SimpleBooleanEncodedValue(KEY, false); + return new SimpleBooleanEncodedValue(KEY, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 5b6fc1c0606..59a9f5fc191 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -10,7 +10,7 @@ public abstract class BikeCommonAccessParser extends AbstractAccessParser implements TagParser { - protected final HashSet oppositeLanes = new HashSet<>(); + private static final Set OPP_LANES = new HashSet<>(Arrays.asList("opposite", "opposite_lane", "opposite_track")); private final Set allowedHighways = new HashSet<>(); private final BooleanEncodedValue roundaboutEnc; @@ -28,10 +28,6 @@ protected BikeCommonAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedVa intendedValues.add("official"); intendedValues.add("permissive"); - oppositeLanes.add("opposite"); - oppositeLanes.add("opposite_lane"); - oppositeLanes.add("opposite_track"); - barriers.add("fence"); allowedHighways.addAll(Arrays.asList("living_street", "steps", "cycleway", "path", "footway", "platform", @@ -137,21 +133,21 @@ public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way protected void handleAccess(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { // handle oneways. The value -1 means it is a oneway but for reverse direction of stored geometry. // The tagging oneway:bicycle=no or cycleway:right:oneway=no or cycleway:left:oneway=no lifts the generic oneway restriction of the way for bike - boolean isOneway = way.hasTag("oneway", oneways) && !way.hasTag("oneway", "-1") && !way.hasTag("bicycle:backward", intendedValues) - || way.hasTag("oneway", "-1") && !way.hasTag("bicycle:forward", intendedValues) - || way.hasTag("oneway:bicycle", oneways) - || way.hasTag("cycleway:left:oneway", oneways) - || way.hasTag("cycleway:right:oneway", oneways) - || way.hasTag("vehicle:backward", restrictedValues) && !way.hasTag("bicycle:forward", intendedValues) - || way.hasTag("vehicle:forward", restrictedValues) && !way.hasTag("bicycle:backward", intendedValues) + boolean isOneway = way.hasTag("oneway", ONEWAYS) && !way.hasTag("oneway", "-1") && !way.hasTag("bicycle:backward", INTENDED) + || way.hasTag("oneway", "-1") && !way.hasTag("bicycle:forward", INTENDED) + || way.hasTag("oneway:bicycle", ONEWAYS) + || way.hasTag("cycleway:left:oneway", ONEWAYS) + || way.hasTag("cycleway:right:oneway", ONEWAYS) + || way.hasTag("vehicle:backward", restrictedValues) && !way.hasTag("bicycle:forward", INTENDED) + || way.hasTag("vehicle:forward", restrictedValues) && !way.hasTag("bicycle:backward", INTENDED) || way.hasTag("bicycle:forward", restrictedValues) || way.hasTag("bicycle:backward", restrictedValues); if ((isOneway || roundaboutEnc.getBool(false, edgeId, edgeIntAccess)) && !way.hasTag("oneway:bicycle", "no") - && !way.hasTag("cycleway", oppositeLanes) - && !way.hasTag("cycleway:left", oppositeLanes) - && !way.hasTag("cycleway:right", oppositeLanes) + && !way.hasTag("cycleway", OPP_LANES) + && !way.hasTag("cycleway:left", OPP_LANES) + && !way.hasTag("cycleway:right", OPP_LANES) && !way.hasTag("cycleway:left:oneway", "no") && !way.hasTag("cycleway:right:oneway", "no")) { boolean isBackward = way.hasTag("oneway", "-1") @@ -163,8 +159,8 @@ protected void handleAccess(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay w accessEnc.setBool(isBackward, edgeId, edgeIntAccess, true); } else { - accessEnc.setBool(false, edgeId, edgeIntAccess, true); accessEnc.setBool(true, edgeId, edgeIntAccess, true); + accessEnc.setBool(false, edgeId, edgeIntAccess, true); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java index 9fb0985372b..cb93ddb3018 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java @@ -1,6 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.EdgeIntAccess; @@ -155,8 +156,8 @@ public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way double speedFwd = applyMaxSpeed(way, speed, false); avgSpeedEnc.setDecimal(false, edgeId, edgeIntAccess, speedFwd); if (avgSpeedEnc.isStoreTwoDirections()) { - speed = applyMaxSpeed(way, speed, true); - avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, speed); + double bwdSpeed = applyMaxSpeed(way, speed, true); + avgSpeedEnc.setDecimal(true, edgeId, edgeIntAccess, bwdSpeed); } } @@ -167,7 +168,7 @@ int getSpeed(ReaderWay way) { if (way.hasTag("railway", "platform")) highwaySpeed = PUSHING_SECTION_SPEED; - // Under certain conditions we need to increase the speed of pushing sections to the speed of a "highway=cycleway" + // Under certain conditions we need to increase the speed of pushing sections to the speed of a "highway=cycleway" else if (way.hasTag("highway", pushingSectionsHighways) && ((way.hasTag("foot", "yes") && way.hasTag("segregated", "yes")) || (way.hasTag("bicycle", intendedValues)))) @@ -180,12 +181,8 @@ else if (way.hasTag("highway", pushingSectionsHighways) if (surfaceSpeed != null) { speed = surfaceSpeed; // boost handling for good surfaces but avoid boosting if pushing section - if (highwaySpeed != null && surfaceSpeed > highwaySpeed) { - if (pushingSectionsHighways.contains(highwayTag)) - speed = highwaySpeed; - else - speed = surfaceSpeed; - } + if (highwaySpeed != null && surfaceSpeed > highwaySpeed && pushingSectionsHighways.contains(highwayTag)) + speed = highwaySpeed; } } else { String tt = way.getTag("tracktype"); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java index 2ef299c4491..c00a7feada6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java @@ -10,29 +10,39 @@ import java.util.List; /** - * This parser scans different OSM tags to identify ways where a cyclist has to get off her bike. + * This parser scans different OSM tags to identify ways where a cyclist has to get off her bike. Like on footway but + * also in reverse oneway direction. */ public class OSMGetOffBikeParser implements TagParser { - private final HashSet pushBikeHighwayTags = new HashSet<>(); - private final List accepted = Arrays.asList("designated", "yes", "official", "permissive"); - private final BooleanEncodedValue offBikeEnc; - public OSMGetOffBikeParser(BooleanEncodedValue getOffBikeEnc) { - // steps -> special handling - this(getOffBikeEnc, Arrays.asList("path", "footway", "pedestrian", "platform")); - } + private final List INTENDED = Arrays.asList("designated", "yes", "official", "permissive"); + // steps -> special handling + private final HashSet GET_OFF_BIKE = new HashSet<>(Arrays.asList("path", "footway", "pedestrian", "platform")); + private final BooleanEncodedValue getOffBikeEnc; + private final BooleanEncodedValue bikeAccessEnc; - public OSMGetOffBikeParser(BooleanEncodedValue getOffBikeEnc, List pushBikeTags) { - offBikeEnc = getOffBikeEnc; - pushBikeHighwayTags.addAll(pushBikeTags); + /** + * @param bikeAccessEnc used to find out if way is oneway and so it does not matter which bike type is used. + */ + public OSMGetOffBikeParser(BooleanEncodedValue getOffBikeEnc, BooleanEncodedValue bikeAccessEnc) { + this.getOffBikeEnc = getOffBikeEnc; + this.bikeAccessEnc = bikeAccessEnc; } @Override public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { String highway = way.getTag("highway"); - if (!way.hasTag("bicycle", accepted) && (pushBikeHighwayTags.contains(highway) || way.hasTag("railway", "platform")) + if (!way.hasTag("bicycle", INTENDED) && (GET_OFF_BIKE.contains(highway) || way.hasTag("railway", "platform")) || "steps".equals(highway) || way.hasTag("bicycle", "dismount")) { - offBikeEnc.setBool(false, edgeId, edgeIntAccess, true); + getOffBikeEnc.setBool(false, edgeId, edgeIntAccess, true); + getOffBikeEnc.setBool(true, edgeId, edgeIntAccess, true); + } + boolean fwd = bikeAccessEnc.getBool(false, edgeId, edgeIntAccess); + boolean bwd = bikeAccessEnc.getBool(true, edgeId, edgeIntAccess); + // get off bike for reverse oneways + if (fwd != bwd) { + if (!fwd) getOffBikeEnc.setBool(false, edgeId, edgeIntAccess, true); + if (!bwd) getOffBikeEnc.setBool(true, edgeId, edgeIntAccess, true); } } } diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 7e205b3abcf..55eddf28409 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -20,7 +20,6 @@ import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; -import com.graphhopper.json.Statement; import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.reader.dem.SkadiProvider; @@ -66,6 +65,8 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import static com.graphhopper.json.Statement.If; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.GHUtility.createCircle; import static com.graphhopper.util.GHUtility.createRectangle; import static com.graphhopper.util.Parameters.Algorithms.*; @@ -303,7 +304,7 @@ private void testImportCloseAndLoad(boolean ch, boolean lm, boolean sort, boolea new Coordinate(7.4207, 43.7344), new Coordinate(7.4174, 43.7345)})); CustomModel customModel = new CustomModel().setDistanceInfluence(0d); - customModel.getPriority().add(Statement.If("in_area51", Statement.Op.MULTIPLY, "0.1")); + customModel.getPriority().add(If("in_area51", MULTIPLY, "0.1")); customModel.getAreas().getFeatures().add(area51Feature); profile = new CustomProfile(profileName).setCustomModel(customModel).setVehicle(vehicle); } @@ -610,7 +611,7 @@ public void testNorthBayreuthBlockedEdges() { assertEquals(122, rsp.getBest().getDistance(), 1); // block road at 49.985759,11.50687 - CustomModel customModel = new CustomModel().addToPriority(Statement.If("in_blocked_area", Statement.Op.MULTIPLY, "0")); + CustomModel customModel = new CustomModel().addToPriority(If("in_blocked_area", MULTIPLY, "0")); customModel.getAreas().getFeatures().add(createCircle("blocked_area", 49.985759, 11.50687, 5)); req.setCustomModel(customModel); rsp = hopper.route(req); @@ -634,13 +635,13 @@ public void testNorthBayreuthBlockedEdges() { // Add blocked point to above area, to increase detour customModel.getAreas().getFeatures().add(createCircle("blocked_point", 50.017578, 11.547527, 5)); - customModel.addToPriority(Statement.If("in_blocked_point", Statement.Op.MULTIPLY, "0")); + customModel.addToPriority(If("in_blocked_point", MULTIPLY, "0")); rsp = hopper.route(req); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(14601, rsp.getBest().getDistance(), 1); // block by edge IDs -> i.e. use small circular area - customModel = new CustomModel().addToPriority(Statement.If("in_blocked_area", Statement.Op.MULTIPLY, "0")); + customModel = new CustomModel().addToPriority(If("in_blocked_area", MULTIPLY, "0")); customModel.getAreas().getFeatures().add(createCircle("blocked_area", 49.979929, 11.520066, 200)); req.setCustomModel(customModel); rsp = hopper.route(req); @@ -711,7 +712,7 @@ public void testCustomModel() { final String customCar = "custom_car"; final String emptyCar = "empty_car"; CustomModel customModel = new CustomModel(); - customModel.addToSpeed(Statement.If("road_class == TERTIARY || road_class == TRACK", Statement.Op.MULTIPLY, "0.1")); + customModel.addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0.1")); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(BAYREUTH). @@ -729,11 +730,11 @@ public void testCustomModel() { assertDistance(hopper, emptyCar, new CustomModel(customModel), 13223); // now we prevent using unclassified roads as well and the route goes even further north CustomModel strictCustomModel = new CustomModel().addToSpeed( - Statement.If("road_class == TERTIARY || road_class == TRACK || road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, "0.1")); + If("road_class == TERTIARY || road_class == TRACK || road_class == UNCLASSIFIED", MULTIPLY, "0.1")); assertDistance(hopper, emptyCar, strictCustomModel, 19289); // we can achieve the same by 'adding' a rule to the server-side custom model CustomModel customModelWithUnclassifiedRule = new CustomModel().addToSpeed( - Statement.If("road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, "0.1") + If("road_class == UNCLASSIFIED", MULTIPLY, "0.1") ); assertDistance(hopper, customCar, customModelWithUnclassifiedRule, 19289); // now we use distance influence to avoid the detour @@ -1261,24 +1262,21 @@ public void testSkadiElevationProvider() { @Test public void testKremsCyclewayInstructionsWithWayTypeInfo() { - final String profile1 = "foot_profile"; - final String profile2 = "bike_profile"; - final String vehicle1 = "foot"; - final String vehicle2 = "bike"; - final String weighting = "fastest"; + final String footProfile = "foot_profile"; + final String bikeProfile = "bike_profile"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(KREMS). setProfiles( - new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting), - new Profile(profile2).setVehicle(vehicle2).setWeighting(weighting)). + new Profile(footProfile).setVehicle("foot").setWeighting("fastest"), + new CustomProfile(bikeProfile).setCustomModel(new CustomModel()).setVehicle("bike")). setStoreOnFlush(true). importOrLoad(); Translation tr = hopper.getTranslationMap().getWithFallBack(Locale.US); GHResponse rsp = hopper.route(new GHRequest(48.410987, 15.599492, 48.383419, 15.659294). - setProfile(profile2)); + setProfile(bikeProfile)); assertFalse(rsp.hasErrors()); ResponsePath res = rsp.getBest(); assertEquals(6931.8, res.getDistance(), .1); @@ -1303,9 +1301,8 @@ public void testKremsCyclewayInstructionsWithWayTypeInfo() { //.. assertEquals("turn right onto Treppelweg", il.get(15).getTurnDescription(tr)); - // do not return 'get off bike' for foot rsp = hopper.route(new GHRequest(48.410987, 15.599492, 48.411172, 15.600371). - setAlgorithm(ASTAR).setProfile(profile1)); + setAlgorithm(ASTAR).setProfile(footProfile)); assertFalse(rsp.hasErrors()); il = rsp.getBest().getInstructions(); assertEquals("continue onto Obere Landstraße", il.get(0).getTurnDescription(tr)); @@ -1394,10 +1391,9 @@ public void testCircularJunctionInstructionsWithCH() { public void testMultipleVehiclesWithCH() { final String bikeProfile = "bike_profile"; final String carProfile = "car_profile"; - final String weighting = "fastest"; List profiles = asList( - new Profile(bikeProfile).setVehicle("bike").setWeighting(weighting), - new Profile(carProfile).setVehicle("car").setWeighting(weighting) + new CustomProfile(bikeProfile).setCustomModel(new CustomModel()).setVehicle("bike"), + new Profile(carProfile).setVehicle("car").setWeighting("fastest") ); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). @@ -2596,7 +2592,7 @@ public void testBarriers() { assertEquals(105, footRsp.getBest().getDistance(), 1); footRsp = hopper.route(new GHRequest(51.290141, 12.365849, 51.290996, 12.366155). - setCustomModel(new CustomModel().addToPriority(Statement.If("road_environment == FORD", Statement.Op.MULTIPLY, "0"))).setProfile("foot")); + setCustomModel(new CustomModel().addToPriority(If("road_environment == FORD", MULTIPLY, "0"))).setProfile("foot")); assertEquals(330, footRsp.getBest().getDistance(), 1); } @@ -2606,7 +2602,7 @@ public void testBarriers() { assertEquals(39, rsp.getBest().getDistance(), 1); rsp = hopper.route(new GHRequest(51.327411, 12.429598, 51.32723, 12.429979). - setCustomModel(new CustomModel().addToPriority(Statement.If("road_access == PRIVATE", Statement.Op.MULTIPLY, "0"))). + setCustomModel(new CustomModel().addToPriority(If("road_access == PRIVATE", MULTIPLY, "0"))). setProfile("car")); assertFalse(rsp.hasErrors()); assertEquals(20, rsp.getBest().getDistance(), 1); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 4738b5fb181..9291f778741 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -17,8 +17,6 @@ */ package com.graphhopper.routing; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import com.graphhopper.GHRequest; import com.graphhopper.GHResponse; import com.graphhopper.GraphHopper; @@ -27,7 +25,6 @@ import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; import com.graphhopper.jackson.Jackson; -import com.graphhopper.json.Statement; import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.Graph; @@ -38,13 +35,13 @@ import org.junit.jupiter.api.Test; import java.io.File; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +import static com.graphhopper.json.Statement.If; import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.Parameters.Algorithms.*; import static org.junit.jupiter.api.Assertions.*; @@ -134,7 +131,7 @@ public void testMonacoMotorcycleCurvature() { queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2423, 141)); queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2253, 120)); queries.add(new Query(43.727592, 7.419333, 43.727712, 7.419333, 0, 1)); - CustomModel model = new CustomModel().setDistanceInfluence(70d).addToPriority(Statement.If("true", MULTIPLY, "curvature")); + CustomModel model = new CustomModel().setDistanceInfluence(70d).addToPriority(If("true", MULTIPLY, "curvature")); GraphHopper hopper = createHopper(MONACO, new CustomProfile("motorcycle").setCustomModel(model). setVehicle("motorcycle")); @@ -226,7 +223,7 @@ public void testSimplePTurn() { static CustomModel getCustomModel(String file) { try { - String string = Helper.readJSONFileWithoutComments(new File("../custom_models/" + file).getAbsolutePath()); + String string = Helper.readJSONFileWithoutComments(new File("../custom_models/", file).getAbsolutePath()); return Jackson.newObjectMapper().readValue(string, CustomModel.class); } catch (Exception ex) { throw new RuntimeException(ex); @@ -330,8 +327,8 @@ public void testNorthBayreuthHikeFastestAnd3D() { queries.add(new Query(49.974972, 11.515657, 49.991022, 11.512299, 2365, 67)); // prefer hiking route 'Markgrafenweg Bayreuth Kulmbach' but avoid tertiary highway from Pechgraben queries.add(new Query(49.990967, 11.545258, 50.023182, 11.555386, 5636, 97)); - GraphHopper hopper = createHopper(BAYREUTH, new CustomProfile("hike").setCustomModel(getCustomModel("hike.json")).setVehicle("roads"), - new Profile("foot").setVehicle("foot") /* make foot vehicle available */); + GraphHopper hopper = createHopper(BAYREUTH, new CustomProfile("hike").setCustomModel(getCustomModel("hike.json")).setVehicle("roads")); + hopper.setVehiclesString("roads,foot"); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -339,8 +336,8 @@ public void testNorthBayreuthHikeFastestAnd3D() { @Test public void testHikeCanUseExtremeSacScales() { - GraphHopper hopper = createHopper(HOHEWARTE, new CustomProfile("hike").setCustomModel(getCustomModel("hike.json")).setVehicle("roads"), - new Profile("foot").setVehicle("foot") /* make foot vehicle available */); + GraphHopper hopper = createHopper(HOHEWARTE, new CustomProfile("hike").setCustomModel(getCustomModel("hike.json")).setVehicle("roads")); + hopper.setVehiclesString("foot,roads"); // do not pull elevation data: hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); GHResponse res = hopper.route(new GHRequest(47.290322, 11.333889, 47.301593, 11.333489).setProfile("hike")); @@ -367,8 +364,12 @@ public void testMonacoBike3D() { queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2870, 154)); // 4. avoid tunnel(s)! queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1795, 96)); - GraphHopper hopper = createHopper(MONACO, new CustomProfile("bike"). - setCustomModel(getCustomModel("bike.json")).setVehicle("bike")); + // atm custom model is intended to be used with 'roads' vehicle when allowing reverse direction for oneways + // but tests here still assert that reverse oneways are excluded + GraphHopper hopper = createHopper(MONACO, + new CustomProfile("bike").setCustomModel(getCustomModel("bike.json"). + addToPriority(If("!bike_access", MULTIPLY, "0"))).setVehicle("roads")); + hopper.setVehiclesString("roads,bike"); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -409,7 +410,8 @@ public void testMonacoBike() { queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3580, 168)); queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2323, 121)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1434, 89)); - GraphHopper hopper = createHopper(MONACO, new Profile("bike").setVehicle("bike").setWeighting("shortest")); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("bike"). + setCustomModel(new CustomModel().setDistanceInfluence(7000d)/*shortest*/).setVehicle("bike")); hopper.importOrLoad(); checkQueries(hopper, queries); } @@ -424,14 +426,14 @@ public void testMonacoMountainBike() { // hard to select between secondary and primary (both are AVOID for mtb) queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1459, 88)); - GraphHopper hopper = createHopper(MONACO, new Profile("mtb").setVehicle("mtb").setWeighting("fastest")); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb")); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); hopper = createHopper(MONACO, - new Profile("mtb").setVehicle("mtb").setWeighting("fastest"), + new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb"), new Profile("racingbike").setVehicle("racingbike").setWeighting("fastest")); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -445,15 +447,14 @@ public void testMonacoRacingBike() { queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2568, 135)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1490, 84)); - GraphHopper hopper = createHopper(MONACO, - new Profile("racingbike").setVehicle("racingbike").setWeighting("fastest")); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("racingbike"). + setCustomModel(new CustomModel()).setVehicle("racingbike")); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(MONACO, - new Profile("racingbike").setVehicle("racingbike").setWeighting("fastest"), + hopper = createHopper(MONACO, new CustomProfile("racingbike").setCustomModel(new CustomModel()).setVehicle("racingbike"), new Profile("bike").setVehicle("bike").setWeighting("fastest") ); hopper.importOrLoad(); @@ -468,7 +469,8 @@ public void testKremsBikeRelation() { queries.add(new Query(48.412294, 15.62007, 48.398306, 15.609667, 3965, 94)); GraphHopper hopper = createHopper(KREMS, - new Profile("bike").setVehicle("bike").setWeighting("fastest")); + new CustomProfile("bike"). + setCustomModel(new CustomModel().setDistanceInfluence(70d)).setVehicle("bike")); hopper.importOrLoad(); checkQueries(hopper, queries); hopper.getBaseGraph(); @@ -476,7 +478,8 @@ public void testKremsBikeRelation() { Helper.removeDir(new File(GH_LOCATION)); hopper = createHopper(KREMS, - new Profile("bike").setVehicle("bike").setWeighting("fastest"), + new CustomProfile("bike"). + setCustomModel(new CustomModel().setDistanceInfluence(70d)).setVehicle("bike"), new Profile("car").setVehicle("car").setWeighting("fastest")); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -489,15 +492,16 @@ public void testKremsMountainBikeRelation() { queries.add(new Query(48.410061, 15.63951, 48.411386, 15.604899, 3101, 94)); queries.add(new Query(48.412294, 15.62007, 48.398306, 15.609667, 3965, 95)); - GraphHopper hopper = createHopper(KREMS, - new Profile("mtb").setVehicle("mtb").setWeighting("fastest")); + GraphHopper hopper = createHopper(KREMS, new CustomProfile("mtb"). + setCustomModel(new CustomModel().setDistanceInfluence(70d)).setVehicle("mtb")); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); hopper = createHopper(KREMS, - new Profile("mtb").setVehicle("mtb").setWeighting("fastest"), + new CustomProfile("mtb"). + setCustomModel(new CustomModel().setDistanceInfluence(70d)).setVehicle("mtb"), new Profile("bike").setVehicle("bike").setWeighting("fastest")); hopper.importOrLoad(); checkQueries(hopper, queries); diff --git a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java index 3e51120a157..95b3a467e46 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java @@ -87,8 +87,8 @@ void explicitString() { "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":3,\"bwd_shift\":-1,\"fwd_mask\":1016,\"bwd_mask\":0," + "\"factor\":0.1,\"use_maximum_as_infinity\":true}", serialized.get(1)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.SimpleBooleanEncodedValue\",\"name\":\"get_off_bike\",\"bits\":1," + - "\"min_storable_value\":0,\"max_storable_value\":1,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + - "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":-1,\"fwd_mask\":1024,\"bwd_mask\":0}", serialized.get(2)); + "\"min_storable_value\":0,\"max_storable_value\":1,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":true,\"fwd_data_index\":0," + + "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":11,\"fwd_mask\":1024,\"bwd_mask\":2048}", serialized.get(2)); EncodedValue ev0 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(0)); assertEquals("lanes", ev0.getName()); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index 2e0be12b13d..2f61be148f2 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -540,4 +540,120 @@ void privateAndFords() { assertTrue(bike.intendedValues.contains("private")); assertFalse(bike.isBarrier(node)); } + + @Test + public void testOneway() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "tertiary"); + assertAccess(way, true, true); + + way.setTag("oneway", "yes"); + assertAccess(way, true, false); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway:bicycle", "yes"); + assertAccess(way, true, false); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("oneway:bicycle", "no"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("oneway:bicycle", "-1"); + assertAccess(way, false, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("cycleway:right:oneway", "no"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("cycleway:right:oneway", "-1"); + assertAccess(way, false, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("vehicle:forward", "no"); + assertAccess(way, false, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("bicycle:forward", "no"); + assertAccess(way, false, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("vehicle:backward", "no"); + assertAccess(way, true, false); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("motor_vehicle:backward", "no"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("bicycle:backward", "no"); + assertAccess(way, true, false); + + way.setTag("bicycle:backward", "yes"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "residential"); + way.setTag("oneway", "yes"); + way.setTag("bicycle:backward", "yes"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "residential"); + way.setTag("oneway", "-1"); + way.setTag("bicycle:forward", "yes"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("bicycle:forward", "use_sidepath"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("bicycle:forward", "use_sidepath"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("oneway", "yes"); + way.setTag("cycleway", "opposite"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "residential"); + way.setTag("oneway", "yes"); + way.setTag("cycleway:left", "opposite_lane"); + assertAccess(way, true, true); + } + + private void assertAccess(ReaderWay way, boolean fwd, boolean bwd) { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edge = 0; + IntsRef edgeFlags = new IntsRef(1); + IntsRef relationFlags = new IntsRef(1); + accessParser.handleWayTags(edge, edgeIntAccess, way, relationFlags); + if (fwd) assertTrue(accessEnc.getBool(false, edge, edgeIntAccess)); + if (bwd) assertTrue(accessEnc.getBool(true, edge, edgeIntAccess)); + } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 662e8eae6f2..654a96f030c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -366,170 +366,6 @@ public void testWayAcceptance() { assertTrue(accessParser.getAccess(way).canSkip()); } - @Test - public void testOneway() { - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "tertiary"); - EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - int edgeId = 0; - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.setTag("oneway", "yes"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("oneway:bicycle", "yes"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("oneway:bicycle", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("oneway:bicycle", "-1"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("cycleway:right:oneway", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("cycleway:right:oneway", "-1"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("vehicle:forward", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("bicycle:forward", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertFalse(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("vehicle:backward", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("motor_vehicle:backward", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - way.clearTags(); - - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("bicycle:backward", "no"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertFalse(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.setTag("bicycle:backward", "yes"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "residential"); - way.setTag("oneway", "yes"); - way.setTag("bicycle:backward", "yes"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "residential"); - way.setTag("oneway", "-1"); - way.setTag("bicycle:forward", "yes"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("bicycle:forward", "use_sidepath"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("bicycle:forward", "use_sidepath"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("oneway", "yes"); - way.setTag("cycleway", "opposite"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - - way.clearTags(); - way.setTag("highway", "residential"); - way.setTag("oneway", "yes"); - way.setTag("cycleway:left", "opposite_lane"); - edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); - accessParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertTrue(accessParser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - assertTrue(accessParser.getAccessEnc().getBool(true, edgeId, edgeIntAccess)); - } - @Test public void testHandleWayTagsInfluencedByRelation() { ReaderWay osmWay = new ReaderWay(1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java index 08eb6a18f1a..1305e455771 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java @@ -1,8 +1,15 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.*; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.ArrayEdgeIntAccess; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.GetOffBike; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.VehicleEncodedValues; import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -10,10 +17,14 @@ public class OSMGetOffBikeParserTest { private final BooleanEncodedValue offBikeEnc = GetOffBike.create(); - private final OSMGetOffBikeParser parser = new OSMGetOffBikeParser(offBikeEnc); + private final BikeAccessParser accessParser; + private final OSMGetOffBikeParser getOffParser; public OSMGetOffBikeParserTest() { - offBikeEnc.init(new EncodedValue.InitializerConfig()); + EncodingManager em = new EncodingManager.Builder().add(offBikeEnc).add(VehicleEncodedValues.bike(new PMap()).getAccessEnc()).build(); + accessParser = new BikeAccessParser(em, new PMap()); + accessParser.init(new DateRangeParser()); + getOffParser = new OSMGetOffBikeParser(offBikeEnc, accessParser.getAccessEnc()); } @Test @@ -96,11 +107,28 @@ public void testHandleCommonWayTags() { assertTrue(isGetOffBike(way)); } + @Test + public void testOneway() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "primary"); + way.setTag("oneway", "yes"); + + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + IntsRef rel = new IntsRef(1); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, new IntsRef(1)); + getOffParser.handleWayTags(edgeId, edgeIntAccess, way, new IntsRef(1)); + + assertFalse(offBikeEnc.getBool(false, edgeId, edgeIntAccess)); + assertTrue(offBikeEnc.getBool(true, edgeId, edgeIntAccess)); + } + private boolean isGetOffBike(ReaderWay way) { EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); int edgeId = 0; - IntsRef relationFlags = new IntsRef(1); - parser.handleWayTags(edgeId, edgeIntAccess, way, relationFlags); + IntsRef rel = new IntsRef(1); + accessParser.handleWayTags(edgeId, edgeIntAccess, way, rel); + getOffParser.handleWayTags(edgeId, edgeIntAccess, way, rel); return offBikeEnc.getBool(false, edgeId, edgeIntAccess); } } \ No newline at end of file diff --git a/custom_models/bike.json b/custom_models/bike.json index a584226e99e..074153ac6bb 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -1,6 +1,21 @@ +// to use this custom model you need to set the following option in the config.yml +// graph.vehicles: roads,bike +// graph.encoded_values: average_slope,max_slope +// profiles: +// - name: bike +// vehicle: roads +// weighting: custom +// custom_model_file: bike.json + { - "distance_influence": 10, + "priority": [ + { "if": "true", "multiply_by": "bike_priority" }, + { "if": "!bike_access && !backward_bike_access", "multiply_by": "0" }, + { "else_if": "!bike_access && backward_bike_access && !roundabout", "multiply_by": "0.2" } + ], "speed": [ + { "if": "true", "limit_to": "bike_average_speed" }, + { "if": "!bike_access && backward_bike_access && !roundabout", "limit_to": "5" }, { "if": "average_slope >= 10", "limit_to": "4" }, { "if": "average_slope >= 5", "multiply_by": "0.45" }, { "if": "average_slope >= 3.5", "multiply_by": "0.7" }, diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index 8fb7e43e511..54b57932efe 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -27,7 +27,6 @@ import com.graphhopper.application.util.TestUtils; import com.graphhopper.config.CHProfile; import com.graphhopper.config.Profile; -import com.graphhopper.json.Statement; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.util.*; import com.graphhopper.util.details.PathDetail; @@ -46,6 +45,8 @@ import java.io.File; import java.util.*; +import static com.graphhopper.json.Statement.If; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.Instruction.FINISH; import static com.graphhopper.util.Instruction.REACHED_VIA; import static org.junit.jupiter.api.Assertions.*; @@ -71,7 +72,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("graph.location", DIR) .setProfiles(Arrays.asList( new Profile("car").setVehicle("car").setWeighting("fastest"), - new Profile("bike").setVehicle("bike").setWeighting("fastest"), + new CustomProfile("bike").setCustomModel(new CustomModel()).setVehicle("bike"), new CustomProfile("my_custom_car").setCustomModel(new CustomModel()).setVehicle("car") )) .setCHProfiles(Arrays.asList(new CHProfile("car"), new CHProfile("bike"))); @@ -368,7 +369,7 @@ public void testCustomModel() { addPoint(new GHPoint(42.532022, 1.519504)). setCustomModel(new CustomModel().setDistanceInfluence(70d) // we reduce the speed in the long tunnel - .addToSpeed(Statement.If("road_environment == TUNNEL", Statement.Op.MULTIPLY, "0.1"))). + .addToSpeed(If("road_environment == TUNNEL", MULTIPLY, "0.1"))). setProfile("my_custom_car"). putHint("ch.disable", true); GHResponse rsp = gh.route(req); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 34dfb46f6ff..2450b86a200 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -18,12 +18,15 @@ package com.graphhopper.application.resources; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; import com.graphhopper.application.util.GraphHopperServerTestConfiguration; import com.graphhopper.config.CHProfile; import com.graphhopper.config.Profile; +import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; @@ -41,6 +44,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import static com.graphhopper.application.util.TestUtils.clientTarget; @@ -63,7 +69,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("datareader.file", "../core/files/north-bayreuth.osm.gz"). putObject("graph.location", DIR). putObject("graph.encoded_values", "max_height,max_weight,max_width,hazmat,toll,surface,track_type,hgv,average_slope,max_slope"). - putObject("custom_models.directory", "../custom_models"). + putObject("custom_models.directory", "../custom_models/"). putObject("custom_areas.directory", "./src/test/resources/com/graphhopper/application/resources/areas"). putObject("import.osm.ignored_highways", ""). setProfiles(Arrays.asList( @@ -76,7 +82,7 @@ private static GraphHopperServerConfiguration createConfig() { new CustomProfile("bus").setVehicle("roads").putHint("custom_model_file", "bus.json"), new CustomProfile("cargo_bike").setVehicle("bike"). putHint("custom_model_file", "cargo_bike.json"), - new CustomProfile("json_bike").setVehicle("bike"). + new CustomProfile("json_bike").setVehicle("roads"). putHint("custom_model_file", "bike.json"), new Profile("foot_profile").setVehicle("foot").setWeighting("fastest"), new CustomProfile("car_no_unclassified").setCustomModel( @@ -219,14 +225,16 @@ public void testCargoBike() throws IOException { @Test public void testJsonBike() { - String jsonQuery = "{" + - " \"points\": [[11.58199, 50.0141], [11.5865, 50.0095]]," + - " \"profile\": \"json_bike\"," + - " \"custom_model\": {}," + - " \"ch.disable\": true" + - "}"; + String jsonQuery = "{\"points\": [[11.58199, 50.0141], [11.5865, 50.0095]]," + + " \"profile\": \"json_bike\", \"ch.disable\": true }"; JsonNode path = getPath(jsonQuery); assertEquals(660, path.get("distance").asDouble(), 10); + + // check reverse oneway is allowed for short distances + jsonQuery = "{\"points\": [[11.545768,50.020137], [11.545728,50.020115]]," + + " \"profile\": \"json_bike\", \"ch.disable\": true }"; + path = getPath(jsonQuery); + assertEquals(4, path.get("distance").asDouble(), 1); } @Test diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java index 24b4a7b2cd5..943a509016e 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java @@ -25,6 +25,8 @@ import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.routing.weighting.custom.CustomProfile; +import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; import io.dropwizard.testing.junit5.DropwizardAppExtension; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -40,6 +42,8 @@ import java.util.Arrays; import static com.graphhopper.application.util.TestUtils.clientTarget; +import static com.graphhopper.json.Statement.If; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static org.junit.jupiter.api.Assertions.*; @ExtendWith(DropwizardExtensionsSupport.class) @@ -58,7 +62,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("graph.location", DIR) .setProfiles(Arrays.asList( new Profile("my_car").setVehicle("car").setWeighting("fastest"), - new Profile("my_bike").setVehicle("bike").setWeighting("short_fastest"), + new CustomProfile("my_bike").setCustomModel(new CustomModel().setDistanceInfluence(200d)).setVehicle("bike"), new Profile("my_feet").setVehicle("foot").setWeighting("shortest") )) .setCHProfiles(Arrays.asList( From 528dde4b950938927096dcdbea25ba417a4d89b2 Mon Sep 17 00:00:00 2001 From: ratrun Date: Wed, 29 Mar 2023 21:31:29 +0200 Subject: [PATCH 016/165] Never treat a highway tagged with cycleway:both as oneway for bicycles (#2776) --- .../routing/util/parsers/BikeCommonAccessParser.java | 1 + .../util/parsers/AbstractBikeTagParserTester.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 59a9f5fc191..305639a1610 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -145,6 +145,7 @@ protected void handleAccess(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay w if ((isOneway || roundaboutEnc.getBool(false, edgeId, edgeIntAccess)) && !way.hasTag("oneway:bicycle", "no") + && !(way.hasTag("cycleway:both") && !way.hasTag("cycleway:both", "no")) && !way.hasTag("cycleway", OPP_LANES) && !way.hasTag("cycleway:left", OPP_LANES) && !way.hasTag("cycleway:right", OPP_LANES) diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index 2f61be148f2..d2ad5ff08b7 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -645,6 +645,18 @@ public void testOneway() { way.setTag("oneway", "yes"); way.setTag("cycleway:left", "opposite_lane"); assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "secondary"); + way.setTag("cycleway:left:oneway", "-1"); + way.setTag("cycleway:both", "track"); + assertAccess(way, true, true); + + way.clearTags(); + way.setTag("highway", "secondary"); + way.setTag("oneway", "yes"); + way.setTag("cycleway:both", "no"); + assertAccess(way, true, false); } private void assertAccess(ReaderWay way, boolean fwd, boolean bwd) { From 42f7f8053ee7bf9d09813b07d4aeb4b13ef7b465 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 30 Mar 2023 09:15:42 +0200 Subject: [PATCH 017/165] include permit->private handling in road_access, #2712, #2749 --- .../util/parsers/OSMRoadAccessParser.java | 4 ++-- .../util/parsers/RoadsAccessParser.java | 6 ++++- .../util/parsers/OSMRoadAccessParserTest.java | 23 +++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java index 2534c747c10..5f7ad0f0bf5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java @@ -18,8 +18,8 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; @@ -69,7 +69,7 @@ private RoadAccess getRoadAccess(String tagValue, RoadAccess accessValue) { if (tagValue != null) { String[] complex = tagValue.split(";"); for (String simple : complex) { - tmpAccessValue = RoadAccess.find(simple); + tmpAccessValue = simple.equals("permit") ? RoadAccess.PRIVATE : RoadAccess.find(simple); if (tmpAccessValue != null && tmpAccessValue.ordinal() > accessValue.ordinal()) { accessValue = tmpAccessValue; } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java index 17be2eef811..b73176e9472 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RoadsAccessParser.java @@ -2,12 +2,16 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.VehicleAccess; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; +/** + * Access parser (boolean) for the 'roads' vehicle. Not to be confused with OSMRoadAccessParser that fills road_access + * enum (for car). + */ public class RoadsAccessParser implements TagParser { private final BooleanEncodedValue accessEnc; diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java index 74aead04caf..d88115dcc47 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java @@ -23,18 +23,23 @@ import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.storage.IntsRef; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; class OSMRoadAccessParserTest { + EnumEncodedValue roadAccessEnc = RoadAccess.create(); + private OSMRoadAccessParser parser; + + @BeforeEach + public void setup() { + roadAccessEnc.init(new EncodedValue.InitializerConfig()); + parser = new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); + } @Test void countryRule() { - EnumEncodedValue roadAccessEnc = RoadAccess.create(); - roadAccessEnc.init(new EncodedValue.InitializerConfig()); - - OSMRoadAccessParser parser = new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); IntsRef relFlags = new IntsRef(2); ReaderWay way = new ReaderWay(27L); way.setTag("highway", "track"); @@ -65,4 +70,14 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati } + @Test + public void testPermit() { + ArrayEdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + ReaderWay way = new ReaderWay(27L); + way.setTag("motor_vehicle", "permit"); + parser.handleWayTags(edgeId, edgeIntAccess, way, new IntsRef(1)); + assertEquals(RoadAccess.PRIVATE, roadAccessEnc.getEnum(false, edgeId, edgeIntAccess)); + } + } \ No newline at end of file From a9216c7a117887e4b078dbdca717514e8005b987 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 30 Mar 2023 13:34:38 +0200 Subject: [PATCH 018/165] add 4 more enc values to config description --- config-example.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config-example.yml b/config-example.yml index 8286cc560ac..57c0638a108 100644 --- a/config-example.yml +++ b/config-example.yml @@ -83,8 +83,9 @@ graphhopper: # Add additional information to every edge. Used for path details (#1548) and custom models (docs/core/custom-models.md) # Default values are: road_class,road_class_link,road_environment,max_speed,road_access - # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water, - # lanes,osm_way_id,toll,track_type,mtb_rating,hike_rating,horse_rating + # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length, + # hazmat,hazmat_tunnel,hazmat_water,lanes,osm_way_id,toll,track_type,mtb_rating,hike_rating,horse_rating, + # country,curvature,average_slope,max_slope # graph.encoded_values: surface,toll,track_type #### Speed, hybrid and flexible mode #### From 402976482c3dbe76cb1d3beda0404435ec0b4155 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 1 Apr 2023 12:58:38 +0200 Subject: [PATCH 019/165] avoid get_off_bike problem for path, fixes #2777 --- .../routing/util/parsers/OSMGetOffBikeParser.java | 11 +++++++---- .../util/parsers/OSMGetOffBikeParserTest.java | 13 ++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java index c00a7feada6..96ff99ce6d8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParser.java @@ -16,8 +16,8 @@ public class OSMGetOffBikeParser implements TagParser { private final List INTENDED = Arrays.asList("designated", "yes", "official", "permissive"); - // steps -> special handling - private final HashSet GET_OFF_BIKE = new HashSet<>(Arrays.asList("path", "footway", "pedestrian", "platform")); + // steps -> special handling, path -> see #2777 + private final HashSet GET_OFF_BIKE = new HashSet<>(Arrays.asList("footway", "pedestrian", "platform")); private final BooleanEncodedValue getOffBikeEnc; private final BooleanEncodedValue bikeAccessEnc; @@ -32,8 +32,11 @@ public OSMGetOffBikeParser(BooleanEncodedValue getOffBikeEnc, BooleanEncodedValu @Override public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { String highway = way.getTag("highway"); - if (!way.hasTag("bicycle", INTENDED) && (GET_OFF_BIKE.contains(highway) || way.hasTag("railway", "platform")) - || "steps".equals(highway) || way.hasTag("bicycle", "dismount")) { + boolean notIntended = !way.hasTag("bicycle", INTENDED) && + (GET_OFF_BIKE.contains(highway) + || way.hasTag("railway", "platform") + || "path".equals(highway) && way.hasTag("foot", "designated") && !way.hasTag("segregated", "yes")); + if ("steps".equals(highway) || way.hasTag("bicycle", "dismount") || notIntended) { getOffBikeEnc.setBool(false, edgeId, edgeIntAccess, true); getOffBikeEnc.setBool(true, edgeId, edgeIntAccess, true); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java index 1305e455771..c3dc0a29ea8 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMGetOffBikeParserTest.java @@ -80,14 +80,19 @@ public void testHandleCommonWayTags() { way.setTag("foot", "yes"); assertFalse(isGetOffBike(way)); + way = new ReaderWay(1); + way.setTag("highway", "track"); + assertFalse(isGetOffBike(way)); + way = new ReaderWay(1); way.setTag("highway", "pedestrian"); assertTrue(isGetOffBike(way)); + // situation for path is unclear, see #2777, let's mark it only if foot=designated way = new ReaderWay(1); way.setTag("highway", "path"); way.setTag("surface", "concrete"); - assertTrue(isGetOffBike(way)); + assertFalse(isGetOffBike(way)); way.setTag("bicycle", "yes"); assertFalse(isGetOffBike(way)); way.setTag("bicycle", "designated"); @@ -97,12 +102,10 @@ public void testHandleCommonWayTags() { way.setTag("bicycle", "permissive"); assertFalse(isGetOffBike(way)); - way = new ReaderWay(1); - way.setTag("highway", "track"); - assertFalse(isGetOffBike(way)); - way = new ReaderWay(1); way.setTag("highway", "path"); + way.setTag("foot", "yes"); + assertFalse(isGetOffBike(way)); // for now only designated will trigger true way.setTag("foot", "designated"); assertTrue(isGetOffBike(way)); } From 1856806c61df9d156c15453ecf40fcf0599c16b0 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 2 Apr 2023 20:45:59 +0200 Subject: [PATCH 020/165] fix bug in bike custom model --- .../routing/RoutingAlgorithmWithOSMTest.java | 16 ++++++++-------- custom_models/bike.json | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 9291f778741..f68fff36089 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -349,22 +349,22 @@ public void testHikeCanUseExtremeSacScales() { public void testMonacoBike3D() { List queries = new ArrayList<>(); // 1. alternative: go over steps 'Rampe Major' => 1.7km vs. around 2.7km - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 1999, 101)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2689, 118)); // 2. - queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 3939, 187)); + queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 4188, 217)); // 3. - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 163)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 167)); // 4. queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1544, 84)); // try reverse direction // 1. - queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2599, 115)); - queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 4230, 201)); - queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2870, 154)); + queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2111, 96)); + queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 3903, 199)); + queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2805, 145)); // 4. avoid tunnel(s)! - queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1795, 96)); - // atm custom model is intended to be used with 'roads' vehicle when allowing reverse direction for oneways + queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1630, 96)); + // atm the custom model is intended to be used with 'roads' vehicle when allowing reverse direction for oneways // but tests here still assert that reverse oneways are excluded GraphHopper hopper = createHopper(MONACO, new CustomProfile("bike").setCustomModel(getCustomModel("bike.json"). diff --git a/custom_models/bike.json b/custom_models/bike.json index 074153ac6bb..1a3c1c35083 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -16,10 +16,10 @@ "speed": [ { "if": "true", "limit_to": "bike_average_speed" }, { "if": "!bike_access && backward_bike_access && !roundabout", "limit_to": "5" }, - { "if": "average_slope >= 10", "limit_to": "4" }, - { "if": "average_slope >= 5", "multiply_by": "0.45" }, - { "if": "average_slope >= 3.5", "multiply_by": "0.7" }, - { "if": "average_slope >= 2", "multiply_by": "0.9" }, - { "if": "average_slope < -5", "multiply_by": "1.25" } + + { "if": "average_slope >= 15", "limit_to": "2"}, + { "else_if": "average_slope >= 7", "limit_to": "4"}, + { "else_if": "average_slope >= 4", "multiply_by": "0.85"}, + { "else_if": "average_slope <= -4", "multiply_by": "1.15"} ] } \ No newline at end of file From ca9b038b477bb6d9fa4feab56e833dafb0478fe3 Mon Sep 17 00:00:00 2001 From: ratrun Date: Mon, 3 Apr 2023 11:20:50 +0200 Subject: [PATCH 021/165] Improve bicycle handling: Now prioritise cycleways with SLIGHT_PREFER (#2785) * Improve bicycle handling: Now prioritise cycleways with SLIGHT_PREFER, fixes #2784 * Add priority handling support for "cycleway:both" i "lane" * Add priority handling support for "cycleway=opposite_track" as discussed in #2786. --- .../util/parsers/BikeCommonPriorityParser.java | 6 +++--- .../routing/util/parsers/BikeTagParserTest.java | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index 0ba95fdfac7..d15fffa7b73 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -175,9 +175,9 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight weightToPrioMap.put(50d, BAD.getValue()); } - String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right")); - if (Arrays.asList("lane", "shared_lane", "share_busway", "shoulder").contains(cycleway)) { - weightToPrioMap.put(100d, UNCHANGED.getValue()); + String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right", "cycleway:both")); + if (Arrays.asList("lane", "shared_lane", "share_busway", "shoulder").contains(cycleway) || "opposite_track".equals(cycleway)) { + weightToPrioMap.put(100d, SLIGHT_PREFER.getValue()); } else if ("track".equals(cycleway)) { weightToPrioMap.put(100d, PREFER.getValue()); } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 654a96f030c..fa8adecd031 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -312,18 +312,30 @@ public void testCycleway() { way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:left", "lane"); - assertPriority(UNCHANGED.getValue(), way); + assertPriority(SLIGHT_PREFER.getValue(), way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:right", "lane"); - assertPriority(UNCHANGED.getValue(), way); + assertPriority(SLIGHT_PREFER.getValue(), way); + + way.clearTags(); + way.setTag("highway", "primary"); + way.setTag("cycleway:both", "lane"); + assertPriority(SLIGHT_PREFER.getValue(), way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("oneway", "yes"); way.setTag("cycleway:left", "opposite_lane"); assertPriority(AVOID.getValue(), way); + + way.clearTags(); + way.setTag("highway", "primary"); + way.setTag("oneway", "yes"); + way.setTag("cycleway", "opposite_track"); + assertPriority(SLIGHT_PREFER.getValue(), way); + } @Test From 8c60d14a508decb6410e438e23931db58d5a85bb Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 13:16:24 +0200 Subject: [PATCH 022/165] custom_model_files arrays (#2787) * replace custom_model_file with custom_model_files array * fix changelog --- CHANGELOG.md | 1 + config-example.yml | 10 ++-- .../weighting/custom/CustomProfile.java | 4 +- .../routing/RoutingAlgorithmWithOSMTest.java | 2 +- custom_models/bike.json | 10 ++-- custom_models/bike_elevation.json | 8 ++++ custom_models/bus.json | 2 +- custom_models/car4wd.json | 2 +- custom_models/foot_elevation.json | 8 ++++ custom_models/hike.json | 8 +--- custom_models/truck.json | 2 +- docs/core/profiles.md | 8 ++-- .../graphhopper/http/GraphHopperManaged.java | 48 +++++++++++-------- .../RouteResourceCustomModelTest.java | 6 +-- .../resources/RouteResourceTruckTest.java | 6 +-- .../resources/RouteResourceTurnCostsTest.java | 7 ++- 16 files changed, 77 insertions(+), 55 deletions(-) create mode 100644 custom_models/bike_elevation.json create mode 100644 custom_models/foot_elevation.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dfb15cdada..4f0913efe0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 8.0 [not yet released] +- custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 diff --git a/config-example.yml b/config-example.yml index 57c0638a108..f315cdc2323 100644 --- a/config-example.yml +++ b/config-example.yml @@ -23,9 +23,10 @@ graphhopper: # - u_turn_costs: 60 (time-penalty for doing a u-turn in seconds (only possible when `turn_costs: true`)). # Note that since the u-turn costs are given in seconds the weighting you use should also calculate the weight # in seconds, so for example it does not work with shortest weighting. - # - custom_model_file: when you specified "weighting: custom" you need to set a json file inside your custom_models.directory - # or working directory that defines the custom_model. If you want an empty model you can also set "custom_model_file: empty". - # You can also use th e`custom_model` field instead and specify your custom model in the profile directly. + # - custom_model_files: when you specified "weighting: custom" you need to set one or more json files which are searched in + # custom_models.directory or the working directory that defines the custom_model. If you want an empty model you can + # set "custom_model_files: [] + # You can also use the `custom_model` field instead and specify your custom model in the profile directly. # # To prevent long running routing queries you should usually enable either speed or hybrid mode for all the given # profiles (see below). Or at least limit the number of `routing.max_visited_nodes`. @@ -43,8 +44,7 @@ graphhopper: # # to use the bike vehicle make sure to not ignore cycleways etc., see import.osm.ignored_highways below # vehicle: bike # weighting: custom -# # the custom model in bike.json is defined to avoid hills -# custom_model_file: bike.json +# custom_model_files: [bike.json, bike_elevation.json] # specify the folder where to find the custom model files custom_models.directory: custom_models diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomProfile.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomProfile.java index 687cc23444f..372d0190be9 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomProfile.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomProfile.java @@ -20,6 +20,8 @@ import com.graphhopper.config.Profile; import com.graphhopper.util.CustomModel; +import java.util.Collections; + public class CustomProfile extends Profile { public CustomProfile(Profile profile) { @@ -37,7 +39,7 @@ public CustomProfile(String name) { public CustomProfile setCustomModel(CustomModel customModel) { customModel.internal(); getHints().putObject(CustomModel.KEY, customModel); - getHints().putObject("custom_model_file", "empty"); + getHints().putObject("custom_model_files", Collections.emptyList()); return this; } diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index f68fff36089..4b6d8ca5ca6 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -367,7 +367,7 @@ public void testMonacoBike3D() { // atm the custom model is intended to be used with 'roads' vehicle when allowing reverse direction for oneways // but tests here still assert that reverse oneways are excluded GraphHopper hopper = createHopper(MONACO, - new CustomProfile("bike").setCustomModel(getCustomModel("bike.json"). + new CustomProfile("bike").setCustomModel(CustomModel.merge(getCustomModel("bike.json"), getCustomModel("bike_elevation.json")). addToPriority(If("!bike_access", MULTIPLY, "0"))).setVehicle("roads")); hopper.setVehiclesString("roads,bike"); hopper.setElevationProvider(new SRTMProvider(DIR)); diff --git a/custom_models/bike.json b/custom_models/bike.json index 1a3c1c35083..801d17866b6 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -1,11 +1,12 @@ // to use this custom model you need to set the following option in the config.yml // graph.vehicles: roads,bike // graph.encoded_values: average_slope,max_slope +// graph.elevation.provider: srtm # enables elevation // profiles: // - name: bike // vehicle: roads // weighting: custom -// custom_model_file: bike.json +// custom_model_files: [bike.json, bike_elevation.json] { "priority": [ @@ -15,11 +16,6 @@ ], "speed": [ { "if": "true", "limit_to": "bike_average_speed" }, - { "if": "!bike_access && backward_bike_access && !roundabout", "limit_to": "5" }, - - { "if": "average_slope >= 15", "limit_to": "2"}, - { "else_if": "average_slope >= 7", "limit_to": "4"}, - { "else_if": "average_slope >= 4", "multiply_by": "0.85"}, - { "else_if": "average_slope <= -4", "multiply_by": "1.15"} + { "if": "!bike_access && backward_bike_access && !roundabout", "limit_to": "5" } ] } \ No newline at end of file diff --git a/custom_models/bike_elevation.json b/custom_models/bike_elevation.json new file mode 100644 index 00000000000..5b19a2eeb9f --- /dev/null +++ b/custom_models/bike_elevation.json @@ -0,0 +1,8 @@ +{ + "speed": [ + { "if": "average_slope >= 15", "limit_to": "2"}, + { "else_if": "average_slope >= 7", "limit_to": "4"}, + { "else_if": "average_slope >= 4", "multiply_by": "0.85"}, + { "else_if": "average_slope <= -4", "multiply_by": "1.15"} + ] +} diff --git a/custom_models/bus.json b/custom_models/bus.json index accaf3a334d..c852206bbbf 100644 --- a/custom_models/bus.json +++ b/custom_models/bus.json @@ -5,7 +5,7 @@ // - name: bus // vehicle: roads // weighting: custom -// custom_model_file: bus.json +// custom_model_files: [bus.json] { "distance_influence": 90, diff --git a/custom_models/car4wd.json b/custom_models/car4wd.json index 0ee6f262332..ee3994e0fa4 100644 --- a/custom_models/car4wd.json +++ b/custom_models/car4wd.json @@ -5,7 +5,7 @@ // - name: car4wd // vehicle: roads // weighting: custom -// custom_model_file: car4wd.json +// custom_model_files: [car4wd.json] { "distance_influence": 1, diff --git a/custom_models/foot_elevation.json b/custom_models/foot_elevation.json new file mode 100644 index 00000000000..a9c970be2fc --- /dev/null +++ b/custom_models/foot_elevation.json @@ -0,0 +1,8 @@ +{ + "speed": [ + { "if": "average_slope >= 15", "limit_to": "1.5"}, + { "else_if": "average_slope >= 7", "limit_to": "2.5"}, + { "else_if": "average_slope >= 4", "multiply_by": "0.85"}, + { "else_if": "average_slope <= -4", "multiply_by": "1.05"} + ] +} diff --git a/custom_models/hike.json b/custom_models/hike.json index 51888f80efe..29cb7965e1a 100644 --- a/custom_models/hike.json +++ b/custom_models/hike.json @@ -6,7 +6,7 @@ // - name: hike // vehicle: roads // weighting: custom -// custom_model_file: hike.json +// custom_model_files: [hike.json, foot_elevation.json] { "priority": [ @@ -18,10 +18,6 @@ "speed": [ { "if": "hike_rating < 1", "limit_to": "foot_average_speed" }, { "else_if": "hike_rating > 2", "limit_to": "2" }, - { "else": "", "limit_to": "4" }, - { "if": "average_slope >= 15", "limit_to": "1.5"}, - { "else_if": "average_slope >= 7", "limit_to": "2.5"}, - { "else_if": "average_slope >= 4", "multiply_by": "0.85"}, - { "else_if": "average_slope <= -4", "multiply_by": "1.05"} + { "else": "", "limit_to": "4" } ] } \ No newline at end of file diff --git a/custom_models/truck.json b/custom_models/truck.json index b0fcdfcc42e..25ab1df3759 100644 --- a/custom_models/truck.json +++ b/custom_models/truck.json @@ -5,7 +5,7 @@ // - name: truck // vehicle: roads // weighting: custom -// custom_model_file: truck.json +// custom_model_files: [truck.json] { "distance_influence": 1, "speed": [ diff --git a/docs/core/profiles.md b/docs/core/profiles.md index 529e5684c75..3dd78b02a4b 100644 --- a/docs/core/profiles.md +++ b/docs/core/profiles.md @@ -83,7 +83,7 @@ profiles: The name and vehicle fields are the same as for standard profiles and the vehicle field is used as the 'base' vehicle for the custom profile. The weighting must be always set to `custom` for custom profiles. The custom model itself goes into the `custom_model` property. Alternatively, you can also set a path to a custom model file using the -`custom_models.directory` and `custom_model_file` properties. +`custom_models.directory` and `custom_model_files` properties. Using custom profiles for your routing requests works just the same way as for standard profiles. Simply add `profile=my_custom_profile` as request parameter to your routing request. @@ -194,12 +194,12 @@ So say your routing request (POST /route) looks like this: where in `config.yml` we have: ```yaml -custom_model_file: path/to/my/custom/models +custom_models.directory: path/to/my/custom/models profiles: - name: my_custom_car vehicle: car weighting: custom - custom_model_file: my_custom_car.json + custom_model_files: [my_custom_car.json] ``` and `my_custom_car.json` looks like this: @@ -244,7 +244,7 @@ then the resulting custom model used for your request will look like this: ``` You do not necessarily need to define a proper custom model on the server side, but you can also use the special -value `custom_model_file: empty` or simply `custom_model: {}`, which means an empty custom model containing no +value `custom_model_files: []` or `custom_model: {}`, which means an empty custom model containing no statements will be used on the server-side. This way you can leave it entirely up to the user/client how the custom model shall look like. diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java index 045b056dfe2..ab3315677cf 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java @@ -27,7 +27,9 @@ import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; -import com.graphhopper.util.*; +import com.graphhopper.util.CustomModel; +import com.graphhopper.util.Helper; +import com.graphhopper.util.JsonFeatureCollection; import io.dropwizard.lifecycle.Managed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,29 +102,35 @@ public static List resolveCustomModelFiles(String customModelFolder, Li newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); } catch (Exception ex) { throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName() - + ". If you are trying to load from a file, use 'custom_model_file' instead.", ex); + + ". If you are trying to load from a file, use 'custom_model_files' instead.", ex); } } else { - String customModelFileName = profile.getHints().getString("custom_model_file", ""); - if (customModelFileName.isEmpty()) - throw new IllegalArgumentException("Missing 'custom_model' or 'custom_model_file' field in profile '" - + profile.getName() + "'. To use default specify custom_model_file: empty"); - if ("empty".equals(customModelFileName)) + if (!profile.getHints().getString("custom_model_file", "").isEmpty()) + throw new IllegalArgumentException("Since 8.0 you must use a custom_model_files array instead of custom_model_file string"); + List customModelFileNames = profile.getHints().getObject("custom_model_files", null); + if (customModelFileNames == null) + throw new IllegalArgumentException("Missing 'custom_model' or 'custom_model_files' field in profile '" + + profile.getName() + "'. To use default specify custom_model_files: []"); + if (customModelFileNames.isEmpty()) { newProfiles.add(new CustomProfile(profile).setCustomModel(customModel = new CustomModel())); - else { - if (customModelFileName.contains(File.separator)) - throw new IllegalArgumentException("Use custom_models.directory for the custom_model_file parent"); - if (!customModelFileName.endsWith(".json")) - throw new IllegalArgumentException("Yaml is no longer supported, see #2672. Use JSON with optional comments //"); - try { - // Somehow dropwizard makes it very hard to find out the folder of config.yml -> use an extra parameter for the folder - String string = Helper.readJSONFileWithoutComments(Paths.get(customModelFolder). - resolve(customModelFileName).toFile().getAbsolutePath()); - customModel = jsonOM.readValue(string, CustomModel.class); - newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); - } catch (Exception ex) { - throw new RuntimeException("Cannot load custom_model from location " + customModelFileName + " for profile " + profile.getName(), ex); + } else { + customModel = new CustomModel(); + for (String file : customModelFileNames) { + if (file.contains(File.separator)) + throw new IllegalArgumentException("Use custom_models.directory for the custom_model_files parent"); + if (!file.endsWith(".json")) + throw new IllegalArgumentException("Yaml is no longer supported, see #2672. Use JSON with optional comments //"); + try { + // Somehow dropwizard makes it very hard to find out the folder of config.yml -> use an extra parameter for the folder + String string = Helper.readJSONFileWithoutComments(Paths.get(customModelFolder). + resolve(file).toFile().getAbsolutePath()); + customModel = CustomModel.merge(customModel, jsonOM.readValue(string, CustomModel.class)); + } catch (Exception ex) { + throw new RuntimeException("Cannot load custom_model from location " + file + " for profile " + profile.getName(), ex); + } } + + newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); } } diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 2450b86a200..1182372660c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -79,11 +79,11 @@ private static GraphHopperServerConfiguration createConfig() { new CustomProfile("car_with_area").setCustomModel(new CustomModel().addToPriority(If("in_external_area52", MULTIPLY, "0.05"))), new CustomProfile("bike").setCustomModel(new CustomModel().setDistanceInfluence(0d)).setVehicle("bike"), new Profile("bike_fastest").setWeighting("fastest").setVehicle("bike"), - new CustomProfile("bus").setVehicle("roads").putHint("custom_model_file", "bus.json"), + new CustomProfile("bus").setVehicle("roads").putHint("custom_model_files", Arrays.asList("bus.json")), new CustomProfile("cargo_bike").setVehicle("bike"). - putHint("custom_model_file", "cargo_bike.json"), + putHint("custom_model_files", Arrays.asList("cargo_bike.json")), new CustomProfile("json_bike").setVehicle("roads"). - putHint("custom_model_file", "bike.json"), + putHint("custom_model_files", Arrays.asList("bike.json", "bike_elevation.json")), new Profile("foot_profile").setVehicle("foot").setWeighting("fastest"), new CustomProfile("car_no_unclassified").setCustomModel( new CustomModel(new CustomModel(). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTruckTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTruckTest.java index b0408ad5716..f9a8b0ce918 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTruckTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTruckTest.java @@ -37,7 +37,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("graph.encoded_values", "max_height,max_weight,max_width,hazmat,toll,surface,hgv"). putObject("import.osm.ignored_highways", ""). putObject("custom_models.directory", "./src/test/resources/com/graphhopper/application/resources"). - setProfiles(Arrays.asList(new CustomProfile("truck").setVehicle("roads").putHint("custom_model_file", "truck.json"))). + setProfiles(Arrays.asList(new CustomProfile("truck").setVehicle("roads").putHint("custom_model_files", Arrays.asList("truck.json")))). setCHProfiles(Arrays.asList(new CHProfile("truck"))); return config; } @@ -65,8 +65,8 @@ public void testDisableCHAndUseCustomModel() { // ... but when we disable CH it works body = "{\"points\": [[11.58199, 50.0141], [11.5865, 50.0095]], \"profile\": \"truck\", \"custom_model\": {}, \"ch.disable\": true}"; JsonNode path = query(body, 200).readEntity(JsonNode.class).get("paths").get(0); - assertEquals(path.get("distance").asDouble(), 1008, 10); - assertEquals(path.get("time").asLong(), 49_000, 1_000); + assertEquals(1008, path.get("distance").asDouble(), 10); + assertEquals(49_000, path.get("time").asLong(), 1_000); } private void assertMessageStartsWith(JsonNode jsonNode, String message) { diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java index 2d453b8ef95..a21279d8eb2 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java @@ -25,6 +25,8 @@ import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.routing.weighting.custom.CustomProfile; +import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; import io.dropwizard.testing.junit5.DropwizardAppExtension; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -38,6 +40,7 @@ import javax.ws.rs.core.Response; import java.io.File; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static com.graphhopper.application.util.TestUtils.clientTarget; @@ -61,8 +64,8 @@ private static GraphHopperServerConfiguration createConfig() { .setProfiles(Arrays.asList( new Profile("my_car_turn_costs").setVehicle("car").setWeighting("fastest").setTurnCosts(true), new Profile("my_car_no_turn_costs").setVehicle("car").setWeighting("fastest").setTurnCosts(false), - new Profile("my_custom_car_turn_costs").setVehicle("car").setWeighting("custom").setTurnCosts(true).putHint("custom_model_file", "empty"), - new Profile("my_custom_car_no_turn_costs").setVehicle("car").setWeighting("custom").setTurnCosts(false).putHint("custom_model_file", "empty") + new CustomProfile("my_custom_car_turn_costs").setCustomModel(new CustomModel()).setVehicle("car").setTurnCosts(true), + new CustomProfile("my_custom_car_no_turn_costs").setCustomModel(new CustomModel()).setVehicle("car").setTurnCosts(false) )) .setCHProfiles(Arrays.asList( new CHProfile("my_car_turn_costs"), From 0dc5dabe469d6139193f83dd5cf584578d92a571 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 14:08:24 +0200 Subject: [PATCH 023/165] certain conditional tags allow to ignore max_weight (#2788) * add max_weight_except encoded value; use conditional tagging to set hgv and max_weight; add maxweightrating:hgv parsing for max_weight * include maxweightrating:hgv for MaxWeightExceptParser too * Apply suggestions from code review Co-authored-by: otbutz * Update MaxWeightExceptParser.java * Update OSMMaxWeightParser.java * fix import --------- Co-authored-by: otbutz --- config-example.yml | 2 +- .../ev/DefaultEncodedValueFactory.java | 2 + .../routing/ev/MaxWeightExcept.java | 35 +++++++++ .../util/parsers/DefaultTagParserFactory.java | 2 + .../util/parsers/MaxWeightExceptParser.java | 59 +++++++++++++++ .../routing/util/parsers/OSMHgvParser.java | 10 ++- .../util/parsers/OSMMaxWeightParser.java | 19 ++++- .../parsers/helpers/OSMValueExtractor.java | 23 ++++++ .../parsers/MaxWeightExceptParserTest.java | 73 +++++++++++++++++++ .../util/parsers/OSMHgvParserTest.java | 50 +++++++++++++ .../util/parsers/OSMMaxWeightParserTest.java | 29 +++++++- .../util/parsers/OSMValueExtractorTest.java | 7 ++ docs/core/custom-models.md | 1 + 13 files changed, 304 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParser.java create mode 100644 core/src/test/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParserTest.java create mode 100644 core/src/test/java/com/graphhopper/routing/util/parsers/OSMHgvParserTest.java diff --git a/config-example.yml b/config-example.yml index f315cdc2323..a64e914f38d 100644 --- a/config-example.yml +++ b/config-example.yml @@ -83,7 +83,7 @@ graphhopper: # Add additional information to every edge. Used for path details (#1548) and custom models (docs/core/custom-models.md) # Default values are: road_class,road_class_link,road_environment,max_speed,road_access - # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length, + # More are: surface,smoothness,max_width,max_height,max_weight,max_weight_except,hgv,max_axle_load,max_length, # hazmat,hazmat_tunnel,hazmat_water,lanes,osm_way_id,toll,track_type,mtb_rating,hike_rating,horse_rating, # country,curvature,average_slope,max_slope # graph.encoded_values: surface,toll,track_type diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index dec908b6b35..c8dfd0a7dab 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -39,6 +39,8 @@ public EncodedValue create(String name, PMap properties) { return MaxSpeed.create(); } else if (MaxWeight.KEY.equals(name)) { return MaxWeight.create(); + } else if (MaxWeightExcept.KEY.equals(name)) { + return MaxWeightExcept.create(); } else if (MaxHeight.KEY.equals(name)) { return MaxHeight.create(); } else if (MaxWidth.KEY.equals(name)) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java b/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java new file mode 100644 index 00000000000..febd41f9274 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java @@ -0,0 +1,35 @@ +package com.graphhopper.routing.ev; + +import java.util.Locale; + +/** + * When the max_weight EncodedValue is not legally binding. E.g. if there is a sign that a delivery vehicle can access + * the road (even if larger than maxweight tag) then DELIVERY of this enum will be set. + */ +public enum MaxWeightExcept { + + NONE, DELIVERY, DESTINATION, FORESTRY; + + public static final String KEY = "max_weight_except"; + + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(MaxWeightExcept.KEY, MaxWeightExcept.class); + } + + @Override + public String toString() { + return name().toLowerCase(Locale.ROOT); + } + + public static MaxWeightExcept find(String name) { + if (name == null || name.isEmpty()) + return NONE; + + for (MaxWeightExcept mwe : values()) { + if (mwe.name().equalsIgnoreCase(name)) + return mwe; + } + + return NONE; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java index f7c19fa1cd0..9e6f905e85f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java @@ -39,6 +39,8 @@ else if (name.equals(MaxSpeed.KEY)) return new OSMMaxSpeedParser(lookup.getDecimalEncodedValue(MaxSpeed.KEY)); else if (name.equals(MaxWeight.KEY)) return new OSMMaxWeightParser(lookup.getDecimalEncodedValue(MaxWeight.KEY)); + else if (name.equals(MaxWeightExcept.KEY)) + return new MaxWeightExceptParser(lookup.getEnumEncodedValue(MaxWeightExcept.KEY, MaxWeightExcept.class)); else if (name.equals(MaxHeight.KEY)) return new OSMMaxHeightParser(lookup.getDecimalEncodedValue(MaxHeight.KEY)); else if (name.equals(MaxWidth.KEY)) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParser.java new file mode 100644 index 00000000000..61f69d58875 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParser.java @@ -0,0 +1,59 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.MaxWeightExcept; +import com.graphhopper.routing.util.TransportationMode; +import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; +import com.graphhopper.storage.IntsRef; + +import java.util.List; +import java.util.stream.Collectors; + +import static com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor.stringToTons; + +public class MaxWeightExceptParser implements TagParser { + private final EnumEncodedValue mweEnc; + private static final List HGV_RESTRICTIONS = OSMRoadAccessParser.toOSMRestrictions(TransportationMode.HGV).stream() + .map(e -> e + ":conditional").collect(Collectors.toList()); + + public MaxWeightExceptParser(EnumEncodedValue mweEnc) { + this.mweEnc = mweEnc; + } + + public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { + // tagging like maxweight:conditional=no/none @ destination/delivery/forestry/service + String condValue = way.getTag("maxweight:conditional", ""); + if (!condValue.isEmpty()) { + String[] values = condValue.split("@"); + if (values.length == 2) { + String key = values[0].trim(); + String value = values[1].trim(); + if ("no".equals(key) || "none".equals(key)) { + if (value.startsWith("(") && value.endsWith(")")) value = value.substring(1, value.length() - 1); + mweEnc.setEnum(false, edgeId, edgeIntAccess, MaxWeightExcept.find(value)); + return; + } + } + } + + // For tagging like vehicle:conditional=destination @ (weight>3.5) AND maxweight=3.5 + // For vehicle:conditional=no @ (weight>3.5) => NONE is used, which is consistent with max_weight being set to 3.5 in this case + for (String restriction : HGV_RESTRICTIONS) { + String value = way.getTag(restriction, ""); + int atIndex = value.indexOf("@"); + if (atIndex > 0) { + double dec = OSMValueExtractor.conditionalWeightToTons(value); + // set it only if the weight value is the same as in max_weight + if (!Double.isNaN(dec) + && (stringToTons(way.getTag("maxweight", "")) == dec + || stringToTons(way.getTag("maxweightrating:hgv", "")) == dec + || stringToTons(way.getTag("maxgcweight", "")) == dec)) { + mweEnc.setEnum(false, edgeId, edgeIntAccess, MaxWeightExcept.find(value.substring(0, atIndex).trim())); + break; + } + } + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java index 03918c5cb31..93b7c77039c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java @@ -1,11 +1,14 @@ + package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.Hgv; -import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.storage.IntsRef; +import static com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor.conditionalWeightToTons; + public class OSMHgvParser implements TagParser { EnumEncodedValue hgvEnc; @@ -15,6 +18,9 @@ public OSMHgvParser(EnumEncodedValue hgvEnc) { @Override public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { - hgvEnc.setEnum(false, edgeId, edgeIntAccess, Hgv.find(way.getTag("hgv"))); + String value = way.getTag("hgv:conditional", ""); + int index = value.indexOf("@"); + Hgv hgvValue = index > 0 && conditionalWeightToTons(value) == 3.5 ? Hgv.find(value.substring(0, index).trim()) : Hgv.find(way.getTag("hgv")); + hgvEnc.setEnum(false, edgeId, edgeIntAccess, hgvValue); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java index 7b397b3263a..43b268cb764 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParser.java @@ -20,14 +20,20 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public class OSMMaxWeightParser implements TagParser { + // do not include OSM tag "height" here as it has completely different meaning (height of peak) + private static final List MAX_WEIGHT_TAGS = Arrays.asList("maxweight", "maxgcweight"/*abandoned*/, "maxweightrating:hgv"); + private static final List HGV_RESTRICTIONS = OSMRoadAccessParser.toOSMRestrictions(TransportationMode.HGV).stream() + .map(e -> e + ":conditional").collect(Collectors.toList()); private final DecimalEncodedValue weightEncoder; public OSMMaxWeightParser(DecimalEncodedValue weightEncoder) { @@ -36,8 +42,15 @@ public OSMMaxWeightParser(DecimalEncodedValue weightEncoder) { @Override public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { - // do not include OSM tag "height" here as it has completely different meaning (height of peak) - List weightTags = Arrays.asList("maxweight", "maxgcweight"); - OSMValueExtractor.extractTons(edgeId, edgeIntAccess, way, weightEncoder, weightTags); + OSMValueExtractor.extractTons(edgeId, edgeIntAccess, way, weightEncoder, MAX_WEIGHT_TAGS); + + // vehicle:conditional no @ (weight > 7.5) + for (String restriction : HGV_RESTRICTIONS) { + String value = way.getTag(restriction, ""); + if (value.startsWith("no") && value.indexOf("@") < 6) { // no,none[ ]@ + double dec = OSMValueExtractor.conditionalWeightToTons(value); + if (!Double.isNaN(dec)) weightEncoder.setDecimal(false, edgeId, edgeIntAccess, dec); + } + } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java index be0e2da0ad0..66ac15dc523 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java @@ -41,6 +41,29 @@ public static void extractTons(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWa // logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); } + /** + * This parses the weight for a conditional value like "delivery @ (weight > 7.5)" + */ + public static double conditionalWeightToTons(String value) { + try { + int index = value.indexOf("weight>"); // maxweight or weight + if (index < 0) { + index = value.indexOf("weight >"); + if (index > 0) index += "weight >".length(); + } else { + index += "weight>".length(); + } + if (index > 0) { + int lastIndex = value.indexOf(')', index); // (value) or value + if (lastIndex < 0) lastIndex = value.length() - 1; + if(lastIndex > index) return OSMValueExtractor.stringToTons(value.substring(index, lastIndex)); + } + return Double.NaN; + } catch (Exception ex) { + throw new RuntimeException("value " + value, ex); + } + } + public static double stringToTons(String value) { value = TON_PATTERN.matcher(toLowerCase(value)).replaceAll("t"); value = MGW_PATTERN.matcher(value).replaceAll("").trim(); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParserTest.java new file mode 100644 index 00000000000..2c769627d04 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MaxWeightExceptParserTest.java @@ -0,0 +1,73 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; +import com.graphhopper.storage.IntsRef; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MaxWeightExceptParserTest { + private final int edgeId = 0; + private EnumEncodedValue mwEnc; + private MaxWeightExceptParser parser; + private IntsRef relFlags; + + @BeforeEach + public void setUp() { + mwEnc = MaxWeightExcept.create(); + mwEnc.init(new EncodedValue.InitializerConfig()); + parser = new MaxWeightExceptParser(mwEnc); + relFlags = new IntsRef(2); + } + + @Test + public void testSimpleTags() { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + ReaderWay readerWay = new ReaderWay(1); + readerWay.setTag("highway", "primary"); + readerWay.setTag("maxweight:conditional", "none @delivery"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.DELIVERY, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.setTag("maxweight:conditional", "no@ (destination)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.DESTINATION, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + } + + @Test + public void testConditionalTags() { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + ReaderWay readerWay = new ReaderWay(1); + readerWay.setTag("highway", "primary"); + readerWay.setTag("hgv:conditional", "no @ (weight > 7.5)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.NONE, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + + // weight=5 is missing + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.clearTags(); + readerWay.setTag("highway", "primary"); + readerWay.setTag("vehicle:conditional", "delivery @ (weight > 5)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.NONE, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.clearTags(); + readerWay.setTag("highway", "primary"); + readerWay.setTag("vehicle:conditional", "delivery @ (weight > 7.5)"); + readerWay.setTag("maxweight", "7.5"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.DELIVERY, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.clearTags(); + readerWay.setTag("highway", "primary"); + readerWay.setTag("hgv:conditional", "destination @ (maxweight > 5)"); + readerWay.setTag("maxweight", "5"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(MaxWeightExcept.DESTINATION, mwEnc.getEnum(false, edgeId, edgeIntAccess)); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHgvParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHgvParserTest.java new file mode 100644 index 00000000000..c2587ead070 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMHgvParserTest.java @@ -0,0 +1,50 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; +import com.graphhopper.storage.IntsRef; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OSMHgvParserTest { + private final int edgeId = 0; + private EnumEncodedValue hgvEnc; + private OSMHgvParser parser; + private IntsRef relFlags; + + @BeforeEach + public void setUp() { + hgvEnc = Hgv.create(); + hgvEnc.init(new EncodedValue.InitializerConfig()); + parser = new OSMHgvParser(hgvEnc); + relFlags = new IntsRef(2); + } + + @Test + public void testSimpleTags() { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + ReaderWay readerWay = new ReaderWay(1); + readerWay.setTag("highway", "primary"); + readerWay.setTag("hgv", "destination"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hgv.DESTINATION, hgvEnc.getEnum(false, edgeId, edgeIntAccess)); + } + + @Test + public void testConditionalTags() { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + ReaderWay readerWay = new ReaderWay(1); + readerWay.setTag("highway", "primary"); + readerWay.setTag("hgv:conditional", "no @ (weight > 3.5)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hgv.NO, hgvEnc.getEnum(false, edgeId, edgeIntAccess)); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + // for now we assume "hgv" to be only above 3.5 + readerWay.setTag("hgv:conditional", "delivery @ (weight > 7.5)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Hgv.MISSING, hgvEnc.getEnum(false, edgeId, edgeIntAccess)); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java index 62a0313dadf..5091cca6e87 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java @@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class OSMMaxWeightParserTest { + private final int edgeId = 0; private DecimalEncodedValue mwEnc; private OSMMaxWeightParser parser; private IntsRef relFlags; @@ -23,9 +24,8 @@ public void setUp() { @Test public void testSimpleTags() { - ReaderWay readerWay = new ReaderWay(1); EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); - int edgeId = 0; + ReaderWay readerWay = new ReaderWay(1); readerWay.setTag("highway", "primary"); readerWay.setTag("maxweight", "5"); parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); @@ -37,4 +37,29 @@ public void testSimpleTags() { parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); assertEquals(25.4, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); } + + @Test + public void testConditionalTags() { + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + ReaderWay readerWay = new ReaderWay(1); + readerWay.setTag("highway", "primary"); + readerWay.setTag("hgv:conditional", "no @ (weight > 7.5)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(7.5, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.setTag("hgv:conditional", "none @ (weight > 10t)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(10, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.setTag("hgv:conditional", "no@ (weight > 7)"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(7, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); + + edgeIntAccess = new ArrayEdgeIntAccess(1); + readerWay.setTag("hgv:conditional", "no @ (maxweight > 6)"); // allow different tagging + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(6, mwEnc.getDecimal(false, edgeId, edgeIntAccess), .01); + } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMValueExtractorTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMValueExtractorTest.java index fe536ca7b73..84ad712ade4 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMValueExtractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMValueExtractorTest.java @@ -4,6 +4,7 @@ import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import org.junit.jupiter.api.Test; +import static com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor.conditionalWeightToTons; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -106,4 +107,10 @@ public void stringToKmhNaN() { assertTrue(Double.isNaN(OSMValueExtractor.stringToKmh("0"))); assertTrue(Double.isNaN(OSMValueExtractor.stringToKmh("-20"))); } + + @Test + public void testConditionalWeightToTons() { + assertEquals(7.5, conditionalWeightToTons("no @ (weight>7.5)")); + assertEquals(7.5, conditionalWeightToTons("delivery @ (Mo-Sa 06:00-12:00); no @ (weight>7.5); no @ (length>12)")); + } } \ No newline at end of file diff --git a/docs/core/custom-models.md b/docs/core/custom-models.md index dc6d6950186..8a796f65f1b 100644 --- a/docs/core/custom-models.md +++ b/docs/core/custom-models.md @@ -80,6 +80,7 @@ encoded values are the following (some of their possible values are given in bra - hgv: (MISSING, YES, DESIGNATED, ...) - track_type: (MISSING, GRADE1, GRADE2, ..., GRADE5) - urban_density: (RURAL, RESIDENTIAL, CITY) +- max_weight_except: (NONE, DELIVERY, DESTINATION, FORESTRY) To learn about all available encoded values you can query the `/info` endpoint From a4ac7a270f4324114f8e0fc0b2b494cb22d96d92 Mon Sep 17 00:00:00 2001 From: bt90 Date: Mon, 3 Apr 2023 14:09:13 +0200 Subject: [PATCH 024/165] Check cycleway access tags (#2786) * Check cycleway access * Test cycleway access * Test with non-preferred highway type * Update contributors --- CONTRIBUTORS.md | 1 + .../routing/util/parsers/BikeCommonPriorityParser.java | 6 +++++- .../graphhopper/routing/util/parsers/BikeTagParserTest.java | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b6eae590ce6..710a1115fe9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,6 +12,7 @@ Here is an overview: * b3nn0, Android improvements * baumboi, path detail and landmark improvements * boldtrn, one of the core developers with motorcycle knowledge :) + * bt90, fixes like #2786 * cgarreau, increase of routing success rate via subnetwork cleanup * chollemans, fixes like #1482 * ChristianSeitzer, motorcycle improvements diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index d15fffa7b73..e239a412abd 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -19,6 +19,9 @@ public abstract class BikeCommonPriorityParser implements TagParser { + // Bicycle tracks subject to compulsory use in Germany and Poland (https://wiki.openstreetmap.org/wiki/DE:Key:cycleway) + private static final List CYCLEWAY_ACCESS_KEYS = Arrays.asList("cycleway:bicycle", "cycleway:both:bicycle", "cycleway:left:bicycle", "cycleway:right:bicycle"); + // Pushing section highways are parts where you need to get off your bike and push it (German: Schiebestrecke) protected final HashSet pushingSectionsHighways = new HashSet<>(); protected final Set preferHighwayTags = new HashSet<>(); @@ -147,7 +150,8 @@ private PriorityCode convertClassValueToPriority(String tagvalue) { */ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { String highway = way.getTag("highway"); - if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official")) { + if (way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, Arrays.asList("designated")) + || way.hasTag("bicycle", "official")) { if ("path".equals(highway)) weightToPrioMap.put(100d, VERY_NICE.getValue()); else diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index fa8adecd031..4134951f81f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -262,6 +262,11 @@ public void testSpeedAndPriority() { way.setTag("highway", "motorway"); way.setTag("bicycle", "yes"); assertPriorityAndSpeed(AVOID.getValue(), 18, way); + + way.clearTags(); + way.setTag("highway", "primary"); + way.setTag("cycleway:bicycle", "designated"); + assertPriority(PREFER.getValue(), way); } @Test From be7209b517c4dd01935ec6c433a56209ae85de34 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 14:13:20 +0200 Subject: [PATCH 025/165] removed parser options block_private and block_fords (#2780) * removed block_private and block_fords * fix issue number * exclude private for all models under custom_models * make intendedValues and others read-only --- CHANGELOG.md | 1 + .../DefaultVehicleEncodedValuesFactory.java | 2 +- .../util/parsers/AbstractAccessParser.java | 41 ++++-------- .../util/parsers/BikeAccessParser.java | 3 +- .../util/parsers/BikeCommonAccessParser.java | 8 --- .../routing/util/parsers/CarAccessParser.java | 15 +---- .../util/parsers/FootAccessParser.java | 11 +--- .../util/parsers/MotorcycleAccessParser.java | 9 +-- .../parsers/MountainBikeAccessParser.java | 3 +- .../util/parsers/RacingBikeAccessParser.java | 3 +- .../util/parsers/WheelchairAccessParser.java | 3 +- .../java/com/graphhopper/GraphHopperTest.java | 62 ++++++++++--------- .../graphhopper/reader/osm/OSMReaderTest.java | 18 +++--- .../routing/RoutingAlgorithmWithOSMTest.java | 19 +++--- .../routing/util/EncodingManagerTest.java | 24 ------- .../parsers/AbstractBikeTagParserTester.java | 53 +--------------- .../util/parsers/BikeTagParserTest.java | 4 +- .../util/parsers/CarTagParserTest.java | 47 ++------------ .../util/parsers/FootTagParserTest.java | 20 ------ .../parsers/MountainBikeTagParserTest.java | 4 +- .../util/parsers/RacingBikeTagParserTest.java | 4 +- .../util/parsers/WheelchairTagParserTest.java | 10 --- custom_models/bike.json | 1 + custom_models/bus.json | 16 ++--- custom_models/car4wd.json | 6 +- custom_models/truck.json | 16 ++--- .../resources/SPTResourceTest.java | 12 +++- 27 files changed, 107 insertions(+), 308 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f0913efe0b..cc8be9c9465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 8.0 [not yet released] +- breaking change: fords and private roads are now always allowed and have to be excluded through the custom model, see e.g. custom_models/bike.json and #2780 - custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index b8feae73b11..fca977db34e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -40,7 +40,7 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu return VehicleEncodedValues.bike(configuration); if (name.equals("bike2")) - throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike.json and #1234"); + throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike.json and #2668"); if (name.equals(RACINGBIKE)) return VehicleEncodedValues.racingbike(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java index bd876cd2fee..bffb07f3a02 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java @@ -9,25 +9,25 @@ import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; import java.util.*; public abstract class AbstractAccessParser implements TagParser { static final Collection FERRIES = Arrays.asList("shuttle_train", "ferry"); static final Collection ONEWAYS = Arrays.asList("yes", "true", "1", "-1"); - static final Collection INTENDED = Arrays.asList("yes", "designated", "official", "permissive"); + static final Collection INTENDED = Arrays.asList("yes", "designated", "official", "permissive", "private", "permit"); // order is important protected final List restrictions = new ArrayList<>(5); protected final Set restrictedValues = new HashSet<>(5); - protected final Set intendedValues = new HashSet<>(INTENDED); - protected final Set ferries = new HashSet<>(FERRIES); - protected final Set oneways = new HashSet<>(ONEWAYS); + protected final Set intendedValues = Collections.unmodifiableSet(new HashSet<>(INTENDED)); + protected final Set ferries = Collections.unmodifiableSet(new HashSet<>(FERRIES)); + protected final Set oneways = Collections.unmodifiableSet(new HashSet<>(ONEWAYS)); // http://wiki.openstreetmap.org/wiki/Mapfeatures#Barrier protected final Set barriers = new HashSet<>(5); protected final BooleanEncodedValue accessEnc; - private boolean blockFords = true; private ConditionalTagInspector conditionalTagInspector; protected AbstractAccessParser(BooleanEncodedValue accessEnc, TransportationMode transportationMode) { @@ -37,12 +37,15 @@ protected AbstractAccessParser(BooleanEncodedValue accessEnc, TransportationMode restrictedValues.add("restricted"); restrictedValues.add("military"); restrictedValues.add("emergency"); - restrictedValues.add("private"); - restrictedValues.add("permit"); restrictions.addAll(OSMRoadAccessParser.toOSMRestrictions(transportationMode)); } + protected void check(PMap properties) { + if (properties.getBool("block_private", false) || properties.getBool("block_fords", false)) + throw new IllegalArgumentException("block_private and block_fords are no longer supported. Use a custom model as described in #2780"); + } + public AbstractAccessParser init(DateRangeParser dateRangeParser) { setConditionalTagInspector(new ConditionalOSMTagInspector(Collections.singletonList(dateRangeParser), restrictions, restrictedValues, intendedValues, false)); @@ -53,25 +56,6 @@ protected void setConditionalTagInspector(ConditionalTagInspector inspector) { conditionalTagInspector = inspector; } - public boolean isBlockFords() { - return blockFords; - } - - protected void blockFords(boolean blockFords) { - this.blockFords = blockFords; - } - - protected void blockPrivate(boolean blockPrivate) { - if (!blockPrivate) { - if (!restrictedValues.remove("private")) - throw new IllegalStateException("no 'private' found in restrictedValues"); - if (!restrictedValues.remove("permit")) - throw new IllegalStateException("no 'permit' found in restrictedValues"); - intendedValues.add("private"); - intendedValues.add("permit"); - } - } - public ConditionalTagInspector getConditionalTagInspector() { return conditionalTagInspector; } @@ -104,10 +88,7 @@ public boolean isBarrier(ReaderNode node) { return true; else if (intendedValues.contains(firstValue)) return false; - else if (node.hasTag("barrier", barriers)) - return true; - else - return blockFords && node.hasTag("ford", "yes"); + return node.hasTag("barrier", barriers); } public final BooleanEncodedValue getAccessEnc() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java index e67fbfe31e6..415f778d1db 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java @@ -11,8 +11,7 @@ public class BikeAccessParser extends BikeCommonAccessParser { public BikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "bike"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + check(properties); } public BikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 305639a1610..45039bd0f1d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -23,11 +23,6 @@ protected BikeCommonAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedVa restrictedValues.add("forestry"); restrictedValues.add("delivery"); - intendedValues.add("yes"); - intendedValues.add("designated"); - intendedValues.add("official"); - intendedValues.add("permissive"); - barriers.add("fence"); allowedHighways.addAll(Arrays.asList("living_street", "steps", "cycleway", "path", "footway", "platform", @@ -97,9 +92,6 @@ public WayAccess getAccess(ReaderWay way) { if (way.hasTag("motorroad", "yes")) return WayAccess.CAN_SKIP; - if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return WayAccess.CAN_SKIP; - if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index 6acf137d0e9..ca2723f6c34 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -35,13 +35,12 @@ public CarAccessParser(EncodedValueLookup lookup, PMap properties) { this( lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car"))), lookup.getBooleanEncodedValue(Roundabout.KEY), - properties, TransportationMode.CAR ); + check(properties); } - public CarAccessParser(BooleanEncodedValue accessEnc, - BooleanEncodedValue roundaboutEnc, PMap properties, + public CarAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc, TransportationMode transportationMode) { super(accessEnc, transportationMode); this.roundaboutEnc = roundaboutEnc; @@ -49,13 +48,6 @@ public CarAccessParser(BooleanEncodedValue accessEnc, restrictedValues.add("forestry"); restrictedValues.add("delivery"); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); - - intendedValues.add("yes"); - intendedValues.add("designated"); - intendedValues.add("permissive"); - barriers.add("kissing_gate"); barriers.add("fence"); barriers.add("bollard"); @@ -117,9 +109,6 @@ public WayAccess getAccess(ReaderWay way) { } } - if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return WayAccess.CAN_SKIP; - if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java index e2a4d4553d5..e8a9f9b8479 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java @@ -39,18 +39,12 @@ public class FootAccessParser extends AbstractAccessParser implements TagParser public FootAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "foot")))); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + check(properties); } protected FootAccessParser(BooleanEncodedValue accessEnc) { super(accessEnc, TransportationMode.FOOT); - intendedValues.add("yes"); - intendedValues.add("designated"); - intendedValues.add("official"); - intendedValues.add("permissive"); - sidewalkValues.add("yes"); sidewalkValues.add("both"); sidewalkValues.add("left"); @@ -151,9 +145,6 @@ public WayAccess getAccess(ReaderWay way) { if (way.hasTag("motorroad", "yes")) return WayAccess.CAN_SKIP; - if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return WayAccess.CAN_SKIP; - if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java index 10862b879d7..2bfeab61de5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java @@ -13,13 +13,12 @@ public class MotorcycleAccessParser extends CarAccessParser { public MotorcycleAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "motorcycle"))), lookup.getBooleanEncodedValue(Roundabout.KEY), - properties, TransportationMode.MOTORCYCLE); } public MotorcycleAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc, - PMap properties, TransportationMode transportationMode) { - super(accessEnc, roundaboutEnc, properties, transportationMode); + TransportationMode transportationMode) { + super(accessEnc, roundaboutEnc, transportationMode); barriers.remove("bus_trap"); barriers.remove("sump_buster"); @@ -71,10 +70,6 @@ public WayAccess getAccess(ReaderWay way) { } } - // do not drive street cars into fords - if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return WayAccess.CAN_SKIP; - if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) return WayAccess.CAN_SKIP; else diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java index ffa0672c005..62b008c7d21 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java @@ -11,8 +11,7 @@ public class MountainBikeAccessParser extends BikeCommonAccessParser { public MountainBikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "mtb"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + check(properties); } protected MountainBikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java index 5843c167e9d..08868402ea1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java @@ -11,8 +11,7 @@ public class RacingBikeAccessParser extends BikeCommonAccessParser { public RacingBikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "racingbike"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + check(properties); } protected RacingBikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java index 83fa8e039d3..1c67e6f652e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java @@ -18,8 +18,7 @@ public class WheelchairAccessParser extends FootAccessParser { public WheelchairAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(properties.getString("name", VehicleAccess.key("wheelchair")))); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + check(properties); } protected WheelchairAccessParser(BooleanEncodedValue accessEnc) { diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 55eddf28409..5c0fbf95dfc 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -23,8 +23,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.reader.dem.SkadiProvider; -import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.AllEdgesIterator; @@ -103,12 +103,12 @@ public void setup() { @ParameterizedTest @CsvSource({ - DIJKSTRA + ",false,708", - ASTAR + ",false,363", - DIJKSTRA_BI + ",false,346", + DIJKSTRA + ",false,714", + ASTAR + ",false,364", + DIJKSTRA_BI + ",false,350", ASTAR_BI + ",false,192", - ASTAR_BI + ",true,46", - DIJKSTRA_BI + ",true,51" + ASTAR_BI + ",true,52", + DIJKSTRA_BI + ",true,46" }) public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expectedVisitedNodes) { final String vehicle = "car"; @@ -155,7 +155,7 @@ public void testMonacoWithInstructions() { setAlgorithm(ASTAR).setProfile(profile)); // identify the number of counts to compare with CH foot route - assertEquals(713, rsp.getHints().getLong("visited_nodes.sum", 0)); + assertEquals(718, rsp.getHints().getLong("visited_nodes.sum", 0)); ResponsePath res = rsp.getBest(); assertEquals(3437.1, res.getDistance(), .1); @@ -424,25 +424,25 @@ public void testImportWithCHANDCustomProfile() { @Test public void testAlternativeRoutes() { - final String profile = "profile"; - final String vehicle = "foot"; - final String weighting = "shortest"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(MONACO). - setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)). + setProfiles(new CustomProfile("foot").setCustomModel(new CustomModel(). + addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")). + setDistanceInfluence(700d)). + setVehicle("foot")). setStoreOnFlush(true). importOrLoad(); GHRequest req = new GHRequest(43.729057, 7.41251, 43.740298, 7.423561). - setAlgorithm(ALT_ROUTE).setProfile(profile); + setAlgorithm(ALT_ROUTE).setProfile("foot"); GHResponse rsp = hopper.route(req); assertFalse(rsp.hasErrors()); assertEquals(2, rsp.getAll().size()); - assertEquals(1310, rsp.getAll().get(0).getTime() / 1000); - assertEquals(1431, rsp.getAll().get(1).getTime() / 1000); + assertEquals(1327, rsp.getAll().get(0).getTime() / 1000); + assertEquals(1436, rsp.getAll().get(1).getTime() / 1000); req.putHint("alternative_route.max_paths", 3); req.putHint("alternative_route.min_plateau_factor", 0.1); @@ -450,9 +450,9 @@ public void testAlternativeRoutes() { assertFalse(rsp.hasErrors()); assertEquals(3, rsp.getAll().size()); - assertEquals(1310, rsp.getAll().get(0).getTime() / 1000); - assertEquals(1431, rsp.getAll().get(1).getTime() / 1000); - assertEquals(1492, rsp.getAll().get(2).getTime() / 1000); + assertEquals(1327, rsp.getAll().get(0).getTime() / 1000); + assertEquals(1436, rsp.getAll().get(1).getTime() / 1000); + assertEquals(1574, rsp.getAll().get(2).getTime() / 1000); } @Test @@ -712,7 +712,9 @@ public void testCustomModel() { final String customCar = "custom_car"; final String emptyCar = "empty_car"; CustomModel customModel = new CustomModel(); - customModel.addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0.1")); + customModel. + addToPriority(If("road_access == PRIVATE", MULTIPLY, "0")). + addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0.1")); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(BAYREUTH). @@ -1463,7 +1465,7 @@ private void executeCHFootRoute(boolean sort) { // identify the number of counts to compare with none-CH foot route which had nearly 700 counts long sum = rsp.getHints().getLong("visited_nodes.sum", 0); assertNotEquals(sum, 0); - assertTrue(sum < 147, "Too many nodes visited " + sum); + assertTrue(sum < 165, "Too many nodes visited " + sum); assertEquals(3437.1, bestPath.getDistance(), .1); assertEquals(85, bestPath.getPoints().size()); @@ -1626,9 +1628,12 @@ public void testCrossQuery() { setGraphHopperLocation(GH_LOCATION). setOSMFile(MONACO). setProfiles( - new Profile(profile1).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.07), - new Profile(profile2).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.10), - new Profile(profile3).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.15) + new CustomProfile(profile1).setCustomModel(new CustomModel(). + addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(70d)).setVehicle("car"), + new CustomProfile(profile2).setCustomModel(new CustomModel(). + addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(100d)).setVehicle("car"), + new CustomProfile(profile3).setCustomModel(new CustomModel(). + addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(150d)).setVehicle("car") ). setStoreOnFlush(true); @@ -1976,16 +1981,13 @@ public void testTurnCostsOnOffCH() { @Test public void testCHOnOffWithTurnCosts() { - final String profile = "my_car"; - final String vehicle = "car"; - final String weighting = "fastest"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(MOSCOW). - setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true)). + setProfiles(new CustomProfile("my_car").setCustomModel(new CustomModel().addToPriority(If("road_access==PRIVATE", MULTIPLY, "0"))) + .setVehicle("car").setTurnCosts(true)). setStoreOnFlush(true); - hopper.getCHPreparationHandler() - .setCHProfiles(new CHProfile(profile)); + hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("my_car")); hopper.importOrLoad(); GHRequest req = new GHRequest(55.813357, 37.5958585, 55.811042, 37.594689); @@ -2665,7 +2667,7 @@ void curbsideWithSubnetwork_issue2502() { GHResponse response = hopper.route(request); assertFalse(response.hasErrors(), response.getErrors().toString()); double distance = response.getBest().getDistance(); - assertEquals(382, distance, 1); + assertEquals(436, distance, 1); } { // B->A @@ -2678,7 +2680,7 @@ void curbsideWithSubnetwork_issue2502() { GHResponse response = hopper.route(request); assertFalse(response.hasErrors(), response.getErrors().toString()); double distance = response.getBest().getDistance(); - assertEquals(2318, distance, 1); + assertEquals(2462, distance, 1); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 8b979c543af..af526d71d0e 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,6 +22,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; +import com.graphhopper.json.Statement; import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; @@ -33,6 +34,8 @@ import com.graphhopper.routing.util.*; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.*; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -49,6 +52,7 @@ import java.util.HashMap; import java.util.List; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.GHUtility.readCountries; import static org.junit.jupiter.api.Assertions.*; @@ -387,23 +391,23 @@ public void testBarrierBetweenWays() { @Test public void testFords() { GraphHopper hopper = new GraphHopper(); - hopper.setVehiclesString("car|block_fords=true"); + CustomProfile profile = new CustomProfile("car").setCustomModel(new CustomModel(). + addToPriority(Statement.If("road_environment == FORD", MULTIPLY, "0"))); + profile.setVehicle("car"); hopper.setOSMFile(getClass().getResource("test-barriers3.xml").getFile()). setGraphHopperLocation(dir). - setProfiles( - new Profile("car").setVehicle("car").setWeighting("fastest") - ). + setProfiles(profile). setMinNetworkSize(0). importOrLoad(); Graph graph = hopper.getBaseGraph(); // our way is split into five edges, because there are two ford nodes assertEquals(5, graph.getEdges()); - BooleanEncodedValue accessEnc = hopper.getEncodingManager().getBooleanEncodedValue(VehicleAccess.key("car")); + Weighting weighting = hopper.createWeighting(profile, new PMap()); int blocked = 0; int notBlocked = 0; AllEdgesIterator edge = graph.getAllEdges(); while (edge.next()) { - if (!edge.get(accessEnc)) + if (Double.isInfinite(weighting.calcEdgeWeight(edge, false))) blocked++; else notBlocked++; @@ -696,7 +700,7 @@ public void testTurnFlagCombination() { hopper.setVehicleTagParserFactory((lookup, name, config) -> { if (name.equals("truck")) { return new VehicleTagParsers( - new CarAccessParser(lookup.getBooleanEncodedValue(VehicleAccess.key("truck")), lookup.getBooleanEncodedValue(Roundabout.KEY), config, TransportationMode.HGV) + new CarAccessParser(lookup.getBooleanEncodedValue(VehicleAccess.key("truck")), lookup.getBooleanEncodedValue(Roundabout.KEY), TransportationMode.HGV) .init(config.getObject("date_range_parser", new DateRangeParser())), new CarAverageSpeedParser(lookup.getDecimalEncodedValue(VehicleSpeed.key("truck")), 120), null diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 4b6d8ca5ca6..700360d39b5 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -426,15 +426,16 @@ public void testMonacoMountainBike() { // hard to select between secondary and primary (both are AVOID for mtb) queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1459, 88)); - GraphHopper hopper = createHopper(MONACO, new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb")); + Profile profile = new CustomProfile("mtb"). + setCustomModel(new CustomModel().addToPriority(If("road_access == PRIVATE", MULTIPLY, "0"))). + setVehicle("mtb"); + GraphHopper hopper = createHopper(MONACO, profile); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(MONACO, - new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb"), - new Profile("racingbike").setVehicle("racingbike").setWeighting("fastest")); + hopper = createHopper(MONACO, profile, new CustomProfile("racingbike").setCustomModel(new CustomModel()).setVehicle("racingbike")); hopper.importOrLoad(); checkQueries(hopper, queries); } @@ -447,16 +448,16 @@ public void testMonacoRacingBike() { queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2568, 135)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1490, 84)); - GraphHopper hopper = createHopper(MONACO, new CustomProfile("racingbike"). - setCustomModel(new CustomModel()).setVehicle("racingbike")); + Profile profile = new CustomProfile("racingbike"). + setCustomModel(new CustomModel().addToPriority(If("road_access == PRIVATE", MULTIPLY, "0"))). + setVehicle("racingbike"); + GraphHopper hopper = createHopper(MONACO, profile); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(MONACO, new CustomProfile("racingbike").setCustomModel(new CustomModel()).setVehicle("racingbike"), - new Profile("bike").setVehicle("bike").setWeighting("fastest") - ); + hopper = createHopper(MONACO, profile, new CustomProfile("bike").setCustomModel(new CustomModel()).setVehicle("bike")); hopper.importOrLoad(); checkQueries(hopper, queries); } diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index 2ecac791e91..d8d8b1812de 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -36,30 +36,6 @@ */ public class EncodingManagerTest { - @Test - public void testSupportFords() { - EncodingManager manager = new EncodingManager.Builder() - .add(VehicleEncodedValues.car(new PMap())) - .add(VehicleEncodedValues.bike(new PMap())) - .add(VehicleEncodedValues.foot(new PMap())). - build(); - - // 1) default -> no block fords - assertFalse(new CarAccessParser(manager, new PMap()).isBlockFords()); - assertFalse(new BikeAccessParser(manager, new PMap()).isBlockFords()); - assertFalse(new FootAccessParser(manager, new PMap()).isBlockFords()); - - // 2) true - assertTrue(new CarAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); - assertTrue(new BikeAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); - assertTrue(new FootAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); - - // 3) false - assertFalse(new CarAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); - assertFalse(new BikeAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); - assertFalse(new FootAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); - } - @Test public void testRegisterOnlyOnceAllowed() { DecimalEncodedValueImpl speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index d2ad5ff08b7..bb45a2adc28 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -54,7 +54,7 @@ public abstract class AbstractBikeTagParserTester { @BeforeEach public void setUp() { encodingManager = createEncodingManager(); - VehicleTagParsers parsers = createBikeTagParsers(encodingManager, new PMap("block_fords=true")); + VehicleTagParsers parsers = createBikeTagParsers(encodingManager); accessParser = (BikeCommonAccessParser) parsers.getAccessParser(); speedParser = (BikeCommonAverageSpeedParser) parsers.getSpeedParser(); priorityParser = (BikeCommonPriorityParser) parsers.getPriorityParser(); @@ -69,7 +69,7 @@ public void setUp() { protected abstract EncodingManager createEncodingManager(); - protected abstract VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap); + protected abstract VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup); protected void assertPriority(int expectedPrio, ReaderWay way) { IntsRef relFlags = osmParsers.handleRelationTags(new ReaderRelation(0), osmParsers.createRelationFlags()); @@ -172,13 +172,6 @@ public void testAccess() { way.setTag("motorroad", "yes"); assertTrue(accessParser.getAccess(way).canSkip()); - way.clearTags(); - way.setTag("highway", "track"); - way.setTag("ford", "yes"); - assertTrue(accessParser.getAccess(way).canSkip()); - way.setTag("bicycle", "yes"); - assertTrue(accessParser.getAccess(way).isWay()); - way.clearTags(); way.setTag("highway", "secondary"); way.setTag("access", "no"); @@ -459,18 +452,6 @@ public void testBarrierAccess() { assertFalse(accessParser.isBarrier(node)); } - @Test - public void testBarrierAccessFord() { - ReaderNode node = new ReaderNode(1, -1, -1); - node.setTag("ford", "yes"); - // barrier! - assertTrue(accessParser.isBarrier(node)); - - node.setTag("bicycle", "yes"); - // no barrier! - assertFalse(accessParser.isBarrier(node)); - } - @Test public void testFerries() { ReaderWay way = new ReaderWay(1); @@ -486,13 +467,6 @@ public void testFerries() { way.setTag("foot", "yes"); assertFalse(accessParser.getAccess(way).isFerry()); - // #1122 - way.clearTags(); - way.setTag("route", "ferry"); - way.setTag("bicycle", "yes"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - // #1562, test if ferry route with bicycle way.clearTags(); way.setTag("route", "ferry"); @@ -511,10 +485,6 @@ public void testFerries() { way.setTag("bicycle", "no"); assertTrue(accessParser.getAccess(way).canSkip()); - way.setTag("bicycle", "designated"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - // test if when foot is set is invalid way.clearTags(); way.setTag("route", "ferry"); @@ -522,25 +492,6 @@ public void testFerries() { assertTrue(accessParser.getAccess(way).canSkip()); } - @Test - void privateAndFords() { - // defaults: do not block fords, block private - BikeCommonAccessParser bike = (BikeCommonAccessParser) createBikeTagParsers(encodingManager, new PMap()).getAccessParser(); - assertFalse(bike.isBlockFords()); - assertTrue(bike.restrictedValues.contains("private")); - assertFalse(bike.intendedValues.contains("private")); - ReaderNode node = new ReaderNode(1, 1, 1); - node.setTag("access", "private"); - assertTrue(bike.isBarrier(node)); - - // block fords, unblock private - bike = (BikeCommonAccessParser) createBikeTagParsers(encodingManager, new PMap("block_fords=true|block_private=false")).getAccessParser(); - assertTrue(bike.isBlockFords()); - assertFalse(bike.restrictedValues.contains("private")); - assertTrue(bike.intendedValues.contains("private")); - assertFalse(bike.isBarrier(node)); - } - @Test public void testOneway() { ReaderWay way = new ReaderWay(1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 4134951f81f..ad2c2c4ccf4 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -46,8 +46,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { - return VehicleTagParsers.bike(lookup, pMap); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { + return VehicleTagParsers.bike(lookup, new PMap()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java index c2dbb4da03e..e49a0746dc7 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java @@ -41,8 +41,8 @@ */ public class CarTagParserTest { private final EncodingManager em = createEncodingManager("car"); - final CarAccessParser parser = createParser(em, new PMap("block_fords=true")); - final CarAverageSpeedParser speedParser = new CarAverageSpeedParser(em, new PMap("block_fords=true")); + final CarAccessParser parser = createParser(em); + final CarAverageSpeedParser speedParser = new CarAverageSpeedParser(em, new PMap()); private final BooleanEncodedValue roundaboutEnc = em.getBooleanEncodedValue(Roundabout.KEY); private final BooleanEncodedValue accessEnc = parser.getAccessEnc(); private final DecimalEncodedValue avSpeedEnc = speedParser.getAverageSpeedEnc(); @@ -60,8 +60,8 @@ private EncodingManager createEncodingManager(String carName) { .build(); } - CarAccessParser createParser(EncodedValueLookup lookup, PMap properties) { - CarAccessParser carTagParser = new CarAccessParser(lookup, properties); + CarAccessParser createParser(EncodedValueLookup lookup) { + CarAccessParser carTagParser = new CarAccessParser(lookup, new PMap()); carTagParser.init(new DateRangeParser()); return carTagParser; } @@ -95,13 +95,6 @@ public void testAccess() { way.setTag("access", "delivery"); assertTrue(parser.getAccess(way).canSkip()); - way.clearTags(); - way.setTag("highway", "unclassified"); - way.setTag("ford", "yes"); - assertTrue(parser.getAccess(way).canSkip()); - way.setTag("motorcar", "yes"); - assertTrue(parser.getAccess(way).isWay()); - way.clearTags(); way.setTag("access", "yes"); way.setTag("motor_vehicle", "no"); @@ -183,16 +176,6 @@ public void testFordAccess() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "unclassified"); way.setTag("ford", "yes"); - - // Node and way are initially blocking - assertTrue(parser.isBlockFords()); - assertTrue(parser.getAccess(way).canSkip()); - assertTrue(parser.isBarrier(node)); - - CarAccessParser tmpParser = new CarAccessParser(em, new PMap("block_fords=false")); - tmpParser.init(new DateRangeParser()); - assertTrue(tmpParser.getAccess(way).isWay()); - assertFalse(tmpParser.isBarrier(node)); } @Test @@ -246,28 +229,6 @@ public void testOneway() { way.clearTags(); } - @Test - public void shouldBlockPrivate() { - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "primary"); - way.setTag("access", "private"); - EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); - int edgeId = 0; - parser.handleWayTags(edgeId, edgeIntAccess, way); - assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); - - final CarAccessParser parser = createParser(em, new PMap("block_private=false")); - edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); - parser.handleWayTags(edgeId, edgeIntAccess, way); - assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - - way.setTag("highway", "primary"); - way.setTag("motor_vehicle", "permit"); // currently handled like "private", see #2712 - edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); - parser.handleWayTags(edgeId, edgeIntAccess, way); - assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); - } - @Test public void testSetAccess() { EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java index 83dd1769706..4101433020d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java @@ -132,13 +132,6 @@ public void testAccess() { way.setTag("sidewalk", "none"); assertTrue(accessParser.getAccess(way).canSkip()); - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("sidewalk", "left"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - way.clearTags(); - way.setTag("highway", "pedestrian"); assertTrue(accessParser.getAccess(way).isWay()); @@ -219,10 +212,6 @@ public void testAccess() { way.setTag("foot", "no"); assertTrue(accessParser.getAccess(way).canSkip()); - way.setTag("foot", "designated"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); way.clearTags(); @@ -496,15 +485,6 @@ public void testFord() { // barrier! node.setTag("foot", "no"); assertTrue(accessParser.isBarrier(node)); - - FootAccessParser blockFordsParser = new FootAccessParser(encodingManager, new PMap("block_fords=true")); - node = new ReaderNode(1, -1, -1); - node.setTag("ford", "no"); - assertFalse(blockFordsParser.isBarrier(node)); - - node = new ReaderNode(1, -1, -1); - node.setTag("ford", "yes"); - assertTrue(blockFordsParser.isBarrier(node)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java index f5507af61ad..d8d87e725a9 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java @@ -40,8 +40,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { - return VehicleTagParsers.mtb(lookup, pMap); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { + return VehicleTagParsers.mtb(lookup, new PMap()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index fc7f8ea2679..f72014acd7e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -46,8 +46,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { - return VehicleTagParsers.racingbike(lookup, pMap); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { + return VehicleTagParsers.racingbike(lookup, new PMap()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java index 60a3d77d88f..9cfbff01241 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java @@ -129,12 +129,6 @@ public void testAccess() { assertTrue(accessParser.getAccess(way).canSkip()); way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("sidewalk", "left"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - way.clearTags(); - way.setTag("highway", "pedestrian"); assertTrue(accessParser.getAccess(way).isWay()); @@ -217,10 +211,6 @@ public void testAccess() { way.setTag("foot", "no"); assertTrue(accessParser.getAccess(way).canSkip()); - way.setTag("foot", "designated"); - way.setTag("access", "private"); - assertTrue(accessParser.getAccess(way).canSkip()); - DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); way.clearTags(); diff --git a/custom_models/bike.json b/custom_models/bike.json index 801d17866b6..3dca3e1695c 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -11,6 +11,7 @@ { "priority": [ { "if": "true", "multiply_by": "bike_priority" }, + { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "!bike_access && !backward_bike_access", "multiply_by": "0" }, { "else_if": "!bike_access && backward_bike_access && !roundabout", "multiply_by": "0.2" } ], diff --git a/custom_models/bus.json b/custom_models/bus.json index c852206bbbf..7d3dbf301b2 100644 --- a/custom_models/bus.json +++ b/custom_models/bus.json @@ -10,19 +10,11 @@ { "distance_influence": 90, "speed": [ - { - "if": "true", - "limit_to": "car_average_speed * 0.9" - }, - { - "if": "true", - "limit_to": "120" - } + { "if": "true", "limit_to": "car_average_speed * 0.9" }, + { "if": "true", "limit_to": "120" } ], "priority": [ - { - "if": "car_access == false || max_width < 3 || max_height < 4", - "multiply_by": "0" - } + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "car_access == false || max_width < 3 || max_height < 4", "multiply_by": "0" } ] } \ No newline at end of file diff --git a/custom_models/car4wd.json b/custom_models/car4wd.json index ee3994e0fa4..ada463899f1 100644 --- a/custom_models/car4wd.json +++ b/custom_models/car4wd.json @@ -20,9 +20,7 @@ } ], "priority": [ - { - "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", - "multiply_by": "0" - } + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", "multiply_by": "0" } ] } \ No newline at end of file diff --git a/custom_models/truck.json b/custom_models/truck.json index 25ab1df3759..87b2db22b83 100644 --- a/custom_models/truck.json +++ b/custom_models/truck.json @@ -9,19 +9,11 @@ { "distance_influence": 1, "speed": [ - { - "if": "true", - "limit_to": "car_average_speed * 0.9" - }, - { - "if": "true", - "limit_to": "95" - } + { "if": "true", "limit_to": "car_average_speed * 0.9" }, + { "if": "true", "limit_to": "95" } ], "priority": [ - { - "if": "car_access == false || hgv == NO || max_width < 3 || max_height < 4", - "multiply_by": "0" - } + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "car_access == false || hgv == NO || max_width < 3 || max_height < 4", "multiply_by": "0" } ] } \ No newline at end of file diff --git a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java index 4e2b9e29eb5..f2dec82f994 100644 --- a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java @@ -22,7 +22,9 @@ import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; import com.graphhopper.application.util.GraphHopperServerTestConfiguration; -import com.graphhopper.config.Profile; +import com.graphhopper.json.Statement; +import com.graphhopper.routing.weighting.custom.CustomProfile; +import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; import io.dropwizard.testing.junit5.DropwizardAppExtension; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -53,8 +55,12 @@ private static GraphHopperServerConfiguration createConfig() { putObject("import.osm.ignored_highways", ""). putObject("graph.location", DIR). setProfiles(Arrays.asList( - new Profile("car_without_turncosts").setVehicle("car").setWeighting("fastest"), - new Profile("car_with_turncosts").setVehicle("car").setWeighting("fastest").setTurnCosts(true) + new CustomProfile("car_without_turncosts").setCustomModel(new CustomModel(). + addToPriority(Statement.If("road_access==PRIVATE", Statement.Op.MULTIPLY, "0"))). + setVehicle("car"), + new CustomProfile("car_with_turncosts").setCustomModel(new CustomModel(). + addToPriority(Statement.If("road_access==PRIVATE", Statement.Op.MULTIPLY, "0"))). + setVehicle("car").setTurnCosts(true) )); return config; } From e89626764f0dad5b31392540f8465c800828264a Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 17:25:40 +0200 Subject: [PATCH 026/165] adjust benchmarks for #2780 --- benchmark/little_custom.json | 10 ++------ benchmark/very_custom.json | 46 ++++++++---------------------------- 2 files changed, 12 insertions(+), 44 deletions(-) diff --git a/benchmark/little_custom.json b/benchmark/little_custom.json index 1b548fecdd9..2fe3a3769be 100644 --- a/benchmark/little_custom.json +++ b/benchmark/little_custom.json @@ -2,14 +2,8 @@ // standard car profile { "priority": [ - { - "if": "road_access == PRIVATE", - "multiply_by": "0.1" - }, - { - "else_if": "road_access == DESTINATION", - "multiply_by": "0.1" - } + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "else_if": "road_access == DESTINATION", "multiply_by": "0.1" } ], "distance_influence": 0 } diff --git a/benchmark/very_custom.json b/benchmark/very_custom.json index 933cb2a2e05..ddd48ba0772 100644 --- a/benchmark/very_custom.json +++ b/benchmark/very_custom.json @@ -1,43 +1,17 @@ // this is a heavily customized model used to benchmark routing with a custom weighting { "speed": [ - { - "if": "road_class == MOTORWAY", - "multiply_by": "0.85" - }, - { - "else_if": "road_class == PRIMARY", - "multiply_by": "0.9" - }, - { - "if": "true", - "limit_to": "110" - } + { "if": "road_class == MOTORWAY", "multiply_by": "0.85" }, + { "else_if": "road_class == PRIMARY", "multiply_by": "0.9" }, + { "if": "true", "limit_to": "110" } ], "priority": [ - { - "if": "max_height < 3.8", - "multiply_by": "0" - }, - { - "if": "max_width < 2.5", - "multiply_by": "0" - }, - { - "if": "road_class == PRIMARY", - "multiply_by": "0.5" - }, - { - "else_if": "road_class != MOTORWAY", - "multiply_by": "0.9" - }, - { - "if": "toll != NO", - "multiply_by": "0.5" - }, - { - "if": "hazmat == NO", - "multiply_by": "0" - } + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "max_height < 3.8", "multiply_by": "0" }, + { "if": "max_width < 2.5", "multiply_by": "0" }, + { "if": "road_class == PRIMARY", "multiply_by": "0.5" }, + { "else_if": "road_class != MOTORWAY", "multiply_by": "0.9" }, + { "if": "toll != NO", "multiply_by": "0.5" }, + { "if": "hazmat == NO", "multiply_by": "0" } ] } \ No newline at end of file From 92bd11f1d61f826bd3b91505d8c3decd1357de78 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 17:58:45 +0200 Subject: [PATCH 027/165] removed motorcycle vehicle (#2781) * removed block_private and block_fords * fix issue number * removed motorcycle vehicle * minor fixes * minor change * move curvature part outside of motorcycle * fix config-example.yml --- config-example.yml | 12 +- .../DefaultVehicleEncodedValuesFactory.java | 12 +- .../util/DefaultVehicleTagParserFactory.java | 2 - .../routing/util/VehicleEncodedValues.java | 15 +- .../util/VehicleEncodedValuesFactory.java | 2 - .../routing/util/VehicleTagParsers.java | 8 - .../routing/util/parsers/CarAccessParser.java | 2 +- .../util/parsers/MotorcycleAccessParser.java | 104 ---------- .../parsers/MotorcycleAverageSpeedParser.java | 83 -------- .../parsers/MotorcyclePriorityParser.java | 51 ----- .../reader/osm/GraphHopperOSMTest.java | 8 +- .../routing/RoutingAlgorithmWithOSMTest.java | 33 +--- .../util/parsers/MotorcycleTagParserTest.java | 184 ------------------ .../routing/util/parsers/TagParsingTest.java | 5 +- custom_models/curvature.json | 5 +- custom_models/motorcycle.json | 27 +++ 16 files changed, 55 insertions(+), 498 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAverageSpeedParser.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/MotorcyclePriorityParser.java delete mode 100644 core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java create mode 100644 custom_models/motorcycle.json diff --git a/config-example.yml b/config-example.yml index a64e914f38d..f672499a702 100644 --- a/config-example.yml +++ b/config-example.yml @@ -46,7 +46,7 @@ graphhopper: # weighting: custom # custom_model_files: [bike.json, bike_elevation.json] - # specify the folder where to find the custom model files + # specify the folder where to find the custom model files - see this folder for more possibilities custom_models.directory: custom_models # Speed mode: @@ -72,11 +72,11 @@ graphhopper: #### Vehicles #### - # The vehicle defines the base for how the routing of a profile behaves. It can be fine tuned using the options: - # name=mycustomvehicle,block_private=true,turn_costs=true,transportation_mode=MOTOR_VEHICLE (only for the roads vehicle) - # Still, it is recommended to avoid changing the vehicle settings and change the custom model instead. - # graph.vehicles: car|block_fords=true,turn_costs=true,bike|turn_costs=true - # Other standard vehicles: foot,bike,mtb,racingbike,motorcycle,wheelchair + # The vehicle defines the base for how the routing of a profile behaves. It can be adjusted with the turn_costs=true + # option or, only for the roads vehicle, there is the transportation_mode option: + # name=mycustomvehicle,turn_costs=true,transportation_mode=MOTOR_VEHICLE + # But you should prefer to configure the turn_costs via the profile configuration. + # Other standard vehicles: foot,bike,mtb,racingbike,wheelchair #### Encoded Values #### diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index fca977db34e..4ce3555607d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -34,13 +34,13 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu return VehicleEncodedValues.car(configuration); if (name.equals("car4wd")) - throw new IllegalArgumentException("Instead of car4wd use the roads vehicle and a custom_model, see custom_models/car4wd.json"); + throw new IllegalArgumentException("Instead of car4wd use custom_models/car4wd.json"); if (name.equals(BIKE)) return VehicleEncodedValues.bike(configuration); if (name.equals("bike2")) - throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike.json and #2668"); + throw new IllegalArgumentException("Instead of bike2 use custom_models/bike.json, see #2668"); if (name.equals(RACINGBIKE)) return VehicleEncodedValues.racingbike(configuration); @@ -51,11 +51,11 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu if (name.equals(FOOT)) return VehicleEncodedValues.foot(configuration); - if (name.equals(HIKE)) - throw new IllegalArgumentException("Instead of hike use the foot vehicle and a custom model, see custom_models/hike.json and #2759"); + if (name.equals("hike")) + throw new IllegalArgumentException("Instead of hike use custom_models/hike.json, see #2759"); - if (name.equals(MOTORCYCLE)) - return VehicleEncodedValues.motorcycle(configuration); + if (name.equals("motorcycle")) + throw new IllegalArgumentException("Instead of motorcycle use custom_models/motorcycle.json, see #2781"); if (name.equals(WHEELCHAIR)) return VehicleEncodedValues.wheelchair(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java index 2ecac823777..f10c566a469 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -37,8 +37,6 @@ public VehicleTagParsers createParsers(EncodedValueLookup lookup, String name, P return VehicleTagParsers.mtb(lookup, configuration); if (name.equals(FOOT)) return VehicleTagParsers.foot(lookup, configuration); - if (name.equals(MOTORCYCLE)) - return VehicleTagParsers.motorcycle(lookup, configuration); if (name.equals(WHEELCHAIR)) return VehicleTagParsers.wheelchair(lookup, configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index d0a0366ca19..89d8a6fe2df 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -27,7 +27,7 @@ import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; public class VehicleEncodedValues { - public static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); + public static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, RACINGBIKE, MOUNTAINBIKE, FOOT, WHEELCHAIR); private final String name; private final BooleanEncodedValue accessEnc; @@ -89,19 +89,6 @@ public static VehicleEncodedValues car(PMap properties) { return new VehicleEncodedValues(name, accessEnc, speedEnc, null, turnCostEnc); } - public static VehicleEncodedValues motorcycle(PMap properties) { - String name = properties.getString("name", "motorcycle"); - int speedBits = properties.getInt("speed_bits", 5); - double speedFactor = properties.getDouble("speed_factor", 5); - boolean speedTwoDirections = properties.getBool("speed_two_directions", true); - int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - BooleanEncodedValue accessEnc = VehicleAccess.create(name); - DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); - DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); - DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, turnCostEnc); - } - public static VehicleEncodedValues roads(PMap properties) { String name = properties.getString("name", "roads"); int speedBits = properties.getInt("speed_bits", 7); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java index 85780abd813..e2b05569059 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java @@ -29,8 +29,6 @@ public interface VehicleEncodedValuesFactory { String RACINGBIKE = "racingbike"; String MOUNTAINBIKE = "mtb"; String FOOT = "foot"; - String HIKE = "hike"; - String MOTORCYCLE = "motorcycle"; String WHEELCHAIR = "wheelchair"; VehicleEncodedValues createVehicleEncodedValues(String name, PMap configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParsers.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParsers.java index f62e13390a8..605800aadda 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParsers.java @@ -79,14 +79,6 @@ public static VehicleTagParsers foot(EncodedValueLookup lookup, PMap properties) ); } - public static VehicleTagParsers motorcycle(EncodedValueLookup lookup, PMap properties) { - return new VehicleTagParsers( - new MotorcycleAccessParser(lookup, properties).init(properties.getObject("date_range_parser", new DateRangeParser())), - new MotorcycleAverageSpeedParser(lookup, properties), - new MotorcyclePriorityParser(lookup, properties) - ); - } - public static VehicleTagParsers wheelchair(EncodedValueLookup lookup, PMap properties) { return new VehicleTagParsers( new WheelchairAccessParser(lookup, properties).init(properties.getObject("date_range_parser", new DateRangeParser())), diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index ca2723f6c34..edce4b2d8ac 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -96,7 +96,7 @@ public WayAccess getAccess(ReaderWay way) { if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable")) return WayAccess.CAN_SKIP; - // multiple restrictions needs special handling, see also motorcycle + // multiple restrictions needs special handling boolean permittedWayConditionallyRestricted = getConditionalTagInspector().isPermittedWayConditionallyRestricted(way); boolean restrictedWayConditionallyPermitted = getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way); if (!firstValue.isEmpty()) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java deleted file mode 100644 index 2bfeab61de5..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAccessParser.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.graphhopper.routing.util.parsers; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.TransportationMode; -import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.util.PMap; - -import java.util.Arrays; - -public class MotorcycleAccessParser extends CarAccessParser { - - public MotorcycleAccessParser(EncodedValueLookup lookup, PMap properties) { - this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "motorcycle"))), - lookup.getBooleanEncodedValue(Roundabout.KEY), - TransportationMode.MOTORCYCLE); - } - - public MotorcycleAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc, - TransportationMode transportationMode) { - super(accessEnc, roundaboutEnc, transportationMode); - - barriers.remove("bus_trap"); - barriers.remove("sump_buster"); - - trackTypeValues.clear(); - trackTypeValues.addAll(Arrays.asList("grade1")); - } - - @Override - public WayAccess getAccess(ReaderWay way) { - String highwayValue = way.getTag("highway"); - String firstValue = way.getFirstPriorityTag(restrictions); - if (highwayValue == null) { - if (way.hasTag("route", ferries)) { - if (restrictedValues.contains(firstValue)) - return WayAccess.CAN_SKIP; - if (intendedValues.contains(firstValue) || - // implied default is allowed only if foot and bicycle is not specified: - firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) - return WayAccess.FERRY; - } - return WayAccess.CAN_SKIP; - } - - if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) { - return WayAccess.CAN_SKIP; - } - - if ("track".equals(highwayValue)) { - String tt = way.getTag("tracktype"); - if (tt != null && !tt.equals("grade1")) - return WayAccess.CAN_SKIP; - } - - if (!highwayValues.contains(highwayValue)) - return WayAccess.CAN_SKIP; - - if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable")) - return WayAccess.CAN_SKIP; - - if (!firstValue.isEmpty()) { - String[] restrict = firstValue.split(";"); - boolean notConditionalyPermitted = !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way); - for (String value : restrict) { - if (restrictedValues.contains(value) && notConditionalyPermitted) - return WayAccess.CAN_SKIP; - if (intendedValues.contains(value)) - return WayAccess.WAY; - } - } - - if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) - return WayAccess.CAN_SKIP; - else - return WayAccess.WAY; - } - - @Override - public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { - WayAccess access = getAccess(way); - if (access.canSkip()) - return; - - if (!access.isFerry()) { - - boolean isRoundabout = roundaboutEnc.getBool(false, edgeId, edgeIntAccess); - if (way.hasTag("oneway", oneways) || isRoundabout) { - if (way.hasTag("oneway", "-1")) { - accessEnc.setBool(true, edgeId, edgeIntAccess, true); - } else { - accessEnc.setBool(false, edgeId, edgeIntAccess, true); - } - } else { - accessEnc.setBool(true, edgeId, edgeIntAccess, true); - accessEnc.setBool(false, edgeId, edgeIntAccess, true); - } - - } else { - accessEnc.setBool(false, edgeId, edgeIntAccess, true); - accessEnc.setBool(true, edgeId, edgeIntAccess, true); - } - } -} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAverageSpeedParser.java deleted file mode 100644 index d8106bcd174..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcycleAverageSpeedParser.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.graphhopper.routing.util.parsers; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.EdgeIntAccess; -import com.graphhopper.routing.ev.VehicleSpeed; -import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; -import com.graphhopper.util.PMap; - -public class MotorcycleAverageSpeedParser extends CarAverageSpeedParser { - public static final double MOTORCYCLE_MAX_SPEED = 120; - - public MotorcycleAverageSpeedParser(EncodedValueLookup lookup, PMap properties) { - this( - lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "motorcycle"))), - lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "motorcycle"))).getNextStorableValue(MOTORCYCLE_MAX_SPEED) - ); - } - - public MotorcycleAverageSpeedParser(DecimalEncodedValue speedEnc, double maxPossibleSpeed) { - super(speedEnc, maxPossibleSpeed); - - defaultSpeedMap.clear(); - - // autobahn - defaultSpeedMap.put("motorway", 100); - defaultSpeedMap.put("motorway_link", 70); - // bundesstraße - defaultSpeedMap.put("trunk", 80); - defaultSpeedMap.put("trunk_link", 75); - // linking bigger town - defaultSpeedMap.put("primary", 65); - defaultSpeedMap.put("primary_link", 60); - // linking towns + villages - defaultSpeedMap.put("secondary", 60); - defaultSpeedMap.put("secondary_link", 50); - // streets without middle line separation - defaultSpeedMap.put("tertiary", 50); - defaultSpeedMap.put("tertiary_link", 40); - defaultSpeedMap.put("unclassified", 30); - defaultSpeedMap.put("residential", 30); - // spielstraße - defaultSpeedMap.put("living_street", 5); - defaultSpeedMap.put("service", 20); - // unknown road - defaultSpeedMap.put("road", 20); - // forestry stuff - defaultSpeedMap.put("track", 15); - - trackTypeSpeedMap.clear(); - trackTypeSpeedMap.put("grade1", 20); - trackTypeSpeedMap.put(null, defaultSpeedMap.get("track")); - } - - @Override - public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way) { - String highwayValue = way.getTag("highway"); - if (highwayValue == null) { - if (way.hasTag("route", ferries)) { - double ferrySpeed = ferrySpeedCalc.getSpeed(way); - setSpeed(false, edgeId, edgeIntAccess, ferrySpeed); - setSpeed(true, edgeId, edgeIntAccess, ferrySpeed); - } - } else { - double speed = getSpeed(way); - setSpeed(true, edgeId, edgeIntAccess, applyMaxSpeed(way, speed, true)); - setSpeed(false, edgeId, edgeIntAccess, applyMaxSpeed(way, speed, true)); - } - } - - protected double applyMaxSpeed(ReaderWay way, double speed, boolean bwd) { - speed = super.applyMaxSpeed(way, speed, bwd); - double maxMCSpeed = OSMValueExtractor.stringToKmh(way.getTag("maxspeed:motorcycle")); - if (isValidSpeed(maxMCSpeed)) - speed = Math.min(maxMCSpeed * 0.9, speed); - - // limit speed to max 30 km/h if bad surface - if (isValidSpeed(speed) && speed > 30 && way.hasTag("surface", badSurfaceSpeedMap)) - speed = 30; - return speed; - } -} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcyclePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcyclePriorityParser.java deleted file mode 100644 index 65c9a56fdb2..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MotorcyclePriorityParser.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.graphhopper.routing.util.parsers; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.EdgeIntAccess; -import com.graphhopper.routing.ev.VehiclePriority; -import com.graphhopper.routing.util.PriorityCode; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.PMap; - -import java.util.HashSet; - -public class MotorcyclePriorityParser implements TagParser { - - private final HashSet avoidSet = new HashSet<>(); - private final HashSet preferSet = new HashSet<>(); - private final DecimalEncodedValue priorityWayEncoder; - - public MotorcyclePriorityParser(EncodedValueLookup lookup, PMap properties) { - this(lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "motorcycle")))); - } - - public MotorcyclePriorityParser(DecimalEncodedValue priorityWayEncoder) { - this.priorityWayEncoder = priorityWayEncoder; - - avoidSet.add("motorway"); - avoidSet.add("trunk"); - avoidSet.add("residential"); - - preferSet.add("primary"); - preferSet.add("secondary"); - preferSet.add("tertiary"); - } - - @Override - public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) { - priorityWayEncoder.setDecimal(false, edgeId, edgeIntAccess, PriorityCode.getValue(handlePriority(way))); - } - - private int handlePriority(ReaderWay way) { - String highway = way.getTag("highway", ""); - if (avoidSet.contains(highway) || way.hasTag("motorroad", "yes")) { - return PriorityCode.BAD.getValue(); - } else if (preferSet.contains(highway)) { - return PriorityCode.BEST.getValue(); - } - - return PriorityCode.UNCHANGED.getValue(); - } -} diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index 92fad8a9502..9cbf4cd1357 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -705,7 +705,6 @@ public void testMultipleCHPreparationsInParallel() { setStoreOnFlush(false). setProfiles( new Profile("car_profile").setVehicle("car").setWeighting("fastest"), - new Profile("moto_profile").setVehicle("motorcycle").setWeighting("fastest"), new Profile("mtb_profile").setVehicle("mtb").setWeighting("fastest"), new Profile("bike_profile").setVehicle("racingbike").setWeighting("fastest"), new Profile("foot_profile").setVehicle("foot").setWeighting("fastest") @@ -715,7 +714,6 @@ public void testMultipleCHPreparationsInParallel() { hopper.getCHPreparationHandler() .setCHProfiles( new CHProfile("car_profile"), - new CHProfile("moto_profile"), new CHProfile("mtb_profile"), new CHProfile("bike_profile"), new CHProfile("foot_profile") @@ -724,7 +722,7 @@ public void testMultipleCHPreparationsInParallel() { hopper.importOrLoad(); - assertEquals(5, hopper.getCHGraphs().size()); + assertEquals(4, hopper.getCHGraphs().size()); for (Map.Entry chGraph : hopper.getCHGraphs().entrySet()) { String name = chGraph.getKey(); Integer shortcutCount = shortcutCountMap.get(name); @@ -754,7 +752,6 @@ public void testMultipleLMPreparationsInParallel() { setStoreOnFlush(false). setProfiles(Arrays.asList( new Profile("car_profile").setVehicle("car").setWeighting("fastest"), - new Profile("moto_profile").setVehicle("motorcycle").setWeighting("fastest"), new Profile("mtb_profile").setVehicle("mtb").setWeighting("fastest"), new Profile("bike_profile").setVehicle("racingbike").setWeighting("fastest"), new Profile("foot_profile").setVehicle("foot").setWeighting("fastest") @@ -764,7 +761,6 @@ public void testMultipleLMPreparationsInParallel() { hopper.getLMPreparationHandler(). setLMProfiles( new LMProfile("car_profile"), - new LMProfile("moto_profile"), new LMProfile("mtb_profile"), new LMProfile("bike_profile"), new LMProfile("foot_profile") @@ -773,7 +769,7 @@ public void testMultipleLMPreparationsInParallel() { hopper.importOrLoad(); - assertEquals(5, hopper.getLandmarks().size()); + assertEquals(4, hopper.getLandmarks().size()); for (Map.Entry landmarks : hopper.getLandmarks().entrySet()) { String name = landmarks.getKey(); Integer landmarksCount = landmarkCount.get(name); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 700360d39b5..72f4e803734 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -106,36 +106,19 @@ private List createMonacoCarQueries() { return queries; } - @Test - public void testMonacoMotorcycle() { - List queries = new ArrayList<>(); - queries.add(new Query(43.730729, 7.42135, 43.727697, 7.419199, 2682, 119)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3728, 170)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.4277, 3156, 165)); - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2423, 141)); - queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2253, 120)); - queries.add(new Query(43.727592, 7.419333, 43.727712, 7.419333, 0, 1)); - GraphHopper hopper = createHopper(MONACO, - new Profile("motorcycle").setVehicle("motorcycle").setWeighting("fastest")); - hopper.setElevationProvider(new SRTMProvider(DIR)); - hopper.importOrLoad(); - checkQueries(hopper, queries); - } - @Test public void testMonacoMotorcycleCurvature() { List queries = new ArrayList<>(); queries.add(new Query(43.730729, 7.42135, 43.727697, 7.419199, 2675, 117)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3727, 170)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.4277, 3157, 165)); - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2423, 141)); - queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2253, 120)); + queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3730, 173)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.4277, 2769, 167)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2373, 137)); + queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2203, 116)); queries.add(new Query(43.727592, 7.419333, 43.727712, 7.419333, 0, 1)); - CustomModel model = new CustomModel().setDistanceInfluence(70d).addToPriority(If("true", MULTIPLY, "curvature")); - - GraphHopper hopper = createHopper(MONACO, new CustomProfile("motorcycle").setCustomModel(model). - setVehicle("motorcycle")); - hopper.setEncodedValuesString("curvature"); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("car").setCustomModel( + CustomModel.merge(getCustomModel("motorcycle.json"), getCustomModel("curvature.json"))).setVehicle("roads")); + hopper.setVehiclesString("car,roads"); + hopper.setEncodedValuesString("curvature,track_type,surface"); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java deleted file mode 100644 index 0d996ae95ed..00000000000 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MotorcycleTagParserTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.parsers; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.PriorityCode; -import com.graphhopper.routing.util.WayAccess; -import com.graphhopper.util.Helper; -import com.graphhopper.util.PMap; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.text.DateFormat; -import java.util.Arrays; -import java.util.Date; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * @author Peter Karich - */ -public class MotorcycleTagParserTest { - private final BooleanEncodedValue motorcycleAccessEnc = VehicleAccess.create("motorcycle"); - private final DecimalEncodedValue motorcycleSpeedEnc = VehicleSpeed.create("motorcycle", 5, 5, true); - private final DecimalEncodedValue motorcyclePriorityEnc = VehiclePriority.create("motorcycle", 4, PriorityCode.getFactor(1), false); - private final DecimalEncodedValue motorcycleCurvatureEnc = new DecimalEncodedValueImpl("motorcycle_curvature", 4, 0.1, false); - private final BooleanEncodedValue footAccessEnc = VehicleAccess.create("foot"); - private final DecimalEncodedValue footSpeedEnc = VehicleSpeed.create("foot", 4, 1, false); - private final EncodingManager em = EncodingManager.start() - .add(motorcycleAccessEnc).add(motorcycleSpeedEnc).add(motorcyclePriorityEnc).add(motorcycleCurvatureEnc) - .add(footAccessEnc).add(footSpeedEnc) - .build(); - private final MotorcycleAccessParser parser; - private final MotorcycleAverageSpeedParser speedParser; - - public MotorcycleTagParserTest() { - parser = new MotorcycleAccessParser(em, new PMap()); - parser.init(new DateRangeParser()); - speedParser = new MotorcycleAverageSpeedParser(em, new PMap()); - } - - @Test - public void testAccess() { - ReaderWay way = new ReaderWay(1); - assertTrue(parser.getAccess(way).canSkip()); - way.setTag("highway", "service"); - assertTrue(parser.getAccess(way).isWay()); - way.setTag("access", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "track"); - assertTrue(parser.getAccess(way).isWay()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "delivery"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "unclassified"); - way.setTag("ford", "yes"); - assertTrue(parser.getAccess(way).isWay()); - way.setTag("motorcycle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("route", "ferry"); - assertTrue(parser.getAccess(way).isFerry()); - way.setTag("motorcycle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("route", "ferry"); - way.setTag("foot", "yes"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("access", "yes"); - way.setTag("motor_vehicle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "yes"); - way.setTag("motor_vehicle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - way.setTag("motor_vehicle", "agricultural;forestry"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "emergency"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("motor_vehicle", "emergency"); - assertTrue(parser.getAccess(way).canSkip()); - - DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); - - way.clearTags(); - way.setTag("highway", "road"); - way.setTag("access:conditional", "no @ (" + simpleDateFormat.format(new Date().getTime()) + ")"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "road"); - way.setTag("access", "no"); - way.setTag("access:conditional", "yes @ (" + simpleDateFormat.format(new Date().getTime()) + ")"); - assertTrue(parser.getAccess(way).isWay()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("service", "emergency_access"); - assertTrue(parser.getAccess(way).canSkip()); - } - - @Test - public void testHandleWayTags() { - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "service"); - assertTrue(parser.getAccess(way).isWay()); - EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); - int edgeId = 0; - speedParser.handleWayTags(edgeId, edgeIntAccess, way, null); - assertEquals(20, speedParser.avgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - assertEquals(20, speedParser.avgSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), .1); - } - - @Test - public void testSetSpeed0_issue367() { - EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); - int edgeId = 0; - motorcycleAccessEnc.setBool(false, edgeId, edgeIntAccess, true); - motorcycleAccessEnc.setBool(true, edgeId, edgeIntAccess, true); - speedParser.getAverageSpeedEnc().setDecimal(false, edgeId, edgeIntAccess, 10); - speedParser.getAverageSpeedEnc().setDecimal(true, edgeId, edgeIntAccess, 10); - - assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(false, edgeId, edgeIntAccess), .1); - assertEquals(10, speedParser.getAverageSpeedEnc().getDecimal(true, edgeId, edgeIntAccess), .1); - - speedParser.setSpeed(false, edgeId, edgeIntAccess, 0); - assertEquals(0, speedParser.avgSpeedEnc.getDecimal(false, edgeId, edgeIntAccess), .1); - assertEquals(10, speedParser.avgSpeedEnc.getDecimal(true, edgeId, edgeIntAccess), .1); - - // speed and access are independent - assertTrue(motorcycleAccessEnc.getBool(false, edgeId, edgeIntAccess)); - assertTrue(motorcycleAccessEnc.getBool(true, edgeId, edgeIntAccess)); - } - - @ParameterizedTest - @ValueSource(strings = {"mofa", "moped", "motorcar", "motor_vehicle", "motorcycle"}) - void footway_etc_not_allowed_despite_vehicle_yes(String vehicle) { - // these highways are blocked, even when we set one of the vehicles to yes - for (String highway : Arrays.asList("footway", "cycleway", "steps", "pedestrian")) { - ReaderWay way = new ReaderWay(1); - way.setTag("highway", highway); - way.setTag(vehicle, "yes"); - assertEquals(WayAccess.CAN_SKIP, parser.getAccess(way)); - } - } -} diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java index 2e44a7dfd3c..487dd396478 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/TagParsingTest.java @@ -129,14 +129,12 @@ public void testSharedEncodedValues() { BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); BooleanEncodedValue footAccessEnc = VehicleAccess.create("foot"); BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); - BooleanEncodedValue motorcycleAccessEnc = VehicleAccess.create("motorcycle"); BooleanEncodedValue mtbAccessEnc = VehicleAccess.create("mtb"); - List accessEncs = Arrays.asList(carAccessEnc, footAccessEnc, bikeAccessEnc, motorcycleAccessEnc, mtbAccessEnc); + List accessEncs = Arrays.asList(carAccessEnc, footAccessEnc, bikeAccessEnc, mtbAccessEnc); EncodingManager manager = EncodingManager.start() .add(carAccessEnc).add(VehicleSpeed.create("car", 5, 5, true)) .add(footAccessEnc).add(VehicleSpeed.create("foot", 4, 1, true)).add(VehiclePriority.create("foot", 4, PriorityCode.getFactor(1), false)) .add(bikeAccessEnc).add(VehicleSpeed.create("bike", 4, 2, false)).add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)) - .add(motorcycleAccessEnc).add(VehicleSpeed.create("motorcycle", 5, 5, true)).add(VehiclePriority.create("motorcycle", 4, PriorityCode.getFactor(1), false)).add(new DecimalEncodedValueImpl("motorcycle_curvature", 5, 5, true)) .add(mtbAccessEnc).add(VehicleSpeed.create("mtb", 4, 2, false)).add(VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false)) .add(RouteNetwork.create(FootNetwork.KEY)) .add(RouteNetwork.create(BikeNetwork.KEY)) @@ -149,7 +147,6 @@ public void testSharedEncodedValues() { new CarAccessParser(manager, new PMap()), new FootAccessParser(manager, new PMap()), new BikeAccessParser(manager, new PMap()), - new MotorcycleAccessParser(manager, new PMap()), new MountainBikeAccessParser(manager, new PMap()) ); for (TagParser tagParser : tagParsers) diff --git a/custom_models/curvature.json b/custom_models/curvature.json index 93f1b3afff4..a1b9494b68b 100644 --- a/custom_models/curvature.json +++ b/custom_models/curvature.json @@ -1,8 +1,9 @@ +// prefer curvy roads { "priority": [ { - "if": "curvature > 0.9", - "multiply_by": "0.3" + "if": "curvature >= 0.98", + "multiply_by": "0.4" } ] } \ No newline at end of file diff --git a/custom_models/motorcycle.json b/custom_models/motorcycle.json new file mode 100644 index 00000000000..4fb747a3410 --- /dev/null +++ b/custom_models/motorcycle.json @@ -0,0 +1,27 @@ +// to use this custom model you need to set the following option in the config.yml +// graph.vehicles: roads|transportation_mode=MOTORCYCLE,car +// graph.urban_density.threads: 4 # expensive to calculate but very useful +// graph.encoded_values: curvature,track_type,surface +// profiles: +// - name: motorcycle +// vehicle: roads +// weighting: custom +// custom_model_files: [motorcycle.json,curvature.json] + +{ + "distance_influence": 90, + "speed": [ + { "if": "true", "multiply_by": "0.9 * car_average_speed" }, + { "if": "true", "limit_to": "120" }, + { "if": "surface==COBBLESTONE || surface==GRASS || surface==GRAVEL || surface==SAND || surface==PAVING_STONES || surface==DIRT || surface==GROUND || surface==UNPAVED || surface==COMPACTED", + "limit_to": "30" + } + ], + "priority": [ + { "if": "!car_access", "multiply_by": "0"}, + { "if": "track_type.ordinal() > 1", "multiply_by": "0" }, + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "road_class == MOTORWAY || road_class == TRUNK", "multiply_by": "0.1" } + // { "if": "urban_density != RURAL", "multiply_by": "0.3" }, + ] +} \ No newline at end of file From 2993296d1fd7bfaefc998ed34588558e37672c43 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 18:22:40 +0200 Subject: [PATCH 028/165] hike and cargo_bike: exclude private roads --- custom_models/cargo_bike.json | 1 + custom_models/hike.json | 1 + 2 files changed, 2 insertions(+) diff --git a/custom_models/cargo_bike.json b/custom_models/cargo_bike.json index 27151acff07..114efb14542 100644 --- a/custom_models/cargo_bike.json +++ b/custom_models/cargo_bike.json @@ -6,6 +6,7 @@ { "else": "", "limit_to": 25 } ], "priority": [ + { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "road_class == STEPS", "multiply_by": 0 }, { "if": "surface == SAND", "multiply_by": 0.5 }, { "if": "track_type != MISSING && track_type != GRADE1", "multiply_by": 0.9 }, diff --git a/custom_models/hike.json b/custom_models/hike.json index 29cb7965e1a..87d28373a93 100644 --- a/custom_models/hike.json +++ b/custom_models/hike.json @@ -10,6 +10,7 @@ { "priority": [ + { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "true", "multiply_by": "foot_priority"}, { "if": "!foot_access && hike_rating < 4", "multiply_by": "0"}, { "if": "foot_network == INTERNATIONAL || foot_network == NATIONAL", "multiply_by": "1.7"}, From 94a5602fd269a523c00300bbaf00fa82d560f198 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 18:26:30 +0200 Subject: [PATCH 029/165] custom models: list priority first for no particular reason --- custom_models/bus.json | 8 ++++---- custom_models/car4wd.json | 9 +++++---- custom_models/cargo_bike.json | 9 +++++---- custom_models/curvature.json | 1 + custom_models/motorcycle.json | 15 ++++++++------- custom_models/truck.json | 9 +++++---- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/custom_models/bus.json b/custom_models/bus.json index 7d3dbf301b2..18adfdcdd0b 100644 --- a/custom_models/bus.json +++ b/custom_models/bus.json @@ -9,12 +9,12 @@ { "distance_influence": 90, - "speed": [ - { "if": "true", "limit_to": "car_average_speed * 0.9" }, - { "if": "true", "limit_to": "120" } - ], "priority": [ { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "car_access == false || max_width < 3 || max_height < 4", "multiply_by": "0" } + ], + "speed": [ + { "if": "true", "limit_to": "car_average_speed * 0.9" }, + { "if": "true", "limit_to": "120" } ] } \ No newline at end of file diff --git a/custom_models/car4wd.json b/custom_models/car4wd.json index ada463899f1..d23de61e73a 100644 --- a/custom_models/car4wd.json +++ b/custom_models/car4wd.json @@ -9,6 +9,10 @@ { "distance_influence": 1, + "priority": [ + { "if": "road_access == PRIVATE", "multiply_by": "0" }, + { "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", "multiply_by": "0" } + ], "speed": [ { "if": "track_type == GRADE4 || track_type == GRADE5", @@ -18,9 +22,6 @@ "else": "", "limit_to": "car_average_speed" } - ], - "priority": [ - { "if": "road_access == PRIVATE", "multiply_by": "0" }, - { "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", "multiply_by": "0" } ] + } \ No newline at end of file diff --git a/custom_models/cargo_bike.json b/custom_models/cargo_bike.json index 114efb14542..ce8cfa00b82 100644 --- a/custom_models/cargo_bike.json +++ b/custom_models/cargo_bike.json @@ -1,10 +1,7 @@ // We assume e-bikes and lower the speed to prefer shorter and not faster routes automatically // prefer better tracks than usually done with bike and avoid all situations where we have to get off the bike + { - "speed": [ - { "if": "road_class == PRIMARY", "limit_to": 28 }, - { "else": "", "limit_to": 25 } - ], "priority": [ { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "road_class == STEPS", "multiply_by": 0 }, @@ -13,5 +10,9 @@ { "if": "get_off_bike", "multiply_by": 0.5 }, { "if": "max_height < 2.3", "multiply_by": 0 }, { "if": "max_width < 1.2", "multiply_by": 0 } + ], + "speed": [ + { "if": "road_class == PRIMARY", "limit_to": 28 }, + { "else": "", "limit_to": 25 } ] } \ No newline at end of file diff --git a/custom_models/curvature.json b/custom_models/curvature.json index a1b9494b68b..e300a5aac4f 100644 --- a/custom_models/curvature.json +++ b/custom_models/curvature.json @@ -1,4 +1,5 @@ // prefer curvy roads + { "priority": [ { diff --git a/custom_models/motorcycle.json b/custom_models/motorcycle.json index 4fb747a3410..c36e1fe9af1 100644 --- a/custom_models/motorcycle.json +++ b/custom_models/motorcycle.json @@ -10,18 +10,19 @@ { "distance_influence": 90, - "speed": [ - { "if": "true", "multiply_by": "0.9 * car_average_speed" }, - { "if": "true", "limit_to": "120" }, - { "if": "surface==COBBLESTONE || surface==GRASS || surface==GRAVEL || surface==SAND || surface==PAVING_STONES || surface==DIRT || surface==GROUND || surface==UNPAVED || surface==COMPACTED", - "limit_to": "30" - } - ], "priority": [ { "if": "!car_access", "multiply_by": "0"}, { "if": "track_type.ordinal() > 1", "multiply_by": "0" }, { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "road_class == MOTORWAY || road_class == TRUNK", "multiply_by": "0.1" } // { "if": "urban_density != RURAL", "multiply_by": "0.3" }, + ], + "speed": [ + { "if": "true", "multiply_by": "0.9 * car_average_speed" }, + { "if": "true", "limit_to": "120" }, + { "if": "surface==COBBLESTONE || surface==GRASS || surface==GRAVEL || surface==SAND || surface==PAVING_STONES || surface==DIRT || surface==GROUND || surface==UNPAVED || surface==COMPACTED", + "limit_to": "30" + } ] + } \ No newline at end of file diff --git a/custom_models/truck.json b/custom_models/truck.json index 87b2db22b83..7e96751d22f 100644 --- a/custom_models/truck.json +++ b/custom_models/truck.json @@ -6,14 +6,15 @@ // vehicle: roads // weighting: custom // custom_model_files: [truck.json] + { "distance_influence": 1, - "speed": [ - { "if": "true", "limit_to": "car_average_speed * 0.9" }, - { "if": "true", "limit_to": "95" } - ], "priority": [ { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "car_access == false || hgv == NO || max_width < 3 || max_height < 4", "multiply_by": "0" } + ], + "speed": [ + { "if": "true", "limit_to": "car_average_speed * 0.9" }, + { "if": "true", "limit_to": "95" } ] } \ No newline at end of file From 69b369bfe7800271158d7e4baffc777291657aa0 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Apr 2023 21:10:10 +0200 Subject: [PATCH 030/165] minor tweak --- .../com/graphhopper/reader/ReaderElement.java | 39 ++++++++----------- .../parsers/BikeCommonPriorityParser.java | 2 +- .../routing/util/parsers/OSMTollParser.java | 2 +- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/ReaderElement.java b/core/src/main/java/com/graphhopper/reader/ReaderElement.java index 9007af9cba6..22f95bf431c 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderElement.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderElement.java @@ -17,7 +17,10 @@ */ package com.graphhopper.reader; -import java.util.*; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; /** @@ -98,16 +101,6 @@ public T getTag(String key, T defaultValue) { return val; } - public List getKeysWithPrefix(String keyPrefix) { - List keys = new ArrayList<>(); - for (String key : properties.keySet()) { - if (key.startsWith(keyPrefix)) { - keys.add(key); - } - } - return keys; - } - public void setTag(String name, Object value) { properties.put(name, value); } @@ -147,8 +140,7 @@ public final boolean hasTag(String key, Collection values) { } /** - * Check a number of tags in the given order for the any of the given values. Used to parse - * hierarchical access restrictions + * Check a number of tags in the given order for any of the given values. */ public boolean hasTag(List keyList, Collection values) { for (String key : keyList) { @@ -158,22 +150,27 @@ public boolean hasTag(List keyList, Collection values) { return false; } - public boolean hasTagWithKeyPrefix(String keyPrefix) { - for (String key : properties.keySet()) { - if (key.startsWith(keyPrefix)) { + /** + * Check a number of tags in the given order if their value is equal to the specified value. + */ + public boolean hasTag(List keyList, Object value) { + for (String key : keyList) { + if (value.equals(getTag(key, null))) return true; - } } return false; } /** * Returns the first existing tag of the specified list where the order is important. + * + * @return an empty string if nothing found */ public String getFirstPriorityTag(List restrictions) { for (String str : restrictions) { - if (hasTag(str)) - return getTag(str); + Object value = properties.get(str); + if (value != null) + return (String) value; } return ""; } @@ -190,10 +187,6 @@ public Type getType() { return type; } - public boolean isType(Type type) { - return this.type == type; - } - @Override public String toString() { return properties.toString(); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index e239a412abd..e476cad6b1d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -150,7 +150,7 @@ private PriorityCode convertClassValueToPriority(String tagvalue) { */ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { String highway = way.getTag("highway"); - if (way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, Arrays.asList("designated")) + if (way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, "designated") || way.hasTag("bicycle", "official")) { if ("path".equals(highway)) weightToPrioMap.put(100d, VERY_NICE.getValue()); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java index 20782dcef7c..25941bb0a6b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java @@ -42,7 +42,7 @@ public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay rea Toll toll; if (readerWay.hasTag("toll", "yes")) { toll = Toll.ALL; - } else if (readerWay.hasTag(HGV_TAGS, Collections.singletonList("yes"))) { + } else if (readerWay.hasTag(HGV_TAGS, "yes")) { toll = Toll.HGV; } else if (readerWay.hasTag("toll", "no")) { toll = Toll.NO; From 9f5a49926a9472aca452d69f76bd91a2012c806b Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 4 Apr 2023 14:51:24 +0200 Subject: [PATCH 031/165] Revert "removed parser options block_private and block_fords (#2780)" This reverts commit be7209b517c4dd01935ec6c433a56209ae85de34. --- CHANGELOG.md | 1 - .../util/parsers/AbstractAccessParser.java | 41 ++++++++---- .../util/parsers/BikeAccessParser.java | 3 +- .../util/parsers/BikeCommonAccessParser.java | 8 +++ .../routing/util/parsers/CarAccessParser.java | 15 ++++- .../util/parsers/FootAccessParser.java | 11 +++- .../parsers/MountainBikeAccessParser.java | 3 +- .../util/parsers/RacingBikeAccessParser.java | 3 +- .../util/parsers/WheelchairAccessParser.java | 3 +- .../java/com/graphhopper/GraphHopperTest.java | 62 +++++++++---------- .../graphhopper/reader/osm/OSMReaderTest.java | 18 +++--- .../routing/RoutingAlgorithmWithOSMTest.java | 19 +++--- .../routing/util/EncodingManagerTest.java | 24 +++++++ .../parsers/AbstractBikeTagParserTester.java | 53 +++++++++++++++- .../util/parsers/BikeTagParserTest.java | 4 +- .../util/parsers/CarTagParserTest.java | 47 ++++++++++++-- .../util/parsers/FootTagParserTest.java | 20 ++++++ .../parsers/MountainBikeTagParserTest.java | 4 +- .../util/parsers/RacingBikeTagParserTest.java | 4 +- .../util/parsers/WheelchairTagParserTest.java | 10 +++ custom_models/bike.json | 1 - custom_models/bus.json | 1 - custom_models/car4wd.json | 1 - .../resources/SPTResourceTest.java | 12 +--- 24 files changed, 272 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc8be9c9465..4f0913efe0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ ### 8.0 [not yet released] -- breaking change: fords and private roads are now always allowed and have to be excluded through the custom model, see e.g. custom_models/bike.json and #2780 - custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java index bffb07f3a02..bd876cd2fee 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/AbstractAccessParser.java @@ -9,25 +9,25 @@ import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.PMap; import java.util.*; public abstract class AbstractAccessParser implements TagParser { static final Collection FERRIES = Arrays.asList("shuttle_train", "ferry"); static final Collection ONEWAYS = Arrays.asList("yes", "true", "1", "-1"); - static final Collection INTENDED = Arrays.asList("yes", "designated", "official", "permissive", "private", "permit"); + static final Collection INTENDED = Arrays.asList("yes", "designated", "official", "permissive"); // order is important protected final List restrictions = new ArrayList<>(5); protected final Set restrictedValues = new HashSet<>(5); - protected final Set intendedValues = Collections.unmodifiableSet(new HashSet<>(INTENDED)); - protected final Set ferries = Collections.unmodifiableSet(new HashSet<>(FERRIES)); - protected final Set oneways = Collections.unmodifiableSet(new HashSet<>(ONEWAYS)); + protected final Set intendedValues = new HashSet<>(INTENDED); + protected final Set ferries = new HashSet<>(FERRIES); + protected final Set oneways = new HashSet<>(ONEWAYS); // http://wiki.openstreetmap.org/wiki/Mapfeatures#Barrier protected final Set barriers = new HashSet<>(5); protected final BooleanEncodedValue accessEnc; + private boolean blockFords = true; private ConditionalTagInspector conditionalTagInspector; protected AbstractAccessParser(BooleanEncodedValue accessEnc, TransportationMode transportationMode) { @@ -37,15 +37,12 @@ protected AbstractAccessParser(BooleanEncodedValue accessEnc, TransportationMode restrictedValues.add("restricted"); restrictedValues.add("military"); restrictedValues.add("emergency"); + restrictedValues.add("private"); + restrictedValues.add("permit"); restrictions.addAll(OSMRoadAccessParser.toOSMRestrictions(transportationMode)); } - protected void check(PMap properties) { - if (properties.getBool("block_private", false) || properties.getBool("block_fords", false)) - throw new IllegalArgumentException("block_private and block_fords are no longer supported. Use a custom model as described in #2780"); - } - public AbstractAccessParser init(DateRangeParser dateRangeParser) { setConditionalTagInspector(new ConditionalOSMTagInspector(Collections.singletonList(dateRangeParser), restrictions, restrictedValues, intendedValues, false)); @@ -56,6 +53,25 @@ protected void setConditionalTagInspector(ConditionalTagInspector inspector) { conditionalTagInspector = inspector; } + public boolean isBlockFords() { + return blockFords; + } + + protected void blockFords(boolean blockFords) { + this.blockFords = blockFords; + } + + protected void blockPrivate(boolean blockPrivate) { + if (!blockPrivate) { + if (!restrictedValues.remove("private")) + throw new IllegalStateException("no 'private' found in restrictedValues"); + if (!restrictedValues.remove("permit")) + throw new IllegalStateException("no 'permit' found in restrictedValues"); + intendedValues.add("private"); + intendedValues.add("permit"); + } + } + public ConditionalTagInspector getConditionalTagInspector() { return conditionalTagInspector; } @@ -88,7 +104,10 @@ public boolean isBarrier(ReaderNode node) { return true; else if (intendedValues.contains(firstValue)) return false; - return node.hasTag("barrier", barriers); + else if (node.hasTag("barrier", barriers)) + return true; + else + return blockFords && node.hasTag("ford", "yes"); } public final BooleanEncodedValue getAccessEnc() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java index 415f778d1db..e67fbfe31e6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeAccessParser.java @@ -11,7 +11,8 @@ public class BikeAccessParser extends BikeCommonAccessParser { public BikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "bike"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - check(properties); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } public BikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java index 45039bd0f1d..305639a1610 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAccessParser.java @@ -23,6 +23,11 @@ protected BikeCommonAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedVa restrictedValues.add("forestry"); restrictedValues.add("delivery"); + intendedValues.add("yes"); + intendedValues.add("designated"); + intendedValues.add("official"); + intendedValues.add("permissive"); + barriers.add("fence"); allowedHighways.addAll(Arrays.asList("living_street", "steps", "cycleway", "path", "footway", "platform", @@ -92,6 +97,9 @@ public WayAccess getAccess(ReaderWay way) { if (way.hasTag("motorroad", "yes")) return WayAccess.CAN_SKIP; + if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) + return WayAccess.CAN_SKIP; + if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index edce4b2d8ac..1d70c9198a1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -35,12 +35,13 @@ public CarAccessParser(EncodedValueLookup lookup, PMap properties) { this( lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car"))), lookup.getBooleanEncodedValue(Roundabout.KEY), + properties, TransportationMode.CAR ); - check(properties); } - public CarAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc, + public CarAccessParser(BooleanEncodedValue accessEnc, + BooleanEncodedValue roundaboutEnc, PMap properties, TransportationMode transportationMode) { super(accessEnc, transportationMode); this.roundaboutEnc = roundaboutEnc; @@ -48,6 +49,13 @@ public CarAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue rounda restrictedValues.add("forestry"); restrictedValues.add("delivery"); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); + + intendedValues.add("yes"); + intendedValues.add("designated"); + intendedValues.add("permissive"); + barriers.add("kissing_gate"); barriers.add("fence"); barriers.add("bollard"); @@ -109,6 +117,9 @@ public WayAccess getAccess(ReaderWay way) { } } + if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) + return WayAccess.CAN_SKIP; + if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java index e8a9f9b8479..e2a4d4553d5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java @@ -39,12 +39,18 @@ public class FootAccessParser extends AbstractAccessParser implements TagParser public FootAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "foot")))); - check(properties); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } protected FootAccessParser(BooleanEncodedValue accessEnc) { super(accessEnc, TransportationMode.FOOT); + intendedValues.add("yes"); + intendedValues.add("designated"); + intendedValues.add("official"); + intendedValues.add("permissive"); + sidewalkValues.add("yes"); sidewalkValues.add("both"); sidewalkValues.add("left"); @@ -145,6 +151,9 @@ public WayAccess getAccess(ReaderWay way) { if (way.hasTag("motorroad", "yes")) return WayAccess.CAN_SKIP; + if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) + return WayAccess.CAN_SKIP; + if (permittedWayConditionallyRestricted) return WayAccess.CAN_SKIP; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java index 62b008c7d21..ffa0672c005 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAccessParser.java @@ -11,7 +11,8 @@ public class MountainBikeAccessParser extends BikeCommonAccessParser { public MountainBikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "mtb"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - check(properties); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } protected MountainBikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java index 08868402ea1..5843c167e9d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikeAccessParser.java @@ -11,7 +11,8 @@ public class RacingBikeAccessParser extends BikeCommonAccessParser { public RacingBikeAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "racingbike"))), lookup.getBooleanEncodedValue(Roundabout.KEY)); - check(properties); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } protected RacingBikeAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java index 1c67e6f652e..83fa8e039d3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java @@ -18,7 +18,8 @@ public class WheelchairAccessParser extends FootAccessParser { public WheelchairAccessParser(EncodedValueLookup lookup, PMap properties) { this(lookup.getBooleanEncodedValue(properties.getString("name", VehicleAccess.key("wheelchair")))); - check(properties); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } protected WheelchairAccessParser(BooleanEncodedValue accessEnc) { diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 5c0fbf95dfc..55eddf28409 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -23,8 +23,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.reader.dem.SkadiProvider; -import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.EdgeIntAccess; import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.AllEdgesIterator; @@ -103,12 +103,12 @@ public void setup() { @ParameterizedTest @CsvSource({ - DIJKSTRA + ",false,714", - ASTAR + ",false,364", - DIJKSTRA_BI + ",false,350", + DIJKSTRA + ",false,708", + ASTAR + ",false,363", + DIJKSTRA_BI + ",false,346", ASTAR_BI + ",false,192", - ASTAR_BI + ",true,52", - DIJKSTRA_BI + ",true,46" + ASTAR_BI + ",true,46", + DIJKSTRA_BI + ",true,51" }) public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expectedVisitedNodes) { final String vehicle = "car"; @@ -155,7 +155,7 @@ public void testMonacoWithInstructions() { setAlgorithm(ASTAR).setProfile(profile)); // identify the number of counts to compare with CH foot route - assertEquals(718, rsp.getHints().getLong("visited_nodes.sum", 0)); + assertEquals(713, rsp.getHints().getLong("visited_nodes.sum", 0)); ResponsePath res = rsp.getBest(); assertEquals(3437.1, res.getDistance(), .1); @@ -424,25 +424,25 @@ public void testImportWithCHANDCustomProfile() { @Test public void testAlternativeRoutes() { + final String profile = "profile"; + final String vehicle = "foot"; + final String weighting = "shortest"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(MONACO). - setProfiles(new CustomProfile("foot").setCustomModel(new CustomModel(). - addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")). - setDistanceInfluence(700d)). - setVehicle("foot")). + setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)). setStoreOnFlush(true). importOrLoad(); GHRequest req = new GHRequest(43.729057, 7.41251, 43.740298, 7.423561). - setAlgorithm(ALT_ROUTE).setProfile("foot"); + setAlgorithm(ALT_ROUTE).setProfile(profile); GHResponse rsp = hopper.route(req); assertFalse(rsp.hasErrors()); assertEquals(2, rsp.getAll().size()); - assertEquals(1327, rsp.getAll().get(0).getTime() / 1000); - assertEquals(1436, rsp.getAll().get(1).getTime() / 1000); + assertEquals(1310, rsp.getAll().get(0).getTime() / 1000); + assertEquals(1431, rsp.getAll().get(1).getTime() / 1000); req.putHint("alternative_route.max_paths", 3); req.putHint("alternative_route.min_plateau_factor", 0.1); @@ -450,9 +450,9 @@ public void testAlternativeRoutes() { assertFalse(rsp.hasErrors()); assertEquals(3, rsp.getAll().size()); - assertEquals(1327, rsp.getAll().get(0).getTime() / 1000); - assertEquals(1436, rsp.getAll().get(1).getTime() / 1000); - assertEquals(1574, rsp.getAll().get(2).getTime() / 1000); + assertEquals(1310, rsp.getAll().get(0).getTime() / 1000); + assertEquals(1431, rsp.getAll().get(1).getTime() / 1000); + assertEquals(1492, rsp.getAll().get(2).getTime() / 1000); } @Test @@ -712,9 +712,7 @@ public void testCustomModel() { final String customCar = "custom_car"; final String emptyCar = "empty_car"; CustomModel customModel = new CustomModel(); - customModel. - addToPriority(If("road_access == PRIVATE", MULTIPLY, "0")). - addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0.1")); + customModel.addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0.1")); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(BAYREUTH). @@ -1465,7 +1463,7 @@ private void executeCHFootRoute(boolean sort) { // identify the number of counts to compare with none-CH foot route which had nearly 700 counts long sum = rsp.getHints().getLong("visited_nodes.sum", 0); assertNotEquals(sum, 0); - assertTrue(sum < 165, "Too many nodes visited " + sum); + assertTrue(sum < 147, "Too many nodes visited " + sum); assertEquals(3437.1, bestPath.getDistance(), .1); assertEquals(85, bestPath.getPoints().size()); @@ -1628,12 +1626,9 @@ public void testCrossQuery() { setGraphHopperLocation(GH_LOCATION). setOSMFile(MONACO). setProfiles( - new CustomProfile(profile1).setCustomModel(new CustomModel(). - addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(70d)).setVehicle("car"), - new CustomProfile(profile2).setCustomModel(new CustomModel(). - addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(100d)).setVehicle("car"), - new CustomProfile(profile3).setCustomModel(new CustomModel(). - addToPriority(If("road_access==PRIVATE", MULTIPLY, "0")).setDistanceInfluence(150d)).setVehicle("car") + new Profile(profile1).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.07), + new Profile(profile2).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.10), + new Profile(profile3).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.15) ). setStoreOnFlush(true); @@ -1981,13 +1976,16 @@ public void testTurnCostsOnOffCH() { @Test public void testCHOnOffWithTurnCosts() { + final String profile = "my_car"; + final String vehicle = "car"; + final String weighting = "fastest"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(MOSCOW). - setProfiles(new CustomProfile("my_car").setCustomModel(new CustomModel().addToPriority(If("road_access==PRIVATE", MULTIPLY, "0"))) - .setVehicle("car").setTurnCosts(true)). + setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true)). setStoreOnFlush(true); - hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("my_car")); + hopper.getCHPreparationHandler() + .setCHProfiles(new CHProfile(profile)); hopper.importOrLoad(); GHRequest req = new GHRequest(55.813357, 37.5958585, 55.811042, 37.594689); @@ -2667,7 +2665,7 @@ void curbsideWithSubnetwork_issue2502() { GHResponse response = hopper.route(request); assertFalse(response.hasErrors(), response.getErrors().toString()); double distance = response.getBest().getDistance(); - assertEquals(436, distance, 1); + assertEquals(382, distance, 1); } { // B->A @@ -2680,7 +2678,7 @@ void curbsideWithSubnetwork_issue2502() { GHResponse response = hopper.route(request); assertFalse(response.hasErrors(), response.getErrors().toString()); double distance = response.getBest().getDistance(); - assertEquals(2462, distance, 1); + assertEquals(2318, distance, 1); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index af526d71d0e..8b979c543af 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,7 +22,6 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; -import com.graphhopper.json.Statement; import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; @@ -34,8 +33,6 @@ import com.graphhopper.routing.util.*; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.*; -import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -52,7 +49,6 @@ import java.util.HashMap; import java.util.List; -import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.GHUtility.readCountries; import static org.junit.jupiter.api.Assertions.*; @@ -391,23 +387,23 @@ public void testBarrierBetweenWays() { @Test public void testFords() { GraphHopper hopper = new GraphHopper(); - CustomProfile profile = new CustomProfile("car").setCustomModel(new CustomModel(). - addToPriority(Statement.If("road_environment == FORD", MULTIPLY, "0"))); - profile.setVehicle("car"); + hopper.setVehiclesString("car|block_fords=true"); hopper.setOSMFile(getClass().getResource("test-barriers3.xml").getFile()). setGraphHopperLocation(dir). - setProfiles(profile). + setProfiles( + new Profile("car").setVehicle("car").setWeighting("fastest") + ). setMinNetworkSize(0). importOrLoad(); Graph graph = hopper.getBaseGraph(); // our way is split into five edges, because there are two ford nodes assertEquals(5, graph.getEdges()); - Weighting weighting = hopper.createWeighting(profile, new PMap()); + BooleanEncodedValue accessEnc = hopper.getEncodingManager().getBooleanEncodedValue(VehicleAccess.key("car")); int blocked = 0; int notBlocked = 0; AllEdgesIterator edge = graph.getAllEdges(); while (edge.next()) { - if (Double.isInfinite(weighting.calcEdgeWeight(edge, false))) + if (!edge.get(accessEnc)) blocked++; else notBlocked++; @@ -700,7 +696,7 @@ public void testTurnFlagCombination() { hopper.setVehicleTagParserFactory((lookup, name, config) -> { if (name.equals("truck")) { return new VehicleTagParsers( - new CarAccessParser(lookup.getBooleanEncodedValue(VehicleAccess.key("truck")), lookup.getBooleanEncodedValue(Roundabout.KEY), TransportationMode.HGV) + new CarAccessParser(lookup.getBooleanEncodedValue(VehicleAccess.key("truck")), lookup.getBooleanEncodedValue(Roundabout.KEY), config, TransportationMode.HGV) .init(config.getObject("date_range_parser", new DateRangeParser())), new CarAverageSpeedParser(lookup.getDecimalEncodedValue(VehicleSpeed.key("truck")), 120), null diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 72f4e803734..6b1cfceae2d 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -409,16 +409,15 @@ public void testMonacoMountainBike() { // hard to select between secondary and primary (both are AVOID for mtb) queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1459, 88)); - Profile profile = new CustomProfile("mtb"). - setCustomModel(new CustomModel().addToPriority(If("road_access == PRIVATE", MULTIPLY, "0"))). - setVehicle("mtb"); - GraphHopper hopper = createHopper(MONACO, profile); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb")); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(MONACO, profile, new CustomProfile("racingbike").setCustomModel(new CustomModel()).setVehicle("racingbike")); + hopper = createHopper(MONACO, + new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb"), + new Profile("racingbike").setVehicle("racingbike").setWeighting("fastest")); hopper.importOrLoad(); checkQueries(hopper, queries); } @@ -431,16 +430,16 @@ public void testMonacoRacingBike() { queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2568, 135)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1490, 84)); - Profile profile = new CustomProfile("racingbike"). - setCustomModel(new CustomModel().addToPriority(If("road_access == PRIVATE", MULTIPLY, "0"))). - setVehicle("racingbike"); - GraphHopper hopper = createHopper(MONACO, profile); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("racingbike"). + setCustomModel(new CustomModel()).setVehicle("racingbike")); hopper.importOrLoad(); checkQueries(hopper, queries); Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(MONACO, profile, new CustomProfile("bike").setCustomModel(new CustomModel()).setVehicle("bike")); + hopper = createHopper(MONACO, new CustomProfile("racingbike").setCustomModel(new CustomModel()).setVehicle("racingbike"), + new Profile("bike").setVehicle("bike").setWeighting("fastest") + ); hopper.importOrLoad(); checkQueries(hopper, queries); } diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index d8d8b1812de..2ecac791e91 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -36,6 +36,30 @@ */ public class EncodingManagerTest { + @Test + public void testSupportFords() { + EncodingManager manager = new EncodingManager.Builder() + .add(VehicleEncodedValues.car(new PMap())) + .add(VehicleEncodedValues.bike(new PMap())) + .add(VehicleEncodedValues.foot(new PMap())). + build(); + + // 1) default -> no block fords + assertFalse(new CarAccessParser(manager, new PMap()).isBlockFords()); + assertFalse(new BikeAccessParser(manager, new PMap()).isBlockFords()); + assertFalse(new FootAccessParser(manager, new PMap()).isBlockFords()); + + // 2) true + assertTrue(new CarAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); + assertTrue(new BikeAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); + assertTrue(new FootAccessParser(manager, new PMap("block_fords=true")).isBlockFords()); + + // 3) false + assertFalse(new CarAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); + assertFalse(new BikeAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); + assertFalse(new FootAccessParser(manager, new PMap("block_fords=false")).isBlockFords()); + } + @Test public void testRegisterOnlyOnceAllowed() { DecimalEncodedValueImpl speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index bb45a2adc28..d2ad5ff08b7 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -54,7 +54,7 @@ public abstract class AbstractBikeTagParserTester { @BeforeEach public void setUp() { encodingManager = createEncodingManager(); - VehicleTagParsers parsers = createBikeTagParsers(encodingManager); + VehicleTagParsers parsers = createBikeTagParsers(encodingManager, new PMap("block_fords=true")); accessParser = (BikeCommonAccessParser) parsers.getAccessParser(); speedParser = (BikeCommonAverageSpeedParser) parsers.getSpeedParser(); priorityParser = (BikeCommonPriorityParser) parsers.getPriorityParser(); @@ -69,7 +69,7 @@ public void setUp() { protected abstract EncodingManager createEncodingManager(); - protected abstract VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup); + protected abstract VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap); protected void assertPriority(int expectedPrio, ReaderWay way) { IntsRef relFlags = osmParsers.handleRelationTags(new ReaderRelation(0), osmParsers.createRelationFlags()); @@ -172,6 +172,13 @@ public void testAccess() { way.setTag("motorroad", "yes"); assertTrue(accessParser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "track"); + way.setTag("ford", "yes"); + assertTrue(accessParser.getAccess(way).canSkip()); + way.setTag("bicycle", "yes"); + assertTrue(accessParser.getAccess(way).isWay()); + way.clearTags(); way.setTag("highway", "secondary"); way.setTag("access", "no"); @@ -452,6 +459,18 @@ public void testBarrierAccess() { assertFalse(accessParser.isBarrier(node)); } + @Test + public void testBarrierAccessFord() { + ReaderNode node = new ReaderNode(1, -1, -1); + node.setTag("ford", "yes"); + // barrier! + assertTrue(accessParser.isBarrier(node)); + + node.setTag("bicycle", "yes"); + // no barrier! + assertFalse(accessParser.isBarrier(node)); + } + @Test public void testFerries() { ReaderWay way = new ReaderWay(1); @@ -467,6 +486,13 @@ public void testFerries() { way.setTag("foot", "yes"); assertFalse(accessParser.getAccess(way).isFerry()); + // #1122 + way.clearTags(); + way.setTag("route", "ferry"); + way.setTag("bicycle", "yes"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + // #1562, test if ferry route with bicycle way.clearTags(); way.setTag("route", "ferry"); @@ -485,6 +511,10 @@ public void testFerries() { way.setTag("bicycle", "no"); assertTrue(accessParser.getAccess(way).canSkip()); + way.setTag("bicycle", "designated"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + // test if when foot is set is invalid way.clearTags(); way.setTag("route", "ferry"); @@ -492,6 +522,25 @@ public void testFerries() { assertTrue(accessParser.getAccess(way).canSkip()); } + @Test + void privateAndFords() { + // defaults: do not block fords, block private + BikeCommonAccessParser bike = (BikeCommonAccessParser) createBikeTagParsers(encodingManager, new PMap()).getAccessParser(); + assertFalse(bike.isBlockFords()); + assertTrue(bike.restrictedValues.contains("private")); + assertFalse(bike.intendedValues.contains("private")); + ReaderNode node = new ReaderNode(1, 1, 1); + node.setTag("access", "private"); + assertTrue(bike.isBarrier(node)); + + // block fords, unblock private + bike = (BikeCommonAccessParser) createBikeTagParsers(encodingManager, new PMap("block_fords=true|block_private=false")).getAccessParser(); + assertTrue(bike.isBlockFords()); + assertFalse(bike.restrictedValues.contains("private")); + assertTrue(bike.intendedValues.contains("private")); + assertFalse(bike.isBarrier(node)); + } + @Test public void testOneway() { ReaderWay way = new ReaderWay(1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index ad2c2c4ccf4..4134951f81f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -46,8 +46,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { - return VehicleTagParsers.bike(lookup, new PMap()); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { + return VehicleTagParsers.bike(lookup, pMap); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java index e49a0746dc7..c2dbb4da03e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/CarTagParserTest.java @@ -41,8 +41,8 @@ */ public class CarTagParserTest { private final EncodingManager em = createEncodingManager("car"); - final CarAccessParser parser = createParser(em); - final CarAverageSpeedParser speedParser = new CarAverageSpeedParser(em, new PMap()); + final CarAccessParser parser = createParser(em, new PMap("block_fords=true")); + final CarAverageSpeedParser speedParser = new CarAverageSpeedParser(em, new PMap("block_fords=true")); private final BooleanEncodedValue roundaboutEnc = em.getBooleanEncodedValue(Roundabout.KEY); private final BooleanEncodedValue accessEnc = parser.getAccessEnc(); private final DecimalEncodedValue avSpeedEnc = speedParser.getAverageSpeedEnc(); @@ -60,8 +60,8 @@ private EncodingManager createEncodingManager(String carName) { .build(); } - CarAccessParser createParser(EncodedValueLookup lookup) { - CarAccessParser carTagParser = new CarAccessParser(lookup, new PMap()); + CarAccessParser createParser(EncodedValueLookup lookup, PMap properties) { + CarAccessParser carTagParser = new CarAccessParser(lookup, properties); carTagParser.init(new DateRangeParser()); return carTagParser; } @@ -95,6 +95,13 @@ public void testAccess() { way.setTag("access", "delivery"); assertTrue(parser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "unclassified"); + way.setTag("ford", "yes"); + assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motorcar", "yes"); + assertTrue(parser.getAccess(way).isWay()); + way.clearTags(); way.setTag("access", "yes"); way.setTag("motor_vehicle", "no"); @@ -176,6 +183,16 @@ public void testFordAccess() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "unclassified"); way.setTag("ford", "yes"); + + // Node and way are initially blocking + assertTrue(parser.isBlockFords()); + assertTrue(parser.getAccess(way).canSkip()); + assertTrue(parser.isBarrier(node)); + + CarAccessParser tmpParser = new CarAccessParser(em, new PMap("block_fords=false")); + tmpParser.init(new DateRangeParser()); + assertTrue(tmpParser.getAccess(way).isWay()); + assertFalse(tmpParser.isBarrier(node)); } @Test @@ -229,6 +246,28 @@ public void testOneway() { way.clearTags(); } + @Test + public void shouldBlockPrivate() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "primary"); + way.setTag("access", "private"); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + int edgeId = 0; + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertFalse(accessEnc.getBool(false, edgeId, edgeIntAccess)); + + final CarAccessParser parser = createParser(em, new PMap("block_private=false")); + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + + way.setTag("highway", "primary"); + way.setTag("motor_vehicle", "permit"); // currently handled like "private", see #2712 + edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); + parser.handleWayTags(edgeId, edgeIntAccess, way); + assertTrue(parser.getAccessEnc().getBool(false, edgeId, edgeIntAccess)); + } + @Test public void testSetAccess() { EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(em.getIntsForFlags()); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java index 4101433020d..83dd1769706 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/FootTagParserTest.java @@ -132,6 +132,13 @@ public void testAccess() { way.setTag("sidewalk", "none"); assertTrue(accessParser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("sidewalk", "left"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "pedestrian"); assertTrue(accessParser.getAccess(way).isWay()); @@ -212,6 +219,10 @@ public void testAccess() { way.setTag("foot", "no"); assertTrue(accessParser.getAccess(way).canSkip()); + way.setTag("foot", "designated"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); way.clearTags(); @@ -485,6 +496,15 @@ public void testFord() { // barrier! node.setTag("foot", "no"); assertTrue(accessParser.isBarrier(node)); + + FootAccessParser blockFordsParser = new FootAccessParser(encodingManager, new PMap("block_fords=true")); + node = new ReaderNode(1, -1, -1); + node.setTag("ford", "no"); + assertFalse(blockFordsParser.isBarrier(node)); + + node = new ReaderNode(1, -1, -1); + node.setTag("ford", "yes"); + assertTrue(blockFordsParser.isBarrier(node)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java index d8d87e725a9..f5507af61ad 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java @@ -40,8 +40,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { - return VehicleTagParsers.mtb(lookup, new PMap()); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { + return VehicleTagParsers.mtb(lookup, pMap); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index f72014acd7e..fc7f8ea2679 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -46,8 +46,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup) { - return VehicleTagParsers.racingbike(lookup, new PMap()); + protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap) { + return VehicleTagParsers.racingbike(lookup, pMap); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java index 9cfbff01241..60a3d77d88f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/WheelchairTagParserTest.java @@ -129,6 +129,12 @@ public void testAccess() { assertTrue(accessParser.getAccess(way).canSkip()); way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("sidewalk", "left"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "pedestrian"); assertTrue(accessParser.getAccess(way).isWay()); @@ -211,6 +217,10 @@ public void testAccess() { way.setTag("foot", "no"); assertTrue(accessParser.getAccess(way).canSkip()); + way.setTag("foot", "designated"); + way.setTag("access", "private"); + assertTrue(accessParser.getAccess(way).canSkip()); + DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); way.clearTags(); diff --git a/custom_models/bike.json b/custom_models/bike.json index 3dca3e1695c..801d17866b6 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -11,7 +11,6 @@ { "priority": [ { "if": "true", "multiply_by": "bike_priority" }, - { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "!bike_access && !backward_bike_access", "multiply_by": "0" }, { "else_if": "!bike_access && backward_bike_access && !roundabout", "multiply_by": "0.2" } ], diff --git a/custom_models/bus.json b/custom_models/bus.json index 18adfdcdd0b..2dba951ed47 100644 --- a/custom_models/bus.json +++ b/custom_models/bus.json @@ -10,7 +10,6 @@ { "distance_influence": 90, "priority": [ - { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "car_access == false || max_width < 3 || max_height < 4", "multiply_by": "0" } ], "speed": [ diff --git a/custom_models/car4wd.json b/custom_models/car4wd.json index d23de61e73a..fa5db9d809e 100644 --- a/custom_models/car4wd.json +++ b/custom_models/car4wd.json @@ -10,7 +10,6 @@ { "distance_influence": 1, "priority": [ - { "if": "road_access == PRIVATE", "multiply_by": "0" }, { "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", "multiply_by": "0" } ], "speed": [ diff --git a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java index f2dec82f994..4e2b9e29eb5 100644 --- a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java @@ -22,9 +22,7 @@ import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; import com.graphhopper.application.util.GraphHopperServerTestConfiguration; -import com.graphhopper.json.Statement; -import com.graphhopper.routing.weighting.custom.CustomProfile; -import com.graphhopper.util.CustomModel; +import com.graphhopper.config.Profile; import com.graphhopper.util.Helper; import io.dropwizard.testing.junit5.DropwizardAppExtension; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -55,12 +53,8 @@ private static GraphHopperServerConfiguration createConfig() { putObject("import.osm.ignored_highways", ""). putObject("graph.location", DIR). setProfiles(Arrays.asList( - new CustomProfile("car_without_turncosts").setCustomModel(new CustomModel(). - addToPriority(Statement.If("road_access==PRIVATE", Statement.Op.MULTIPLY, "0"))). - setVehicle("car"), - new CustomProfile("car_with_turncosts").setCustomModel(new CustomModel(). - addToPriority(Statement.If("road_access==PRIVATE", Statement.Op.MULTIPLY, "0"))). - setVehicle("car").setTurnCosts(true) + new Profile("car_without_turncosts").setVehicle("car").setWeighting("fastest"), + new Profile("car_with_turncosts").setVehicle("car").setWeighting("fastest").setTurnCosts(true) )); return config; } From 8ceab61325ac56416be88730db5168077fc64bcc Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 5 Apr 2023 13:53:51 +0200 Subject: [PATCH 032/165] A*: infinite approximation means the target is unreachable --- core/src/main/java/com/graphhopper/routing/AStar.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AStar.java b/core/src/main/java/com/graphhopper/routing/AStar.java index deb2e8f0117..ec34360029c 100644 --- a/core/src/main/java/com/graphhopper/routing/AStar.java +++ b/core/src/main/java/com/graphhopper/routing/AStar.java @@ -85,12 +85,14 @@ public Path calcPath(int from, int to, int fromOutEdge, int toInEdge) { this.toInEdge = toInEdge; checkAlreadyRun(); this.to = to; + if (fromOutEdge == NO_EDGE || toInEdge == NO_EDGE) + return extractPath(); weightApprox.setTo(to); double weightToGoal = weightApprox.approximate(from); + if (Double.isInfinite(weightToGoal)) + return extractPath(); AStarEntry startEntry = new AStarEntry(EdgeIterator.NO_EDGE, from, 0 + weightToGoal, 0); fromHeap.add(startEntry); - if (fromOutEdge == NO_EDGE || toInEdge == NO_EDGE) - return extractPath(); if (!traversalMode.isEdgeBased()) fromMap.put(from, currEdge); runAlgo(); @@ -123,6 +125,8 @@ private void runAlgo() { if (ase == null || ase.weightOfVisitedPath > tmpWeight) { int neighborNode = iter.getAdjNode(); currWeightToGoal = weightApprox.approximate(neighborNode); + if (Double.isInfinite(currWeightToGoal)) + continue; estimationFullWeight = tmpWeight + currWeightToGoal; if (ase == null) { ase = new AStarEntry(iter.getEdge(), neighborNode, estimationFullWeight, tmpWeight, currEdge); From a08eee11b875cb680ef1c85c5632f7c2fadbe7f7 Mon Sep 17 00:00:00 2001 From: ratrun Date: Sat, 8 Apr 2023 12:01:48 +0200 Subject: [PATCH 033/165] Make the MiniGraphUI working again. (#2793) --- tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java index 06fb256a847..22eb477d58b 100644 --- a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java +++ b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java @@ -104,7 +104,7 @@ public static void main(String[] strs) { .setVehicle("car") .setTurnCosts(true) .setWeighting("fastest") - )); + )).putObject("import.osm.ignored_highways", ""); ghConfig.setCHProfiles(Arrays.asList( new CHProfile("profile") )); From adc31b20b0f1f52ffd6806761c3669c4164c96fa Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 11 Apr 2023 13:14:07 +0200 Subject: [PATCH 034/165] Use separate logger for OSM warnings --- config-example.yml | 31 ++++++++++++------- .../com/graphhopper/reader/osm/OSMReader.java | 9 +++--- .../java/com/graphhopper/util/GHUtility.java | 1 + 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/config-example.yml b/config-example.yml index f672499a702..54f4ae4401a 100644 --- a/config-example.yml +++ b/config-example.yml @@ -221,14 +221,23 @@ server: # See https://www.dropwizard.io/en/latest/manual/core.html#logging logging: appenders: - - type: file - time_zone: UTC - current_log_filename: logs/graphhopper.log - log_format: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" - archive: true - archived_log_filename_pattern: ./logs/graphhopper-%d.log.gz - archived_file_count: 30 - never_block: true - - type: console - time_zone: UTC - log_format: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" + - type: file + time_zone: UTC + current_log_filename: logs/graphhopper.log + log_format: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" + archive: true + archived_log_filename_pattern: ./logs/graphhopper-%d.log.gz + archived_file_count: 30 + never_block: true + - type: console + time_zone: UTC + log_format: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" + loggers: + "com.graphhopper.osm_warning": + level: DEBUG + additive: false + appenders: + - type: file + currentLogFilename: logs/osm_warnings.log + archive: false + logFormat: '[%level] %msg%n' \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 5ca65dd7b46..f9b13a59e80 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -58,6 +58,7 @@ import java.util.stream.Collectors; import static com.graphhopper.search.KVStorage.KeyValue.*; +import static com.graphhopper.util.GHUtility.OSM_WARNING_LOGGER; import static com.graphhopper.util.Helper.nf; import static java.util.Collections.emptyList; @@ -449,14 +450,14 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier if (durationTag == null) { // no duration tag -> we cannot derive speed. happens very frequently for short ferries, but also for some long ones, see: #2532 if (isFerry(way) && distance > 500_000) - LOGGER.warn("Long ferry OSM way without duration tag: " + way.getId() + ", distance: " + Math.round(distance / 1000.0) + " km"); + OSM_WARNING_LOGGER.warn("Long ferry OSM way without duration tag: " + way.getId() + ", distance: " + Math.round(distance / 1000.0) + " km"); return; } long durationInSeconds; try { durationInSeconds = OSMReaderUtility.parseDuration(durationTag); } catch (Exception e) { - LOGGER.warn("Could not parse duration tag '" + durationTag + "' in OSM way: " + way.getId()); + OSM_WARNING_LOGGER.warn("Could not parse duration tag '" + durationTag + "' in OSM way: " + way.getId()); return; } @@ -464,7 +465,7 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier if (speedInKmPerHour < 0.1d) { // Often there are mapping errors like duration=30:00 (30h) instead of duration=00:30 (30min). In this case we // ignore the duration tag. If no such cases show up anymore, because they were fixed, maybe raise the limit to find some more. - LOGGER.warn("Unrealistic low speed calculated from duration. Maybe the duration is too long, or it is applied to a way that only represents a part of the connection? OSM way: " + OSM_WARNING_LOGGER.warn("Unrealistic low speed calculated from duration. Maybe the duration is too long, or it is applied to a way that only represents a part of the connection? OSM way: " + way.getId() + ". duration=" + durationTag + " (= " + Math.round(durationInSeconds / 60.0) + " minutes), distance=" + distance + " m"); return; @@ -602,7 +603,7 @@ private static void warnOfRestriction(ReaderRelation restrictionRelation, OSMRes if (!e.isWithoutWarning()) { restrictionRelation.getTags().remove("graphhopper:via_node"); List members = restrictionRelation.getMembers().stream().map(m -> m.getRole() + " " + m.getType().toString().toLowerCase() + " " + m.getRef()).collect(Collectors.toList()); - LOGGER.warn("Restriction relation " + restrictionRelation.getId() + " " + e.getMessage() + ". tags: " + restrictionRelation.getTags() + ", members: " + members + ". Relation ignored."); + OSM_WARNING_LOGGER.warn("Restriction relation " + restrictionRelation.getId() + " " + e.getMessage() + ". tags: " + restrictionRelation.getTags() + ", members: " + members + ". Relation ignored."); } } diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 30f165390cc..6df07f1b690 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -66,6 +66,7 @@ * @author Peter Karich */ public class GHUtility { + public static final Logger OSM_WARNING_LOGGER = LoggerFactory.getLogger("com.graphhopper.osm_warning"); private static final Logger LOGGER = LoggerFactory.getLogger(GHUtility.class); /** From 40148308c5e24263fa658200c14cf0971697f336 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 11 Apr 2023 13:35:13 +0200 Subject: [PATCH 035/165] osm_warning -> osm_warnings --- config-example.yml | 2 +- core/src/main/java/com/graphhopper/util/GHUtility.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config-example.yml b/config-example.yml index 54f4ae4401a..1f0d28ed796 100644 --- a/config-example.yml +++ b/config-example.yml @@ -233,7 +233,7 @@ logging: time_zone: UTC log_format: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" loggers: - "com.graphhopper.osm_warning": + "com.graphhopper.osm_warnings": level: DEBUG additive: false appenders: diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 6df07f1b690..ec4d58e06d2 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -66,7 +66,7 @@ * @author Peter Karich */ public class GHUtility { - public static final Logger OSM_WARNING_LOGGER = LoggerFactory.getLogger("com.graphhopper.osm_warning"); + public static final Logger OSM_WARNING_LOGGER = LoggerFactory.getLogger("com.graphhopper.osm_warnings"); private static final Logger LOGGER = LoggerFactory.getLogger(GHUtility.class); /** From a0f20c3391d81beb2cbebeee4812efc09ab79419 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 8 Apr 2023 23:21:46 +0200 Subject: [PATCH 036/165] update graphhopper maps to latest --- web-bundle/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml index 853496a4c8d..b041ba456dd 100644 --- a/web-bundle/pom.xml +++ b/web-bundle/pom.xml @@ -7,7 +7,7 @@ jar 8.0-SNAPSHOT - 0.0.0-8922383db6f937fddb44acc702f2b45844566575 + 0.0.0-65144ede0dfbb1b0484ee3558e23d35a032204b7 GraphHopper Dropwizard Bundle Use the GraphHopper routing engine as a web-service From 8832fa26972bbe63e32179624cd03cf24c32d389 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 8 Apr 2023 23:43:07 +0200 Subject: [PATCH 037/165] maps: avoid URI too long for bigger custom models --- config-example.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config-example.yml b/config-example.yml index 1f0d28ed796..f70b82fbaf4 100644 --- a/config-example.yml +++ b/config-example.yml @@ -212,6 +212,8 @@ server: port: 8989 # for security reasons bind to localhost bind_host: localhost + # increase GET request limit - not necessary if /maps UI is not used or used without custom models + max_request_header_size: 50k request_log: appenders: [] admin_connectors: From 409808ccfd9cd05f93123a35c17bf30e0f834917 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 11 Apr 2023 18:11:14 +0200 Subject: [PATCH 038/165] avoid IllegalStateException if duplicate path detail --- .../graphhopper/util/details/PathDetailsFromEdges.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java index 39da194f606..8873b7ad927 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java @@ -24,10 +24,8 @@ import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * This class calculates a PathDetail list in a similar fashion to the instruction calculation, @@ -60,6 +58,10 @@ public static Map> calcDetails(Path path, EncodedValueL int previousIndex, Graph graph) { if (!path.isFound() || requestedPathDetails.isEmpty()) return Collections.emptyMap(); + HashSet uniquePD = new HashSet<>(requestedPathDetails.size()); + Collection res = requestedPathDetails.stream().filter(pd -> !uniquePD.add(pd)).collect(Collectors.toList()); + if (!res.isEmpty()) throw new IllegalArgumentException("Do not use duplicate path details: " + res); + List pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, path, evLookup, weighting, graph); if (pathBuilders.isEmpty()) return Collections.emptyMap(); From 1f1709c18008c4ef9aeb7b1a77ea20efa24992ea Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 12 Apr 2023 21:17:59 +0200 Subject: [PATCH 039/165] bike custom model: fix roundabout --- custom_models/bike.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_models/bike.json b/custom_models/bike.json index 801d17866b6..74a81723925 100644 --- a/custom_models/bike.json +++ b/custom_models/bike.json @@ -11,8 +11,8 @@ { "priority": [ { "if": "true", "multiply_by": "bike_priority" }, - { "if": "!bike_access && !backward_bike_access", "multiply_by": "0" }, - { "else_if": "!bike_access && backward_bike_access && !roundabout", "multiply_by": "0.2" } + { "if": "!bike_access && (!backward_bike_access || roundabout)", "multiply_by": "0" }, + { "else_if": "!bike_access && backward_bike_access", "multiply_by": "0.2" } ], "speed": [ { "if": "true", "limit_to": "bike_average_speed" }, From 66e3c9c080b5e95fd14c3b7107cd03a80ac5bda2 Mon Sep 17 00:00:00 2001 From: bt90 Date: Wed, 12 Apr 2023 22:28:56 +0200 Subject: [PATCH 040/165] Prefer bicycle_road/cycleway (#2790) * Prefer bicycle roads and cycle streets * Handle pushing section priority * Add unittests * Simplify check * Move test into dedicated method * Update changelog --- CHANGELOG.md | 1 + .../parsers/BikeCommonPriorityParser.java | 12 ++++++++---- .../util/parsers/BikeTagParserTest.java | 19 ++++++++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f0913efe0b..86bbfb3b257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 +- prefer cycleways, bicycle_road and cyclestreet for bike routing, see #2784 and #2778 ### 7.0 [14 Mar 2023] diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index e476cad6b1d..22e28612833 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -150,8 +150,7 @@ private PriorityCode convertClassValueToPriority(String tagvalue) { */ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { String highway = way.getTag("highway"); - if (way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, "designated") - || way.hasTag("bicycle", "official")) { + if (isDesignated(way)) { if ("path".equals(highway)) weightToPrioMap.put(100d, VERY_NICE.getValue()); else @@ -180,7 +179,7 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight } String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right", "cycleway:both")); - if (Arrays.asList("lane", "shared_lane", "share_busway", "shoulder").contains(cycleway) || "opposite_track".equals(cycleway)) { + if (Arrays.asList("lane", "opposite_track", "shared_lane", "share_busway", "shoulder").contains(cycleway)) { weightToPrioMap.put(100d, SLIGHT_PREFER.getValue()); } else if ("track".equals(cycleway)) { weightToPrioMap.put(100d, PREFER.getValue()); @@ -194,7 +193,7 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight PriorityCode pushingSectionPrio = SLIGHT_AVOID; if (way.hasTag("bicycle", "yes") || way.hasTag("bicycle", "permissive")) pushingSectionPrio = PREFER; - if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official")) + if (isDesignated(way)) pushingSectionPrio = VERY_NICE; if (way.hasTag("foot", "yes")) { pushingSectionPrio = PriorityCode.values()[pushingSectionPrio.ordinal() - 1]; @@ -231,6 +230,11 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight } } + boolean isDesignated(ReaderWay way) { + return way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, "designated") + || way.hasTag("bicycle_road", "yes") || way.hasTag("cyclestreet", "yes") || way.hasTag("bicycle", "official"); + } + // TODO duplicated in average speed void addPushingSection(String highway) { pushingSectionsHighways.add(highway); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 4134951f81f..36e5bb5da65 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -262,11 +262,6 @@ public void testSpeedAndPriority() { way.setTag("highway", "motorway"); way.setTag("bicycle", "yes"); assertPriorityAndSpeed(AVOID.getValue(), 18, way); - - way.clearTags(); - way.setTag("highway", "primary"); - way.setTag("cycleway:bicycle", "designated"); - assertPriority(PREFER.getValue(), way); } @Test @@ -341,6 +336,20 @@ public void testCycleway() { way.setTag("cycleway", "opposite_track"); assertPriority(SLIGHT_PREFER.getValue(), way); + way.clearTags(); + way.setTag("highway", "primary"); + way.setTag("cycleway:bicycle", "designated"); + assertPriority(PREFER.getValue(), way); + + way.clearTags(); + way.setTag("highway", "path"); + way.setTag("bicycle_road", "yes"); + assertPriority(VERY_NICE.getValue(), way); + + way.clearTags(); + way.setTag("highway", "path"); + way.setTag("cyclestreet", "yes"); + assertPriority(VERY_NICE.getValue(), way); } @Test From a5683faf710d9b2cd21466cd6f97913d95f17f3c Mon Sep 17 00:00:00 2001 From: Olaf Flebbe at Bosch eBike <123375381+OlafFlebbeBosch@users.noreply.github.com> Date: Wed, 12 Apr 2023 22:50:12 +0200 Subject: [PATCH 041/165] i18n: update da_DK (#2794) --- .../resources/com/graphhopper/util/da_DK.txt | 79 +++++++++++-------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/core/src/main/resources/com/graphhopper/util/da_DK.txt b/core/src/main/resources/com/graphhopper/util/da_DK.txt index ac275e6a4a3..1039fa59491 100644 --- a/core/src/main/resources/com/graphhopper/util/da_DK.txt +++ b/core/src/main/resources/com/graphhopper/util/da_DK.txt @@ -13,9 +13,9 @@ turn_slight_right=drej lidt til højre turn_sharp_left=drej skarpt til venstre turn_sharp_right=drej skarpt til højre u_turn=foretag en U-vending -toward_destination= -toward_destination_ref_only= -toward_destination_with_ref= +toward_destination=%1$s og kør mod %2$s +toward_destination_ref_only=%1$s mod %2$s +toward_destination_with_ref=%1$s og tag %2$s mod %3$s unknown=ukendt instruktionsskilt '%1$s' via=via hour_abbr=t @@ -39,13 +39,17 @@ roundabout_exit_onto=I rundskørslen, tag udkørsel %1$s ind på %2$s web.total_ascend=%1$s samlet stigning web.total_descend=%1$s samlet fald web.way_contains_ford=der er et vadested undervejs -web.way_contains_ferry= -web.way_contains_private= -web.way_contains_toll= -web.way_crosses_border= -web.way_contains= -web.tracks= -web.steps= +web.way_contains_ferry=Rute med færger +web.way_contains_private=Rute med private veje +web.way_contains_toll=Rute med betalingsveje +web.way_crosses_border=Rute der krydser landegrænser +web.way_contains=Rute inkluderer %1$s +web.tracks=Grusveje uden asfalt +web.steps=Trapper +web.footways=Fortove +web.steep_sections=Stejle sektioner +web.private_sections= +web.get_off_bike_for=Føreren skal stige af og cyklen skal skubbes %1$s pt_transfer_to=omstigning til %1$s web.start_label=Start web.intermediate_label=Via @@ -57,16 +61,20 @@ web.center_map=Centrer kort her web.show_coords=Vis koordinater web.query_osm= web.route=Rute -web.add_to_route= +web.add_to_route=Tilføj placering web.delete_from_route=Fjern fra rute web.open_custom_model_box= -web.help_custom_model= +web.help_custom_model=Hjælp web.apply_custom_model= -web.exclude_motorway_example= -web.limit_speed_example= -web.exclude_area_example= -web.combined_example= -web.examples_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= +web.exclude_motorway_example=Eksludér motorvej +web.limit_speed_example=Max hastighed +web.cargo_bike_example=Ladcykel +web.exclude_area_example=Eksludér område +web.combined_example=Kombinerede eksempler +web.examples_custom_model=Eksempler web.marker=Markør web.gh_offline_info=Er GraphHopper API offline? web.refresh_button=Genindlæs siden @@ -74,17 +82,17 @@ web.server_status=Status web.zoom_in=Zoom ind web.zoom_out=Zoom ud web.drag_to_reorder=Træk for at ændre rækkefølgen -web.route_timed_out= -web.route_request_failed= +web.route_timed_out=Ruteberegning fejlede +web.route_request_failed=Ukendt fejl web.current_location= web.searching_location= web.searching_location_failed= web.via_hint=Via web.from_hint=Fra web.gpx_export_button=Eksportér GPX-fil -web.gpx_button= -web.hide_button= -web.details_button= +web.gpx_button=GPX +web.hide_button=Gem +web.details_button=Detaljer web.to_hint=Til web.route_info=%1$s med køretid %2$s web.search_button=Søg @@ -105,18 +113,21 @@ web.bus=Bus web.truck=Lastbil web.staticlink=statisk link web.motorcycle=Motorcykel -web.back_to_map= -web.distance_unit= -web.waiting_for_gps= -navigate.in_km_singular= -navigate.in_km= -navigate.in_m= -navigate.for_km= -navigate.then= -navigate.in_mi_singular= -navigate.in_mi= -navigate.in_ft= -navigate.for_mi= +web.back_to_map=Tilbage +web.distance_unit=Distance er i %1$s +web.waiting_for_gps=Venter på GPS signal +navigate.in_km_singular=Om 1 kilometer +navigate.in_km=Om %1$s kilometer +navigate.in_m=Om %1$s meter +navigate.for_km=i %1$s kilometer +navigate.then=så +navigate.in_mi_singular=Om 1 mil +navigate.in_mi=Om %1$s mil +navigate.in_ft=Om %1$s fod +navigate.for_mi=i %1$s mil navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= From 56a662001202db102053cd8aec110be200f4501a Mon Sep 17 00:00:00 2001 From: otbutz Date: Fri, 14 Apr 2023 12:41:58 +0200 Subject: [PATCH 042/165] Improve surface parser (#2792) * Move synonyms into Surface * Add support for unhewn_cobblestone * Handle surface subtypes * Treat pebblestone as gravel * Treat grass_paver as grass * Add support for wooden surfaces * Test all synonyms * Check subtypes in dedicated test * Update changelog --- CHANGELOG.md | 1 + .../com/graphhopper/routing/ev/Surface.java | 30 ++++++++++-- .../util/parsers/OSMSurfaceParser.java | 9 ---- .../util/parsers/OSMSurfaceParserTest.java | 48 +++++++++++++++++++ 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86bbfb3b257..ec64d3ddc29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 - prefer cycleways, bicycle_road and cyclestreet for bike routing, see #2784 and #2778 +- add support for further surfaces like pebblestones or concrete:lanes, see #2751 ### 7.0 [14 Mar 2023] diff --git a/core/src/main/java/com/graphhopper/routing/ev/Surface.java b/core/src/main/java/com/graphhopper/routing/ev/Surface.java index a76be0c4b03..8f2cecbdaf3 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Surface.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Surface.java @@ -19,6 +19,9 @@ import com.graphhopper.util.Helper; +import java.util.HashMap; +import java.util.Map; + /** * This enum defines the road surface of an edge like unpaved or asphalt. If not tagged the value will be MISSING, which * the default and best surface value (as surface is currently often not tagged). All unknown surface tags will get @@ -29,11 +32,26 @@ public enum Surface { MISSING("missing"), PAVED("paved"), ASPHALT("asphalt"), CONCRETE("concrete"), PAVING_STONES("paving_stones"), COBBLESTONE("cobblestone"), UNPAVED("unpaved"), COMPACTED("compacted"), FINE_GRAVEL("fine_gravel"), GRAVEL("gravel"), - GROUND("ground"), DIRT("dirt"), GRASS("grass"), SAND("sand"), + GROUND("ground"), DIRT("dirt"), GRASS("grass"), SAND("sand"), WOOD("wood"), OTHER("other"); public static final String KEY = "surface"; + private static final Map SURFACE_MAP = new HashMap<>(); + static { + for (Surface surface : values()) { + if (surface == MISSING || surface == OTHER) + continue; + SURFACE_MAP.put(surface.name, surface); + } + SURFACE_MAP.put("metal", PAVED); + SURFACE_MAP.put("sett", COBBLESTONE); + SURFACE_MAP.put("unhewn_cobblestone", COBBLESTONE); + SURFACE_MAP.put("earth", DIRT); + SURFACE_MAP.put("pebblestone", GRAVEL); + SURFACE_MAP.put("grass_paver", GRASS); + } + public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Surface.class); } @@ -52,10 +70,12 @@ public String toString() { public static Surface find(String name) { if (Helper.isEmpty(name)) return MISSING; - try { - return Surface.valueOf(Helper.toUpperCase(name)); - } catch (IllegalArgumentException ex) { - return OTHER; + + int colonIndex = name.indexOf(":"); + if (colonIndex != -1) { + name = name.substring(0, colonIndex); } + + return SURFACE_MAP.getOrDefault(name, OTHER); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java index 808070af301..cbe2becb9d9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMSurfaceParser.java @@ -40,15 +40,6 @@ public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay rea if (surface == MISSING) return; - if (surfaceTag.equals("metal")) - surface = PAVED; - else if (surfaceTag.equals("sett")) - surface = COBBLESTONE; - else if (surfaceTag.equals("wood")) - surface = UNPAVED; - else if (surfaceTag.equals("earth")) - surface = DIRT; - surfaceEnc.setEnum(false, edgeId, edgeIntAccess, surface); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java index 4765dc0bf6c..a5651c4c552 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMSurfaceParserTest.java @@ -35,8 +35,56 @@ public void testSimpleTags() { assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); assertTrue(Surface.COBBLESTONE.ordinal() > Surface.ASPHALT.ordinal()); + readerWay.setTag("surface", "wood"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.WOOD, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + } + + @Test + public void testSynonyms() { + IntsRef relFlags = new IntsRef(2); + ReaderWay readerWay = new ReaderWay(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + readerWay.setTag("highway", "primary"); + readerWay.setTag("surface", "metal"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.PAVED, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + + readerWay.setTag("surface", "sett"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + + readerWay.setTag("surface", "unhewn_cobblestone"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + readerWay.setTag("surface", "earth"); parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); assertEquals(Surface.DIRT, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + + readerWay.setTag("surface", "pebblestone"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.GRAVEL, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + + readerWay.setTag("surface", "grass_paver"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.GRASS, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + } + + @Test + public void testSubtypes() { + IntsRef relFlags = new IntsRef(2); + ReaderWay readerWay = new ReaderWay(1); + EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1); + int edgeId = 0; + readerWay.setTag("highway", "primary"); + readerWay.setTag("surface", "concrete:plates"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.CONCRETE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); + + readerWay.setTag("surface", "cobblestone:flattened"); + parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags); + assertEquals(Surface.COBBLESTONE, surfaceEnc.getEnum(false, edgeId, edgeIntAccess)); } } \ No newline at end of file From 5ffd5f90603b4627b61b89f5f1223025c2e88c31 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 17 Apr 2023 15:05:32 +0200 Subject: [PATCH 043/165] avoid config mistakes --- .../main/java/com/graphhopper/http/GraphHopperManaged.java | 3 +++ .../resources/RouteResourceCustomModelTest.java | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java index ab3315677cf..ae7ce9c45a9 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java @@ -44,6 +44,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class GraphHopperManaged implements Managed { @@ -96,6 +97,8 @@ public static List resolveCustomModelFiles(String customModelFolder, Li Object cm = profile.getHints().getObject("custom_model", null); CustomModel customModel; if (cm != null) { + if (!profile.getHints().getObject("custom_model_files", Collections.emptyList()).isEmpty()) + throw new IllegalArgumentException("Do not use custom_model_files and custom_model together"); try { // custom_model can be an object tree (read from config) or an object (e.g. from tests) customModel = jsonOM.readValue(jsonOM.writeValueAsBytes(cm), CustomModel.class); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 1182372660c..0a0ce3d63cf 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -18,15 +18,12 @@ package com.graphhopper.application.resources; -import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; import com.graphhopper.application.util.GraphHopperServerTestConfiguration; import com.graphhopper.config.CHProfile; import com.graphhopper.config.Profile; -import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; @@ -43,10 +40,6 @@ import javax.ws.rs.core.Response; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringWriter; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Arrays; import static com.graphhopper.application.util.TestUtils.clientTarget; From bdc7a3bc9f6d358640b00fadc0cf92a7d12d46e5 Mon Sep 17 00:00:00 2001 From: Andi Date: Tue, 18 Apr 2023 09:12:10 +0200 Subject: [PATCH 044/165] Add timeout_ms parameter for routing requests (#2795) --- CHANGELOG.md | 1 + config-example.yml | 4 +++ .../java/com/graphhopper/GraphHopper.java | 1 + .../java/com/graphhopper/routing/AStar.java | 3 +- .../routing/AbstractBidirAlgo.java | 22 ++++++++++++- .../routing/AbstractRoutingAlgorithm.java | 20 ++++++++++++ .../graphhopper/routing/AlgorithmOptions.java | 10 ++++++ .../graphhopper/routing/AlternativeRoute.java | 7 +---- .../com/graphhopper/routing/Dijkstra.java | 3 +- .../routing/DijkstraOneToMany.java | 4 +-- .../java/com/graphhopper/routing/Router.java | 8 +++++ .../com/graphhopper/routing/RouterConfig.java | 14 +++++++++ .../graphhopper/routing/RoutingAlgorithm.java | 5 +++ .../RoutingAlgorithmFactorySimple.java | 4 +-- .../routing/ch/CHRoutingAlgorithmFactory.java | 5 +-- .../routing/lm/LMRoutingAlgorithmFactory.java | 3 ++ .../java/com/graphhopper/GraphHopperTest.java | 7 +++++ docs/web/api-doc.md | 31 ++++++++++--------- .../java/com/graphhopper/util/Parameters.java | 2 ++ .../resources/RouteResourceLeipzigTest.java | 31 +++++++++++++++++++ 20 files changed, 155 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec64d3ddc29..32538783457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 8.0 [not yet released] +- routing requests can be configured to timeout after some time, see #2795 - custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 - bike vehicles are now allowed to go in reverse direction of oneways, see custom_models/bike.json #196 diff --git a/config-example.yml b/config-example.yml index f70b82fbaf4..c66af497667 100644 --- a/config-example.yml +++ b/config-example.yml @@ -163,6 +163,10 @@ graphhopper: # connection between two points within the given visited nodes. The default is Integer.MAX_VALUE. Useful for flexibility mode # routing.max_visited_nodes: 1000000 + # The maximum time in milliseconds after which a routing request will be aborted. This has some routing algorithm + # specific caveats, but generally it should allow the prevention of long-running requests. The default is Long.MAX_VALUE + # routing.timeout_ms: 300000 + # Control how many active landmarks are picked per default, this can improve query performance # routing.lm.active_landmarks: 4 diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index bb62f2fcdfb..be5e25e0c01 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -601,6 +601,7 @@ public GraphHopper init(GraphHopperConfig ghConfig) { // routing routerConfig.setMaxVisitedNodes(ghConfig.getInt(Routing.INIT_MAX_VISITED_NODES, routerConfig.getMaxVisitedNodes())); + routerConfig.setTimeoutMillis(ghConfig.getLong(Routing.INIT_TIMEOUT_MS, routerConfig.getTimeoutMillis())); routerConfig.setMaxRoundTripRetries(ghConfig.getInt(RoundTrip.INIT_MAX_RETRIES, routerConfig.getMaxRoundTripRetries())); routerConfig.setNonChMaxWaypointDistance(ghConfig.getInt(Parameters.NON_CH.MAX_NON_CH_POINT_DISTANCE, routerConfig.getNonChMaxWaypointDistance())); routerConfig.setInstructionsEnabled(ghConfig.getBool(Routing.INIT_INSTRUCTIONS, routerConfig.isInstructionsEnabled())); diff --git a/core/src/main/java/com/graphhopper/routing/AStar.java b/core/src/main/java/com/graphhopper/routing/AStar.java index ec34360029c..7fbfa7a3362 100644 --- a/core/src/main/java/com/graphhopper/routing/AStar.java +++ b/core/src/main/java/com/graphhopper/routing/AStar.java @@ -84,6 +84,7 @@ public Path calcPath(int from, int to, int fromOutEdge, int toInEdge) { this.fromOutEdge = fromOutEdge; this.toInEdge = toInEdge; checkAlreadyRun(); + setupFinishTime(); this.to = to; if (fromOutEdge == NO_EDGE || toInEdge == NO_EDGE) return extractPath(); @@ -106,7 +107,7 @@ private void runAlgo() { if (currEdge.isDeleted()) continue; visitedNodes++; - if (isMaxVisitedNodesExceeded() || finished()) + if (isMaxVisitedNodesExceeded() || finished() || isTimeoutExceeded()) break; int currNode = currEdge.adjNode; diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java index 85ebd1c47fb..c501804f9a9 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java @@ -43,6 +43,8 @@ public abstract class AbstractBidirAlgo implements EdgeToEdgeRoutingAlgorithm { protected SPTEntry bestBwdEntry; protected double bestWeight = Double.MAX_VALUE; protected int maxVisitedNodes = Integer.MAX_VALUE; + protected long timeoutMillis = Long.MAX_VALUE; + private long finishTimeMillis = Long.MAX_VALUE; PriorityQueue pqOpenSetFrom; PriorityQueue pqOpenSetTo; protected boolean updateBestPath = true; @@ -89,6 +91,7 @@ public Path calcPath(int from, int to, int fromOutEdge, int toInEdge) { this.fromOutEdge = fromOutEdge; this.toInEdge = toInEdge; checkAlreadyRun(); + setupFinishTime(); init(from, 0, to, 0); runAlgo(); return extractPath(); @@ -146,7 +149,7 @@ protected void postInit(int from, int to) { protected abstract void postInitTo(); protected void runAlgo() { - while (!finished() && !isMaxVisitedNodesExceeded()) { + while (!finished() && !isMaxVisitedNodesExceeded() && !isTimeoutExceeded()) { if (!finishedFrom) finishedFrom = !fillEdgesFrom(); @@ -263,6 +266,11 @@ public void setMaxVisitedNodes(int numberOfNodes) { this.maxVisitedNodes = numberOfNodes; } + @Override + public void setTimeoutMillis(long timeoutMillis) { + this.timeoutMillis = timeoutMillis; + } + protected void checkAlreadyRun() { if (alreadyRun) throw new IllegalStateException("Create a new instance per call"); @@ -270,6 +278,14 @@ protected void checkAlreadyRun() { alreadyRun = true; } + protected void setupFinishTime() { + try { + this.finishTimeMillis = Math.addExact(System.currentTimeMillis(), timeoutMillis); + } catch (ArithmeticException e) { + this.finishTimeMillis = Long.MAX_VALUE; + } + } + @Override public String getName() { return getClass().getSimpleName(); @@ -279,4 +295,8 @@ protected boolean isMaxVisitedNodesExceeded() { return maxVisitedNodes < getVisitedNodes(); } + protected boolean isTimeoutExceeded() { + return finishTimeMillis < Long.MAX_VALUE && System.currentTimeMillis() > finishTimeMillis; + } + } diff --git a/core/src/main/java/com/graphhopper/routing/AbstractRoutingAlgorithm.java b/core/src/main/java/com/graphhopper/routing/AbstractRoutingAlgorithm.java index e969f8e8732..7fd22c7c494 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractRoutingAlgorithm.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractRoutingAlgorithm.java @@ -37,6 +37,8 @@ public abstract class AbstractRoutingAlgorithm implements RoutingAlgorithm { protected final NodeAccess nodeAccess; protected final EdgeExplorer edgeExplorer; protected int maxVisitedNodes = Integer.MAX_VALUE; + protected long timeoutMillis = Long.MAX_VALUE; + private long finishTimeMillis = Long.MAX_VALUE; private boolean alreadyRun; /** @@ -59,6 +61,11 @@ public void setMaxVisitedNodes(int numberOfNodes) { this.maxVisitedNodes = numberOfNodes; } + @Override + public void setTimeoutMillis(long timeoutMillis) { + this.timeoutMillis = timeoutMillis; + } + protected boolean accept(EdgeIteratorState iter, int prevOrNextEdgeId) { // for edge-based traversal we leave it for TurnWeighting to decide whether or not a u-turn is acceptable, // but for node-based traversal we exclude such a turn for performance reasons already here @@ -72,6 +79,14 @@ protected void checkAlreadyRun() { alreadyRun = true; } + protected void setupFinishTime() { + try { + this.finishTimeMillis = Math.addExact(System.currentTimeMillis(), timeoutMillis); + } catch (ArithmeticException e) { + this.finishTimeMillis = Long.MAX_VALUE; + } + } + @Override public List calcPaths(int from, int to) { return Collections.singletonList(calcPath(from, to)); @@ -94,4 +109,9 @@ public String toString() { protected boolean isMaxVisitedNodesExceeded() { return maxVisitedNodes < getVisitedNodes(); } + + protected boolean isTimeoutExceeded() { + return finishTimeMillis < Long.MAX_VALUE && System.currentTimeMillis() > finishTimeMillis; + } + } diff --git a/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java b/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java index b208fadf476..57b2a170e9d 100644 --- a/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java +++ b/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java @@ -29,6 +29,7 @@ public class AlgorithmOptions { private String algorithm = Parameters.Algorithms.DIJKSTRA_BI; private TraversalMode traversalMode = TraversalMode.NODE_BASED; private int maxVisitedNodes = Integer.MAX_VALUE; + private long timeoutMillis = Long.MAX_VALUE; public AlgorithmOptions() { } @@ -55,6 +56,11 @@ public AlgorithmOptions setMaxVisitedNodes(int maxVisitedNodes) { return this; } + public AlgorithmOptions setTimeoutMillis(long timeoutMillis) { + this.timeoutMillis = timeoutMillis; + return this; + } + public AlgorithmOptions setHints(PMap pMap) { this.hints = new PMap(pMap); return this; @@ -72,6 +78,10 @@ public int getMaxVisitedNodes() { return maxVisitedNodes; } + public long getTimeoutMillis() { + return timeoutMillis; + } + public PMap getHints() { return hints; } diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index 6170b53ef90..605fbc44ef1 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -122,11 +122,6 @@ static double calcSortBy(double weightInfluence, double weight, return weightInfluence * weight + shareInfluence * shareWeight + plateauInfluence * plateauWeight; } - @Override - public void setMaxVisitedNodes(int numberOfNodes) { - this.maxVisitedNodes = numberOfNodes; - } - public List calcAlternatives(int from, int to) { Path bestPath = searchBest(from, to); return calcAlternatives(bestPath, maxPaths, @@ -201,7 +196,7 @@ public boolean finished() { if (finishedFrom && finishedTo) return true; - if (isMaxVisitedNodesExceeded()) + if (isMaxVisitedNodesExceeded() || isTimeoutExceeded()) return true; // The following condition is necessary to avoid traversing the full graph if areas are disconnected diff --git a/core/src/main/java/com/graphhopper/routing/Dijkstra.java b/core/src/main/java/com/graphhopper/routing/Dijkstra.java index f52dd20d12d..c20ffea5d07 100644 --- a/core/src/main/java/com/graphhopper/routing/Dijkstra.java +++ b/core/src/main/java/com/graphhopper/routing/Dijkstra.java @@ -57,6 +57,7 @@ protected void initCollections(int size) { @Override public Path calcPath(int from, int to) { checkAlreadyRun(); + setupFinishTime(); this.to = to; SPTEntry startEntry = new SPTEntry(from, 0); fromHeap.add(startEntry); @@ -72,7 +73,7 @@ protected void runAlgo() { if (currEdge.isDeleted()) continue; visitedNodes++; - if (isMaxVisitedNodesExceeded() || finished()) + if (isMaxVisitedNodesExceeded() || finished() || isTimeoutExceeded()) break; int currNode = currEdge.adjNode; diff --git a/core/src/main/java/com/graphhopper/routing/DijkstraOneToMany.java b/core/src/main/java/com/graphhopper/routing/DijkstraOneToMany.java index b2ec769c322..09a8987ee05 100644 --- a/core/src/main/java/com/graphhopper/routing/DijkstraOneToMany.java +++ b/core/src/main/java/com/graphhopper/routing/DijkstraOneToMany.java @@ -141,7 +141,7 @@ public int findEndNode(int from, int to) { if (parentNode != EMPTY_PARENT && weights[to] <= weights[currNode]) return to; - if (heap.isEmpty() || isMaxVisitedNodesExceeded()) + if (heap.isEmpty() || isMaxVisitedNodesExceeded() || isTimeoutExceeded()) return NOT_FOUND; currNode = heap.poll(); @@ -187,7 +187,7 @@ public int findEndNode(int from, int to) { } } - if (heap.isEmpty() || isMaxVisitedNodesExceeded() || isWeightLimitExceeded()) + if (heap.isEmpty() || isMaxVisitedNodesExceeded() || isWeightLimitExceeded() || isTimeoutExceeded()) return NOT_FOUND; // calling just peek and not poll is important if the next query is cached diff --git a/core/src/main/java/com/graphhopper/routing/Router.java b/core/src/main/java/com/graphhopper/routing/Router.java index f972a72e689..153d11f6b2f 100644 --- a/core/src/main/java/com/graphhopper/routing/Router.java +++ b/core/src/main/java/com/graphhopper/routing/Router.java @@ -426,6 +426,12 @@ private List getTurnCostProfiles() { int getMaxVisitedNodes(PMap hints) { return hints.getInt(Parameters.Routing.MAX_VISITED_NODES, routerConfig.getMaxVisitedNodes()); } + + long getTimeoutMillis(PMap hints) { + // we silently use the minimum between the requested timeout and the server-side limit + // see: https://github.com/graphhopper/graphhopper/pull/2795#discussion_r1168371343 + return Math.min(routerConfig.getTimeoutMillis(), hints.getLong(TIMEOUT_MS, routerConfig.getTimeoutMillis())); + } } private static class CHSolver extends Solver { @@ -468,6 +474,7 @@ protected PathCalculator createPathCalculator(QueryGraph queryGraph) { PMap opts = new PMap(request.getHints()); opts.putObject(ALGORITHM, request.getAlgorithm()); opts.putObject(MAX_VISITED_NODES, getMaxVisitedNodes(request.getHints())); + opts.putObject(TIMEOUT_MS, getTimeoutMillis(request.getHints())); return new CHPathCalculator(new CHRoutingAlgorithmFactory(getRoutingCHGraph(profile.getName()), queryGraph), opts); } @@ -520,6 +527,7 @@ protected AlgorithmOptions getAlgoOpts() { setAlgorithm(request.getAlgorithm()). setTraversalMode(profile.isTurnCosts() ? TraversalMode.EDGE_BASED : TraversalMode.NODE_BASED). setMaxVisitedNodes(getMaxVisitedNodes(request.getHints())). + setTimeoutMillis(getTimeoutMillis(request.getHints())). setHints(request.getHints()); // use A* for round trips diff --git a/core/src/main/java/com/graphhopper/routing/RouterConfig.java b/core/src/main/java/com/graphhopper/routing/RouterConfig.java index 398b0d05f9b..6884958cb54 100644 --- a/core/src/main/java/com/graphhopper/routing/RouterConfig.java +++ b/core/src/main/java/com/graphhopper/routing/RouterConfig.java @@ -23,6 +23,7 @@ */ public class RouterConfig { private int maxVisitedNodes = Integer.MAX_VALUE; + private long timeoutMillis = Long.MAX_VALUE; private int maxRoundTripRetries = 3; private int nonChMaxWaypointDistance = Integer.MAX_VALUE; private boolean calcPoints = true; @@ -43,6 +44,19 @@ public void setMaxVisitedNodes(int maxVisitedNodes) { this.maxVisitedNodes = maxVisitedNodes; } + public long getTimeoutMillis() { + return timeoutMillis; + } + + /** + * Limits the runtime of routing requests to the given amount of milliseconds. This only works up to a certain + * precision, but should be sufficient to cancel long-running requests in most cases. The exact implementation of + * the timeout depends on the routing algorithm. + */ + public void setTimeoutMillis(long timeoutMillis) { + this.timeoutMillis = timeoutMillis; + } + public int getMaxRoundTripRetries() { return maxRoundTripRetries; } diff --git a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithm.java b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithm.java index a395998a803..cee5913eeae 100644 --- a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithm.java +++ b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithm.java @@ -45,6 +45,11 @@ public interface RoutingAlgorithm { */ void setMaxVisitedNodes(int numberOfNodes); + /** + * Limit the search to the given time in milliseconds + */ + void setTimeoutMillis(long timeoutMillis); + /** * @return name of this algorithm */ diff --git a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java index d7840439b17..ead2ea34b3c 100644 --- a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java +++ b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java @@ -61,14 +61,14 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) ra = aStar; } else if (ALT_ROUTE.equalsIgnoreCase(algoStr)) { - AlternativeRoute altRouteAlgo = new AlternativeRoute(g, weighting, opts.getTraversalMode(), opts.getHints()); - ra = altRouteAlgo; + ra = new AlternativeRoute(g, weighting, opts.getTraversalMode(), opts.getHints()); } else { throw new IllegalArgumentException("Algorithm " + algoStr + " not found in " + getClass().getName()); } ra.setMaxVisitedNodes(opts.getMaxVisitedNodes()); + ra.setTimeoutMillis(opts.getTimeoutMillis()); return ra; } diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHRoutingAlgorithmFactory.java b/core/src/main/java/com/graphhopper/routing/ch/CHRoutingAlgorithmFactory.java index a31cbc1f1ed..d23cc58670e 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHRoutingAlgorithmFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHRoutingAlgorithmFactory.java @@ -27,8 +27,7 @@ import com.graphhopper.util.PMap; import static com.graphhopper.util.Parameters.Algorithms.*; -import static com.graphhopper.util.Parameters.Routing.ALGORITHM; -import static com.graphhopper.util.Parameters.Routing.MAX_VISITED_NODES; +import static com.graphhopper.util.Parameters.Routing.*; /** * Given a {@link RoutingCHGraph} and possibly a {@link QueryGraph} this class sets up and creates routing @@ -51,6 +50,8 @@ public EdgeToEdgeRoutingAlgorithm createAlgo(PMap opts) { : createAlgoNodeBased(routingCHGraph, opts); if (opts.has(MAX_VISITED_NODES)) algo.setMaxVisitedNodes(opts.getInt(MAX_VISITED_NODES, Integer.MAX_VALUE)); + if (opts.has(TIMEOUT_MS)) + algo.setTimeoutMillis(opts.getLong(TIMEOUT_MS, Long.MAX_VALUE)); return algo; } diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java index 5944a5207de..b7016b24398 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java @@ -53,18 +53,21 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) AStar algo = new AStar(g, weighting, opts.getTraversalMode()); algo.setApproximation(getApproximator(g, weighting, activeLM, epsilon)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); + algo.setTimeoutMillis(opts.getTimeoutMillis()); return algo; } else if (ASTAR_BI.equalsIgnoreCase(algoStr) || Helper.isEmpty(algoStr)) { double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStarBi.EPSILON, 1); AStarBidirection algo = new AStarBidirection(g, weighting, opts.getTraversalMode()); algo.setApproximation(getApproximator(g, weighting, activeLM, epsilon)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); + algo.setTimeoutMillis(opts.getTimeoutMillis()); return algo; } else if (ALT_ROUTE.equalsIgnoreCase(algoStr)) { double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStarBi.EPSILON, 1); AlternativeRoute algo = new AlternativeRoute(g, weighting, opts.getTraversalMode(), opts.getHints()); algo.setApproximation(getApproximator(g, weighting, activeLM, epsilon)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); + algo.setTimeoutMillis(opts.getTimeoutMillis()); return algo; } else { throw new IllegalArgumentException("Landmarks algorithm only supports algorithm=" diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 55eddf28409..fba7a630c63 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -71,6 +71,7 @@ import static com.graphhopper.util.GHUtility.createRectangle; import static com.graphhopper.util.Parameters.Algorithms.*; import static com.graphhopper.util.Parameters.Curbsides.*; +import static com.graphhopper.util.Parameters.Routing.TIMEOUT_MS; import static com.graphhopper.util.Parameters.Routing.U_TURN_COSTS; import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.*; @@ -137,6 +138,12 @@ public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expec assertEquals(43.7276852, res.getWaypoints().getLat(0), 1e-7); assertEquals(43.7495432, res.getWaypoints().getLat(1), 1e-7); + + // when we set a timeout no route is found, at least as long as it is negative + req.putHint(TIMEOUT_MS, -1); + rsp = hopper.route(req); + assertTrue(rsp.hasErrors()); + assertTrue(rsp.getErrors().toString().contains("ConnectionNotFoundException"), rsp.getErrors().toString()); } @Test diff --git a/docs/web/api-doc.md b/docs/web/api-doc.md index 310defb68ce..08cc6507cbd 100644 --- a/docs/web/api-doc.md +++ b/docs/web/api-doc.md @@ -25,21 +25,22 @@ Please note that unlike to the GET endpoint, points are specified in `[longitude All official parameters are shown in the following table -Parameter | Default | Description -:-----------|:--------|:----------- -point | - | Specify multiple points for which the route should be calculated. The order is important. Specify at least two points. -locale | en | The locale of the resulting turn instructions. E.g. `pt_PT` for Portuguese or `de` for German -instructions| true | If instruction should be calculated and returned -profile | - | The profile to be used for the route calculation. -elevation | false | If `true` a third dimension - the elevation - is included in the polyline or in the GeoJson. IMPORTANT: If enabled you have to use a modified version of the decoding method or set points_encoded to `false`. See the points_encoded attribute for more details. Additionally a request can fail if the vehicle does not support elevation. See the features object for every vehicle. -points_encoded | true | If `false` the coordinates in `point` and `snapped_waypoints` are returned as array using the order [lon,lat,elevation] for every point. If `true` the coordinates will be encoded as string leading to less bandwidth usage. You'll need a special handling for the decoding of this string on the client-side. We provide open source code in [Java](https://github.com/graphhopper/graphhopper/blob/d70b63660ac5200b03c38ba3406b8f93976628a6/web/src/main/java/com/graphhopper/http/WebHelper.java#L43) and [JavaScript](https://github.com/graphhopper/graphhopper/blob/d70b63660ac5200b03c38ba3406b8f93976628a6/web/src/main/webapp/js/ghrequest.js#L139). It is especially important to use no 3rd party client if you set `elevation=true`! -debug | false | If true, the output will be formatted. -calc_points | true | If the points for the route should be calculated at all printing out only distance and time. -point_hint | - | Optional parameter. Specifies a hint for each `point` parameter to prefer a certain street for the closest location lookup. E.g. if there is an address or house with two or more neighboring streets you can control for which street the closest location is looked up. -snap_prevention | - | Optional parameter to avoid snapping to a certain road class or road environment. Current supported values: `motorway`, `trunk`, `ferry`, `tunnel`, `bridge` and `ford`. Multiple values are specified like `snap_prevention=ferry&snap_prevention=motorway` -details | - | Optional parameter. You can request additional details for the route: `average_speed`, `street_name`, `edge_id`, `road_class`, `road_environment`, `max_speed` and `time` (and see which other values are configured in `graph.encoded_values`). Multiple values are specified like `details=average_speed&details=time`. The returned format for one detail segment is `[fromRef, toRef, value]`. The `ref` references the points of the response. Value can also be `null` if the property does not exist for one detail segment. -curbside | any | Optional parameter applicable to edge-based routing only. It specifies on which side a query point should be relative to the driver when she leaves/arrives at a start/target/via point. Possible values: right, left, any. Specify for every point parameter. See similar heading parameter. -force_curbside | true | Optional parameter. If it is set to true there will be an exception in case the curbside parameters cannot be fulfilled (e.g. specifying the wrong side for one-ways). + Parameter | Default | Description +:----------------|:--------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + point | - | Specify multiple points for which the route should be calculated. The order is important. Specify at least two points. + locale | en | The locale of the resulting turn instructions. E.g. `pt_PT` for Portuguese or `de` for German + instructions | true | If instruction should be calculated and returned + profile | - | The profile to be used for the route calculation. + elevation | false | If `true` a third dimension - the elevation - is included in the polyline or in the GeoJson. IMPORTANT: If enabled you have to use a modified version of the decoding method or set points_encoded to `false`. See the points_encoded attribute for more details. Additionally a request can fail if the vehicle does not support elevation. See the features object for every vehicle. + points_encoded | true | If `false` the coordinates in `point` and `snapped_waypoints` are returned as array using the order [lon,lat,elevation] for every point. If `true` the coordinates will be encoded as string leading to less bandwidth usage. You'll need a special handling for the decoding of this string on the client-side. We provide open source code in [Java](https://github.com/graphhopper/graphhopper/blob/d70b63660ac5200b03c38ba3406b8f93976628a6/web/src/main/java/com/graphhopper/http/WebHelper.java#L43) and [JavaScript](https://github.com/graphhopper/graphhopper/blob/d70b63660ac5200b03c38ba3406b8f93976628a6/web/src/main/webapp/js/ghrequest.js#L139). It is especially important to use no 3rd party client if you set `elevation=true`! + debug | false | If true, the output will be formatted. + calc_points | true | If the points for the route should be calculated at all printing out only distance and time. + point_hint | - | Optional parameter. Specifies a hint for each `point` parameter to prefer a certain street for the closest location lookup. E.g. if there is an address or house with two or more neighboring streets you can control for which street the closest location is looked up. + snap_prevention | - | Optional parameter to avoid snapping to a certain road class or road environment. Current supported values: `motorway`, `trunk`, `ferry`, `tunnel`, `bridge` and `ford`. Multiple values are specified like `snap_prevention=ferry&snap_prevention=motorway` + details | - | Optional parameter. You can request additional details for the route: `average_speed`, `street_name`, `edge_id`, `road_class`, `road_environment`, `max_speed` and `time` (and see which other values are configured in `graph.encoded_values`). Multiple values are specified like `details=average_speed&details=time`. The returned format for one detail segment is `[fromRef, toRef, value]`. The `ref` references the points of the response. Value can also be `null` if the property does not exist for one detail segment. + curbside | any | Optional parameter applicable to edge-based routing only. It specifies on which side a query point should be relative to the driver when she leaves/arrives at a start/target/via point. Possible values: right, left, any. Specify for every point parameter. See similar heading parameter. + force_curbside | true | Optional parameter. If it is set to true there will be an exception in case the curbside parameters cannot be fulfilled (e.g. specifying the wrong side for one-ways). + timeout_ms | inf | Optional parameter. Limits the request runtime to the minimum between the given value in milli-seconds and the server-side timeout configuration ### Hybrid diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index e7d946e40bd..2755cabef29 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -97,6 +97,8 @@ public static final class Routing { public static final String U_TURN_COSTS = "u_turn_costs"; public static final String MAX_VISITED_NODES = "max_visited_nodes"; public static final String INIT_MAX_VISITED_NODES = ROUTING_INIT_PREFIX + "max_visited_nodes"; + public static final String TIMEOUT_MS = "timeout_ms"; + public static final String INIT_TIMEOUT_MS = ROUTING_INIT_PREFIX + "timeout_ms"; /** * if true the response will contain turn instructions */ diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceLeipzigTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceLeipzigTest.java index cd31b542349..e4fdcc45449 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceLeipzigTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceLeipzigTest.java @@ -31,6 +31,8 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import javax.ws.rs.core.Response; import java.io.File; @@ -38,6 +40,7 @@ import java.util.Random; import static com.graphhopper.application.util.TestUtils.clientTarget; +import static com.graphhopper.util.Parameters.Algorithms.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -72,6 +75,34 @@ void testNoErrors() { queryRandomRoutes(1000, 51.342534, 51.34285, 12.384917, 12.385278); } + @ParameterizedTest + @CsvSource(value = { + "86,-1,algorithm=" + DIJKSTRA_BI, + "110,-1,algorithm=" + ASTAR_BI, + "30834,1,ch.disable=true&algorithm=" + DIJKSTRA, + "21137,1,ch.disable=true&algorithm=" + ASTAR, + "14800,1,ch.disable=true&algorithm=" + DIJKSTRA_BI, + "10536,1,ch.disable=true&algorithm=" + ASTAR_BI + }) + void testTimeout(int expectedVisitedNodes, int timeout, String args) { + { + // for a long timeout the route calculation works + long longTimeout = 10_000; + Response response = clientTarget(app, "/route?timeout_ms=" + longTimeout + "&profile=my_car&point=51.319685,12.335525&point=51.367294,12.434745&" + args).request().buildGet().invoke(); + assertEquals(200, response.getStatus()); + JsonNode jsonNode = response.readEntity(JsonNode.class); + // by checking the visited nodes we make sure different algorithms are used + assertEquals(expectedVisitedNodes, jsonNode.get("hints").get("visited_nodes.sum").asInt()); + } + { + // for a short timeout the route calculation fails, for CH we need to use a negative number, because it is too fast + Response response = clientTarget(app, "/route?timeout_ms=" + timeout + "&profile=my_car&point=51.319685,12.335525&point=51.367294,12.434745&" + args).request().buildGet().invoke(); + assertEquals(400, response.getStatus()); + JsonNode jsonNode = response.readEntity(JsonNode.class); + assertTrue(jsonNode.get("message").asText().contains("Connection between locations not found"), jsonNode.get("message").asText()); + } + } + private static void queryRandomRoutes(int numQueries, double minLat, double maxLat, double minLon, double maxLon) { final long seed = System.nanoTime(); Random rnd = new Random(seed); From ec2b7a14458c423ca42482339baca74fe349115c Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 09:50:32 +0200 Subject: [PATCH 045/165] Upgrade to dropwizard 2.1.6 (#2653) * upgrade to dropwizard 2.1.1 * try 2.1.4 * latest 2.1.6 --------- Co-authored-by: easbar --- pom.xml | 2 +- .../application/resources/IsochroneResourceTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 71571981b93..a15b364f172 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ io.dropwizard dropwizard-dependencies - 2.0.34 + 2.1.6 pom import diff --git a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java index 6aa197138cd..3160ced3e2b 100644 --- a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java @@ -265,11 +265,11 @@ public void requestNotANumber() { Response response = clientTarget(app, "/isochrone?profile=fast_car&point=42.531073,1.573792&time_limit=wurst") .request().buildGet().invoke(); - assertEquals(400, response.getStatus()); + assertEquals(404, response.getStatus()); JsonNode json = response.readEntity(JsonNode.class); String message = json.path("message").asText(); - assertEquals("query param time_limit is not a number.", message); + assertEquals("HTTP 404 Not Found", message); } @Disabled("block_area is no longer supported and to use custom models we'd need a POST endpoint for isochrones") From 19dbd9700883bd474b8ef6aadfea1f0ee49632ca Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 09:50:45 +0200 Subject: [PATCH 046/165] resurrect appveyor --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1924a299654..e9b43350b38 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ version: '{build}' skip_tags: true clone_depth: 10 -image: Visual Studio 2019 +image: Visual Studio 2022 environment: MAVEN_OPTS: -Xmx1g JAVA_OPTS: -Xmx1g @@ -9,6 +9,7 @@ environment: install: - java -version - mvn --version +build: off branches: only: - master From 064d9b9fd71ae217982bb6f333b8e7bdb23700c2 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 10:25:47 +0200 Subject: [PATCH 047/165] appveyor: revert part of the change --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index e9b43350b38..6e39e4f4ecb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,6 @@ environment: install: - java -version - mvn --version -build: off branches: only: - master From 442948ceb76d93c3e0bc83c3cb6f4411b89bdf88 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 21:15:14 +0200 Subject: [PATCH 048/165] upgrade commons-io + junit-bom + osmosis-osm-binary --- core/pom.xml | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 6d7d227a886..f3019350b99 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -85,7 +85,7 @@ org.openstreetmap.osmosis osmosis-osm-binary - 0.47.3 + 0.48.3 org.slf4j diff --git a/pom.xml b/pom.xml index a15b364f172..cf796e0ba53 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.junit junit-bom - 5.6.0 + 5.9.1 pom import @@ -120,7 +120,7 @@ commons-io commons-io - 2.7 + 2.11.0 org.mapdb From c2a7b4052cfedd46ac995cb2b3fe9d2c0f38b19d Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 21:32:49 +0200 Subject: [PATCH 049/165] bike: differentiate between bad highways (#2796) * bike: there is a difference between avoid highways like trunk and secondary * add one more test for secondary * avoid creation of values() --- .../routing/util/PriorityCode.java | 19 ++++++++++ .../parsers/BikeCommonPriorityParser.java | 38 +++++++++++-------- .../util/parsers/BikePriorityParser.java | 7 ---- .../parsers/MountainBikePriorityParser.java | 5 --- .../java/com/graphhopper/GraphHopperTest.java | 8 ++-- .../routing/RoutingAlgorithmWithOSMTest.java | 28 +++++++------- .../parsers/AbstractBikeTagParserTester.java | 2 +- .../util/parsers/BikeTagParserTest.java | 26 +++++++++---- .../parsers/MountainBikeTagParserTest.java | 2 +- .../util/parsers/RacingBikeTagParserTest.java | 8 ++-- .../resources/RouteResourceClientHCTest.java | 2 +- .../RouteResourceCustomModelTest.java | 2 +- 12 files changed, 85 insertions(+), 62 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java b/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java index 249032775e0..a9bb651480f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java +++ b/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java @@ -17,6 +17,9 @@ */ package com.graphhopper.routing.util; +import java.util.Collections; +import java.util.TreeSet; + /** * Used to store a priority value in the way flags of an edge. Used in combination with * PriorityWeighting @@ -36,7 +39,13 @@ public enum PriorityCode { PREFER(12), VERY_NICE(13), BEST(15); + private final int value; + public static final TreeSet VALUES = new TreeSet<>(); + + static { + Collections.addAll(VALUES, values()); + } PriorityCode(int value) { this.value = value; @@ -53,4 +62,14 @@ public static double getFactor(int value) { public static double getValue(int value) { return getFactor(value); } + + public PriorityCode worse() { + PriorityCode ret = VALUES.lower(this); + return ret == null ? EXCLUDE : ret; + } + + public PriorityCode better() { + PriorityCode ret = VALUES.higher(this); + return ret == null ? BEST : ret; + } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index 22e28612833..589de7aa867 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -2,8 +2,8 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.EdgeIntAccess; +import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RouteNetwork; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.storage.IntsRef; @@ -25,7 +25,7 @@ public abstract class BikeCommonPriorityParser implements TagParser { // Pushing section highways are parts where you need to get off your bike and push it (German: Schiebestrecke) protected final HashSet pushingSectionsHighways = new HashSet<>(); protected final Set preferHighwayTags = new HashSet<>(); - protected final Set avoidHighwayTags = new HashSet<>(); + private final Map avoidHighwayTags = new HashMap<>(); protected final Set unpavedSurfaceTags = new HashSet<>(); protected final Set ferries = new HashSet<>(FERRIES); protected final Set intendedValues = new HashSet<>(INTENDED); @@ -67,10 +67,16 @@ protected BikeCommonPriorityParser(DecimalEncodedValue priorityEnc, DecimalEncod unpavedSurfaceTags.add("sand"); unpavedSurfaceTags.add("wood"); - avoidHighwayTags.add("steps"); - avoidHighwayTags.add("motorway"); - avoidHighwayTags.add("motorway_link"); - avoidHighwayTags.add("bridleway"); + avoidHighwayTags.put("motorway", REACH_DESTINATION); + avoidHighwayTags.put("motorway_link", REACH_DESTINATION); + avoidHighwayTags.put("trunk", REACH_DESTINATION); + avoidHighwayTags.put("trunk_link", REACH_DESTINATION); + avoidHighwayTags.put("primary", BAD); + avoidHighwayTags.put("primary_link", BAD); + avoidHighwayTags.put("secondary", AVOID); + avoidHighwayTags.put("secondary_link", AVOID); + avoidHighwayTags.put("steps", AVOID); + avoidHighwayTags.put("bridleway", AVOID); routeMap.put(INTERNATIONAL, BEST.getValue()); routeMap.put(NATIONAL, BEST.getValue()); @@ -131,8 +137,6 @@ private PriorityCode convertClassValueToPriority(String tagvalue) { return VERY_NICE; case 1: return PREFER; - case 0: - return UNCHANGED; case -1: return SLIGHT_AVOID; case -2: @@ -171,11 +175,12 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight if (way.hasTag("tunnel", intendedValues)) weightToPrioMap.put(40d, UNCHANGED.getValue()); } - } else if (avoidHighwayTags.contains(highway) + } else if (avoidHighwayTags.containsKey(highway) || isValidSpeed(maxSpeed) && maxSpeed >= avoidSpeedLimit && !"track".equals(highway)) { - weightToPrioMap.put(50d, AVOID.getValue()); + PriorityCode priorityCode = avoidHighwayTags.get(highway); + weightToPrioMap.put(50d, priorityCode == null ? AVOID.getValue() : priorityCode.getValue()); if (way.hasTag("tunnel", intendedValues) || way.hasTag("hazmat", intendedValues)) - weightToPrioMap.put(50d, BAD.getValue()); + weightToPrioMap.put(50d, Math.max(REACH_DESTINATION.getValue(), priorityCode == null ? BAD.getValue() : priorityCode.worse().worse().getValue())); } String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right", "cycleway:both")); @@ -196,9 +201,9 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight if (isDesignated(way)) pushingSectionPrio = VERY_NICE; if (way.hasTag("foot", "yes")) { - pushingSectionPrio = PriorityCode.values()[pushingSectionPrio.ordinal() - 1]; + pushingSectionPrio = pushingSectionPrio.worse(); if (way.hasTag("segregated", "yes")) - pushingSectionPrio = PriorityCode.values()[pushingSectionPrio.ordinal() + 1]; + pushingSectionPrio = pushingSectionPrio.better(); } weightToPrioMap.put(100d, pushingSectionPrio.getValue()); } @@ -223,16 +228,17 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight if (way.hasTag("scenic", "yes") || maxSpeed > 0 && maxSpeed <= wayTypeSpeed) { int lastEntryValue = weightToPrioMap.lastEntry().getValue(); if (lastEntryValue < BEST.getValue()) { - int lastEntryIndex = Arrays.stream(PriorityCode.values()).filter(pc -> pc.getValue() == lastEntryValue).findFirst().orElse(UNCHANGED).ordinal(); + // TODO migrate weightToPrioMap to Map + PriorityCode priorityCode = PriorityCode.VALUES.stream().filter(pc -> pc.getValue() == lastEntryValue).findFirst().orElse(UNCHANGED); // Increase the PriorityCode by one step - weightToPrioMap.put(110d, PriorityCode.values()[lastEntryIndex + 1].getValue()); + weightToPrioMap.put(110d, priorityCode.better().getValue()); } } } boolean isDesignated(ReaderWay way) { return way.hasTag("bicycle", "designated") || way.hasTag(CYCLEWAY_ACCESS_KEYS, "designated") - || way.hasTag("bicycle_road", "yes") || way.hasTag("cyclestreet", "yes") || way.hasTag("bicycle", "official"); + || way.hasTag("bicycle_road", "yes") || way.hasTag("cyclestreet", "yes") || way.hasTag("bicycle", "official"); } // TODO duplicated in average speed diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikePriorityParser.java index 1d5d147f9b2..80d6a14e492 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikePriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikePriorityParser.java @@ -18,13 +18,6 @@ public BikePriorityParser(DecimalEncodedValue priorityEnc, DecimalEncodedValue s addPushingSection("path"); - avoidHighwayTags.add("trunk"); - avoidHighwayTags.add("trunk_link"); - avoidHighwayTags.add("primary"); - avoidHighwayTags.add("primary_link"); - avoidHighwayTags.add("secondary"); - avoidHighwayTags.add("secondary_link"); - preferHighwayTags.add("service"); preferHighwayTags.add("tertiary"); preferHighwayTags.add("tertiary_link"); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java index d81e7246205..fa35a902e2e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java @@ -26,11 +26,6 @@ protected MountainBikePriorityParser(DecimalEncodedValue speedEnc, DecimalEncode routeMap.put(REGIONAL, PREFER.getValue()); routeMap.put(LOCAL, BEST.getValue()); - avoidHighwayTags.add("primary"); - avoidHighwayTags.add("primary_link"); - avoidHighwayTags.add("secondary"); - avoidHighwayTags.add("secondary_link"); - preferHighwayTags.add("road"); preferHighwayTags.add("track"); preferHighwayTags.add("path"); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index fba7a630c63..4dcdf5035b5 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -482,11 +482,11 @@ public void testAlternativeRoutesBike() { assertEquals(3, rsp.getAll().size()); // via ramsenthal - assertEquals(2865, rsp.getAll().get(0).getTime() / 1000); + assertEquals(2888, rsp.getAll().get(0).getTime() / 1000); // via unterwaiz assertEquals(3318, rsp.getAll().get(1).getTime() / 1000); // via eselslohe -> theta; BTW: here smaller time as 2nd alternative due to priority influences time order - assertEquals(3093, rsp.getAll().get(2).getTime() / 1000); + assertEquals(3116, rsp.getAll().get(2).getTime() / 1000); } @Test @@ -1423,8 +1423,8 @@ public void testMultipleVehiclesWithCH() { .setProfile(bikeProfile)); res = rsp.getBest(); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); - assertEquals(511, res.getTime() / 1000f, 1); - assertEquals(2481, res.getDistance(), 1); + assertEquals(536, res.getTime() / 1000f, 1); + assertEquals(2521, res.getDistance(), 1); rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) .setProfile("profile3")); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 6b1cfceae2d..564579a627f 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -332,21 +332,21 @@ public void testHikeCanUseExtremeSacScales() { public void testMonacoBike3D() { List queries = new ArrayList<>(); // 1. alternative: go over steps 'Rampe Major' => 1.7km vs. around 2.7km - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2689, 118)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2670, 118)); // 2. - queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 4188, 217)); + queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 4250, 220)); // 3. queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 167)); // 4. - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1544, 84)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1557, 87)); // try reverse direction // 1. queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2111, 96)); - queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 3903, 199)); + queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 4132, 194)); queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2805, 145)); // 4. avoid tunnel(s)! - queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1630, 96)); + queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1723, 96)); // atm the custom model is intended to be used with 'roads' vehicle when allowing reverse direction for oneways // but tests here still assert that reverse oneways are excluded GraphHopper hopper = createHopper(MONACO, @@ -403,11 +403,11 @@ public void testMonacoBike() { public void testMonacoMountainBike() { List queries = new ArrayList<>(); // for mtb it is also ok to go over steps (43.7318,7.423) -> 1900m vs 2600m (in latest OSM data all bikes are forbidden and steps aren't taken) - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3655, 176)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2331, 121)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2323, 111)); + queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3655, 179)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2629, 152)); // hard to select between secondary and primary (both are AVOID for mtb) - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1459, 88)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1496, 92)); GraphHopper hopper = createHopper(MONACO, new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb")); hopper.importOrLoad(); @@ -425,10 +425,10 @@ public void testMonacoMountainBike() { @Test public void testMonacoRacingBike() { List queries = new ArrayList<>(); - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2597, 118)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3589, 170)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2568, 135)); - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1490, 84)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111)); + queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 4022, 207)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2651, 167)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1516, 86)); GraphHopper hopper = createHopper(MONACO, new CustomProfile("racingbike"). setCustomModel(new CustomModel()).setVehicle("racingbike")); @@ -564,7 +564,7 @@ public void testMonacoVia() { public void testHarsdorf() { List queries = new ArrayList<>(); // TODO somehow the bigger road is take even if we make it less preferred (e.g. introduce AVOID AT ALL costs for lanes=2&&maxspeed>50) - queries.add(new Query(50.004333, 11.600254, 50.044449, 11.543434, 6952, 190)); + queries.add(new Query(50.004333, 11.600254, 50.044449, 11.543434, 6951, 190)); // choose Unterloher Weg and the following residential + cycleway // list.add(new OneRun(50.004333, 11.600254, 50.044449, 11.543434, 6931, 184)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index d2ad5ff08b7..35676583276 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -401,7 +401,7 @@ public void testAvoidMotorway() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "motorway"); osmWay.setTag("bicycle", "yes"); - assertPriority(AVOID.getValue(), osmWay); + assertPriority(REACH_DESTINATION.getValue(), osmWay); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 36e5bb5da65..8a2dd58e86e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -54,10 +54,10 @@ protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap public void testSpeedAndPriority() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(BAD.getValue(), 18, way); way.setTag("scenic", "yes"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 18, way); + assertPriorityAndSpeed(AVOID_MORE.getValue(), 18, way); // Pushing section: this is fine as we obey the law! way.clearTags(); @@ -236,7 +236,7 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "primary"); way.setTag("surface", "fine_gravel"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(BAD.getValue(), 18, way); way.clearTags(); way.setTag("highway", "track"); @@ -247,11 +247,11 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "primary"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(BAD.getValue(), 18, way); way.clearTags(); way.setTag("highway", "primary"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(BAD.getValue(), 18, way); way.clearTags(); way.setTag("highway", "residential"); @@ -261,7 +261,11 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "motorway"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(REACH_DESTINATION.getValue(), 18, way); + + way.clearTags(); + way.setTag("highway", "trunk"); + assertPriorityAndSpeed(REACH_DESTINATION.getValue(), 18, way); } @Test @@ -305,7 +309,7 @@ public void testCycleway() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("surface", "paved"); - assertPriority(AVOID.getValue(), way); + assertPriority(BAD.getValue(), way); way.setTag("cycleway", "track"); assertPriority(PREFER.getValue(), way); @@ -328,7 +332,7 @@ public void testCycleway() { way.setTag("highway", "primary"); way.setTag("oneway", "yes"); way.setTag("cycleway:left", "opposite_lane"); - assertPriority(AVOID.getValue(), way); + assertPriority(BAD.getValue(), way); way.clearTags(); way.setTag("highway", "primary"); @@ -350,6 +354,12 @@ public void testCycleway() { way.setTag("highway", "path"); way.setTag("cyclestreet", "yes"); assertPriority(VERY_NICE.getValue(), way); + + way.clearTags(); + way.setTag("highway", "secondary"); + way.setTag("cycleway", "lane"); + way.setTag("cycleway:lane", "advisory"); + assertPriority(SLIGHT_PREFER.getValue(), way); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java index f5507af61ad..05e377ef056 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java @@ -48,7 +48,7 @@ protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap public void testSpeedAndPriority() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); - assertPriorityAndSpeed(AVOID.getValue(), 18, way); + assertPriorityAndSpeed(BAD.getValue(), 18, way); way.setTag("highway", "residential"); assertPriorityAndSpeed(PREFER.getValue(), 16, way); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index fc7f8ea2679..a9a789e3056 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -243,22 +243,22 @@ public void testPriority_avoidanceOfHighMaxSpeed() { assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED.getValue(), 20, osmWay); osmWay.setTag("highway", "motorway"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, AVOID.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index 54b57932efe..b2d9bdb325c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -403,7 +403,7 @@ public void testWaypointIndicesAndLegDetails(TestParam p) { GHResponse response = gh.route(req); ResponsePath path = response.getBest(); - assertEquals(5333, path.getDistance(), 5); + assertEquals(5428, path.getDistance(), 5); assertEquals(9, path.getWaypoints().size()); assertEquals(path.getTime(), path.getPathDetails().get("leg_time").stream().mapToLong(d -> (long) d.getValue()).sum(), 1); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 0a0ce3d63cf..19531b16a68 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -287,7 +287,7 @@ public void testSubnetworkRemovalPerProfile() { " \"ch.disable\": true" + "}"; path = getPath(body); - assertEquals(5370, path.get("distance").asDouble(), 5); + assertEquals(5827, path.get("distance").asDouble(), 5); } @Test From 8b293e56ac227b60721f602b627294148bd7acd1 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 19 Apr 2023 21:57:13 +0200 Subject: [PATCH 050/165] reduce calling PriorityCode.getValue, code review in #2796 --- .../routing/util/PriorityCode.java | 24 ++- .../parsers/BikeCommonPriorityParser.java | 55 +++--- .../parsers/MountainBikePriorityParser.java | 9 +- .../parsers/RacingBikePriorityParser.java | 9 +- .../parsers/AbstractBikeTagParserTester.java | 30 +-- .../util/parsers/BikeTagParserTest.java | 176 +++++++++--------- .../parsers/MountainBikeTagParserTest.java | 29 ++- .../util/parsers/RacingBikeTagParserTest.java | 54 +++--- 8 files changed, 196 insertions(+), 190 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java b/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java index a9bb651480f..39b56d590a8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java +++ b/core/src/main/java/com/graphhopper/routing/util/PriorityCode.java @@ -17,8 +17,8 @@ */ package com.graphhopper.routing.util; -import java.util.Collections; -import java.util.TreeSet; +import java.util.Map; +import java.util.TreeMap; /** * Used to store a priority value in the way flags of an edge. Used in combination with @@ -41,10 +41,13 @@ public enum PriorityCode { BEST(15); private final int value; - public static final TreeSet VALUES = new TreeSet<>(); + public static final TreeMap VALUES = new TreeMap<>(); static { - Collections.addAll(VALUES, values()); + PriorityCode[] v = values(); + for (PriorityCode priorityCode : v) { + VALUES.put(priorityCode.getValue(), priorityCode); + } } PriorityCode(int value) { @@ -64,12 +67,17 @@ public static double getValue(int value) { } public PriorityCode worse() { - PriorityCode ret = VALUES.lower(this); - return ret == null ? EXCLUDE : ret; + Map.Entry ret = VALUES.lowerEntry(this.getValue()); + return ret == null ? EXCLUDE : ret.getValue(); + } + + public static PriorityCode valueOf(int integ) { + Map.Entry ret = VALUES.ceilingEntry(integ); + return ret == null ? BEST : ret.getValue(); } public PriorityCode better() { - PriorityCode ret = VALUES.higher(this); - return ret == null ? BEST : ret; + Map.Entry ret = VALUES.higherEntry(this.getValue()); + return ret == null ? BEST : ret.getValue(); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index 589de7aa867..c78c37bc788 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -109,16 +109,16 @@ public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way * @return new priority based on priorityFromRelation and on the tags in ReaderWay. */ int handlePriority(ReaderWay way, double wayTypeSpeed, Integer priorityFromRelation) { - TreeMap weightToPrioMap = new TreeMap<>(); + TreeMap weightToPrioMap = new TreeMap<>(); if (priorityFromRelation == null) - weightToPrioMap.put(0d, UNCHANGED.getValue()); + weightToPrioMap.put(0d, UNCHANGED); else - weightToPrioMap.put(110d, priorityFromRelation); + weightToPrioMap.put(110d, PriorityCode.valueOf(priorityFromRelation)); collect(way, wayTypeSpeed, weightToPrioMap); // pick priority with biggest order value - return weightToPrioMap.lastEntry().getValue(); + return weightToPrioMap.lastEntry().getValue().getValue(); } // Conversion of class value to priority. See http://wiki.openstreetmap.org/wiki/Class:bicycle @@ -152,46 +152,48 @@ private PriorityCode convertClassValueToPriority(String tagvalue) { * @param weightToPrioMap associate a weight with every priority. This sorted map allows * subclasses to 'insert' more important priorities as well as overwrite determined priorities. */ - void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { + void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { String highway = way.getTag("highway"); if (isDesignated(way)) { if ("path".equals(highway)) - weightToPrioMap.put(100d, VERY_NICE.getValue()); + weightToPrioMap.put(100d, VERY_NICE); else - weightToPrioMap.put(100d, PREFER.getValue()); + weightToPrioMap.put(100d, PREFER); } if ("cycleway".equals(highway)) { if (way.hasTag("foot", intendedValues) && !way.hasTag("segregated", "yes")) - weightToPrioMap.put(100d, PREFER.getValue()); + weightToPrioMap.put(100d, PREFER); else - weightToPrioMap.put(100d, VERY_NICE.getValue()); + weightToPrioMap.put(100d, VERY_NICE); } double maxSpeed = Math.max(getMaxSpeed(way, false), getMaxSpeed(way, true)); if (preferHighwayTags.contains(highway) || (isValidSpeed(maxSpeed) && maxSpeed <= 30)) { if (!isValidSpeed(maxSpeed) || maxSpeed < avoidSpeedLimit) { - weightToPrioMap.put(40d, PREFER.getValue()); + weightToPrioMap.put(40d, PREFER); if (way.hasTag("tunnel", intendedValues)) - weightToPrioMap.put(40d, UNCHANGED.getValue()); + weightToPrioMap.put(40d, UNCHANGED); } } else if (avoidHighwayTags.containsKey(highway) || isValidSpeed(maxSpeed) && maxSpeed >= avoidSpeedLimit && !"track".equals(highway)) { PriorityCode priorityCode = avoidHighwayTags.get(highway); - weightToPrioMap.put(50d, priorityCode == null ? AVOID.getValue() : priorityCode.getValue()); - if (way.hasTag("tunnel", intendedValues) || way.hasTag("hazmat", intendedValues)) - weightToPrioMap.put(50d, Math.max(REACH_DESTINATION.getValue(), priorityCode == null ? BAD.getValue() : priorityCode.worse().worse().getValue())); + weightToPrioMap.put(50d, priorityCode == null ? AVOID : priorityCode); + if (way.hasTag("tunnel", intendedValues) || way.hasTag("hazmat", intendedValues)) { + PriorityCode worse = priorityCode == null ? BAD : priorityCode.worse().worse(); + weightToPrioMap.put(50d, worse == EXCLUDE ? REACH_DESTINATION : worse); + } } String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right", "cycleway:both")); if (Arrays.asList("lane", "opposite_track", "shared_lane", "share_busway", "shoulder").contains(cycleway)) { - weightToPrioMap.put(100d, SLIGHT_PREFER.getValue()); + weightToPrioMap.put(100d, SLIGHT_PREFER); } else if ("track".equals(cycleway)) { - weightToPrioMap.put(100d, PREFER.getValue()); + weightToPrioMap.put(100d, PREFER); } if (way.hasTag("bicycle", "use_sidepath")) { - weightToPrioMap.put(100d, REACH_DESTINATION.getValue()); + weightToPrioMap.put(100d, REACH_DESTINATION); } if (pushingSectionsHighways.contains(highway) || "parking_aisle".equals(way.getTag("service"))) { @@ -205,34 +207,29 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight if (way.hasTag("segregated", "yes")) pushingSectionPrio = pushingSectionPrio.better(); } - weightToPrioMap.put(100d, pushingSectionPrio.getValue()); + weightToPrioMap.put(100d, pushingSectionPrio); } if (way.hasTag("railway", "tram")) - weightToPrioMap.put(50d, AVOID_MORE.getValue()); + weightToPrioMap.put(50d, AVOID_MORE); if (way.hasTag("lcn", "yes")) - weightToPrioMap.put(100d, PREFER.getValue()); + weightToPrioMap.put(100d, PREFER); String classBicycleValue = way.getTag(classBicycleKey); if (classBicycleValue != null) { // We assume that humans are better in classifying preferences compared to our algorithm above -> weight = 100 - weightToPrioMap.put(100d, convertClassValueToPriority(classBicycleValue).getValue()); + weightToPrioMap.put(100d, convertClassValueToPriority(classBicycleValue)); } else { String classBicycle = way.getTag("class:bicycle"); if (classBicycle != null) - weightToPrioMap.put(100d, convertClassValueToPriority(classBicycle).getValue()); + weightToPrioMap.put(100d, convertClassValueToPriority(classBicycle)); } // Increase the priority for scenic routes or in case that maxspeed limits our average speed as compensation. See #630 if (way.hasTag("scenic", "yes") || maxSpeed > 0 && maxSpeed <= wayTypeSpeed) { - int lastEntryValue = weightToPrioMap.lastEntry().getValue(); - if (lastEntryValue < BEST.getValue()) { - // TODO migrate weightToPrioMap to Map - PriorityCode priorityCode = PriorityCode.VALUES.stream().filter(pc -> pc.getValue() == lastEntryValue).findFirst().orElse(UNCHANGED); - // Increase the PriorityCode by one step - weightToPrioMap.put(110d, priorityCode.better().getValue()); - } + PriorityCode lastEntryValue = weightToPrioMap.lastEntry().getValue(); + if (lastEntryValue.getValue() < BEST.getValue()) weightToPrioMap.put(110d, lastEntryValue.better()); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java index fa35a902e2e..d9687113480 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikePriorityParser.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.util.PMap; import java.util.TreeMap; @@ -39,18 +40,18 @@ protected MountainBikePriorityParser(DecimalEncodedValue speedEnc, DecimalEncode } @Override - void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { + void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { super.collect(way, wayTypeSpeed, weightToPrioMap); String highway = way.getTag("highway"); if ("track".equals(highway)) { String trackType = way.getTag("tracktype"); if ("grade1".equals(trackType)) - weightToPrioMap.put(50d, UNCHANGED.getValue()); + weightToPrioMap.put(50d, UNCHANGED); else if (trackType == null) - weightToPrioMap.put(90d, PREFER.getValue()); + weightToPrioMap.put(90d, PREFER); else if (trackType.startsWith("grade")) - weightToPrioMap.put(100d, VERY_NICE.getValue()); + weightToPrioMap.put(100d, VERY_NICE); } } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java index fc630f3bed8..4f7d48c5fdd 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java @@ -2,6 +2,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.util.PMap; import java.util.TreeMap; @@ -41,18 +42,18 @@ protected RacingBikePriorityParser(DecimalEncodedValue priorityEnc, DecimalEncod } @Override - void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { + void collect(ReaderWay way, double wayTypeSpeed, TreeMap weightToPrioMap) { super.collect(way, wayTypeSpeed, weightToPrioMap); String highway = way.getTag("highway"); if ("service".equals(highway) || "residential".equals(highway)) { - weightToPrioMap.put(40d, SLIGHT_AVOID.getValue()); + weightToPrioMap.put(40d, SLIGHT_AVOID); } else if ("track".equals(highway)) { String trackType = way.getTag("tracktype"); if ("grade1".equals(trackType)) - weightToPrioMap.put(110d, PREFER.getValue()); + weightToPrioMap.put(110d, PREFER); else if (trackType == null || trackType.startsWith("grade")) - weightToPrioMap.put(110d, AVOID_MORE.getValue()); + weightToPrioMap.put(110d, AVOID_MORE); } } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index 35676583276..9fa55a3085d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -71,24 +71,24 @@ public void setUp() { protected abstract VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap pMap); - protected void assertPriority(int expectedPrio, ReaderWay way) { + protected void assertPriority(PriorityCode expectedPrio, ReaderWay way) { IntsRef relFlags = osmParsers.handleRelationTags(new ReaderRelation(0), osmParsers.createRelationFlags()); ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); int edgeId = 0; osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); + assertEquals(PriorityCode.getValue(expectedPrio.getValue()), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); } - protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way) { + protected void assertPriorityAndSpeed(PriorityCode expectedPrio, double expectedSpeed, ReaderWay way) { assertPriorityAndSpeed(expectedPrio, expectedSpeed, way, new ReaderRelation(0)); } - protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way, ReaderRelation rel) { + protected void assertPriorityAndSpeed(PriorityCode expectedPrio, double expectedSpeed, ReaderWay way, ReaderRelation rel) { IntsRef relFlags = osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags()); ArrayEdgeIntAccess intAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); int edgeId = 0; osmParsers.handleWayTags(edgeId, intAccess, way, relFlags); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); + assertEquals(PriorityCode.getValue(expectedPrio.getValue()), priorityEnc.getDecimal(false, edgeId, intAccess), 0.01); assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(false, edgeId, intAccess), 0.1); assertEquals(expectedSpeed, avgSpeedEnc.getDecimal(true, edgeId, intAccess), 0.1); } @@ -323,17 +323,17 @@ public void testTramStations() { public void testAvoidTunnel() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "residential"); - assertPriority(PREFER.getValue(), osmWay); + assertPriority(PREFER, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriority(UNCHANGED.getValue(), osmWay); + assertPriority(UNCHANGED, osmWay); osmWay.setTag("highway", "secondary"); osmWay.setTag("tunnel", "yes"); - assertPriority(BAD.getValue(), osmWay); + assertPriority(BAD, osmWay); osmWay.setTag("bicycle", "designated"); - assertPriority(PREFER.getValue(), osmWay); + assertPriority(PREFER, osmWay); } @Test @@ -342,21 +342,21 @@ public void testTram() { // very dangerous way.setTag("highway", "secondary"); way.setTag("railway", "tram"); - assertPriority(AVOID_MORE.getValue(), way); + assertPriority(AVOID_MORE, way); // should be safe now way.setTag("bicycle", "designated"); - assertPriority(PREFER.getValue(), way); + assertPriority(PREFER, way); } @Test public void testService() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "service"); - assertPriorityAndSpeed(PREFER.getValue(), 12, way); + assertPriorityAndSpeed(PREFER, 12, way); way.setTag("service", "parking_aisle"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); + assertPriorityAndSpeed(SLIGHT_AVOID, 4, way); } @Test @@ -382,7 +382,7 @@ public void testReduceToMaxSpeed() { public void testPreferenceForSlowSpeed() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "tertiary"); - assertPriority(PREFER.getValue(), osmWay); + assertPriority(PREFER, osmWay); } @Test @@ -401,7 +401,7 @@ public void testAvoidMotorway() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "motorway"); osmWay.setTag("bicycle", "yes"); - assertPriority(REACH_DESTINATION.getValue(), osmWay); + assertPriority(REACH_DESTINATION, osmWay); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 8a2dd58e86e..3829dcbb8d9 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -54,218 +54,218 @@ protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap public void testSpeedAndPriority() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.setTag("scenic", "yes"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 18, way); + assertPriorityAndSpeed(AVOID_MORE, 18, way); // Pushing section: this is fine as we obey the law! way.clearTags(); way.setTag("highway", "footway"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); // Use pushing section irrespective of the pavement way.setTag("surface", "paved"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "path"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "secondary"); way.setTag("bicycle", "dismount"); - assertPriorityAndSpeed(AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "secondary"); way.setTag("hazmat", "designated"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.clearTags(); way.setTag("highway", "footway"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 10, way); + assertPriorityAndSpeed(PREFER, 10, way); way.setTag("segregated", "no"); - assertPriorityAndSpeed(PREFER.getValue(), 10, way); + assertPriorityAndSpeed(PREFER, 10, way); way.setTag("segregated", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.clearTags(); way.setTag("highway", "footway"); way.setTag("surface", "paved"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 10, way); + assertPriorityAndSpeed(PREFER, 10, way); way.setTag("surface", "cobblestone"); - assertPriorityAndSpeed(PREFER.getValue(), 8, way); + assertPriorityAndSpeed(PREFER, 8, way); way.setTag("segregated", "yes"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.clearTags(); way.setTag("highway", "platform"); way.setTag("surface", "paved"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 10, way); + assertPriorityAndSpeed(PREFER, 10, way); way.setTag("segregated", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.clearTags(); way.setTag("highway", "cycleway"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 18, way); + assertPriorityAndSpeed(VERY_NICE, 18, way); int cyclewaySpeed = 18; way.setTag("foot", "yes"); way.setTag("segregated", "yes"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.setTag("segregated", "no"); - assertPriorityAndSpeed(PREFER.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(PREFER, cyclewaySpeed, way); // Make sure that "highway=cycleway" and "highway=path" with "bicycle=designated" give the same result way.clearTags(); way.setTag("highway", "path"); way.setTag("bicycle", "designated"); // Assume foot=no for designated in absence of a foot tag - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.setTag("foot", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(PREFER, cyclewaySpeed, way); way.setTag("foot", "no"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.setTag("segregated", "yes"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.setTag("segregated", "no"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 10, way); + assertPriorityAndSpeed(PREFER, 10, way); way.setTag("segregated", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(PREFER, cyclewaySpeed, way); way.setTag("surface", "unpaved"); - assertPriorityAndSpeed(PREFER.getValue(), 12, way); + assertPriorityAndSpeed(PREFER, 12, way); way.setTag("surface", "paved"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.clearTags(); way.setTag("highway", "path"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); // use pushing section way.clearTags(); way.setTag("highway", "path"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "path"); way.setTag("surface", "ground"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "platform"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "footway"); way.setTag("surface", "paved"); way.setTag("bicycle", "designated"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.clearTags(); way.setTag("highway", "platform"); way.setTag("surface", "paved"); way.setTag("bicycle", "designated"); - assertPriorityAndSpeed(VERY_NICE.getValue(), cyclewaySpeed, way); + assertPriorityAndSpeed(VERY_NICE, cyclewaySpeed, way); way.clearTags(); way.setTag("highway", "track"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); + assertPriorityAndSpeed(UNCHANGED, 12, way); way.setTag("tracktype", "grade1"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 18, way); + assertPriorityAndSpeed(UNCHANGED, 18, way); way.setTag("highway", "track"); way.setTag("tracktype", "grade2"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); + assertPriorityAndSpeed(UNCHANGED, 12, way); // test speed for allowed get off the bike types way.setTag("highway", "track"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); + assertPriorityAndSpeed(UNCHANGED, 12, way); way.clearTags(); way.setTag("highway", "steps"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 2, way); + assertPriorityAndSpeed(SLIGHT_AVOID, 2, way); way.clearTags(); way.setTag("highway", "residential"); way.setTag("bicycle", "use_sidepath"); - assertPriorityAndSpeed(REACH_DESTINATION.getValue(), 18, way); + assertPriorityAndSpeed(REACH_DESTINATION, 18, way); way.clearTags(); way.setTag("highway", "steps"); way.setTag("surface", "wood"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), MIN_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, MIN_SPEED, way); way.setTag("maxspeed", "20"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), MIN_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, MIN_SPEED, way); way.clearTags(); way.setTag("highway", "track"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 18, way); + assertPriorityAndSpeed(UNCHANGED, 18, way); way.clearTags(); way.setTag("highway", "path"); way.setTag("surface", "ground"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "track"); way.setTag("bicycle", "yes"); way.setTag("surface", "fine_gravel"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 18, way); + assertPriorityAndSpeed(UNCHANGED, 18, way); way.setTag("surface", "unknown_surface"); - assertPriorityAndSpeed(UNCHANGED.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(UNCHANGED, PUSHING_SECTION_SPEED, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("surface", "fine_gravel"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.clearTags(); way.setTag("highway", "track"); way.setTag("surface", "gravel"); way.setTag("tracktype", "grade2"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); + assertPriorityAndSpeed(UNCHANGED, 12, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("surface", "paved"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.clearTags(); way.setTag("highway", "primary"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.clearTags(); way.setTag("highway", "residential"); way.setTag("surface", "asphalt"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.clearTags(); way.setTag("highway", "motorway"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(REACH_DESTINATION.getValue(), 18, way); + assertPriorityAndSpeed(REACH_DESTINATION, 18, way); way.clearTags(); way.setTag("highway", "trunk"); - assertPriorityAndSpeed(REACH_DESTINATION.getValue(), 18, way); + assertPriorityAndSpeed(REACH_DESTINATION, 18, way); } @Test @@ -309,57 +309,57 @@ public void testCycleway() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("surface", "paved"); - assertPriority(BAD.getValue(), way); + assertPriority(BAD, way); way.setTag("cycleway", "track"); - assertPriority(PREFER.getValue(), way); + assertPriority(PREFER, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:left", "lane"); - assertPriority(SLIGHT_PREFER.getValue(), way); + assertPriority(SLIGHT_PREFER, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:right", "lane"); - assertPriority(SLIGHT_PREFER.getValue(), way); + assertPriority(SLIGHT_PREFER, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:both", "lane"); - assertPriority(SLIGHT_PREFER.getValue(), way); + assertPriority(SLIGHT_PREFER, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("oneway", "yes"); way.setTag("cycleway:left", "opposite_lane"); - assertPriority(BAD.getValue(), way); + assertPriority(BAD, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("oneway", "yes"); way.setTag("cycleway", "opposite_track"); - assertPriority(SLIGHT_PREFER.getValue(), way); + assertPriority(SLIGHT_PREFER, way); way.clearTags(); way.setTag("highway", "primary"); way.setTag("cycleway:bicycle", "designated"); - assertPriority(PREFER.getValue(), way); + assertPriority(PREFER, way); way.clearTags(); way.setTag("highway", "path"); way.setTag("bicycle_road", "yes"); - assertPriority(VERY_NICE.getValue(), way); + assertPriority(VERY_NICE, way); way.clearTags(); way.setTag("highway", "path"); way.setTag("cyclestreet", "yes"); - assertPriority(VERY_NICE.getValue(), way); + assertPriority(VERY_NICE, way); way.clearTags(); way.setTag("highway", "secondary"); way.setTag("cycleway", "lane"); way.setTag("cycleway:lane", "advisory"); - assertPriority(SLIGHT_PREFER.getValue(), way); + assertPriority(SLIGHT_PREFER, way); } @Test @@ -408,37 +408,37 @@ public void testHandleWayTagsInfluencedByRelation() { osmWay.setTag("highway", "road"); // unchanged - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, osmWay); + assertPriorityAndSpeed(UNCHANGED, 12, osmWay); // "lcn=yes" is in fact no relation, but shall be treated the same like a relation with "network=lcn" osmWay.setTag("lcn", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 12, osmWay); + assertPriorityAndSpeed(PREFER, 12, osmWay); osmWay.removeTag("lcn"); // relation code is PREFER ReaderRelation osmRel = new ReaderRelation(1); osmRel.setTag("route", "bicycle"); - assertPriorityAndSpeed(PREFER.getValue(), 12, osmWay, osmRel); + assertPriorityAndSpeed(PREFER, 12, osmWay, osmRel); osmRel.setTag("network", "lcn"); - assertPriorityAndSpeed(PREFER.getValue(), 12, osmWay, osmRel); + assertPriorityAndSpeed(PREFER, 12, osmWay, osmRel); // relation code is NICE osmRel.setTag("network", "rcn"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 12, osmWay, osmRel); + assertPriorityAndSpeed(VERY_NICE, 12, osmWay, osmRel); osmWay.setTag("lcn", "yes"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 12, osmWay, osmRel); + assertPriorityAndSpeed(VERY_NICE, 12, osmWay, osmRel); // relation code is BEST osmRel.setTag("network", "ncn"); - assertPriorityAndSpeed(BEST.getValue(), 12, osmWay, osmRel); + assertPriorityAndSpeed(BEST, 12, osmWay, osmRel); // PREFER relation, but tertiary road => no get off the bike but road wayTypeCode and faster osmWay.clearTags(); osmWay.setTag("highway", "tertiary"); osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); - assertPriorityAndSpeed(PREFER.getValue(), 18, osmWay, osmRel); + assertPriorityAndSpeed(PREFER, 18, osmWay, osmRel); } @Test @@ -448,7 +448,7 @@ public void testUnchangedRelationShouldNotInfluencePriority() { ReaderRelation osmRel = new ReaderRelation(1); osmRel.setTag("description", "something"); - assertPriorityAndSpeed(AVOID.getValue(), 18, osmWay, osmRel); + assertPriorityAndSpeed(AVOID, 18, osmWay, osmRel); } @Test @@ -512,24 +512,24 @@ public void testMaxSpeed() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "tertiary"); way.setTag("maxspeed", "90"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 18, way); + assertPriorityAndSpeed(UNCHANGED, 18, way); way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("maxspeed", "90"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); + assertPriorityAndSpeed(UNCHANGED, 12, way); // here we are limited by the maxspeed way = new ReaderWay(1); way.setTag("highway", "secondary"); way.setTag("maxspeed", "10"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 10, way); + assertPriorityAndSpeed(VERY_NICE, 10, way); way = new ReaderWay(1); way.setTag("highway", "residential"); way.setTag("maxspeed", "15"); // todo: speed is larger than maxspeed tag due to rounding and storable max speed is 30 - assertPriorityAndSpeed(VERY_NICE.getValue(), 16, way); + assertPriorityAndSpeed(VERY_NICE, 16, way); } // Issue 407 : Always block kissing_gate except for mountainbikes @@ -560,36 +560,36 @@ public void testClassBicycle() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "tertiary"); way.setTag("class:bicycle", "3"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); // Test that priority cannot get better than best way.setTag("scenic", "yes"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); way.setTag("scenic", "no"); way.setTag("class:bicycle", "2"); - assertPriority(VERY_NICE.getValue(), way); + assertPriority(VERY_NICE, way); way.setTag("class:bicycle", "1"); - assertPriority(PREFER.getValue(), way); + assertPriority(PREFER, way); way.setTag("class:bicycle", "0"); - assertPriority(UNCHANGED.getValue(), way); + assertPriority(UNCHANGED, way); way.setTag("class:bicycle", "invalidvalue"); - assertPriority(UNCHANGED.getValue(), way); + assertPriority(UNCHANGED, way); way.setTag("class:bicycle", "-1"); - assertPriority(SLIGHT_AVOID.getValue(), way); + assertPriority(SLIGHT_AVOID, way); way.setTag("class:bicycle", "-2"); - assertPriority(AVOID.getValue(), way); + assertPriority(AVOID, way); way.setTag("class:bicycle", "-3"); - assertPriority(AVOID_MORE.getValue(), way); + assertPriority(AVOID_MORE, way); way.setTag("highway", "residential"); way.setTag("bicycle", "designated"); way.setTag("class:bicycle", "3"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); // Now we test overriding by a specific class subtype way.setTag("class:bicycle:touring", "2"); - assertPriority(VERY_NICE.getValue(), way); + assertPriority(VERY_NICE, way); way.setTag("maxspeed", "15"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java index 05e377ef056..8ba023d69c7 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java @@ -22,7 +22,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.VehicleEncodedValues; import com.graphhopper.routing.util.VehicleTagParsers; import com.graphhopper.util.PMap; @@ -48,39 +47,39 @@ protected VehicleTagParsers createBikeTagParsers(EncodedValueLookup lookup, PMap public void testSpeedAndPriority() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "primary"); - assertPriorityAndSpeed(BAD.getValue(), 18, way); + assertPriorityAndSpeed(BAD, 18, way); way.setTag("highway", "residential"); - assertPriorityAndSpeed(PREFER.getValue(), 16, way); + assertPriorityAndSpeed(PREFER, 16, way); // Test pushing section speeds way.setTag("highway", "footway"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.setTag("highway", "track"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.setTag("highway", "steps"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); + assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); way.clearTags(); // test speed for allowed pushing section types way.setTag("highway", "track"); way.setTag("bicycle", "yes"); - assertPriorityAndSpeed(PREFER.getValue(), 18, way); + assertPriorityAndSpeed(PREFER, 18, way); way.setTag("highway", "track"); way.setTag("bicycle", "yes"); way.setTag("tracktype", "grade3"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 12, way); + assertPriorityAndSpeed(VERY_NICE, 12, way); way.setTag("surface", "paved"); - assertPriorityAndSpeed(VERY_NICE.getValue(), 18, way); + assertPriorityAndSpeed(VERY_NICE, 18, way); way.clearTags(); way.setTag("highway", "path"); way.setTag("surface", "ground"); - assertPriorityAndSpeed(PREFER.getValue(), 16, way); + assertPriorityAndSpeed(PREFER, 16, way); } @Test @@ -145,20 +144,20 @@ public void testHandleWayTagsInfluencedByRelation() { ReaderRelation osmRel = new ReaderRelation(1); // unchanged - assertPriorityAndSpeed(PriorityCode.PREFER.getValue(), 18, osmWay); + assertPriorityAndSpeed(PREFER, 18, osmWay); // relation code is PREFER osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); - assertPriorityAndSpeed(PriorityCode.PREFER.getValue(), 18, osmWay); + assertPriorityAndSpeed(PREFER, 18, osmWay); // relation code is PREFER osmRel.setTag("network", "rcn"); - assertPriorityAndSpeed(PriorityCode.PREFER.getValue(), 18, osmWay); + assertPriorityAndSpeed(PREFER, 18, osmWay); // relation code is PREFER osmRel.setTag("network", "ncn"); - assertPriorityAndSpeed(PriorityCode.PREFER.getValue(), 18, osmWay); + assertPriorityAndSpeed(PREFER, 18, osmWay); // PREFER relation, but tertiary road // => no pushing section but road wayTypeCode and faster @@ -167,7 +166,7 @@ public void testHandleWayTagsInfluencedByRelation() { osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); - assertPriorityAndSpeed(PriorityCode.PREFER.getValue(), 18, osmWay); + assertPriorityAndSpeed(PREFER, 18, osmWay); } // Issue 407 : Always block kissing_gate execpt for mountainbikes diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index a9a789e3056..a700d22f92e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -57,14 +57,14 @@ public void testAvoidTunnel() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "residential"); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 18, osmWay); + assertPriorityAndSpeed(SLIGHT_AVOID, 18, osmWay); osmWay.setTag("highway", "secondary"); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(UNCHANGED, 20, osmWay); osmWay.setTag("bicycle", "designated"); - assertPriorityAndSpeed(PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(PREFER, 20, osmWay); } @Test @@ -72,10 +72,10 @@ public void testAvoidTunnel() { public void testService() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "service"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 12, way); + assertPriorityAndSpeed(SLIGHT_AVOID, 12, way); way.setTag("service", "parking_aisle"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); + assertPriorityAndSpeed(SLIGHT_AVOID, 4, way); } @Test @@ -179,34 +179,34 @@ public void testHandleWayTagsInfluencedByRelation() { ReaderRelation osmRel = new ReaderRelation(1); osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 2, osmWay, osmRel); + assertPriorityAndSpeed(AVOID_MORE, 2, osmWay, osmRel); // relation code is OUTSTANDING NICE but as unpaved, the speed is still PUSHING_SECTION_SPEED/2 osmRel.setTag("network", "icn"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 2, osmWay, osmRel); + assertPriorityAndSpeed(AVOID_MORE, 2, osmWay, osmRel); // Now we assume bicycle=yes, anyhow still unpaved osmWay.setTag("bicycle", "yes"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 2, osmWay, osmRel); + assertPriorityAndSpeed(AVOID_MORE, 2, osmWay, osmRel); // Now we assume bicycle=yes, and paved osmWay.setTag("tracktype", "grade1"); - assertPriorityAndSpeed(PREFER.getValue(), 20, osmWay, osmRel); + assertPriorityAndSpeed(PREFER, 20, osmWay, osmRel); // Now we assume bicycle=yes, and unpaved as part of a cycle relation osmWay.setTag("tracktype", "grade2"); osmWay.setTag("bicycle", "yes"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 10, osmWay, osmRel); + assertPriorityAndSpeed(AVOID_MORE, 10, osmWay, osmRel); // Now we assume bicycle=yes, and unpaved not part of a cycle relation osmWay.clearTags(); osmWay.setTag("highway", "track"); osmWay.setTag("tracktype", "grade3"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), PUSHING_SECTION_SPEED, osmWay); + assertPriorityAndSpeed(AVOID_MORE, PUSHING_SECTION_SPEED, osmWay); // Now we assume bicycle=yes, and tracktype = null osmWay.clearTags(); osmWay.setTag("highway", "track"); - assertPriorityAndSpeed(AVOID_MORE.getValue(), 2, osmWay); + assertPriorityAndSpeed(AVOID_MORE, 2, osmWay); } @Test @@ -228,56 +228,56 @@ public void testPriority_avoidanceOfHighMaxSpeed() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "tertiary"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER, 20, osmWay); osmWay.setTag("maxspeed", "60"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER, 20, osmWay); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, PREFER, 20, osmWay); osmWay.setTag("maxspeed", "90"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED, 20, osmWay); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED, 20, osmWay); osmWay.setTag("highway", "motorway"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD.getValue(), PUSHING_SECTION_SPEED, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD, PUSHING_SECTION_SPEED, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED.getValue(), PUSHING_SECTION_SPEED, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED, PUSHING_SECTION_SPEED, osmWay); } private void assertPriorityAndSpeed(EncodingManager encodingManager, DecimalEncodedValue priorityEnc, DecimalEncodedValue speedEnc, - List parsers, int expectedPrio, double expectedSpeed, ReaderWay way) { + List parsers, PriorityCode expectedPrio, double expectedSpeed, ReaderWay way) { EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(encodingManager.getIntsForFlags()); int edgeId = 0; for (TagParser p : parsers) p.handleWayTags(edgeId, edgeIntAccess, way, null); - assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), 0.01); + assertEquals(PriorityCode.getValue(expectedPrio.getValue()), priorityEnc.getDecimal(false, edgeId, edgeIntAccess), 0.01); assertEquals(expectedSpeed, speedEnc.getDecimal(false, edgeId, edgeIntAccess), 0.1); } @@ -286,9 +286,9 @@ public void testClassBicycle() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "tertiary"); way.setTag("class:bicycle:roadcycling", "3"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); way.setTag("class:bicycle", "-2"); - assertPriority(BEST.getValue(), way); + assertPriority(BEST, way); } } From 97a7eaa4ba1bb304291b59adb70f7418aabf73e7 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 20 Apr 2023 09:19:57 +0200 Subject: [PATCH 051/165] minor test rename --- .../resources/{MvtResourceTest.java => MVTResourceTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename web/src/test/java/com/graphhopper/application/resources/{MvtResourceTest.java => MVTResourceTest.java} (99%) diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MVTResourceTest.java similarity index 99% rename from web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java rename to web/src/test/java/com/graphhopper/application/resources/MVTResourceTest.java index dee45fec099..3ec466b8fbf 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MVTResourceTest.java @@ -46,7 +46,7 @@ * @author Peter Karich */ @ExtendWith(DropwizardExtensionsSupport.class) -public class MvtResourceTest { +public class MVTResourceTest { private static final String DIR = "./target/andorra-gh/"; private static final DropwizardAppExtension app = new DropwizardAppExtension<>(GraphHopperApplication.class, createConfig()); From 9fde3fbfb4b31133018b3fcd1d696ef614caf815 Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 20 Apr 2023 10:48:33 +0200 Subject: [PATCH 052/165] Update nl and cz translations (#2799) * Update nl and cz translations * Fix nl translation --- .../resources/com/graphhopper/util/cs_CZ.txt | 128 ++++++++++-------- .../resources/com/graphhopper/util/nl.txt | 50 ++++--- 2 files changed, 103 insertions(+), 75 deletions(-) diff --git a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt index aaf0f046e43..01180ab4919 100644 --- a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt +++ b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt @@ -1,8 +1,8 @@ # do not edit manually, instead use spreadsheet https://t.co/f086oJXAEI and script ./core/files/update-translations.sh continue=pokračujte -continue_onto=pokračujte na %1$s -finish=Cíl! +continue_onto=pokračujte směr %1$s +finish=příjezd do cíle keep_left=držte se vlevo keep_right=držte se vpravo turn_onto=%1$s na %2$s @@ -13,11 +13,11 @@ turn_slight_right=odbočte mírně vpravo turn_sharp_left=odbočte ostře vlevo turn_sharp_right=odbočte ostře vpravo u_turn=otočte se -toward_destination= -toward_destination_ref_only= -toward_destination_with_ref= +toward_destination=%1$s a jeďte směr %2$s +toward_destination_ref_only=%1$s směr %2$s +toward_destination_with_ref=%1$s a jeďte na %2$s směr %3$s unknown=neznámý pokyn „%1$s“ -via=přes +via=přes hour_abbr=h day_abbr=d min_abbr=min @@ -32,20 +32,25 @@ way=cesta small_way=pešina paved=zpevněná unpaved=nezpevněná -stopover=zastávka %1$s +stopover=průjezdní bod %1$s roundabout_enter=Vjeďte na kruhový objezd roundabout_exit=Na kruhovém objezdu použijte %1$s. výjezd roundabout_exit_onto=Na kruhovém objezdu použijte %1$s. výjezd, směrem na %2$s -web.total_ascend=Celkové stoupání %1$s -web.total_descend=Celkové klesání %1$s -web.way_contains_ford=na cestě je brod -web.way_contains_ferry= -web.way_contains_private= -web.way_contains_toll= -web.way_crosses_border= -web.way_contains= -web.tracks= -web.steps= +web.total_ascend=celkové stoupání %1$s +web.total_descend=celkové klesání %1$s +web.way_contains_ford=Trasa obsahuje brody +web.way_contains_ferry=Trasa obsahuje přívozy +web.way_contains_private=Trasa obsahuje soukromé cesty +web.way_contains_toll=Trasa obsahuje zpoplatněné úseky +web.way_crosses_border=Trasa obsahuje překročení hranic +web.way_contains=Trasa obsahuje %1$s +web.tracks=nezpevněné cesty +web.steps=schody +web.footways=stezky pro pěší +web.steep_sections=příkré úseky +web.private_sections=soukromé úseky +web.trunk_roads_warn= +web.get_off_bike_for=Je třeba sesednout z kola a %1$s jej tlačit pt_transfer_to=přestupte na %1$s web.start_label=Start web.intermediate_label=Zastávka @@ -53,20 +58,26 @@ web.end_label=Cíl web.set_start=Nastavit jako start web.set_intermediate=Nastavit jako zastávku web.set_end=Nastavit jako cíl -web.center_map=Vycentrovat sem mapu +web.center_map=Vycentrovat mapu sem web.show_coords=Zobrazit souřadnice -web.query_osm= +web.query_osm=Dotaz do OSM web.route=Trasa -web.add_to_route= +web.add_to_route=Přidat místo web.delete_from_route=Odstranit z trasy -web.open_custom_model_box= -web.help_custom_model= -web.apply_custom_model= -web.exclude_motorway_example= -web.limit_speed_example= -web.exclude_area_example= -web.combined_example= -web.examples_custom_model= +web.open_custom_model_box=Otevřít rámeček s vlastním modelem +web.draw_areas_enabled=Kreslit a měnit oblasti na mapě +web.help_custom_model=Nápověda +web.apply_custom_model=Použít +web.custom_model_enabled=Vlastní model aktivní +web.settings=Nastavení +web.settings_close=Zavřít +web.exclude_motorway_example=Vynechat dálnice +web.limit_speed_example=Rychlostní omezení +web.cargo_bike_example=Nákladní kolo +web.prefer_bike_network= +web.exclude_area_example=Vynechat oblast +web.combined_example=Kombinovaný příklad +web.examples_custom_model=Příklady web.marker=Značka web.gh_offline_info=API GraphHopper je offline? web.refresh_button=Obnovit stránku @@ -74,26 +85,26 @@ web.server_status=Stav web.zoom_in=Přiblížit web.zoom_out=Oddálit web.drag_to_reorder=Přetažením změníte pořadí -web.route_timed_out= -web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= -web.via_hint=Přes +web.route_timed_out=Časový limit výpočtu trasy překročen +web.route_request_failed=Trasa nemohla být vypočítána +web.current_location=Aktuální pozice +web.searching_location=Hledá se pozice +web.searching_location_failed=Nepodařilo se najít pozici +web.via_hint=Přes web.from_hint=Z web.gpx_export_button=Export do GPX web.gpx_button= -web.hide_button= -web.details_button= +web.hide_button=Skrýt +web.details_button=Detaily web.to_hint=Do web.route_info=%1$s bude trvat %2$s web.search_button=Vyhledat web.more_button=více -web.pt_route_info=dorazí v %1$s, %2$s přestup(y) (%3$s) -web.pt_route_info_walking=dorazí v %1$s (%2$s) -web.locations_not_found=Navigování není dostupné. Pozice nenalezena v této oblasti. -web.search_with_nominatim= -web.powered_by= +web.pt_route_info=dorazí v %1$s, %2$s přestup(y) (%3$s) +web.pt_route_info_walking=dorazí v %1$s pěšky (%2$s) +web.locations_not_found= +web.search_with_nominatim=Hledat pomocí Nominatim +web.powered_by=Běží na web.bike=Kolo web.racingbike=Závodní kolo web.mtb=Horské kolo @@ -103,20 +114,23 @@ web.hike=Turistika web.small_truck=Dodávka web.bus=Autobus web.truck=Nákladní automobil -web.staticlink=neměnný odkaz +web.staticlink=statický odkaz web.motorcycle=Motocykl -web.back_to_map= -web.distance_unit= -web.waiting_for_gps= -navigate.in_km_singular= -navigate.in_km= -navigate.in_m= -navigate.for_km= -navigate.then= -navigate.in_mi_singular= -navigate.in_mi= -navigate.in_ft= -navigate.for_mi= -navigate.warning= -navigate.accept_risks_after_warning= -navigate.start_navigation= +web.back_to_map=Zpět +web.distance_unit=Vzdálenosti jsou uváděny v %1$s +web.waiting_for_gps=Čekání na signál GPS… +navigate.in_km_singular=Po jednom kilometru +navigate.in_km=Po %1$s kilometech +navigate.in_m=Po %1$s metrech +navigate.for_km=%1$s kilometrů +navigate.then=a poté +navigate.in_mi_singular=Po jedné míli +navigate.in_mi=Po %1$s mílích +navigate.in_ft=Po %1$s stopách +navigate.for_mi=%1$s mil +navigate.warning=POZOR: Navigace je vysoce experimentální. Použití je na vlastní nebezpečí, soustřeďte se na řízení a věnujte pozornost dopravní situaci. Neovládejte přístroj za jízdy! +navigate.accept_risks_after_warning=Rozumím a souhlasím +navigate.start_navigation=Navigace +navigate.vector_tiles_for_navigation=Použít vektorové dlaždice +navigate.full_screen_for_navigation=Použít celou obrazovku +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/nl.txt b/core/src/main/resources/com/graphhopper/util/nl.txt index 94cd3034efc..8e160bfbd98 100644 --- a/core/src/main/resources/com/graphhopper/util/nl.txt +++ b/core/src/main/resources/com/graphhopper/util/nl.txt @@ -26,7 +26,7 @@ m_abbr=m mi_abbr=mi ft_abbr=ft road=weg -off_bike=voetpad +off_bike=stap af cycleway=fietspad way=weg small_way=voetpad @@ -39,13 +39,18 @@ roundabout_exit_onto=neem afslag %1$s naar %2$s op de rotonde web.total_ascend=%1$s totale klim web.total_descend=%1$s totale daling web.way_contains_ford=Er is een doorwaadbare plaats -web.way_contains_ferry= -web.way_contains_private= -web.way_contains_toll= -web.way_crosses_border= -web.way_contains= -web.tracks= -web.steps= +web.way_contains_ferry=route met veerponten +web.way_contains_private=route met privé wegen +web.way_contains_toll=route met tolwegen +web.way_crosses_border=route met grensovergangen +web.way_contains=route bevat %1$s +web.tracks=route bevat onverharde wegen +web.steps=trappen +web.footways=voetpaden +web.steep_sections=route bevat stijle hellingen +web.private_sections=privé gedeelten +web.trunk_roads_warn= +web.get_off_bike_for=stap af en duw voor %1$s pt_transfer_to=Stap over op de %1$s web.start_label=Start web.intermediate_label=Tussenstop @@ -55,15 +60,21 @@ web.set_intermediate=Stel in als tussenstop web.set_end=Stel in als einde web.center_map=Centreer de kaart hier web.show_coords=Laat coordinaten zien -web.query_osm= +web.query_osm=Query OSM web.route=Route -web.add_to_route= +web.add_to_route=voeg locatie toe web.delete_from_route=Van route verwijderen web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -74,17 +85,17 @@ web.server_status=Status web.zoom_in=Zoom in web.zoom_out=Zoom uit web.drag_to_reorder=Slepen om opnieuw te organiseren -web.route_timed_out= +web.route_timed_out=server berekening time out web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= +web.current_location=huidige locatie +web.searching_location=zoek locatie +web.searching_location_failed=locatie zoeken mislukt web.via_hint=via web.from_hint=van web.gpx_export_button=GPX export -web.gpx_button= -web.hide_button= -web.details_button= +web.gpx_button=GPX export te groot +web.hide_button=verberg +web.details_button=details web.to_hint=naar web.route_info=%1$s duurt %2$s web.search_button=zoek @@ -105,7 +116,7 @@ web.bus=bus web.truck=vrachtwagen web.staticlink=statische link web.motorcycle=motorfiets -web.back_to_map= +web.back_to_map=Terug web.distance_unit= web.waiting_for_gps= navigate.in_km_singular=Over 1 kilometer @@ -120,3 +131,6 @@ navigate.for_mi=Voor %1$s mijl navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= From b279af80788777d22ce6716073c05c0ec38a172e Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 20 Apr 2023 15:56:09 +0200 Subject: [PATCH 053/165] upgrade janino to latest version 3.1.9; remove our workaround for 3.1.6 and below --- core/pom.xml | 2 +- .../routing/weighting/custom/CustomModelParser.java | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index f3019350b99..1c77cb30a43 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -47,7 +47,7 @@ org.codehaus.janino janino - 3.1.2 + 3.1.9 org.locationtech.jts diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index ae308da14e7..5ecee49e0d8 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -411,14 +411,6 @@ private static Java.CompilationUnit injectStatements(List p boolean speedInjected = false; boolean priorityInjected = false; - @Override - public Java.FieldDeclaration copyFieldDeclaration(Java.FieldDeclaration subject) throws CompileException { - // for https://github.com/janino-compiler/janino/issues/135 - Java.FieldDeclaration fd = super.copyFieldDeclaration(subject); - fd.setEnclosingScope(subject.getEnclosingScope()); - return fd; - } - @Override public Java.MethodDeclarator copyMethodDeclarator(Java.MethodDeclarator subject) throws CompileException { if (subject.name.equals("getSpeed") && !speedStatements.isEmpty() && !speedInjected) { From 050d56a9aba021df52e37f29713e5eb787ced1f4 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 22 Apr 2023 09:49:44 +0200 Subject: [PATCH 054/165] cleanup of EnumEncodedValue (#2800) * remove custom toString in EnumEncodedValue and avoid calling Enum::values() * API JSON response must not change * custom toString necessary for Country and HazmatTunnel * fix imports --- .../com/graphhopper/routing/ev/Country.java | 2 ++ .../com/graphhopper/routing/ev/Crossing.java | 2 +- .../com/graphhopper/routing/ev/Footway.java | 23 ++++++-------- .../com/graphhopper/routing/ev/Hazmat.java | 12 +++----- .../graphhopper/routing/ev/HazmatTunnel.java | 21 ++++--------- .../graphhopper/routing/ev/HazmatWater.java | 12 +++----- .../java/com/graphhopper/routing/ev/Hgv.java | 11 ++----- .../routing/ev/MaxWeightExcept.java | 13 ++++---- .../graphhopper/routing/ev/RoadAccess.java | 12 ++------ .../com/graphhopper/routing/ev/RoadClass.java | 30 ++++++------------- .../routing/ev/RoadEnvironment.java | 11 ++----- .../graphhopper/routing/ev/RouteNetwork.java | 11 ++----- .../graphhopper/routing/ev/Smoothness.java | 15 ++-------- .../com/graphhopper/routing/ev/Surface.java | 24 ++++++--------- .../java/com/graphhopper/routing/ev/Toll.java | 12 +++----- .../com/graphhopper/routing/ev/TrackType.java | 11 ++----- .../graphhopper/routing/ev/UrbanDensity.java | 16 ++++------ .../graphhopper/reader/osm/OSMReaderTest.java | 2 +- .../resources/RouteResourceTest.java | 6 ++-- 19 files changed, 77 insertions(+), 169 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/Country.java b/core/src/main/java/com/graphhopper/routing/ev/Country.java index c618412cba9..5bfe944f89f 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Country.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Country.java @@ -269,4 +269,6 @@ public String getAlpha2() { public static EnumEncodedValue create() { return new EnumEncodedValue<>(Country.KEY, Country.class); } + + // for backward compatibility: no custom toString() } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Crossing.java b/core/src/main/java/com/graphhopper/routing/ev/Crossing.java index e5ddba670a5..b3909b49c86 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Crossing.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Crossing.java @@ -15,7 +15,7 @@ public enum Crossing { @Override public String toString() { - return Helper.toLowerCase(name()); + return Helper.toLowerCase(super.toString()); } public static Crossing find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Footway.java b/core/src/main/java/com/graphhopper/routing/ev/Footway.java index bddfb017721..c99dddcc6c9 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Footway.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Footway.java @@ -18,9 +18,10 @@ package com.graphhopper.routing.ev; +import com.graphhopper.util.Helper; + public enum Footway { - MISSING("missing"), SIDEWALK("sidewalk"), CROSSING("crossing"), ACCESS_AISLE("access_aisle"), - LINK("link"), TRAFFIC_ISLAND("traffic_island"), ALLEY("alley"); + MISSING, SIDEWALK, CROSSING, ACCESS_AISLE, LINK, TRAFFIC_ISLAND, ALLEY; public static final String KEY = "footway"; @@ -28,25 +29,19 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Footway.class); } - private final String name; - - Footway(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static Footway find(String name) { if (name == null || name.isEmpty()) return MISSING; - for (Footway footway : values()) - if (footway.name().equalsIgnoreCase(name)) - return footway; - - return MISSING; + try { + return Footway.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return MISSING; + } } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java b/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java index 9fef11dfb66..41e1fb79ade 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Hazmat.java @@ -1,11 +1,13 @@ package com.graphhopper.routing.ev; +import com.graphhopper.util.Helper; + /** * Defines general restrictions for the transport of hazardous materials.
* If not tagged it will be {@link #YES} */ public enum Hazmat { - YES("yes"), NO("no"); + YES, NO; public static final String KEY = "hazmat"; @@ -13,14 +15,8 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Hazmat.class); } - private final String name; - - Hazmat(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java b/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java index 202e5e25746..75ba789892b 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java +++ b/core/src/main/java/com/graphhopper/routing/ev/HazmatTunnel.java @@ -10,23 +10,23 @@ public enum HazmatTunnel { /** * driving with any dangerous goods allowed */ - A("A"), + A, /** * no goods with very large explosion range */ - B("B"), + B, /** * no goods with large explosion or poisoning range */ - C("C"), + C, /** * no goods which threaten a large explosion, poisoning or fire */ - D("D"), + D, /** * forbids all dangerous goods except: UN 2919,3291, 3331, 3359, 3373 */ - E("E"); + E; public static final String KEY = "hazmat_tunnel"; @@ -34,14 +34,5 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, HazmatTunnel.class); } - private final String name; - - HazmatTunnel(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } + // for backward compatibility: no custom toString() } diff --git a/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java b/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java index d91cf98d915..d39c6262ae0 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java +++ b/core/src/main/java/com/graphhopper/routing/ev/HazmatWater.java @@ -1,11 +1,13 @@ package com.graphhopper.routing.ev; +import com.graphhopper.util.Helper; + /** * Defines general restrictions for the transport of goods through water protection areas.
* If not tagged it will be {@link #YES} */ public enum HazmatWater { - YES("yes"), PERMISSIVE("permissive"), NO("no"); + YES, PERMISSIVE, NO; public static final String KEY = "hazmat_water"; @@ -13,14 +15,8 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, HazmatWater.class); } - private final String name; - - HazmatWater(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Hgv.java b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java index 7284f6acb33..1bb492c28e4 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Hgv.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java @@ -25,8 +25,7 @@ * value OTHER. The NO value does not permit any access. */ public enum Hgv { - MISSING("missing"), YES("yes"), DESIGNATED("designated"), DESTINATION("destination"), - DELIVERY("delivery"), DISCOURAGED("discouraged"), AGRICULTURAL("agricultural"), NO("no"); + MISSING, YES, DESIGNATED, DESTINATION, DELIVERY, DISCOURAGED, AGRICULTURAL, NO; public static final String KEY = "hgv"; @@ -34,15 +33,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(Hgv.KEY, Hgv.class); } - private final String name; - - Hgv(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static Hgv find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java b/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java index febd41f9274..d25cc79e476 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxWeightExcept.java @@ -1,6 +1,6 @@ package com.graphhopper.routing.ev; -import java.util.Locale; +import com.graphhopper.util.Helper; /** * When the max_weight EncodedValue is not legally binding. E.g. if there is a sign that a delivery vehicle can access @@ -18,18 +18,17 @@ public static EnumEncodedValue create() { @Override public String toString() { - return name().toLowerCase(Locale.ROOT); + return Helper.toLowerCase(super.toString()); } public static MaxWeightExcept find(String name) { if (name == null || name.isEmpty()) return NONE; - for (MaxWeightExcept mwe : values()) { - if (mwe.name().equalsIgnoreCase(name)) - return mwe; + try { + return MaxWeightExcept.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return NONE; } - - return NONE; } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java b/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java index ebcaf71a4a8..768beb6cdbd 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadAccess.java @@ -25,9 +25,7 @@ * value OTHER. The NO value does not permit any access. */ public enum RoadAccess { - YES("yes"), DESTINATION("destination"), CUSTOMERS("customers"), DELIVERY("delivery"), - FORESTRY("forestry"), AGRICULTURAL("agricultural"), - PRIVATE("private"), OTHER("other"), NO("no"); + YES, DESTINATION, CUSTOMERS, DELIVERY, FORESTRY, AGRICULTURAL, PRIVATE, OTHER, NO; public static final String KEY = "road_access"; @@ -35,15 +33,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class); } - private final String name; - - RoadAccess(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static RoadAccess find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java b/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java index 88f56c9b5f9..806b6dbccf0 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadClass.java @@ -17,18 +17,15 @@ */ package com.graphhopper.routing.ev; +import com.graphhopper.util.Helper; + /** * This enum defines the road class of an edge. It is heavily influenced from the highway tag in OSM that can be * primary, cycleway etc. All edges that do not fit get OTHER as value. */ public enum RoadClass { - OTHER("other"), MOTORWAY("motorway"), - TRUNK("trunk"), PRIMARY("primary"), SECONDARY("secondary"), - TERTIARY("tertiary"), RESIDENTIAL("residential"), UNCLASSIFIED("unclassified"), - SERVICE("service"), ROAD("road"), TRACK("track"), - BRIDLEWAY("bridleway"), STEPS("steps"), CYCLEWAY("cycleway"), - PATH("path"), LIVING_STREET("living_street"), FOOTWAY("footway"), - PEDESTRIAN("pedestrian"), PLATFORM("platform"), CORRIDOR("corridor"); + OTHER, MOTORWAY, TRUNK, PRIMARY, SECONDARY, TERTIARY, RESIDENTIAL, UNCLASSIFIED, + SERVICE, ROAD, TRACK, BRIDLEWAY, STEPS, CYCLEWAY, PATH, LIVING_STREET, FOOTWAY, PEDESTRIAN, PLATFORM, CORRIDOR; public static final String KEY = "road_class"; @@ -36,27 +33,18 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class); } - private final String name; - - RoadClass(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static RoadClass find(String name) { if (name == null || name.isEmpty()) return OTHER; - - for (RoadClass roadClass : values()) { - if (roadClass.name().equalsIgnoreCase(name)) { - return roadClass; - } + try { + return RoadClass.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return OTHER; } - - return OTHER; } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java b/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java index 6c60eff74b2..97b76126caa 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RoadEnvironment.java @@ -24,8 +24,7 @@ * that do not fit get "other" as value. */ public enum RoadEnvironment { - OTHER("other"), ROAD("road"), FERRY("ferry"), - TUNNEL("tunnel"), BRIDGE("bridge"), FORD("ford"); + OTHER, ROAD, FERRY, TUNNEL, BRIDGE, FORD; public static final String KEY = "road_environment"; @@ -33,15 +32,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class); } - private final String name; - - RoadEnvironment(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static RoadEnvironment find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java b/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java index 2fc739e9c86..7caf2796e73 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java +++ b/core/src/main/java/com/graphhopper/routing/ev/RouteNetwork.java @@ -25,8 +25,7 @@ */ public enum RouteNetwork { - MISSING("missing"), INTERNATIONAL("international"), NATIONAL("national"), REGIONAL("regional"), - LOCAL("local"), OTHER("other"); + MISSING, INTERNATIONAL, NATIONAL, REGIONAL, LOCAL, OTHER; public static String key(String prefix) { return prefix + "_network"; @@ -36,15 +35,9 @@ public static EnumEncodedValue create(String name) { return new EnumEncodedValue<>(name, RouteNetwork.class); } - private final String name; - - RouteNetwork(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static RouteNetwork find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java index 29e41106503..b05046af571 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java @@ -20,15 +20,12 @@ import com.graphhopper.util.Helper; /** - * This enum defines the road smoothness of an edge. If not tagged the value will be MISSING, which is the default. + * This enum defines the road smoothness of an edge. If not tagged the value will be MISSING, which is the default. * All unknown smoothness tags will get OTHER . */ public enum Smoothness { // Order is important to make it roughly comparable - MISSING("missing"), - EXCELLENT("excellent"), GOOD("good"), INTERMEDIATE("intermediate"), BAD("bad"), VERY_BAD("very_bad"), - HORRIBLE("horrible"), VERY_HORRIBLE("very_horrible"), IMPASSABLE("impassable"), - OTHER("other"); + MISSING, EXCELLENT, GOOD, INTERMEDIATE, BAD, VERY_BAD, HORRIBLE, VERY_HORRIBLE, IMPASSABLE, OTHER; public static final String KEY = "smoothness"; @@ -36,15 +33,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Smoothness.class); } - private final String name; - - Smoothness(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static Smoothness find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Surface.java b/core/src/main/java/com/graphhopper/routing/ev/Surface.java index 8f2cecbdaf3..4c30bd3a84a 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Surface.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Surface.java @@ -28,21 +28,21 @@ * OTHER (the worst surface). */ public enum Surface { - // Order is important to make it roughly comparable - MISSING("missing"), - PAVED("paved"), ASPHALT("asphalt"), CONCRETE("concrete"), PAVING_STONES("paving_stones"), COBBLESTONE("cobblestone"), - UNPAVED("unpaved"), COMPACTED("compacted"), FINE_GRAVEL("fine_gravel"), GRAVEL("gravel"), - GROUND("ground"), DIRT("dirt"), GRASS("grass"), SAND("sand"), WOOD("wood"), - OTHER("other"); + // Order is important to make ordinal roughly comparable + MISSING, + PAVED, ASPHALT, CONCRETE, PAVING_STONES, COBBLESTONE, + UNPAVED, COMPACTED, FINE_GRAVEL, GRAVEL, GROUND, DIRT, GRASS, SAND, WOOD, + OTHER; public static final String KEY = "surface"; - private static final Map SURFACE_MAP = new HashMap<>(); + private static final Map SURFACE_MAP = new HashMap<>(); + static { for (Surface surface : values()) { if (surface == MISSING || surface == OTHER) continue; - SURFACE_MAP.put(surface.name, surface); + SURFACE_MAP.put(surface.toString(), surface); } SURFACE_MAP.put("metal", PAVED); SURFACE_MAP.put("sett", COBBLESTONE); @@ -56,15 +56,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Surface.class); } - private final String name; - - Surface(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static Surface find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Toll.java b/core/src/main/java/com/graphhopper/routing/ev/Toll.java index 4a4eff5c6ad..b5ee2c4f869 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Toll.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Toll.java @@ -17,12 +17,14 @@ */ package com.graphhopper.routing.ev; +import com.graphhopper.util.Helper; + /** * This enum defines the toll value like MISSING (default), NO (no toll), HGV * (toll for heavy goods vehicles) and ALL (all vehicles) */ public enum Toll { - MISSING("missing"), NO("no"), HGV("hgv"), ALL("all"); + MISSING, NO, HGV, ALL; public static final String KEY = "toll"; @@ -30,14 +32,8 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, Toll.class); } - private final String name; - - Toll(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/TrackType.java b/core/src/main/java/com/graphhopper/routing/ev/TrackType.java index bc178222923..e36652f5bd0 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/TrackType.java +++ b/core/src/main/java/com/graphhopper/routing/ev/TrackType.java @@ -27,8 +27,7 @@ * @see Tracktype Wiki */ public enum TrackType { - MISSING("missing"), GRADE1("grade1"), GRADE2("grade2"), - GRADE3("grade3"), GRADE4("grade4"), GRADE5("grade5"); + MISSING, GRADE1, GRADE2, GRADE3, GRADE4, GRADE5; public static final String KEY = "track_type"; @@ -36,15 +35,9 @@ public static EnumEncodedValue create() { return new EnumEncodedValue<>(KEY, TrackType.class); } - private final String name; - - TrackType(String name) { - this.name = name; - } - @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } public static TrackType find(String name) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java b/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java index b5500259eeb..249fc9a1f5b 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java +++ b/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java @@ -18,23 +18,19 @@ package com.graphhopper.routing.ev; -public enum UrbanDensity { - RURAL("rural"), RESIDENTIAL("residential"), CITY("city"); +import com.graphhopper.util.Helper; - public static EnumEncodedValue create() { - return new EnumEncodedValue<>(KEY, UrbanDensity.class); - } +public enum UrbanDensity { + RURAL, RESIDENTIAL, CITY; public static final String KEY = "urban_density"; - private final String name; - - UrbanDensity(String name) { - this.name = name; + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, UrbanDensity.class); } @Override public String toString() { - return name; + return Helper.toLowerCase(super.toString()); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 8b979c543af..9067dd16bb8 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -917,7 +917,7 @@ protected File _getOSMFile() { assertFalse(response.hasErrors(), response.getErrors().toString()); List list = response.getBest().getPathDetails().get(RoadClass.KEY); assertEquals(3, list.size()); - assertEquals(RoadClass.MOTORWAY.toString(), list.get(0).getValue()); + assertEquals("motorway", list.get(0).getValue()); response = gh.route(new GHRequest(51.2492152, 9.4317166, 52.133, 9.1) .setProfile("profile") diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index d364a777b74..75edc224295 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -267,13 +267,13 @@ public void testPathDetailsRoadClass() { GHResponse rsp = client.route(request); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(4, rsp.getBest().getPathDetails().get(RoadClass.KEY).size()); - assertEquals(RoadClass.PRIMARY.toString(), rsp.getBest().getPathDetails().get(RoadClass.KEY).get(3).getValue()); + assertEquals("primary", rsp.getBest().getPathDetails().get(RoadClass.KEY).get(3).getValue()); assertFalse((Boolean) rsp.getBest().getPathDetails().get(RoadClassLink.KEY).get(0).getValue()); List roadEnvList = rsp.getBest().getPathDetails().get(RoadEnvironment.KEY); assertEquals(10, roadEnvList.size()); - assertEquals(RoadEnvironment.ROAD.toString(), roadEnvList.get(0).getValue()); - assertEquals(RoadEnvironment.TUNNEL.toString(), roadEnvList.get(6).getValue()); + assertEquals("road", roadEnvList.get(0).getValue()); + assertEquals("tunnel", roadEnvList.get(6).getValue()); } @Test From c2d4bf32193e6cdbf77882853a7848759d8544dc Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 22 Apr 2023 09:57:13 +0200 Subject: [PATCH 055/165] always use unix LF, related #2791 --- .../graphhopper/routing/ev/Smoothness.java | 100 ++++---- .../util/countryrules/CountryRule.java | 2 +- .../util/countryrules/CountryRuleFactory.java | 8 +- .../europe/AlbaniaCountryRule.java | 4 +- .../europe/AndorraCountryRule.java | 4 +- .../europe/AustriaCountryRule.java | 4 +- .../europe/BelarusCountryRule.java | 4 +- .../europe/BelgiumCountryRule.java | 86 +++---- .../europe/BulgariaCountryRule.java | 86 +++---- .../europe/CroatiaCountryRule.java | 86 +++---- .../europe/CzechiaCountryRule.java | 86 +++---- .../europe/DenmarkCountryRule.java | 86 +++---- .../europe/EstoniaCountryRule.java | 4 +- .../europe/FaroeIslandsCountryRule.java | 4 +- .../europe/FinlandCountryRule.java | 4 +- .../europe/FranceCountryRule.java | 86 +++---- .../europe/GermanyCountryRule.java | 6 +- .../europe/GibraltarCountryRule.java | 4 +- .../europe/GreeceCountryRule.java | 6 +- .../europe/GuernseyCountryRule.java | 4 +- .../europe/HungaryCountryRule.java | 98 ++++---- .../europe/IcelandCountryRule.java | 4 +- .../europe/IsleOfManCountryRule.java | 4 +- .../countryrules/europe/ItalyCountryRule.java | 86 +++---- .../europe/JerseyCountryRule.java | 4 +- .../europe/LatviaCountryRule.java | 4 +- .../europe/LiechtensteinCountryRule.java | 4 +- .../europe/LithuaniaCountryRule.java | 4 +- .../europe/LuxembourgCountryRule.java | 86 +++---- .../countryrules/europe/MaltaCountryRule.java | 4 +- .../europe/MonacoCountryRule.java | 4 +- .../europe/NetherlandsCountryRule.java | 86 +++---- .../europe/PolandCountryRule.java | 86 +++---- .../europe/PortugalCountryRule.java | 86 +++---- .../europe/RomaniaCountryRule.java | 86 +++---- .../europe/RomaniaSpatialRule.java | 96 +++---- .../europe/SanMarinoCountryRule.java | 4 +- .../europe/SerbiaCountryRule.java | 86 +++---- .../europe/SlovakiaCountryRule.java | 94 +++---- .../europe/SloveniaCountryRule.java | 94 +++---- .../countryrules/europe/SpainCountryRule.java | 86 +++---- .../europe/SwedenCountryRule.java | 86 +++---- .../europe/SwitzerlandCountryRule.java | 100 ++++---- .../europe/UkraineCountryRule.java | 4 +- .../europe/VaticanCityCountryRule.java | 4 +- .../resources/com/graphhopper/util/zh_TW.txt | 238 +++++++++--------- docs/core/heading.md | 148 +++++------ .../graphhopper/example/HeadingExample.java | 159 ++++++------ .../example/HeadingExampleTest.java | 17 +- 49 files changed, 1267 insertions(+), 1269 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java index b05046af571..c9ac18a1efa 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Smoothness.java @@ -1,50 +1,50 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.ev; - -import com.graphhopper.util.Helper; - -/** - * This enum defines the road smoothness of an edge. If not tagged the value will be MISSING, which is the default. - * All unknown smoothness tags will get OTHER . - */ -public enum Smoothness { - // Order is important to make it roughly comparable - MISSING, EXCELLENT, GOOD, INTERMEDIATE, BAD, VERY_BAD, HORRIBLE, VERY_HORRIBLE, IMPASSABLE, OTHER; - - public static final String KEY = "smoothness"; - - public static EnumEncodedValue create() { - return new EnumEncodedValue<>(KEY, Smoothness.class); - } - - @Override - public String toString() { - return Helper.toLowerCase(super.toString()); - } - - public static Smoothness find(String name) { - if (Helper.isEmpty(name)) - return MISSING; - try { - return Smoothness.valueOf(Helper.toUpperCase(name)); - } catch (IllegalArgumentException ex) { - return OTHER; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.ev; + +import com.graphhopper.util.Helper; + +/** + * This enum defines the road smoothness of an edge. If not tagged the value will be MISSING, which is the default. + * All unknown smoothness tags will get OTHER . + */ +public enum Smoothness { + // Order is important to make it roughly comparable + MISSING, EXCELLENT, GOOD, INTERMEDIATE, BAD, VERY_BAD, HORRIBLE, VERY_HORRIBLE, IMPASSABLE, OTHER; + + public static final String KEY = "smoothness"; + + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Smoothness.class); + } + + @Override + public String toString() { + return Helper.toLowerCase(super.toString()); + } + + public static Smoothness find(String name) { + if (Helper.isEmpty(name)) + return MISSING; + try { + return Smoothness.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return OTHER; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java index 24f544eb737..7de723ab9b5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java @@ -34,7 +34,7 @@ default double getMaxSpeed(ReaderWay readerWay, TransportationMode transportatio default RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportationMode, RoadAccess currentRoadAccess) { return currentRoadAccess; } - + default Toll getToll(ReaderWay readerWay, Toll currentToll) { return currentToll; } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java index f9ed9e7f0fb..974f7b93431 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java @@ -28,11 +28,11 @@ import com.graphhopper.routing.util.countryrules.europe.*; public class CountryRuleFactory { - + private final Map rules = new EnumMap<>(Country.class); - + public CountryRuleFactory() { - + // Europe rules.put(ALB, new AlbaniaCountryRule()); rules.put(AND, new AndorraCountryRule()); @@ -88,7 +88,7 @@ public CountryRuleFactory() { public CountryRule getCountryRule(Country country) { return rules.get(country); } - + public Map getCountryToRuleMap() { return rules; } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java index 4201501ae82..484cce045e5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class AlbaniaCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java index 2de857f7aa1..6aaaf1df852 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class AndorraCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java index 6fb3accdb9a..9914bd34129 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java @@ -73,7 +73,7 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati return RoadAccess.YES; } } - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { @@ -84,7 +84,7 @@ public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK) { return Toll.ALL; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java index 9b3b11dc837..96bc500b09e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java @@ -24,7 +24,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class BelarusCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { @@ -35,7 +35,7 @@ public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (roadClass == RoadClass.MOTORWAY) { return Toll.HGV; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java index ba9b30ac1f2..6616d71b82a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Belgian roads - * - * @author Thomas Butz - */ -public class BelgiumCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Belgian roads + * + * @author Thomas Butz + */ +public class BelgiumCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java index a8e642a4554..bb1dc372fad 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Bulgarian roads - * - * @author Thomas Butz - */ -public class BulgariaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Bulgarian roads + * + * @author Thomas Butz + */ +public class BulgariaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java index 948eb5a4283..9d5a9df449a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Croatian roads - * - * @author Thomas Butz - */ -public class CroatiaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Croatian roads + * + * @author Thomas Butz + */ +public class CroatiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java index a29e23d929d..c3ca0fb777b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for the roads of the Czech Republic. - * - * @author Thomas Butz - */ -public class CzechiaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for the roads of the Czech Republic. + * + * @author Thomas Butz + */ +public class CzechiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java index 177cdaab890..ddec29d0adc 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Polish roads - * - * @author Thomas Butz - */ -public class DenmarkCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Polish roads + * + * @author Thomas Butz + */ +public class DenmarkCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java index 3d00d7278dd..b1c7f7dc17a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java @@ -24,7 +24,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class EstoniaCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { @@ -35,7 +35,7 @@ public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { return Toll.HGV; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java index 3838ba68d67..41c50eaa063 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class FaroeIslandsCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java index 687cfa95428..e16319ca964 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class FinlandCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java index e35f2977e23..dc999897851 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for French roads - * - * @author Thomas Butz - */ -public class FranceCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for French roads + * + * @author Thomas Butz + */ +public class FranceCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java index 35a59490ea8..01c68860a46 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java @@ -81,18 +81,18 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati return RoadAccess.YES; } } - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { return Toll.HGV; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java index adfbcf0b741..f9a1e35cc58 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class GibraltarCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java index 4d28cbc0872..0be76db3a8e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java @@ -24,18 +24,18 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class GreeceCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); if (roadClass == RoadClass.MOTORWAY) { return Toll.ALL; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java index 6c5e5e47dd9..6d50fb64ca7 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class GuernseyCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java index 6e288bda384..4955ab2aeaa 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java @@ -1,49 +1,49 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Hungarian roads - * - * @author Thomas Butz - */ -public class HungaryCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - switch (roadClass) { - case MOTORWAY: - return Toll.ALL; - case TRUNK: - case PRIMARY: - return Toll.HGV; - default: - return currentToll; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Hungarian roads + * + * @author Thomas Butz + */ +public class HungaryCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + return Toll.ALL; + case TRUNK: + case PRIMARY: + return Toll.HGV; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java index 1342e71da7c..d5ff358f297 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class IcelandCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java index cb391439a6c..b0d0638bcde 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class IsleOfManCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java index ba70969f299..ebe34e43a5a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Italian roads - * - * @author Thomas Butz - */ -public class ItalyCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Italian roads + * + * @author Thomas Butz + */ +public class ItalyCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java index c3220b4a9eb..ab188db022e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class JerseyCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java index e55b9e7d0a9..b128df7627f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java @@ -24,7 +24,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class LatviaCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { @@ -35,7 +35,7 @@ public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { return Toll.HGV; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java index d7e636b6578..1f9f5bcdcc0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class LiechtensteinCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java index 66d1f6499d8..84805a5b4ff 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java @@ -24,7 +24,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class LithuaniaCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { @@ -35,7 +35,7 @@ public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { return Toll.HGV; } - + return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java index 19b6b9f7883..722c54cc88c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Luxembourgish roads - * - * @author Thomas Butz - */ -public class LuxembourgCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Luxembourgish roads + * + * @author Thomas Butz + */ +public class LuxembourgCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java index 88a3ae03cc5..bc535ae1e4f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class MaltaCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java index 277137176f6..770cdda92c9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class MonacoCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java index 2d8aa038b05..9cac3121068 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Netherlands roads - * - * @author Thomas Butz - */ -public class NetherlandsCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Netherlands roads + * + * @author Thomas Butz + */ +public class NetherlandsCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java index fb26f885f38..c9b96943bb5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Polish roads - * - * @author Thomas Butz - */ -public class PolandCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Polish roads + * + * @author Thomas Butz + */ +public class PolandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java index 8f3c6c85b76..8214e9847a9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Portuguese roads - * - * @author Thomas Butz - */ -public class PortugalCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Portuguese roads + * + * @author Thomas Butz + */ +public class PortugalCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java index cb310251e1f..104471dd59c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Croatian roads - * - * @author Thomas Butz - */ -public class RomaniaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Croatian roads + * + * @author Thomas Butz + */ +public class RomaniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java index efa447f344c..93bbdf80a58 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java @@ -1,48 +1,48 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Romanian roads - * - * @author Thomas Butz - */ -public class RomaniaSpatialRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - switch (roadClass) { - case MOTORWAY: - case TRUNK: - case PRIMARY: - return Toll.ALL; - default: - return currentToll; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Romanian roads + * + * @author Thomas Butz + */ +public class RomaniaSpatialRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + case PRIMARY: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java index ec4ae43c31c..a6bc8e35e78 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class SanMarinoCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java index 5ced7eac829..95b17ead157 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Serbian roads - * - * @author Thomas Butz - */ -public class SerbiaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Serbian roads + * + * @author Thomas Butz + */ +public class SerbiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java index be03fe0da76..4a3dc00b0f1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java @@ -1,47 +1,47 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Slovakian roads - * - * @author Thomas Butz - */ -public class SlovakiaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - switch (roadClass) { - case MOTORWAY: - case TRUNK: - return Toll.ALL; - default: - return currentToll; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Slovakian roads + * + * @author Thomas Butz + */ +public class SlovakiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java index 5bfcc699222..c39f4ccbcd5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java @@ -1,47 +1,47 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Slovenian roads - * - * @author Thomas Butz - */ -public class SloveniaCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - switch (roadClass) { - case MOTORWAY: - case TRUNK: - return Toll.ALL; - default: - return currentToll; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Slovenian roads + * + * @author Thomas Butz + */ +public class SloveniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java index 727b06b22f9..8b08ca00c37 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Spanish roads - * - * @author Thomas Butz - */ -public class SpainCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.ALL; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Spanish roads + * + * @author Thomas Butz + */ +public class SpainCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java index 4d303b2f246..7cf8d43a2a9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java @@ -1,43 +1,43 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Swedish roads - * - * @author Thomas Butz - */ -public class SwedenCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (RoadClass.MOTORWAY == roadClass) - return Toll.HGV; - return currentToll; - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Swedish roads + * + * @author Thomas Butz + */ +public class SwedenCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java index 04745249df7..1039c3846ad 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java @@ -1,50 +1,50 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.routing.util.countryrules.europe; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.countryrules.CountryRule; - -/** - * Defines the default rules for Swiss roads - * - * @author Thomas Butz - */ -public class SwitzerlandCountryRule implements CountryRule { - - @Override - public Toll getToll(ReaderWay readerWay, Toll currentToll) { - if (currentToll != Toll.MISSING) { - return currentToll; - } - - RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); - if (currentToll != null) - return currentToll; - - switch (roadClass) { - case MOTORWAY: - case TRUNK: - return Toll.ALL; - default: - return currentToll; - } - } -} +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Swiss roads + * + * @author Thomas Butz + */ +public class SwitzerlandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (currentToll != null) + return currentToll; + + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java index acbed2fb5b0..13e84f6c2aa 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class UkraineCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java index 1c1e7f50af0..0fe662ccf18 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java @@ -23,13 +23,13 @@ import com.graphhopper.routing.util.countryrules.CountryRule; public class VaticanCityCountryRule implements CountryRule { - + @Override public Toll getToll(ReaderWay readerWay, Toll currentToll) { if (currentToll != Toll.MISSING) { return currentToll; } - + return Toll.NO; } } diff --git a/core/src/main/resources/com/graphhopper/util/zh_TW.txt b/core/src/main/resources/com/graphhopper/util/zh_TW.txt index 6c7fd1debda..45b70dfbc52 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_TW.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_TW.txt @@ -1,122 +1,122 @@ # do not edit manually, instead use spreadsheet https://t.co/f086oJXAEI and script ./core/files/update-translations.sh -continue=繼續 -continue_onto=繼續行駛到 %1$s -finish=抵達目的地 -keep_left=保持左側 -keep_right=保持右側 -turn_onto=%1$s 進入%2$s -turn_left=左轉 -turn_right=右轉 -turn_slight_left=微靠左轉 -turn_slight_right=微靠右轉 -turn_sharp_left=左急轉 -turn_sharp_right=右急轉 -u_turn=迴轉 -toward_destination= -toward_destination_ref_only= -toward_destination_with_ref= -unknown=未知指示標誌 '%1$s' -via=途經 -hour_abbr=小時 -day_abbr=天 -min_abbr=分鐘 -km_abbr=公里 -m_abbr=公尺 -mi_abbr=英里 -ft_abbr=英尺 -road=道路 -off_bike=下自行車 -cycleway=自行車道 -way=路 -small_way=小路 -paved=路面有鋪設 -unpaved=路面無鋪設 -stopover=中途點 %1$s -roundabout_enter=進入圓環 -roundabout_exit=於 %1$s 個出口離開圓環 -roundabout_exit_onto=於 %1$s 個出口離開圓環,進入 %2$s -web.total_ascend=總共上昇 %1$s -web.total_descend=總共下降 %1$s -web.way_contains_ford=路徑中含有淺灘 -web.way_contains_ferry=搭乘渡輪 -web.way_contains_private=私人道路 -web.way_contains_toll=收費道路 -web.way_crosses_border= -web.way_contains= -web.tracks= -web.steps= -pt_transfer_to=變換至 %1$s -web.start_label=出發點 -web.intermediate_label=途經點 -web.end_label=抵達點 -web.set_start=設為出發點 -web.set_intermediate=設為途經點 -web.set_end=設為抵達點 -web.center_map=設為地圖中心 -web.show_coords=顯示坐標 -web.query_osm= -web.route=路線 -web.add_to_route= -web.delete_from_route=從路線中移除 -web.open_custom_model_box= -web.help_custom_model= -web.apply_custom_model= -web.exclude_motorway_example= -web.limit_speed_example= -web.exclude_area_example= -web.combined_example= -web.examples_custom_model= -web.marker=標記 -web.gh_offline_info=GraphHopper API 離線狀態? -web.refresh_button=刷新頁面 -web.server_status=狀態 -web.zoom_in=放大 -web.zoom_out=縮小 -web.drag_to_reorder=拖曳排序 -web.route_timed_out= -web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= -web.via_hint=途經 -web.from_hint=起點 -web.gpx_export_button=匯出GPS -web.gpx_button= -web.hide_button= -web.details_button= -web.to_hint=迄點 -web.route_info=%1$s 需時 %2$s -web.search_button=搜尋 -web.more_button=更多 -web.pt_route_info=於 %1$s 抵達,%2$s 次轉乘 (%3$s) -web.pt_route_info_walking=於 %1$s 抵達,僅步行 (%2$s) -web.locations_not_found=無法進行規劃。無法在此區域內找到指定的地點 -web.search_with_nominatim= -web.powered_by= -web.bike=自行車 -web.racingbike=競技自行車 -web.mtb=登山車 -web.car=汽車 -web.foot=步行 -web.hike=健行 -web.small_truck=小貨車 -web.bus=公車 -web.truck=貨車 -web.staticlink=永久鏈結 -web.motorcycle=摩托車 -web.back_to_map= -web.distance_unit= -web.waiting_for_gps= -navigate.in_km_singular= -navigate.in_km= -navigate.in_m= -navigate.for_km= -navigate.then= -navigate.in_mi_singular= -navigate.in_mi= -navigate.in_ft= -navigate.for_mi= -navigate.warning= -navigate.accept_risks_after_warning= +continue=繼續 +continue_onto=繼續行駛到 %1$s +finish=抵達目的地 +keep_left=保持左側 +keep_right=保持右側 +turn_onto=%1$s 進入%2$s +turn_left=左轉 +turn_right=右轉 +turn_slight_left=微靠左轉 +turn_slight_right=微靠右轉 +turn_sharp_left=左急轉 +turn_sharp_right=右急轉 +u_turn=迴轉 +toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= +unknown=未知指示標誌 '%1$s' +via=途經 +hour_abbr=小時 +day_abbr=天 +min_abbr=分鐘 +km_abbr=公里 +m_abbr=公尺 +mi_abbr=英里 +ft_abbr=英尺 +road=道路 +off_bike=下自行車 +cycleway=自行車道 +way=路 +small_way=小路 +paved=路面有鋪設 +unpaved=路面無鋪設 +stopover=中途點 %1$s +roundabout_enter=進入圓環 +roundabout_exit=於 %1$s 個出口離開圓環 +roundabout_exit_onto=於 %1$s 個出口離開圓環,進入 %2$s +web.total_ascend=總共上昇 %1$s +web.total_descend=總共下降 %1$s +web.way_contains_ford=路徑中含有淺灘 +web.way_contains_ferry=搭乘渡輪 +web.way_contains_private=私人道路 +web.way_contains_toll=收費道路 +web.way_crosses_border= +web.way_contains= +web.tracks= +web.steps= +pt_transfer_to=變換至 %1$s +web.start_label=出發點 +web.intermediate_label=途經點 +web.end_label=抵達點 +web.set_start=設為出發點 +web.set_intermediate=設為途經點 +web.set_end=設為抵達點 +web.center_map=設為地圖中心 +web.show_coords=顯示坐標 +web.query_osm= +web.route=路線 +web.add_to_route= +web.delete_from_route=從路線中移除 +web.open_custom_model_box= +web.help_custom_model= +web.apply_custom_model= +web.exclude_motorway_example= +web.limit_speed_example= +web.exclude_area_example= +web.combined_example= +web.examples_custom_model= +web.marker=標記 +web.gh_offline_info=GraphHopper API 離線狀態? +web.refresh_button=刷新頁面 +web.server_status=狀態 +web.zoom_in=放大 +web.zoom_out=縮小 +web.drag_to_reorder=拖曳排序 +web.route_timed_out= +web.route_request_failed= +web.current_location= +web.searching_location= +web.searching_location_failed= +web.via_hint=途經 +web.from_hint=起點 +web.gpx_export_button=匯出GPS +web.gpx_button= +web.hide_button= +web.details_button= +web.to_hint=迄點 +web.route_info=%1$s 需時 %2$s +web.search_button=搜尋 +web.more_button=更多 +web.pt_route_info=於 %1$s 抵達,%2$s 次轉乘 (%3$s) +web.pt_route_info_walking=於 %1$s 抵達,僅步行 (%2$s) +web.locations_not_found=無法進行規劃。無法在此區域內找到指定的地點 +web.search_with_nominatim= +web.powered_by= +web.bike=自行車 +web.racingbike=競技自行車 +web.mtb=登山車 +web.car=汽車 +web.foot=步行 +web.hike=健行 +web.small_truck=小貨車 +web.bus=公車 +web.truck=貨車 +web.staticlink=永久鏈結 +web.motorcycle=摩托車 +web.back_to_map= +web.distance_unit= +web.waiting_for_gps= +navigate.in_km_singular= +navigate.in_km= +navigate.in_m= +navigate.for_km= +navigate.then= +navigate.in_mi_singular= +navigate.in_mi= +navigate.in_ft= +navigate.for_mi= +navigate.warning= +navigate.accept_risks_after_warning= navigate.start_navigation= diff --git a/docs/core/heading.md b/docs/core/heading.md index 0fb1371bded..44f6e181a1e 100644 --- a/docs/core/heading.md +++ b/docs/core/heading.md @@ -1,74 +1,74 @@ -# Heading - -The flexible and hybrid modes allow adding a desired heading (north based azimuth between 0 and 360 degree) to any point. Adding a heading makes it more likely that a route starts towards the provided direction, because roads going into other directions are penalized (see the [heading_penalty](#heading-penalty) parameter). - -A heading with the value 'NaN' won't be enforced and a heading not within [0, 360] will trigger an IllegalArgumentException. It is important to note that if you force the heading at via or end points the outgoing heading needs to be specified. I.e. if you want to force "coming from south" to a destination you need to specify the resulting "heading towards north" instead, which is 0. - -## Example - -For this example we use [andorra.osm.pbf](../../core/files/andorra.osm.pbf). - -You can follow this example in 2 ways: - -1. The Graphhopper example - module ([HeadingExample.java](../../example/src/main/java/com/graphhopper/example/HeadingExample.java)) -2. With requests to a self-hosted server (the urls used in the following). You can self-host a graphhopper web server as - described [here](https://github.com/graphhopper/graphhopper#installation) - -The docs for the API can be found [here](../../docs/web/api-doc.md#parameters) - -### Use Case - -We will route from point -`42.566757, 1.597751` -to point -`42.567396, 1.597807` - -#### Without Heading - -`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false` - -![without_heading](./images/without_heading.PNG) - -(the images are created by putting the resulting coordinates LineString in a GeoJSON and plotting them) - -#### With Heading: Start Direction - -The first heading parameter defines the start direction which should be preferred. In this case, we can set it -to `heading towards west` (270 degree) and we see that a different route is returned - -`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270` - -Note that since the 'heading' parameter is currently not supported for speed mode, we need to disable it by -using `ch.disable=true` - -![with_heading_start](./images/with_heading_start.PNG) - -#### With Heading: Start and End Direction - -For all via or end points we can also specify a prefered heading. Especially at the end point it must be noted that we -still need to define the direction as `heading towards`. In this case, we want to prefer `coming from north`, but we -need to specify it with `heading towards south` (180 degree), although we know that the route ends here - -`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270&heading=180&` - -![with_heading_start_stop](./images/with_heading_start_stop.PNG) - -#### With Heading: End Direction - -Headings with value 'NaN' won't be enforced. We can omit the start heading and only enforce a end heading - -`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=NaN&heading=180&ch.disable=true` - -![with_heading_stop](./images/with_heading_stop.PNG) - -## Heading Penalty - -As stated in the docs - -> Penalty for omitting a specified heading. The penalty corresponds to the accepted time delay in seconds in comparison to the route without a heading. - -We can modify the `heading_penalty`, which by default is 120 seconds. If we, in our use case with start and end heading, reduce it to 10 seconds, the route is equivalent to the route without a heading - -`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270&heading=180&heading_penalty=10&ch.disable=true` - +# Heading + +The flexible and hybrid modes allow adding a desired heading (north based azimuth between 0 and 360 degree) to any point. Adding a heading makes it more likely that a route starts towards the provided direction, because roads going into other directions are penalized (see the [heading_penalty](#heading-penalty) parameter). + +A heading with the value 'NaN' won't be enforced and a heading not within [0, 360] will trigger an IllegalArgumentException. It is important to note that if you force the heading at via or end points the outgoing heading needs to be specified. I.e. if you want to force "coming from south" to a destination you need to specify the resulting "heading towards north" instead, which is 0. + +## Example + +For this example we use [andorra.osm.pbf](../../core/files/andorra.osm.pbf). + +You can follow this example in 2 ways: + +1. The Graphhopper example + module ([HeadingExample.java](../../example/src/main/java/com/graphhopper/example/HeadingExample.java)) +2. With requests to a self-hosted server (the urls used in the following). You can self-host a graphhopper web server as + described [here](https://github.com/graphhopper/graphhopper#installation) + +The docs for the API can be found [here](../../docs/web/api-doc.md#parameters) + +### Use Case + +We will route from point +`42.566757, 1.597751` +to point +`42.567396, 1.597807` + +#### Without Heading + +`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false` + +![without_heading](./images/without_heading.PNG) + +(the images are created by putting the resulting coordinates LineString in a GeoJSON and plotting them) + +#### With Heading: Start Direction + +The first heading parameter defines the start direction which should be preferred. In this case, we can set it +to `heading towards west` (270 degree) and we see that a different route is returned + +`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270` + +Note that since the 'heading' parameter is currently not supported for speed mode, we need to disable it by +using `ch.disable=true` + +![with_heading_start](./images/with_heading_start.PNG) + +#### With Heading: Start and End Direction + +For all via or end points we can also specify a prefered heading. Especially at the end point it must be noted that we +still need to define the direction as `heading towards`. In this case, we want to prefer `coming from north`, but we +need to specify it with `heading towards south` (180 degree), although we know that the route ends here + +`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270&heading=180&` + +![with_heading_start_stop](./images/with_heading_start_stop.PNG) + +#### With Heading: End Direction + +Headings with value 'NaN' won't be enforced. We can omit the start heading and only enforce a end heading + +`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=NaN&heading=180&ch.disable=true` + +![with_heading_stop](./images/with_heading_stop.PNG) + +## Heading Penalty + +As stated in the docs + +> Penalty for omitting a specified heading. The penalty corresponds to the accepted time delay in seconds in comparison to the route without a heading. + +We can modify the `heading_penalty`, which by default is 120 seconds. If we, in our use case with start and end heading, reduce it to 10 seconds, the route is equivalent to the route without a heading + +`localhost:8989/route?profile=car&point=42.566757,1.597751&point=42.567396,1.597807&type=json&instructions=false&points_encoded=false&ch.disable=true&heading=270&heading=180&heading_penalty=10&ch.disable=true` + diff --git a/example/src/main/java/com/graphhopper/example/HeadingExample.java b/example/src/main/java/com/graphhopper/example/HeadingExample.java index 9cfa227fedd..89fa0980924 100644 --- a/example/src/main/java/com/graphhopper/example/HeadingExample.java +++ b/example/src/main/java/com/graphhopper/example/HeadingExample.java @@ -1,7 +1,5 @@ package com.graphhopper.example; -import java.util.Arrays; - import com.graphhopper.GHRequest; import com.graphhopper.GHResponse; import com.graphhopper.GraphHopper; @@ -10,87 +8,88 @@ import com.graphhopper.util.Parameters; import com.graphhopper.util.shapes.GHPoint; -public class HeadingExample -{ - public static void main(String[] args) { - String relDir = args.length == 1 ? args[0] : ""; - GraphHopper hopper = createGraphHopperInstance(relDir + "core/files/andorra.osm.pbf"); - - without_heading(hopper); - with_heading_start(hopper); - with_heading_start_stop(hopper); - with_heading_stop(hopper); - with_heading_start_stop_lower_penalty(hopper); - } - - /** - * See {@link RoutingExample#createGraphHopperInstance} for more comments on creating the GraphHopper instance. - */ - static GraphHopper createGraphHopperInstance(String ghLoc) { - GraphHopper hopper = new GraphHopper(); - hopper.setOSMFile(ghLoc); - hopper.setGraphHopperLocation("target/heading-graph-cache"); - hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(false)); - hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car")); - hopper.importOrLoad(); - return hopper; - } - - static void without_heading(GraphHopper hopper) { - GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). - setProfile("car"); - GHResponse response = hopper.route(request); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); - assert Math.round(response.getBest().getDistance()) == 84; - } +import java.util.Arrays; + +public class HeadingExample { + public static void main(String[] args) { + String relDir = args.length == 1 ? args[0] : ""; + GraphHopper hopper = createGraphHopperInstance(relDir + "core/files/andorra.osm.pbf"); + + without_heading(hopper); + with_heading_start(hopper); + with_heading_start_stop(hopper); + with_heading_stop(hopper); + with_heading_start_stop_lower_penalty(hopper); + } + + /** + * See {@link RoutingExample#createGraphHopperInstance} for more comments on creating the GraphHopper instance. + */ + static GraphHopper createGraphHopperInstance(String ghLoc) { + GraphHopper hopper = new GraphHopper(); + hopper.setOSMFile(ghLoc); + hopper.setGraphHopperLocation("target/heading-graph-cache"); + hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(false)); + hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car")); + hopper.importOrLoad(); + return hopper; + } + + static void without_heading(GraphHopper hopper) { + GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). + setProfile("car"); + GHResponse response = hopper.route(request); + if (response.hasErrors()) + throw new RuntimeException(response.getErrors().toString()); + assert Math.round(response.getBest().getDistance()) == 84; + } - static void with_heading_start(GraphHopper hopper) { - GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). - setHeadings(Arrays.asList(270d)). - // important: if CH is enabled on the server-side we need to disable it for each request that uses heading, - // because heading is not supported by CH - putHint(Parameters.CH.DISABLE, true). - setProfile("car"); - GHResponse response = hopper.route(request); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); - assert Math.round(response.getBest().getDistance()) == 264; - } + static void with_heading_start(GraphHopper hopper) { + GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). + setHeadings(Arrays.asList(270d)). + // important: if CH is enabled on the server-side we need to disable it for each request that uses heading, + // because heading is not supported by CH + putHint(Parameters.CH.DISABLE, true). + setProfile("car"); + GHResponse response = hopper.route(request); + if (response.hasErrors()) + throw new RuntimeException(response.getErrors().toString()); + assert Math.round(response.getBest().getDistance()) == 264; + } - static void with_heading_start_stop(GraphHopper hopper) { - GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). - setHeadings(Arrays.asList(270d, 180d)). - putHint(Parameters.CH.DISABLE, true). - setProfile("car"); - GHResponse response = hopper.route(request); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); - assert Math.round(response.getBest().getDistance()) == 434; - } + static void with_heading_start_stop(GraphHopper hopper) { + GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). + setHeadings(Arrays.asList(270d, 180d)). + putHint(Parameters.CH.DISABLE, true). + setProfile("car"); + GHResponse response = hopper.route(request); + if (response.hasErrors()) + throw new RuntimeException(response.getErrors().toString()); + assert Math.round(response.getBest().getDistance()) == 434; + } - static void with_heading_stop(GraphHopper hopper) { - GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). - setHeadings(Arrays.asList(Double.NaN, 180d)). - putHint(Parameters.CH.DISABLE, true). - setProfile("car"); - GHResponse response = hopper.route(request); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); - assert Math.round(response.getBest().getDistance()) == 201; - } + static void with_heading_stop(GraphHopper hopper) { + GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). + setHeadings(Arrays.asList(Double.NaN, 180d)). + putHint(Parameters.CH.DISABLE, true). + setProfile("car"); + GHResponse response = hopper.route(request); + if (response.hasErrors()) + throw new RuntimeException(response.getErrors().toString()); + assert Math.round(response.getBest().getDistance()) == 201; + } - static void with_heading_start_stop_lower_penalty(GraphHopper hopper) { - GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). - setHeadings(Arrays.asList(270d, 180d)). - putHint(Parameters.Routing.HEADING_PENALTY, 10). - putHint(Parameters.CH.DISABLE, true). - setProfile("car"); - GHResponse response = hopper.route(request); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); - // same distance as without_heading - assert Math.round(response.getBest().getDistance()) == 84; - } + static void with_heading_start_stop_lower_penalty(GraphHopper hopper) { + GHRequest request = new GHRequest(new GHPoint(42.566757, 1.597751), new GHPoint(42.567396, 1.597807)). + setHeadings(Arrays.asList(270d, 180d)). + putHint(Parameters.Routing.HEADING_PENALTY, 10). + putHint(Parameters.CH.DISABLE, true). + setProfile("car"); + GHResponse response = hopper.route(request); + if (response.hasErrors()) + throw new RuntimeException(response.getErrors().toString()); + // same distance as without_heading + assert Math.round(response.getBest().getDistance()) == 84; + } } diff --git a/example/src/test/java/com/graphhopper/example/HeadingExampleTest.java b/example/src/test/java/com/graphhopper/example/HeadingExampleTest.java index 453e8ba5357..c9f73ceebdf 100644 --- a/example/src/test/java/com/graphhopper/example/HeadingExampleTest.java +++ b/example/src/test/java/com/graphhopper/example/HeadingExampleTest.java @@ -1,16 +1,15 @@ package com.graphhopper.example; -import java.io.File; - +import com.graphhopper.util.Helper; import org.junit.jupiter.api.Test; -import com.graphhopper.util.Helper; +import java.io.File; public class HeadingExampleTest { - - @Test - public void main() { - Helper.removeDir(new File("target/heading-graph-cache")); - HeadingExample.main(new String[]{"../"}); - } + + @Test + public void main() { + Helper.removeDir(new File("target/heading-graph-cache")); + HeadingExample.main(new String[]{"../"}); + } } From 71616049f9e11bae49f6c0360152c0133f39d36f Mon Sep 17 00:00:00 2001 From: otbutz Date: Sat, 22 Apr 2023 10:06:59 +0200 Subject: [PATCH 056/165] Add root editorconfig (#2791) --- .editorconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..30746a602df --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +root = true + +# https://github.com/graphhopper/graphhopper/blob/master/CONTRIBUTING.md#code-formatting + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 100 +tab_width = 4 + +[*.java] +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = true +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false From 862faa760d71cdc80bbf497fffa17ab780fc220e Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 22 Apr 2023 10:12:17 +0200 Subject: [PATCH 057/165] Update CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4101ba83eb4..24c9466643b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,8 +30,8 @@ All contributions like pull requests, bug fixes, documentation changes and trans ## Code formatting -We use IntelliJ defaults and a very similar configuration for NetBeans defined in the root pom.xml. For eclipse there is this [configuration](https://github.com/graphhopper/graphhopper/files/481920/GraphHopper.Formatter.zip). Also for other IDEs -it should be simple to match: +We use IntelliJ defaults. For eclipse there is this [configuration](https://github.com/graphhopper/graphhopper/files/481920/GraphHopper.Formatter.zip). +For other IDEs we use [editorconfig](https://github.com/graphhopper/graphhopper/pull/2791) or the following rules: * Java indent is 4 spaces * Line width is 100 characters From c496fce509f3541685e2a797faab18498ff50835 Mon Sep 17 00:00:00 2001 From: ratrun Date: Mon, 24 Apr 2023 13:11:15 +0200 Subject: [PATCH 058/165] Prefer bigger roads for racebike (#2802) * Make the MiniGraphUI working again. * Improve priority handling for race bikes as discussed in #2796 * Adopt expected Monaco test result for race bike profile --- .../routing/util/parsers/BikeCommonPriorityParser.java | 2 +- .../routing/util/parsers/RacingBikePriorityParser.java | 7 +++++++ .../graphhopper/routing/RoutingAlgorithmWithOSMTest.java | 2 +- .../util/parsers/AbstractBikeTagParserTester.java | 8 -------- .../routing/util/parsers/BikeTagParserTest.java | 9 +++++++++ .../routing/util/parsers/RacingBikeTagParserTest.java | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index c78c37bc788..8648f6af775 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -25,7 +25,7 @@ public abstract class BikeCommonPriorityParser implements TagParser { // Pushing section highways are parts where you need to get off your bike and push it (German: Schiebestrecke) protected final HashSet pushingSectionsHighways = new HashSet<>(); protected final Set preferHighwayTags = new HashSet<>(); - private final Map avoidHighwayTags = new HashMap<>(); + protected final Map avoidHighwayTags = new HashMap<>(); protected final Set unpavedSurfaceTags = new HashSet<>(); protected final Set ferries = new HashSet<>(FERRIES); protected final Set intendedValues = new HashSet<>(INTENDED); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java index 4f7d48c5fdd..015bb712df4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/RacingBikePriorityParser.java @@ -31,6 +31,13 @@ protected RacingBikePriorityParser(DecimalEncodedValue priorityEnc, DecimalEncod preferHighwayTags.add("tertiary_link"); preferHighwayTags.add("residential"); + avoidHighwayTags.put("motorway", BAD); + avoidHighwayTags.put("motorway_link", BAD); + avoidHighwayTags.put("trunk", BAD); + avoidHighwayTags.put("trunk_link", BAD); + avoidHighwayTags.put("primary", AVOID_MORE); + avoidHighwayTags.put("primary_link", AVOID_MORE); + routeMap.put(INTERNATIONAL, BEST.getValue()); routeMap.put(NATIONAL, BEST.getValue()); routeMap.put(REGIONAL, VERY_NICE.getValue()); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 564579a627f..fab92ced74e 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -426,7 +426,7 @@ public void testMonacoMountainBike() { public void testMonacoRacingBike() { List queries = new ArrayList<>(); queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 4022, 207)); + queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3615, 184)); queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2651, 167)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1516, 86)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index 9fa55a3085d..f4a60606f24 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -396,14 +396,6 @@ public void testHandleWayTagsCallsHandlePriority() { assertEquals(PriorityCode.getValue(VERY_NICE.getValue()), priorityEnc.getDecimal(false, edgeId, intAccess), 1e-3); } - @Test - public void testAvoidMotorway() { - ReaderWay osmWay = new ReaderWay(1); - osmWay.setTag("highway", "motorway"); - osmWay.setTag("bicycle", "yes"); - assertPriority(REACH_DESTINATION, osmWay); - } - @Test public void testLockedGate() { ReaderNode node = new ReaderNode(1, -1, -1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index 3829dcbb8d9..b8371c5160f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -592,4 +592,13 @@ public void testClassBicycle() { way.setTag("maxspeed", "15"); assertPriority(BEST, way); } + + @Test + public void testAvoidMotorway() { + ReaderWay osmWay = new ReaderWay(1); + osmWay.setTag("highway", "motorway"); + osmWay.setTag("bicycle", "yes"); + assertPriority(REACH_DESTINATION, osmWay); + } + } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java index a700d22f92e..015d47977b6 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/RacingBikeTagParserTest.java @@ -243,7 +243,7 @@ public void testPriority_avoidanceOfHighMaxSpeed() { assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, UNCHANGED, 20, osmWay); osmWay.setTag("highway", "motorway"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, BAD, 18, osmWay); osmWay.setTag("tunnel", "yes"); assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parsers, REACH_DESTINATION, 18, osmWay); From d77faa1b4d5298b2dbd8f4a380b3e89132fe3b2f Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 24 Apr 2023 15:19:09 +0200 Subject: [PATCH 059/165] changelog for #2796 and #2802 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32538783457..f6a165d9a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 8.0 [not yet released] +- bike routing better avoids dangerous roads, see #2796 and #2802 - routing requests can be configured to timeout after some time, see #2795 - custom_model_file string changed to custom_model_files array, see #2787 - renamed EdgeKVStorage to KVStorage as it is (temporarily) used for node tage too, see #2705 From b0c1d819c0b8a603e948b6e7f42f1b17929d0129 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Tue, 25 Apr 2023 13:42:36 -0700 Subject: [PATCH 060/165] This is a 400 user error, not an ERROR in the logging sense --- .../src/main/java/com/graphhopper/resources/RouteResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java index 76debaa25c0..7362e4cea6c 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java @@ -139,7 +139,7 @@ public Response doGet( if (ghResponse.hasErrors()) { MultiException ex = new MultiException(ghResponse.getErrors()); - logger.error(logStr, ex); + logger.info(logStr, ex); throw ex; } else { logger.info(logStr + ", alternatives: " + ghResponse.getAll().size() From d8d9c9c0c3425158d2a53d733dacd8ce40036563 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 28 Apr 2023 12:28:17 +0200 Subject: [PATCH 061/165] Simplify WaySegmentParser.Builder --- .../com/graphhopper/reader/osm/OSMReader.java | 3 +- .../reader/osm/WaySegmentParser.java | 93 ++++++------------- 2 files changed, 31 insertions(+), 65 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index f9b13a59e80..67f108d02c2 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -161,8 +161,7 @@ public void readGraph() throws IOException { if (!baseGraph.isInitialized()) throw new IllegalStateException("BaseGraph must be initialize before we can read OSM"); - WaySegmentParser waySegmentParser = new WaySegmentParser.Builder(baseGraph.getNodeAccess()) - .setDirectory(baseGraph.getDirectory()) + WaySegmentParser waySegmentParser = new WaySegmentParser.Builder(baseGraph.getNodeAccess(), baseGraph.getDirectory()) .setElevationProvider(eleProvider) .setWayFilter(this::acceptWay) .setSplitNodeFilter(this::isBarrierNode) diff --git a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java index 52593f6401d..2f5f8c3ff5d 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java +++ b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java @@ -25,7 +25,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.storage.Directory; -import com.graphhopper.storage.RAMDirectory; import com.graphhopper.util.Helper; import com.graphhopper.util.PointAccess; import com.graphhopper.util.PointList; @@ -49,7 +48,7 @@ /** * This class parses a given OSM file and splits OSM ways into 'segments' at all intersections (or 'junctions'). * Intersections can be either crossings of different OSM ways or duplicate appearances of the same node within one - * way (when the way contains a loop). Furthermore, this class creates artificial segments at certain nodes. This class + * way (when the way contains a loop). Furthermore, this class creates artificial segments at certain nodes. It * also provides several hooks/callbacks to customize the processing of nodes, ways and relations. *

* The OSM file is read twice. The first time we ignore OSM nodes and only determine the OSM node IDs at which accepted @@ -66,32 +65,24 @@ public class WaySegmentParser { private static final Logger LOGGER = LoggerFactory.getLogger(WaySegmentParser.class); private static final Set INCLUDE_IF_NODE_TAGS = new HashSet<>(Arrays.asList("barrier", "highway", "railway", "crossing", "ford")); - private final ElevationProvider eleProvider; - private final Predicate wayFilter; - private final Predicate splitNodeFilter; - private final WayPreprocessor wayPreprocessor; - private final Consumer relationPreprocessor; - private final RelationProcessor relationProcessor; - private final EdgeHandler edgeHandler; - private final int workerThreads; + private ElevationProvider elevationProvider = ElevationProvider.NOOP; + private Predicate wayFilter = way -> true; + private Predicate splitNodeFilter = node -> false; + private WayPreprocessor wayPreprocessor = (way, supplier) -> { + }; + private Consumer relationPreprocessor = relation -> { + }; + private RelationProcessor relationProcessor = (relation, map) -> { + }; + private EdgeHandler edgeHandler = (from, to, pointList, way, nodeTags) -> + System.out.println("edge " + from + "->" + to + " (" + pointList.size() + " points)"); + private int workerThreads = 2; private final OSMNodeData nodeData; private Date timestamp; - private WaySegmentParser(PointAccess nodeAccess, Directory directory, ElevationProvider eleProvider, - Predicate wayFilter, Predicate splitNodeFilter, WayPreprocessor wayPreprocessor, - Consumer relationPreprocessor, RelationProcessor relationProcessor, - EdgeHandler edgeHandler, int workerThreads) { - this.eleProvider = eleProvider; - this.wayFilter = wayFilter; - this.splitNodeFilter = splitNodeFilter; - this.wayPreprocessor = wayPreprocessor; - this.relationPreprocessor = relationPreprocessor; - this.relationProcessor = relationProcessor; - this.edgeHandler = edgeHandler; - this.workerThreads = workerThreads; - - this.nodeData = new OSMNodeData(nodeAccess, directory); + private WaySegmentParser(OSMNodeData nodeData) { + this.nodeData = nodeData; } /** @@ -215,7 +206,7 @@ public void handleNode(ReaderNode node) { LOGGER.info("pass2 - processed nodes: " + nf(nodeCounter) + ", accepted nodes: " + nf(acceptedNodes) + ", " + Helper.getMemInfo()); - int nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), () -> eleProvider.getEle(node)); + int nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), () -> elevationProvider.getEle(node)); if (nodeType == EMPTY_NODE) return; @@ -421,42 +412,21 @@ protected OSMInput openOsmInputFile(File osmFile, SkipOptions skipOptions) throw } public static class Builder { - private final PointAccess nodeAccess; - private Directory directory = new RAMDirectory(); - private ElevationProvider elevationProvider = ElevationProvider.NOOP; - private Predicate wayFilter = way -> true; - private Predicate splitNodeFilter = node -> false; - private WayPreprocessor wayPreprocessor = (way, supplier) -> { - }; - private Consumer relationPreprocessor = relation -> { - }; - private RelationProcessor relationProcessor = (relation, map) -> { - }; - private EdgeHandler edgeHandler = (from, to, pointList, way, nodeTags) -> - System.out.println("edge " + from + "->" + to + " (" + pointList.size() + " points)"); - private int workerThreads = 2; + private final WaySegmentParser waySegmentParser; /** - * @param nodeAccess used to store tower node coordinates while parsing the ways + * @param pointAccess used to store tower node coordinates while parsing the ways + * @param directory the directory to be used to store temporary data */ - public Builder(PointAccess nodeAccess) { - // instead of requiring a PointAccess here we could also just use some temporary in-memory storage by default - this.nodeAccess = nodeAccess; - } - - /** - * @param directory the directory to be used to store temporary data - */ - public Builder setDirectory(Directory directory) { - this.directory = directory; - return this; + public Builder(PointAccess pointAccess, Directory directory) { + waySegmentParser = new WaySegmentParser(new OSMNodeData(pointAccess, directory)); } /** * @param elevationProvider used to determine the elevation of an OSM node */ public Builder setElevationProvider(ElevationProvider elevationProvider) { - this.elevationProvider = elevationProvider; + waySegmentParser.elevationProvider = elevationProvider; return this; } @@ -464,7 +434,7 @@ public Builder setElevationProvider(ElevationProvider elevationProvider) { * @param wayFilter return true for OSM ways that should be considered and false otherwise */ public Builder setWayFilter(Predicate wayFilter) { - this.wayFilter = wayFilter; + waySegmentParser.wayFilter = wayFilter; return this; } @@ -472,7 +442,7 @@ public Builder setWayFilter(Predicate wayFilter) { * @param splitNodeFilter return true if the given OSM node should be duplicated to create an artificial edge */ public Builder setSplitNodeFilter(Predicate splitNodeFilter) { - this.splitNodeFilter = splitNodeFilter; + waySegmentParser.splitNodeFilter = splitNodeFilter; return this; } @@ -480,7 +450,7 @@ public Builder setSplitNodeFilter(Predicate splitNodeFilter) { * @param wayPreprocessor callback function that is called for each accepted OSM way during the second pass */ public Builder setWayPreprocessor(WayPreprocessor wayPreprocessor) { - this.wayPreprocessor = wayPreprocessor; + waySegmentParser.wayPreprocessor = wayPreprocessor; return this; } @@ -488,7 +458,7 @@ public Builder setWayPreprocessor(WayPreprocessor wayPreprocessor) { * @param relationPreprocessor callback function that receives OSM relations during the first pass */ public Builder setRelationPreprocessor(Consumer relationPreprocessor) { - this.relationPreprocessor = relationPreprocessor; + waySegmentParser.relationPreprocessor = relationPreprocessor; return this; } @@ -496,7 +466,7 @@ public Builder setRelationPreprocessor(Consumer relationPreproce * @param relationProcessor callback function that receives OSM relations during the second pass */ public Builder setRelationProcessor(RelationProcessor relationProcessor) { - this.relationProcessor = relationProcessor; + waySegmentParser.relationProcessor = relationProcessor; return this; } @@ -504,7 +474,7 @@ public Builder setRelationProcessor(RelationProcessor relationProcessor) { * @param edgeHandler callback function that is called for each edge (way segment) */ public Builder setEdgeHandler(EdgeHandler edgeHandler) { - this.edgeHandler = edgeHandler; + waySegmentParser.edgeHandler = edgeHandler; return this; } @@ -512,15 +482,12 @@ public Builder setEdgeHandler(EdgeHandler edgeHandler) { * @param workerThreads the number of threads used for the low level reading of the OSM file */ public Builder setWorkerThreads(int workerThreads) { - this.workerThreads = workerThreads; + waySegmentParser.workerThreads = workerThreads; return this; } public WaySegmentParser build() { - return new WaySegmentParser( - nodeAccess, directory, elevationProvider, wayFilter, splitNodeFilter, wayPreprocessor, relationPreprocessor, relationProcessor, - edgeHandler, workerThreads - ); + return waySegmentParser; } } From f7fd08ae6bcc76b106ae0183421f385f55bc1510 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 28 Apr 2023 18:33:29 +0200 Subject: [PATCH 062/165] Release some memory earlier after reading OSM --- core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java | 3 ++- core/src/main/java/com/graphhopper/coll/LongIntMap.java | 2 ++ .../main/java/com/graphhopper/reader/osm/OSMNodeData.java | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java b/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java index e556083e464..3d9d9a4c63f 100644 --- a/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java +++ b/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java @@ -131,7 +131,8 @@ public int getMemoryUsage() { return Math.round(root.getCapacity() / Helper.MB); } - void clear() { + @Override + public void clear() { size = 0; height = 1; root = new BTreeEntry(initLeafSize, true); diff --git a/core/src/main/java/com/graphhopper/coll/LongIntMap.java b/core/src/main/java/com/graphhopper/coll/LongIntMap.java index 907756d997c..00bd2e0c505 100644 --- a/core/src/main/java/com/graphhopper/coll/LongIntMap.java +++ b/core/src/main/java/com/graphhopper/coll/LongIntMap.java @@ -30,4 +30,6 @@ public interface LongIntMap { void optimize(); int getMemoryUsage(); + + void clear(); } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 3c442c01e84..2d72f13ab3b 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -30,7 +30,6 @@ import com.graphhopper.util.shapes.GHPoint3D; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.function.DoubleSupplier; import java.util.function.IntUnaryOperator; @@ -268,8 +267,12 @@ public Map getTags(long osmNodeId) { } public void release() { + idsByOsmNodeIds.clear(); pillarNodes.clear(); nodeKVStorage.clear(); + nodeTagIndicesByOsmNodeIds.clear(); + nodesToBeSplit.clear(); + nodeKVStorage.clear(); } public int towerNodeToId(int towerId) { From 3501a456ffbd9b47c6403264738d95d5e6e2d73c Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Fri, 28 Apr 2023 13:16:00 -0700 Subject: [PATCH 063/165] profile name, not vehicle name --- .../gtfs/PtRouterFreeWalkImpl.java | 4 ++-- .../com/graphhopper/gtfs/PtRouterImpl.java | 4 ++-- .../graphhopper/GraphHopperMultimodalIT.java | 20 ++++++++++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java index a0452862d4b..b6326417288 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java @@ -166,10 +166,10 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getName()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getName()))); } GHResponse route() { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java index 9f0313881d9..5238727cc1a 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java @@ -165,10 +165,10 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getName()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getName()))); } GHResponse route() { diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java index 50074d923c5..38f3a523efc 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java @@ -23,7 +23,9 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.index.LocationIndex; +import com.graphhopper.util.CustomModel; import com.graphhopper.util.Helper; import com.graphhopper.util.TranslationMap; import com.graphhopper.util.details.PathDetail; @@ -60,9 +62,14 @@ public static void init() { ghConfig.putObject("import.osm.ignored_highways", ""); ghConfig.putObject("gtfs.file", "files/sample-feed"); ghConfig.putObject("graph.location", GRAPH_LOC); + CustomProfile carLocal = new CustomProfile("car_custom"); + carLocal.setVehicle("car"); + carLocal.setWeighting("custom"); + carLocal.setCustomModel(new CustomModel()); ghConfig.setProfiles(Arrays.asList( new Profile("foot").setVehicle("foot").setWeighting("fastest"), - new Profile("car").setVehicle("car").setWeighting("fastest"))); + new Profile("car_default").setVehicle("car").setWeighting("fastest"), + carLocal)); Helper.removeDir(new File(GRAPH_LOC)); graphHopperGtfs = new GraphHopperGtfs(ghConfig); graphHopperGtfs.init(ghConfig); @@ -322,6 +329,17 @@ public void testLineStringWhenWalking() { assertThat(legGeometry).isEqualTo(readWktLineString("LINESTRING (-116.765169 36.906693, -116.764614 36.907243, -116.763438 36.908382, -116.762615 36.907825, -116.762241 36.908175)")); } + @Test + public void testCustomProfileAccess() { + Request ghRequest = new Request( + 36.91311729030539, -116.76769495010377, + 36.91260259593356, -116.76149368286134 + ); + ghRequest.setAccessProfile("car_custom"); + ghRequest.setEarliestDepartureTime(LocalDateTime.of(2007, 1, 1, 6, 40, 0).atZone(zoneId).toInstant()); + GHResponse response = graphHopper.route(ghRequest); + } + private Duration legDuration(Trip.Leg leg) { return Duration.between(departureTime(leg), arrivalTime(leg)); } From 4637096fb334e5421b0d98e1de187bcb97af3443 Mon Sep 17 00:00:00 2001 From: easbar Date: Sat, 29 Apr 2023 07:47:16 +0200 Subject: [PATCH 064/165] Fix --- core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 2d72f13ab3b..841ee96b362 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -269,10 +269,9 @@ public Map getTags(long osmNodeId) { public void release() { idsByOsmNodeIds.clear(); pillarNodes.clear(); - nodeKVStorage.clear(); nodeTagIndicesByOsmNodeIds.clear(); - nodesToBeSplit.clear(); nodeKVStorage.clear(); + nodesToBeSplit.clear(); } public int towerNodeToId(int towerId) { From 948294f3ed3304cfaf05a25627f9278b7cf095a6 Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 1 May 2023 20:13:56 +0200 Subject: [PATCH 065/165] Add check for pillar node overflow --- core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 841ee96b362..1c274c82d08 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -173,6 +173,8 @@ private int addTowerNode(long osmId, double lat, double lon, double ele) { } private int addPillarNode(long osmId, double lat, double lon, double ele) { + if (nextPillarId < 0) + throw new IllegalStateException("Pillar node id overflow, too many pillar nodes"); pillarNodes.setNode(nextPillarId, lat, lon, ele); int id = pillarNodeToId(nextPillarId); idsByOsmNodeIds.put(osmId, id); From 88fcf94ab07514cf3ea2b4b97c846ef99b3b3c6c Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 4 May 2023 20:07:59 +0200 Subject: [PATCH 066/165] OSMNodeData.nodeKVStorage: add missing create --- core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 1c274c82d08..38aa6e0aea4 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -90,7 +90,7 @@ public OSMNodeData(PointAccess nodeAccess, Directory directory) { nodeTagIndicesByOsmNodeIds = new GHLongIntBTree(200); nodesToBeSplit = new LongScatterSet(); - nodeKVStorage = new KVStorage(directory, false); + nodeKVStorage = new KVStorage(directory, false).create(100); } public boolean is3D() { From 17dcf52f5a0f673a0cee9a399f5aaca778ad5d68 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 6 May 2023 12:01:20 +0200 Subject: [PATCH 067/165] ferry: hgv=yes allows car even if car tagging is missing --- .../graphhopper/routing/util/parsers/CarAccessParser.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java index 1d70c9198a1..8e7bcb5a3b8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/CarAccessParser.java @@ -85,15 +85,16 @@ public WayAccess getAccess(ReaderWay way) { return WayAccess.CAN_SKIP; if (intendedValues.contains(firstValue) || // implied default is allowed only if foot and bicycle is not specified: - firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) + firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle") || + // if hgv is allowed than smaller trucks and cars are allowed too + way.hasTag("hgv", "yes")) return WayAccess.FERRY; } return WayAccess.CAN_SKIP; } - if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) { + if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) return WayAccess.CAN_SKIP; - } if ("track".equals(highwayValue) && !trackTypeValues.contains(way.getTag("tracktype"))) return WayAccess.CAN_SKIP; From aa09e14b11c5efbdc20236b884f2610aafddba41 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 8 May 2023 14:54:09 +0200 Subject: [PATCH 068/165] B-tree: Make space for values configurable (#2814) * initial working version * make to and from long more clear * make it working for negative keys and values * nextLong(bounds) only for more recent JDKs * fix javadoc * Use long for pillar node id stack variables * use long where it could be a pillar or tower node * simulate large amount of pillar nodes * remove second check for pillar nodes * use 0 as start again * minor * make empty value configurable * changes for review --------- Co-authored-by: easbar --- ...LongIntBTree.java => GHLongLongBTree.java} | 166 ++++++++---- .../{LongIntMap.java => LongLongMap.java} | 8 +- .../graphhopper/reader/osm/OSMNodeData.java | 102 +++---- .../graphhopper/reader/osm/PillarInfo.java | 29 +- .../graphhopper/reader/osm/SegmentNode.java | 4 +- .../reader/osm/WaySegmentParser.java | 8 +- .../graphhopper/coll/GHLongIntBTreeTest.java | 176 ------------ .../graphhopper/coll/GHLongLongBTreeTest.java | 254 ++++++++++++++++++ 8 files changed, 438 insertions(+), 309 deletions(-) rename core/src/main/java/com/graphhopper/coll/{GHLongIntBTree.java => GHLongLongBTree.java} (67%) rename core/src/main/java/com/graphhopper/coll/{LongIntMap.java => LongLongMap.java} (89%) delete mode 100644 core/src/test/java/com/graphhopper/coll/GHLongIntBTreeTest.java create mode 100644 core/src/test/java/com/graphhopper/coll/GHLongLongBTreeTest.java diff --git a/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java b/core/src/main/java/com/graphhopper/coll/GHLongLongBTree.java similarity index 67% rename from core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java rename to core/src/main/java/com/graphhopper/coll/GHLongLongBTree.java index 3d9d9a4c63f..df8c1d3a285 100644 --- a/core/src/main/java/com/graphhopper/coll/GHLongIntBTree.java +++ b/core/src/main/java/com/graphhopper/coll/GHLongLongBTree.java @@ -24,15 +24,14 @@ import java.util.Arrays; /** - * An in-memory simple B-Tree. Later we'll use DataAccess to allow on-disc storage for very large - * data sets. Delete not supported. - *

+ * An in-memory B-Tree with configurable value size (1-8 bytes). Delete not supported. + * (Later we could use DataAccess to allow on-disc storage for very large data sets.) * * @author Peter Karich */ -public class GHLongIntBTree implements LongIntMap { - private final static Logger logger = LoggerFactory.getLogger(GHLongIntBTree.class); - private final int noNumberValue = -1; +public class GHLongLongBTree implements LongLongMap { + private final static Logger logger = LoggerFactory.getLogger(GHLongLongBTree.class); + private final long emptyValue; private final int maxLeafEntries; private final int initLeafSize; private final int splitIndex; @@ -40,15 +39,23 @@ public class GHLongIntBTree implements LongIntMap { private long size; private int height; private BTreeEntry root; + private final int bytesPerValue; + private final long maxValue; - public GHLongIntBTree(int maxLeafEntries) { + public GHLongLongBTree(int maxLeafEntries, int bytesPerValue, long emptyValue) { this.maxLeafEntries = maxLeafEntries; - if (maxLeafEntries < 1) { + this.bytesPerValue = bytesPerValue; + if (bytesPerValue > 8) + throw new IllegalArgumentException("Values can have 8 bytes maximum but requested was " + bytesPerValue); + this.emptyValue = emptyValue; + + // reserve one bit for negative values + this.maxValue = (1L << (bytesPerValue * 8 - 1)) - 1; + if (maxLeafEntries < 1) throw new IllegalArgumentException("illegal maxLeafEntries:" + maxLeafEntries); - } - if (maxLeafEntries % 2 == 0) { + + if (maxLeafEntries % 2 == 0) maxLeafEntries++; - } splitIndex = maxLeafEntries / 2; if (maxLeafEntries < 10) { @@ -90,27 +97,29 @@ static int binarySearch(long[] keys, int start, int len, long key) { } @Override - public int put(long key, int value) { - if (key == noNumberValue) { - throw new IllegalArgumentException("Illegal key " + key); - } + public long put(long key, long value) { + if (value > maxValue) + throw new IllegalArgumentException("Value " + value + " exceeded max value: " + maxValue + + ". Increase bytesPerValue (" + bytesPerValue + ")"); + if (value == emptyValue) + throw new IllegalArgumentException("Value cannot be the 'empty value' " + emptyValue); ReturnValue rv = root.put(key, value); if (rv.tree != null) { height++; root = rv.tree; } - if (rv.oldValue == noNumberValue) { + if (rv.oldValue == null) { // successfully inserted size++; if (size % 1000000 == 0) optimize(); } - return rv.oldValue; + return rv.oldValue == null ? emptyValue : toLong(rv.oldValue); } @Override - public int get(long key) { + public long get(long key) { return root.get(key); } @@ -138,12 +147,8 @@ public void clear() { root = new BTreeEntry(initLeafSize, true); } - int getNoNumberValue() { - return noNumberValue; - } - - void flush() { - throw new IllegalStateException("not supported yet"); + public long getEmptyValue() { + return emptyValue; } private int getEntries() { @@ -166,33 +171,83 @@ public String toString() { return "Height:" + height() + ", entries:" + getEntries(); } + @Override + public long getMaxValue() { + return maxValue; + } + void print() { logger.info(root.toString(1)); } static class ReturnValue { - int oldValue; + byte[] oldValue; BTreeEntry tree; - public ReturnValue() { - } - - public ReturnValue(int oldValue) { + public ReturnValue(byte[] oldValue) { this.oldValue = oldValue; } } + long toLong(byte[] b) { + return toLong(b, 0); + } + + long toLong(byte[] bytes, int offset) { + long res = 0; + if (bytesPerValue == 8) res |= (long) bytes[offset + 7] << 56; + else if (bytesPerValue > 7) res |= ((long) bytes[offset + 7] << 56); + + if (bytesPerValue == 7) res |= (long) bytes[offset + 6] << 48; + else if (bytesPerValue > 6) res |= ((long) bytes[offset + 6] & 0xFF) << 48; + + if (bytesPerValue == 6) res |= (long) bytes[offset + 5] << 40; + else if (bytesPerValue > 5) res |= ((long) bytes[offset + 5] & 0xFF) << 40; + + if (bytesPerValue == 5) res |= (long) bytes[offset + 4] << 32; + else if (bytesPerValue > 4) res |= ((long) bytes[offset + 4] & 0xFF) << 32; + + if (bytesPerValue == 4) res |= (long) bytes[offset + 3] << 24; + else if (bytesPerValue > 3) res |= ((long) bytes[offset + 3] & 0xFF) << 24; + + if (bytesPerValue == 3) res |= (long) bytes[offset + 2] << 16; + else if (bytesPerValue > 2) res |= ((long) bytes[offset + 2] & 0xFF) << 16; + + if (bytesPerValue == 2) res |= (long) bytes[offset + 1] << 8; + else if (bytesPerValue > 1) res |= ((long) bytes[offset + 1] & 0xFF) << 8; + + res |= ((long) bytes[offset] & 0xff); + return res; + } + + final byte[] fromLong(long value) { + byte[] bytes = new byte[bytesPerValue]; + fromLong(bytes, value, 0); + return bytes; + } + + final void fromLong(byte[] bytes, long value, int offset) { + if (bytesPerValue > 7) bytes[offset + 7] = (byte) (value >> 56); + if (bytesPerValue > 6) bytes[offset + 6] = (byte) (value >> 48); + if (bytesPerValue > 5) bytes[offset + 5] = (byte) (value >> 40); + if (bytesPerValue > 4) bytes[offset + 4] = (byte) (value >> 32); + if (bytesPerValue > 3) bytes[offset + 3] = (byte) (value >> 24); + if (bytesPerValue > 2) bytes[offset + 2] = (byte) (value >> 16); + if (bytesPerValue > 1) bytes[offset + 1] = (byte) (value >> 8); + bytes[offset] = (byte) (value); + } + class BTreeEntry { int entrySize; long[] keys; - int[] values; + byte[] values; BTreeEntry[] children; boolean isLeaf; public BTreeEntry(int tmpSize, boolean leaf) { this.isLeaf = leaf; keys = new long[tmpSize]; - values = new int[tmpSize]; + values = new byte[tmpSize * bytesPerValue]; if (!isLeaf) { // in a b-tree we need one more entry to point to all children! @@ -204,12 +259,14 @@ public BTreeEntry(int tmpSize, boolean leaf) { * @return the old value which was associated with the specified key or if no update it * returns noNumberValue */ - ReturnValue put(long key, int newValue) { + ReturnValue put(long key, long newValue) { int index = binarySearch(keys, 0, entrySize, key); if (index >= 0) { // update - int oldValue = values[index]; - values[index] = newValue; + byte[] oldValue = new byte[bytesPerValue]; + System.arraycopy(values, index * bytesPerValue, oldValue, 0, bytesPerValue); + // copy newValue to values + fromLong(values, newValue, index * bytesPerValue); return new ReturnValue(oldValue); } @@ -217,23 +274,21 @@ ReturnValue put(long key, int newValue) { ReturnValue downTreeRV; if (isLeaf || children[index] == null) { // insert - downTreeRV = new ReturnValue(noNumberValue); + downTreeRV = new ReturnValue(null); downTreeRV.tree = checkSplitEntry(); if (downTreeRV.tree == null) { - insertKeyValue(index, key, newValue); + insertKeyValue(index, key, fromLong(newValue)); } else if (index <= splitIndex) { - downTreeRV.tree.children[0].insertKeyValue(index, key, newValue); + downTreeRV.tree.children[0].insertKeyValue(index, key, fromLong(newValue)); } else { - downTreeRV.tree.children[1].insertKeyValue(index - splitIndex - 1, key, newValue); + downTreeRV.tree.children[1].insertKeyValue(index - splitIndex - 1, key, fromLong(newValue)); } return downTreeRV; } downTreeRV = children[index].put(key, newValue); - if (downTreeRV.oldValue != noNumberValue) // only update - { + if (downTreeRV.oldValue != null) // only update return downTreeRV; - } if (downTreeRV.tree != null) { // split this treeEntry if it is too big @@ -274,7 +329,8 @@ BTreeEntry checkSplitEntry() { BTreeEntry newTree = new BTreeEntry(1, false); newTree.entrySize = 1; newTree.keys[0] = this.keys[splitIndex]; - newTree.values[0] = this.values[splitIndex]; + + System.arraycopy(this.values, splitIndex * bytesPerValue, newTree.values, 0, bytesPerValue); newTree.children[0] = newLeftChild; newTree.children[1] = newRightChild; return newTree; @@ -282,7 +338,7 @@ BTreeEntry checkSplitEntry() { void copy(BTreeEntry fromChild, BTreeEntry toChild, int from, int count) { System.arraycopy(fromChild.keys, from, toChild.keys, 0, count); - System.arraycopy(fromChild.values, from, toChild.values, 0, count); + System.arraycopy(fromChild.values, from * bytesPerValue, toChild.values, 0, count * bytesPerValue); if (!fromChild.isLeaf) { System.arraycopy(fromChild.children, from, toChild.children, 0, count + 1); } @@ -290,24 +346,24 @@ void copy(BTreeEntry fromChild, BTreeEntry toChild, int from, int count) { toChild.entrySize = count; } - void insertKeyValue(int index, long key, int newValue) { + void insertKeyValue(int index, long key, byte[] newValueFromIdx0) { ensureSize(entrySize + 1); int count = entrySize - index; if (count > 0) { System.arraycopy(keys, index, keys, index + 1, count); - System.arraycopy(values, index, values, index + 1, count); + System.arraycopy(values, index * bytesPerValue, values, index * bytesPerValue + bytesPerValue, count * bytesPerValue); if (!isLeaf) { System.arraycopy(children, index + 1, children, index + 2, count); } } keys[index] = key; - values[index] = newValue; + System.arraycopy(newValueFromIdx0, 0, values, index * bytesPerValue, bytesPerValue); entrySize++; } void insertTree(int index, BTreeEntry tree) { - insertKeyValue(index, tree.keys[0], tree.values[0]); + insertKeyValue(index, tree.keys[0], tree.values); if (!isLeaf) { // overwrite children children[index] = tree.children[0]; @@ -316,14 +372,14 @@ void insertTree(int index, BTreeEntry tree) { } } - int get(long key) { + long get(long key) { int index = binarySearch(keys, 0, entrySize, key); if (index >= 0) { - return values[index]; + return toLong(values, index * bytesPerValue); } index = ~index; if (isLeaf || children[index] == null) { - return noNumberValue; + return emptyValue; } return children[index].get(key); } @@ -362,7 +418,7 @@ void ensureSize(int size) { } int newSize = Math.min(maxLeafEntries, Math.max(size + 1, Math.round(size * factor))); keys = Arrays.copyOf(keys, newSize); - values = Arrays.copyOf(values, newSize); + values = Arrays.copyOf(values, newSize * bytesPerValue); if (!isLeaf) { children = Arrays.copyOf(children, newSize + 1); } @@ -372,7 +428,7 @@ void compact() { int tolerance = 1; if (entrySize + tolerance < keys.length) { keys = Arrays.copyOf(keys, entrySize); - values = Arrays.copyOf(values, entrySize); + values = Arrays.copyOf(values, entrySize * bytesPerValue); if (!isLeaf) { children = Arrays.copyOf(children, entrySize + 1); } @@ -393,11 +449,7 @@ String toString(int height) { if (i > 0) { str += ","; } - if (keys[i] == noNumberValue) { - str += "-"; - } else { - str += keys[i]; - } + str += keys[i]; } str += "\n"; if (!isLeaf) { diff --git a/core/src/main/java/com/graphhopper/coll/LongIntMap.java b/core/src/main/java/com/graphhopper/coll/LongLongMap.java similarity index 89% rename from core/src/main/java/com/graphhopper/coll/LongIntMap.java rename to core/src/main/java/com/graphhopper/coll/LongLongMap.java index 00bd2e0c505..33cad5705c6 100644 --- a/core/src/main/java/com/graphhopper/coll/LongIntMap.java +++ b/core/src/main/java/com/graphhopper/coll/LongLongMap.java @@ -20,13 +20,15 @@ /** * @author Peter Karich */ -public interface LongIntMap { - int put(long key, int value); +public interface LongLongMap { + long put(long key, long value); - int get(long key); + long get(long key); long getSize(); + long getMaxValue(); + void optimize(); int getMemoryUsage(); diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 38aa6e0aea4..7749ce266de 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -20,8 +20,8 @@ import com.carrotsearch.hppc.LongScatterSet; import com.carrotsearch.hppc.LongSet; -import com.graphhopper.coll.GHLongIntBTree; -import com.graphhopper.coll.LongIntMap; +import com.graphhopper.coll.GHLongLongBTree; +import com.graphhopper.coll.LongLongMap; import com.graphhopper.reader.ReaderNode; import com.graphhopper.search.KVStorage; import com.graphhopper.storage.Directory; @@ -32,17 +32,16 @@ import java.util.Collections; import java.util.Map; import java.util.function.DoubleSupplier; -import java.util.function.IntUnaryOperator; +import java.util.function.LongUnaryOperator; import java.util.stream.Collectors; /** * This class stores OSM node data while reading an OSM file in {@link WaySegmentParser}. It is not trivial to do this * in a memory-efficient way. We use the following approach: *

- * - For each OSM node we store an integer id that points to the nodes coordinates. We use both positive and negative
- *   ids to make use of the full integer range (~4 billion nodes). We separate nodes into (potential) tower nodes and
- *   pillar nodes. We use the negative ids for tower nodes and positive ids for pillar nodes. In the future we might
- *   have to consider the fact that there are more pillar nodes than tower nodes and use a different separation.
+ * - For each OSM node we store an id that points to the nodes coordinates. We separate nodes into
+ *   (potential) tower nodes and pillar nodes. We use the negative ids for tower nodes and positive
+ *   ids for pillar nodes. The tower nodes are limited to ~2 billion nodes as we later use the ID as positive integer.
  * - We reserve a few special ids like {@link #JUNCTION_NODE} to distinguish the different node types when we read the
  *   OSM file for the first time (pass1) in {@link WaySegmentParser}. We then assign actual ids in the second pass.
  * - We store the node coordinates for tower and pillar nodes in different places. The pillar node storage is only
@@ -54,21 +53,21 @@
  * 
*/ class OSMNodeData { - static final int JUNCTION_NODE = -2; - static final int EMPTY_NODE = -1; - static final int END_NODE = 0; - static final int INTERMEDIATE_NODE = 1; - static final int CONNECTION_NODE = 2; + static final long JUNCTION_NODE = -2; + static final long EMPTY_NODE = -1; + static final long END_NODE = 0; + static final long INTERMEDIATE_NODE = 1; + static final long CONNECTION_NODE = 2; // this map stores our internal node id for each OSM node - private final LongIntMap idsByOsmNodeIds; + private final LongLongMap idsByOsmNodeIds; // here we store node coordinates, separated for pillar and tower nodes private final PillarInfo pillarNodes; private final PointAccess towerNodes; // this map stores an index for each OSM node we keep the node tags of. a value of -1 means there is no entry yet. - private final LongIntMap nodeTagIndicesByOsmNodeIds; + private final LongLongMap nodeTagIndicesByOsmNodeIds; // stores node tags private final KVStorage nodeKVStorage; @@ -76,19 +75,19 @@ class OSMNodeData { private final LongSet nodesToBeSplit; private int nextTowerId = 0; - private int nextPillarId = 0; + private long nextPillarId = 0; // we use negative ids to create artificial OSM node ids private long nextArtificialOSMNodeId = -Long.MAX_VALUE; public OSMNodeData(PointAccess nodeAccess, Directory directory) { - // We use GHLongIntBTree, because it is based on a tree, not an array, so it can store as many entries as there - // are longs. This also makes it memory efficient, because there is no need to pre-allocate memory for empty - // entries, and it also avoids allocating a new array and copying into it when increasing the size. - idsByOsmNodeIds = new GHLongIntBTree(200); + // We use a b-tree that can store as many entries as there are longs. A tree is also more + // memory efficient, because there is no waste for empty entries, and it also avoids + // allocating big arrays when growing the size. + idsByOsmNodeIds = new GHLongLongBTree(200, 5, EMPTY_NODE); towerNodes = nodeAccess; pillarNodes = new PillarInfo(towerNodes.is3D(), directory); - nodeTagIndicesByOsmNodeIds = new GHLongIntBTree(200); + nodeTagIndicesByOsmNodeIds = new GHLongLongBTree(200, 4, -1); nodesToBeSplit = new LongScatterSet(); nodeKVStorage = new KVStorage(directory, false).create(100); } @@ -101,30 +100,30 @@ public boolean is3D() { * @return the internal id stored for the given OSM node id. use {@link #isTowerNode} etc. to find out what this * id means */ - public int getId(long osmNodeId) { + public long getId(long osmNodeId) { return idsByOsmNodeIds.get(osmNodeId); } - public static boolean isTowerNode(int id) { + public static boolean isTowerNode(long id) { // tower nodes are indexed -3, -4, -5, ... return id < JUNCTION_NODE; } - public static boolean isPillarNode(int id) { + public static boolean isPillarNode(long id) { // pillar nodes are indexed 3, 4, 5, .. return id > CONNECTION_NODE; } - public static boolean isNodeId(int id) { + public static boolean isNodeId(long id) { return id > CONNECTION_NODE || id < JUNCTION_NODE; } - public void setOrUpdateNodeType(long osmNodeId, int newNodeType, IntUnaryOperator nodeTypeUpdate) { - int curr = idsByOsmNodeIds.get(osmNodeId); + public void setOrUpdateNodeType(long osmNodeId, long newNodeType, LongUnaryOperator nodeTypeUpdate) { + long curr = idsByOsmNodeIds.get(osmNodeId); if (curr == EMPTY_NODE) idsByOsmNodeIds.put(osmNodeId, newNodeType); else - idsByOsmNodeIds.put(osmNodeId, nodeTypeUpdate.applyAsInt(curr)); + idsByOsmNodeIds.put(osmNodeId, nodeTypeUpdate.applyAsLong(curr)); } /** @@ -151,8 +150,8 @@ public long getNodeTagCapacity() { * * @return the node type this OSM node was associated with before this method was called */ - public int addCoordinatesIfMapped(long osmNodeId, double lat, double lon, DoubleSupplier getEle) { - int nodeType = idsByOsmNodeIds.get(osmNodeId); + public long addCoordinatesIfMapped(long osmNodeId, double lat, double lon, DoubleSupplier getEle) { + long nodeType = idsByOsmNodeIds.get(osmNodeId); if (nodeType == EMPTY_NODE) return nodeType; else if (nodeType == JUNCTION_NODE || nodeType == CONNECTION_NODE) @@ -164,19 +163,22 @@ else if (nodeType == INTERMEDIATE_NODE || nodeType == END_NODE) return nodeType; } - private int addTowerNode(long osmId, double lat, double lon, double ele) { + private long addTowerNode(long osmId, double lat, double lon, double ele) { towerNodes.setNode(nextTowerId, lat, lon, ele); - int id = towerNodeToId(nextTowerId); + long id = towerNodeToId(nextTowerId); idsByOsmNodeIds.put(osmId, id); nextTowerId++; + if (nextTowerId == Integer.MAX_VALUE) + throw new IllegalStateException("Tower node id overflow, too many tower nodes"); return id; } - private int addPillarNode(long osmId, double lat, double lon, double ele) { - if (nextPillarId < 0) - throw new IllegalStateException("Pillar node id overflow, too many pillar nodes"); + private long addPillarNode(long osmId, double lat, double lon, double ele) { + long id = pillarNodeToId(nextPillarId); + if (id > idsByOsmNodeIds.getMaxValue()) + throw new IllegalStateException("id for pillar node cannot be bigger than " + idsByOsmNodeIds.getMaxValue()); + pillarNodes.setNode(nextPillarId, lat, lon, ele); - int id = pillarNodeToId(nextPillarId); idsByOsmNodeIds.put(osmId, id); nextPillarId++; return id; @@ -194,14 +196,14 @@ SegmentNode addCopyOfNode(SegmentNode node) { final long newOsmId = nextArtificialOSMNodeId++; if (idsByOsmNodeIds.put(newOsmId, INTERMEDIATE_NODE) != EMPTY_NODE) throw new IllegalStateException("Artificial osm node id already exists: " + newOsmId); - int id = addPillarNode(newOsmId, point.getLat(), point.getLon(), point.getEle()); + long id = addPillarNode(newOsmId, point.getLat(), point.getLon(), point.getEle()); return new SegmentNode(newOsmId, id, node.tags); } - int convertPillarToTowerNode(int id, long osmNodeId) { + long convertPillarToTowerNode(long id, long osmNodeId) { if (!isPillarNode(id)) throw new IllegalArgumentException("Not a pillar node: " + id); - int pillar = idToPillarNode(id); + long pillar = idToPillarNode(id); double lat = pillarNodes.getLat(pillar); double lon = pillarNodes.getLon(pillar); double ele = pillarNodes.getEle(pillar); @@ -212,14 +214,14 @@ int convertPillarToTowerNode(int id, long osmNodeId) { return addTowerNode(osmNodeId, lat, lon, ele); } - public GHPoint3D getCoordinates(int id) { + public GHPoint3D getCoordinates(long id) { if (isTowerNode(id)) { int tower = idToTowerNode(id); return towerNodes.is3D() ? new GHPoint3D(towerNodes.getLat(tower), towerNodes.getLon(tower), towerNodes.getEle(tower)) : new GHPoint3D(towerNodes.getLat(tower), towerNodes.getLon(tower), Double.NaN); } else if (isPillarNode(id)) { - int pillar = idToPillarNode(id); + long pillar = idToPillarNode(id); return pillarNodes.is3D() ? new GHPoint3D(pillarNodes.getLat(pillar), pillarNodes.getLon(pillar), pillarNodes.getEle(pillar)) : new GHPoint3D(pillarNodes.getLat(pillar), pillarNodes.getLon(pillar), Double.NaN); @@ -227,7 +229,7 @@ public GHPoint3D getCoordinates(int id) { return null; } - public void addCoordinatesToPointList(int id, PointList pointList) { + public void addCoordinatesToPointList(long id, PointList pointList) { double lat, lon; double ele = Double.NaN; if (isTowerNode(id)) { @@ -237,7 +239,7 @@ public void addCoordinatesToPointList(int id, PointList pointList) { if (towerNodes.is3D()) ele = towerNodes.getEle(tower); } else if (isPillarNode(id)) { - int pillar = idToPillarNode(id); + long pillar = idToPillarNode(id); lat = pillarNodes.getLat(pillar); lon = pillarNodes.getLon(pillar); if (pillarNodes.is3D()) @@ -248,7 +250,7 @@ public void addCoordinatesToPointList(int id, PointList pointList) { } public void setTags(ReaderNode node) { - int tagIndex = nodeTagIndicesByOsmNodeIds.get(node.getId()); + int tagIndex = Math.toIntExact(nodeTagIndicesByOsmNodeIds.get(node.getId())); if (tagIndex == -1) { long pointer = nodeKVStorage.add(node.getTags().entrySet().stream().map(m -> new KVStorage.KeyValue(m.getKey(), m.getValue() instanceof String ? KVStorage.cutString((String) m.getValue()) : m.getValue())). @@ -262,7 +264,7 @@ public void setTags(ReaderNode node) { } public Map getTags(long osmNodeId) { - int tagIndex = nodeTagIndicesByOsmNodeIds.get(osmNodeId); + int tagIndex = Math.toIntExact(nodeTagIndicesByOsmNodeIds.get(osmNodeId)); if (tagIndex < 0) return Collections.emptyMap(); return nodeKVStorage.getMap(tagIndex); @@ -276,19 +278,21 @@ public void release() { nodesToBeSplit.clear(); } - public int towerNodeToId(int towerId) { + public long towerNodeToId(long towerId) { return -towerId - 3; } - public int idToTowerNode(int id) { - return -id - 3; + public int idToTowerNode(long id) { + if (-id - 3L > Integer.MAX_VALUE) + throw new IllegalStateException("Invalid tower node id: " + id + ", limit exceeded"); + return Math.toIntExact(-id - 3); } - public int pillarNodeToId(int pillarId) { + public long pillarNodeToId(long pillarId) { return pillarId + 3; } - public int idToPillarNode(int id) { + public long idToPillarNode(long id) { return id - 3; } diff --git a/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java b/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java index 4439d90638f..3aca5a49a44 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java +++ b/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java @@ -28,7 +28,7 @@ * * @author Peter Karich */ -public class PillarInfo implements PointAccess { +public class PillarInfo { private static final int LAT = 0 * 4, LON = 1 * 4, ELE = 2 * 4; private final boolean enabled3D; private final DataAccess da; @@ -42,26 +42,22 @@ public PillarInfo(boolean enabled3D, Directory dir) { this.rowSizeInBytes = getDimension() * 4; } - @Override public boolean is3D() { return enabled3D; } - @Override public int getDimension() { return enabled3D ? 3 : 2; } - @Override - public void ensureNode(int nodeId) { - long tmp = (long) nodeId * rowSizeInBytes; + public void ensureNode(long nodeId) { + long tmp = nodeId * rowSizeInBytes; da.ensureCapacity(tmp + rowSizeInBytes); } - @Override - public void setNode(int nodeId, double lat, double lon, double ele) { + public void setNode(long nodeId, double lat, double lon, double ele) { ensureNode(nodeId); - long tmp = (long) nodeId * rowSizeInBytes; + long tmp = nodeId * rowSizeInBytes; da.setInt(tmp + LAT, Helper.degreeToInt(lat)); da.setInt(tmp + LON, Helper.degreeToInt(lon)); @@ -69,24 +65,21 @@ public void setNode(int nodeId, double lat, double lon, double ele) { da.setInt(tmp + ELE, Helper.eleToInt(ele)); } - @Override - public double getLat(int id) { - int intVal = da.getInt((long) id * rowSizeInBytes + LAT); + public double getLat(long id) { + int intVal = da.getInt(id * rowSizeInBytes + LAT); return Helper.intToDegree(intVal); } - @Override - public double getLon(int id) { - int intVal = da.getInt((long) id * rowSizeInBytes + LON); + public double getLon(long id) { + int intVal = da.getInt(id * rowSizeInBytes + LON); return Helper.intToDegree(intVal); } - @Override - public double getEle(int id) { + public double getEle(long id) { if (!is3D()) return Double.NaN; - int intVal = da.getInt((long) id * rowSizeInBytes + ELE); + int intVal = da.getInt(id * rowSizeInBytes + ELE); return Helper.intToEle(intVal); } diff --git a/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java b/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java index cbd2b8b6288..7b12520df94 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java +++ b/core/src/main/java/com/graphhopper/reader/osm/SegmentNode.java @@ -22,10 +22,10 @@ class SegmentNode { long osmNodeId; - int id; + long id; Map tags; - public SegmentNode(long osmNodeId, int id, Map tags) { + public SegmentNode(long osmNodeId, long id, Map tags) { this.osmNodeId = osmNodeId; this.id = id; this.tags = tags; diff --git a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java index 2f5f8c3ff5d..391975a00da 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java +++ b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java @@ -206,7 +206,7 @@ public void handleNode(ReaderNode node) { LOGGER.info("pass2 - processed nodes: " + nf(nodeCounter) + ", accepted nodes: " + nf(acceptedNodes) + ", " + Helper.getMemInfo()); - int nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), () -> elevationProvider.getEle(node)); + long nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), () -> elevationProvider.getEle(node)); if (nodeType == EMPTY_NODE) return; @@ -348,7 +348,7 @@ void handleSegment(List segment, ReaderWay way) { int to = -1; for (int i = 0; i < segment.size(); i++) { SegmentNode node = segment.get(i); - int id = node.id; + long id = node.id; if (!isNodeId(id)) throw new IllegalStateException("Invalid id for node: " + node.osmNodeId + " when handling segment " + segment + " for way: " + way.getId()); if (isPillarNode(id) && (i == 0 || i == segment.size() - 1)) { @@ -387,9 +387,9 @@ public void onFinish() { } public int getInternalNodeIdOfOSMNode(long nodeOsmId) { - int id = nodeData.getId(nodeOsmId); + long id = nodeData.getId(nodeOsmId); if (isTowerNode(id)) - return -id - 3; + return -((int) id) - 3; return -1; } } diff --git a/core/src/test/java/com/graphhopper/coll/GHLongIntBTreeTest.java b/core/src/test/java/com/graphhopper/coll/GHLongIntBTreeTest.java deleted file mode 100644 index 14cb617cb31..00000000000 --- a/core/src/test/java/com/graphhopper/coll/GHLongIntBTreeTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.graphhopper.coll; - -import org.junit.jupiter.api.Test; - -import java.util.LinkedHashSet; -import java.util.Random; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author Peter Karich - */ -public class GHLongIntBTreeTest { - @Test - public void testThrowException_IfPutting_NoNumber() { - GHLongIntBTree instance = new GHLongIntBTree(2); - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> instance.put(-1, 1)); - assertTrue(ex.getMessage().contains("Illegal key -1")); - } - - @Test - public void testEmptyValueIfMissing() { - GHLongIntBTree instance = new GHLongIntBTree(2); - long key = 9485854858458484L; - instance.put(key, 21); - assertEquals(21, instance.get(key)); - assertEquals(-1, instance.get(404)); - } - - @Test - public void testTwoSplits() { - GHLongIntBTree instance = new GHLongIntBTree(3); - instance.put(1, 2); - instance.put(2, 4); - instance.put(3, 6); - - assertEquals(1, instance.height()); - instance.put(4, 8); - assertEquals(2, instance.height()); - - instance.put(5, 10); - instance.put(6, 12); - instance.put(7, 14); - instance.put(8, 16); - instance.put(9, 18); - - assertEquals(2, instance.height()); - instance.put(10, 20); - assertEquals(3, instance.height()); - - assertEquals(3, instance.height()); - assertEquals(10, instance.getSize()); - assertEquals(0, instance.getMemoryUsage()); - - check(instance, 1); - } - - @Test - public void testSplitAndOverwrite() { - GHLongIntBTree instance = new GHLongIntBTree(3); - instance.put(1, 2); - instance.put(2, 4); - instance.put(3, 6); - instance.put(2, 5); - - assertEquals(3, instance.getSize()); - assertEquals(1, instance.height()); - - assertEquals(5, instance.get(2)); - assertEquals(6, instance.get(3)); - } - - void check(GHLongIntBTree instance, int from) { - for (int i = from; i < instance.getSize(); i++) { - assertEquals(i * 2, instance.get(i)); - } - } - - @Test - public void testPut() { - GHLongIntBTree instance = new GHLongIntBTree(3); - instance.put(2, 4); - instance.put(7, 14); - instance.put(5, 10); - instance.put(6, 12); - instance.put(3, 6); - instance.put(4, 8); - instance.put(9, 18); - instance.put(0, 0); - - instance.put(1, 2); - instance.put(8, 16); - - check(instance, 0); - - instance.put(10, 20); - instance.put(11, 22); - - assertEquals(12, instance.getSize()); - assertEquals(3, instance.height()); - - assertEquals(12, instance.get(6)); - check(instance, 0); - } - - @Test - public void testUpdate() { - GHLongIntBTree instance = new GHLongIntBTree(2); - int result = instance.put(100, 10); - assertEquals(instance.getNoNumberValue(), result); - - result = instance.get(100); - assertEquals(10, result); - - result = instance.put(100, 9); - assertEquals(10, result); - - result = instance.get(100); - assertEquals(9, result); - } - - @Test - public void testRandom() { - for (int j = 3; j < 12; j += 4) { - GHLongIntBTree instance = new GHLongIntBTree(j); - final int size = 500; - final long seed = System.nanoTime(); - Random rand = new Random(seed); - Set addedValues = new LinkedHashSet<>(size); - for (int i = 0; i < size; i++) { - int val = rand.nextInt(size); - addedValues.add(val); - try { - instance.put(val, val); -// System.out.println(i + "--------------" + val); -// instance.print(); -// System.out.println("\n\n"); - } catch (Exception ex) { - ex.printStackTrace(); - fail(j + "| Problem with " + i + ", seed: " + seed + " " + ex); - } - - assertEquals(addedValues.size(), instance.getSize(), j + "| Size not equal to set! In " + i + " added " + val); - } - int i = 0; - for (int val : addedValues) { - assertEquals(val, instance.get(val), j + "| Problem with " + i); - i++; - } - instance.optimize(); - i = 0; - for (int val : addedValues) { - assertEquals(val, instance.get(val), j + "| Problem with " + i); - i++; - } - } - } -} diff --git a/core/src/test/java/com/graphhopper/coll/GHLongLongBTreeTest.java b/core/src/test/java/com/graphhopper/coll/GHLongLongBTreeTest.java new file mode 100644 index 00000000000..8aadeb1df32 --- /dev/null +++ b/core/src/test/java/com/graphhopper/coll/GHLongLongBTreeTest.java @@ -0,0 +1,254 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.coll; + +import org.junit.jupiter.api.Test; + +import java.util.LinkedHashSet; +import java.util.Random; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Peter Karich + */ +public class GHLongLongBTreeTest { + + @Test + public void testThrowException_IfPutting_NoNumber() { + GHLongLongBTree instance = new GHLongLongBTree(2, 4, -1); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> instance.put(1, -1)); + assertTrue(ex.getMessage().contains("Value cannot be the 'empty value' -1")); + } + + @Test + public void testEmptyValueIfMissing() { + GHLongLongBTree instance = new GHLongLongBTree(2, 4, -1); + long key = 9485854858458484L; + assertEquals(-1, instance.put(key, 21)); + assertEquals(21, instance.get(key)); + assertEquals(-1, instance.get(404)); + } + + @Test + public void testTwoSplits() { + GHLongLongBTree instance = new GHLongLongBTree(3, 4, -1); + instance.put(1, 2); + instance.put(2, 4); + instance.put(3, 6); + + assertEquals(1, instance.height()); + instance.put(4, 8); + assertEquals(2, instance.height()); + + instance.put(5, 10); + instance.put(6, 12); + instance.put(7, 14); + instance.put(8, 16); + instance.put(9, 18); + + assertEquals(2, instance.height()); + instance.put(10, 20); + assertEquals(3, instance.height()); + + assertEquals(3, instance.height()); + assertEquals(10, instance.getSize()); + assertEquals(0, instance.getMemoryUsage()); + + check(instance, 1); + } + + @Test + public void testSplitAndOverwrite() { + GHLongLongBTree instance = new GHLongLongBTree(3, 4, -1); + instance.put(1, 2); + instance.put(2, 4); + instance.put(3, 6); + instance.put(2, 5); + + assertEquals(3, instance.getSize()); + assertEquals(1, instance.height()); + + assertEquals(5, instance.get(2)); + assertEquals(6, instance.get(3)); + } + + void check(GHLongLongBTree instance, int from) { + for (int i = from; i < instance.getSize(); i++) { + assertEquals(i * 2L, instance.get(i), "idx:" + i); + } + } + + @Test + public void testPut() { + GHLongLongBTree instance = new GHLongLongBTree(3, 4, -1); + instance.put(2, 4); + assertEquals(4, instance.get(2)); + + instance.put(7, 14); + assertEquals(4, instance.get(2)); + assertEquals(14, instance.get(7)); + + instance.put(5, 10); + instance.put(6, 12); + instance.put(3, 6); + instance.put(4, 8); + instance.put(9, 18); + instance.put(0, 0); + instance.put(1, 2); + instance.put(8, 16); + + check(instance, 0); + + instance.put(10, 20); + instance.put(11, 22); + + assertEquals(12, instance.getSize()); + assertEquals(3, instance.height()); + + assertEquals(12, instance.get(6)); + check(instance, 0); + } + + @Test + public void testUpdate() { + GHLongLongBTree instance = new GHLongLongBTree(2, 4, -1); + long result = instance.put(100, 10); + assertEquals(instance.getEmptyValue(), result); + + result = instance.get(100); + assertEquals(10, result); + + result = instance.put(100, 9); + assertEquals(10, result); + + result = instance.get(100); + assertEquals(9, result); + } + + @Test + public void testNegativeValues() { + GHLongLongBTree instance = new GHLongLongBTree(2, 5, -1); + + // negative => two's complement + byte[] bytes = instance.fromLong(-3); + assertEquals(-3, instance.toLong(bytes)); + + instance.put(0, -3); + instance.put(4, -2); + instance.put(3, Integer.MIN_VALUE); + instance.put(2, 2L * Integer.MIN_VALUE); + instance.put(1, 4L * Integer.MIN_VALUE); + + assertEquals(-3, instance.get(0)); + assertEquals(-2, instance.get(4)); + assertEquals(4L * Integer.MIN_VALUE, instance.get(1)); + assertEquals(2L * Integer.MIN_VALUE, instance.get(2)); + assertEquals(Integer.MIN_VALUE, instance.get(3)); + } + + @Test + public void testNegativeKey() { + GHLongLongBTree instance = new GHLongLongBTree(2, 5, -1); + + instance.put(-3, 0); + instance.put(-2, 4); + instance.put(Integer.MIN_VALUE, 3); + instance.put(2L * Integer.MIN_VALUE, 2); + instance.put(4L * Integer.MIN_VALUE, 1); + + assertEquals(0, instance.get(-3)); + assertEquals(4, instance.get(-2)); + assertEquals(1, instance.get(4L * Integer.MIN_VALUE)); + assertEquals(2, instance.get(2L * Integer.MIN_VALUE)); + assertEquals(3, instance.get(Integer.MIN_VALUE)); + } + + @Test + public void testInternalFromToLong() { + Random rand = new Random(0); + for (int byteCnt = 4; byteCnt < 9; byteCnt++) { + for (int i = 0; i < 1000; i++) { + GHLongLongBTree instance = new GHLongLongBTree(2, byteCnt, -1); + long val = rand.nextLong() % instance.getMaxValue(); + byte[] bytes = instance.fromLong(val); + assertEquals(val, instance.toLong(bytes)); + } + } + } + + @Test + public void testDifferentEmptyValue() { + GHLongLongBTree instance = new GHLongLongBTree(2, 3, -2); + instance.put(123, -1); + instance.put(12, 2); + assertEquals(-2, instance.get(1234)); + assertEquals(-1, instance.get(123)); + assertEquals(2, instance.get(12)); + } + + @Test + public void testLargeValue() { + GHLongLongBTree instance = new GHLongLongBTree(2, 5, -1); + for (int key = 0; key < 100; key++) { + long val = 1L << 32 - 1; + for (int i = 0; i < 8; i++) { + instance.put(key, val); + assertEquals(val, instance.get(key), "i:" + i + ", key:" + key + ", val:" + val); + val *= 2; + } + } + } + + @Test + public void testRandom() { + final long seed = System.nanoTime(); + Random rand = new Random(seed); + final int size = 10_000; + for (int bytesPerValue = 4; bytesPerValue <= 8; bytesPerValue++) { + for (int j = 3; j < 12; j += 4) { + GHLongLongBTree instance = new GHLongLongBTree(j, bytesPerValue, -1); + Set addedValues = new LinkedHashSet<>(size); + for (int i = 0; i < size; i++) { + int val = rand.nextInt(); + addedValues.add(val); + try { + instance.put(val, val); + } catch (Exception ex) { + ex.printStackTrace(); + fail(j + "| Problem with " + i + ", seed: " + seed + " " + ex); + } + + assertEquals(addedValues.size(), instance.getSize(), j + "| Size not equal to set! In " + i + " added " + val); + } + int i = 0; + for (int val : addedValues) { + assertEquals(val, instance.get(val), j + "| Problem with " + i); + i++; + } + instance.optimize(); + i = 0; + for (int val : addedValues) { + assertEquals(val, instance.get(val), j + "| Problem with " + i); + i++; + } + } + } + } +} From ac64643383c86e236355d5e19f307ebdce4b4a6d Mon Sep 17 00:00:00 2001 From: Lukas Weber <32765578+lukasalexanderweber@users.noreply.github.com> Date: Mon, 8 May 2023 14:56:32 +0200 Subject: [PATCH 069/165] clarify foot access parser (#2801) --- .../util/parsers/FootAccessParser.java | 40 ++++++++----------- .../util/parsers/WheelchairAccessParser.java | 18 +-------- 2 files changed, 19 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java index e2a4d4553d5..6e9bb411193 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/FootAccessParser.java @@ -30,9 +30,7 @@ public class FootAccessParser extends AbstractAccessParser implements TagParser { - final Set safeHighwayTags = new HashSet<>(); final Set allowedHighwayTags = new HashSet<>(); - final Set avoidHighwayTags = new HashSet<>(); final Set allowedSacScale = new HashSet<>(); protected HashSet sidewalkValues = new HashSet<>(5); protected Map routeMap = new HashMap<>(); @@ -58,27 +56,23 @@ protected FootAccessParser(BooleanEncodedValue accessEnc) { barriers.add("fence"); - safeHighwayTags.add("footway"); - safeHighwayTags.add("path"); - safeHighwayTags.add("steps"); - safeHighwayTags.add("pedestrian"); - safeHighwayTags.add("living_street"); - safeHighwayTags.add("track"); - safeHighwayTags.add("residential"); - safeHighwayTags.add("service"); - safeHighwayTags.add("platform"); - - avoidHighwayTags.add("trunk"); - avoidHighwayTags.add("trunk_link"); - avoidHighwayTags.add("primary"); - avoidHighwayTags.add("primary_link"); - avoidHighwayTags.add("secondary"); - avoidHighwayTags.add("secondary_link"); - avoidHighwayTags.add("tertiary"); - avoidHighwayTags.add("tertiary_link"); - - allowedHighwayTags.addAll(safeHighwayTags); - allowedHighwayTags.addAll(avoidHighwayTags); + allowedHighwayTags.add("footway"); + allowedHighwayTags.add("path"); + allowedHighwayTags.add("steps"); + allowedHighwayTags.add("pedestrian"); + allowedHighwayTags.add("living_street"); + allowedHighwayTags.add("track"); + allowedHighwayTags.add("residential"); + allowedHighwayTags.add("service"); + allowedHighwayTags.add("platform"); + allowedHighwayTags.add("trunk"); + allowedHighwayTags.add("trunk_link"); + allowedHighwayTags.add("primary"); + allowedHighwayTags.add("primary_link"); + allowedHighwayTags.add("secondary"); + allowedHighwayTags.add("secondary_link"); + allowedHighwayTags.add("tertiary"); + allowedHighwayTags.add("tertiary_link"); allowedHighwayTags.add("cycleway"); allowedHighwayTags.add("unclassified"); allowedHighwayTags.add("road"); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java index 83fa8e039d3..a0836292904 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/WheelchairAccessParser.java @@ -33,22 +33,8 @@ protected WheelchairAccessParser(BooleanEncodedValue accessEnc) { barriers.add("kissing_gate"); barriers.add("stile"); - safeHighwayTags.add("footway"); - safeHighwayTags.add("pedestrian"); - safeHighwayTags.add("living_street"); - safeHighwayTags.add("residential"); - safeHighwayTags.add("service"); - safeHighwayTags.add("platform"); - - safeHighwayTags.remove("steps"); - safeHighwayTags.remove("track"); - - allowedHighwayTags.clear(); - allowedHighwayTags.addAll(safeHighwayTags); - allowedHighwayTags.addAll(avoidHighwayTags); - allowedHighwayTags.add("cycleway"); - allowedHighwayTags.add("unclassified"); - allowedHighwayTags.add("road"); + allowedHighwayTags.remove("steps"); + allowedHighwayTags.remove("track"); excludeSurfaces.add("cobblestone"); excludeSurfaces.add("gravel"); From 67476095328996ded5956708cf9bf5c0b129900a Mon Sep 17 00:00:00 2001 From: ratrun Date: Mon, 8 May 2023 15:10:25 +0200 Subject: [PATCH 070/165] De-prioritise steps for bicycles (#2804) * De-prioritise steps for bicycles, fixes #2803 original discovery Also use MIN_SPEED for highway=steps in the mtb profile * Don't explicitly call setHighwaySpeed for Mountainbike for values which are used in BikeCommonAverageSpeedParser * De-prioritise steps for bicycles to BAD * Also initialize the avoidHighwayTags with BAD just in order to avoid confusion. * Remove steps from the avoidHighwayTags map --- .../util/parsers/BikeCommonAverageSpeedParser.java | 5 ++--- .../util/parsers/BikeCommonPriorityParser.java | 6 ++++-- .../parsers/MountainBikeAverageSpeedParser.java | 4 ---- .../routing/RoutingAlgorithmWithOSMTest.java | 14 +++++++------- .../util/parsers/AbstractBikeTagParserTester.java | 10 ++++++++++ .../routing/util/parsers/BikeTagParserTest.java | 6 +++--- .../util/parsers/MountainBikeTagParserTest.java | 4 ---- .../RouteResourceProfileSelectionTest.java | 2 +- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java index cb93ddb3018..2a9e1ceaf3c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonAverageSpeedParser.java @@ -73,8 +73,7 @@ protected BikeCommonAverageSpeedParser(DecimalEncodedValue speedEnc, EnumEncoded setHighwaySpeed("living_street", PUSHING_SECTION_SPEED); setHighwaySpeed("steps", MIN_SPEED); - final int CYCLEWAY_SPEED = 18; // Make sure cycleway and path use same speed value, see #634 - setHighwaySpeed("cycleway", CYCLEWAY_SPEED); + setHighwaySpeed("cycleway", 18); setHighwaySpeed("path", 10); setHighwaySpeed("footway", 6); setHighwaySpeed("platform", PUSHING_SECTION_SPEED); @@ -171,7 +170,7 @@ int getSpeed(ReaderWay way) { // Under certain conditions we need to increase the speed of pushing sections to the speed of a "highway=cycleway" else if (way.hasTag("highway", pushingSectionsHighways) && ((way.hasTag("foot", "yes") && way.hasTag("segregated", "yes")) - || (way.hasTag("bicycle", intendedValues)))) + || (way.hasTag("bicycle", intendedValues)) && !way.hasTag("highway", "steps"))) highwaySpeed = getHighwaySpeed("cycleway"); String s = way.getTag("surface"); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java index 8648f6af775..e391c944811 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/BikeCommonPriorityParser.java @@ -75,7 +75,6 @@ protected BikeCommonPriorityParser(DecimalEncodedValue priorityEnc, DecimalEncod avoidHighwayTags.put("primary_link", BAD); avoidHighwayTags.put("secondary", AVOID); avoidHighwayTags.put("secondary_link", AVOID); - avoidHighwayTags.put("steps", AVOID); avoidHighwayTags.put("bridleway", AVOID); routeMap.put(INTERNATIONAL, BEST.getValue()); @@ -200,13 +199,16 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap w PriorityCode pushingSectionPrio = SLIGHT_AVOID; if (way.hasTag("bicycle", "yes") || way.hasTag("bicycle", "permissive")) pushingSectionPrio = PREFER; - if (isDesignated(way)) + if (isDesignated(way) && (!way.hasTag("highway","steps"))) pushingSectionPrio = VERY_NICE; if (way.hasTag("foot", "yes")) { pushingSectionPrio = pushingSectionPrio.worse(); if (way.hasTag("segregated", "yes")) pushingSectionPrio = pushingSectionPrio.better(); } + if (way.hasTag("highway","steps")) { + pushingSectionPrio = BAD; + } weightToPrioMap.put(100d, pushingSectionPrio); } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAverageSpeedParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAverageSpeedParser.java index 650f72da2e8..ca61a94e125 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAverageSpeedParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/MountainBikeAverageSpeedParser.java @@ -35,12 +35,8 @@ protected MountainBikeAverageSpeedParser(DecimalEncodedValue speedEnc, EnumEncod setSurfaceSpeed("sand", 10); setSurfaceSpeed("wood", 10); - setHighwaySpeed("living_street", PUSHING_SECTION_SPEED); - setHighwaySpeed("steps", PUSHING_SECTION_SPEED); - setHighwaySpeed("path", 18); setHighwaySpeed("footway", PUSHING_SECTION_SPEED); - setHighwaySpeed("pedestrian", PUSHING_SECTION_SPEED); setHighwaySpeed("track", 18); setHighwaySpeed("residential", 16); } diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index fab92ced74e..180da299ac6 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -338,11 +338,11 @@ public void testMonacoBike3D() { // 3. queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 167)); // 4. - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1557, 87)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1593, 85)); // try reverse direction // 1. - queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2111, 96)); + queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2788, 116)); queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 4132, 194)); queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2805, 145)); // 4. avoid tunnel(s)! @@ -392,7 +392,7 @@ public void testMonacoBike() { queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 1642, 87)); queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3580, 168)); queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2323, 121)); - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1434, 89)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1446, 91)); GraphHopper hopper = createHopper(MONACO, new CustomProfile("bike"). setCustomModel(new CustomModel().setDistanceInfluence(7000d)/*shortest*/).setVehicle("bike")); hopper.importOrLoad(); @@ -403,11 +403,11 @@ public void testMonacoBike() { public void testMonacoMountainBike() { List queries = new ArrayList<>(); // for mtb it is also ok to go over steps (43.7318,7.423) -> 1900m vs 2600m (in latest OSM data all bikes are forbidden and steps aren't taken) - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2323, 111)); - queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3655, 179)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2629, 152)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111)); + queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3655, 185)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2651, 167)); // hard to select between secondary and primary (both are AVOID for mtb) - queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1496, 92)); + queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1867, 107)); GraphHopper hopper = createHopper(MONACO, new CustomProfile("mtb").setCustomModel(new CustomModel()).setVehicle("mtb")); hopper.importOrLoad(); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java index f4a60606f24..d3b3a8d6b6d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/AbstractBikeTagParserTester.java @@ -359,6 +359,16 @@ public void testService() { assertPriorityAndSpeed(SLIGHT_AVOID, 4, way); } + @Test + public void testSteps() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "steps"); + assertPriorityAndSpeed(BAD, 2, way); + + way.setTag("bicycle", "designated"); + assertPriorityAndSpeed(BAD, 2, way); + } + @Test public void testSacScale() { ReaderWay way = new ReaderWay(1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java index b8371c5160f..89f49d2f1d0 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/BikeTagParserTest.java @@ -200,7 +200,7 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "steps"); - assertPriorityAndSpeed(SLIGHT_AVOID, 2, way); + assertPriorityAndSpeed(BAD, 2, way); way.clearTags(); way.setTag("highway", "residential"); @@ -210,9 +210,9 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "steps"); way.setTag("surface", "wood"); - assertPriorityAndSpeed(SLIGHT_AVOID, MIN_SPEED, way); + assertPriorityAndSpeed(BAD, MIN_SPEED, way); way.setTag("maxspeed", "20"); - assertPriorityAndSpeed(SLIGHT_AVOID, MIN_SPEED, way); + assertPriorityAndSpeed(BAD, MIN_SPEED, way); way.clearTags(); way.setTag("highway", "track"); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java index 8ba023d69c7..acc46340994 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/MountainBikeTagParserTest.java @@ -59,10 +59,6 @@ public void testSpeedAndPriority() { way.setTag("highway", "track"); assertPriorityAndSpeed(PREFER, 18, way); - way.setTag("highway", "steps"); - assertPriorityAndSpeed(SLIGHT_AVOID, PUSHING_SECTION_SPEED, way); - way.clearTags(); - // test speed for allowed pushing section types way.setTag("highway", "track"); way.setTag("bicycle", "yes"); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java index 943a509016e..9180a942952 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java @@ -88,7 +88,7 @@ public static void cleanUp() { @ValueSource(strings = {"CH", "LM", "flex"}) public void selectUsingProfile(String mode) { assertDistance("my_car", mode, 3563); - assertDistance("my_bike", mode, 3085); + assertDistance("my_bike", mode, 3296); assertDistance("my_feet", mode, 2935); assertError("my_pink_car", mode, "The requested profile 'my_pink_car' does not exist"); } From 9a62484103bdd7a3c5b03f4f9d1838388625eeb5 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 8 May 2023 17:21:05 +0200 Subject: [PATCH 071/165] i18n: updated tr (@ihsanguldur) and added new translation for Kazakh kz --- core/files/update-translations.sh | 2 +- .../com/graphhopper/util/TranslationMap.java | 7 +- .../resources/com/graphhopper/util/ar.txt | 14 + .../resources/com/graphhopper/util/ast.txt | 16 +- .../resources/com/graphhopper/util/az.txt | 14 + .../resources/com/graphhopper/util/bg.txt | 14 + .../resources/com/graphhopper/util/bn_BN.txt | 14 + .../resources/com/graphhopper/util/ca.txt | 14 + .../resources/com/graphhopper/util/da_DK.txt | 3 + .../resources/com/graphhopper/util/de_DE.txt | 24 +- .../resources/com/graphhopper/util/el.txt | 14 + .../resources/com/graphhopper/util/en_US.txt | 18 +- .../resources/com/graphhopper/util/eo.txt | 14 + .../resources/com/graphhopper/util/es.txt | 14 + .../resources/com/graphhopper/util/fa.txt | 14 + .../resources/com/graphhopper/util/fi.txt | 14 + .../resources/com/graphhopper/util/fil.txt | 14 + .../resources/com/graphhopper/util/fr_CH.txt | 14 + .../resources/com/graphhopper/util/fr_FR.txt | 14 + .../resources/com/graphhopper/util/gl.txt | 14 + .../resources/com/graphhopper/util/he.txt | 14 + .../resources/com/graphhopper/util/hr_HR.txt | 14 + .../resources/com/graphhopper/util/hsb.txt | 14 + .../resources/com/graphhopper/util/hu_HU.txt | 14 + .../resources/com/graphhopper/util/in_ID.txt | 14 + .../resources/com/graphhopper/util/it.txt | 14 + .../resources/com/graphhopper/util/ja.txt | 14 + .../resources/com/graphhopper/util/ko.txt | 14 + .../resources/com/graphhopper/util/kz.txt | 136 ++++++++++ .../resources/com/graphhopper/util/lt_LT.txt | 14 + .../resources/com/graphhopper/util/nb_NO.txt | 13 + .../resources/com/graphhopper/util/ne.txt | 14 + .../resources/com/graphhopper/util/nl.txt | 16 +- .../resources/com/graphhopper/util/pl_PL.txt | 16 +- .../resources/com/graphhopper/util/pt_BR.txt | 14 + .../resources/com/graphhopper/util/pt_PT.txt | 14 + .../resources/com/graphhopper/util/ro.txt | 20 +- .../resources/com/graphhopper/util/ru.txt | 14 + .../resources/com/graphhopper/util/sk.txt | 14 + .../resources/com/graphhopper/util/sl_SI.txt | 14 + .../resources/com/graphhopper/util/sr_RS.txt | 14 + .../resources/com/graphhopper/util/sv_SE.txt | 13 + .../resources/com/graphhopper/util/tr.txt | 15 +- .../resources/com/graphhopper/util/uk.txt | 14 + .../resources/com/graphhopper/util/vi_VN.txt | 14 + .../resources/com/graphhopper/util/zh_CN.txt | 14 + .../resources/com/graphhopper/util/zh_HK.txt | 14 + .../resources/com/graphhopper/util/zh_TW.txt | 254 +++++++++--------- 48 files changed, 884 insertions(+), 145 deletions(-) create mode 100644 core/src/main/resources/com/graphhopper/util/kz.txt diff --git a/core/files/update-translations.sh b/core/files/update-translations.sh index 487ba417158..7ad22690e41 100755 --- a/core/files/update-translations.sh +++ b/core/files/update-translations.sh @@ -3,7 +3,7 @@ cd $HOME/.. destination=src/main/resources/com/graphhopper/util/ -translations="en_US SKIP SKIP ar ast az bg bn_BN ca cs_CZ da_DK de_DE el eo es fa fil fi fr_FR fr_CH gl he hr_HR hsb hu_HU in_ID it ja ko lt_LT nb_NO ne nl pl_PL pt_BR pt_PT ro ru sk sl_SI sr_RS sv_SE tr uk vi_VN zh_CN zh_HK zh_TW" +translations="en_US SKIP SKIP ar ast az bg bn_BN ca cs_CZ da_DK de_DE el eo es fa fil fi fr_FR fr_CH gl he hr_HR hsb hu_HU in_ID it ja ko kz lt_LT nb_NO ne nl pl_PL pt_BR pt_PT ro ru sk sl_SI sr_RS sv_SE tr uk vi_VN zh_CN zh_HK zh_TW" file=$1 # You can execute the following diff --git a/core/src/main/java/com/graphhopper/util/TranslationMap.java b/core/src/main/java/com/graphhopper/util/TranslationMap.java index 44272da22e3..570f5b8de1d 100644 --- a/core/src/main/java/com/graphhopper/util/TranslationMap.java +++ b/core/src/main/java/com/graphhopper/util/TranslationMap.java @@ -34,9 +34,10 @@ public class TranslationMap { // ISO codes (639-1), use 'en_US' as reference private static final List LOCALES = Arrays.asList("ar", "ast", "bg", "bn_BN", "ca", "cs_CZ", "da_DK", "de_DE", "el", "eo", "es", "en_US", "fa", "fil", "fi", - "fr_FR", "fr_CH", "gl", "he", "hr_HR", "hsb", "hu_HU", "in_ID", "it", "ja", "ko", "lt_LT", "nb_NO", "ne", - "nl", "pl_PL", "pt_BR", "pt_PT", "ro", "ru", "sk", "sl_SI", "sr_RS", "sv_SE", "tr", "uk", - "vi_VN", "zh_CN", "zh_HK", "zh_TW"); + "fr_FR", "fr_CH", "gl", "he", "hr_HR", "hsb", "hu_HU", "in_ID", "it", "ja", "ko", + "kz", "lt_LT", "nb_NO", "ne", "nl", "pl_PL", "pt_BR", "pt_PT", "ro", "ru", "sk", + "sl_SI", "sr_RS", "sv_SE", "tr", "uk", "vi_VN", "zh_CN", "zh_HK", "zh_TW"); + private final Map translations = new HashMap<>(); public static int countOccurence(String phrase, String splitter) { diff --git a/core/src/main/resources/com/graphhopper/util/ar.txt b/core/src/main/resources/com/graphhopper/util/ar.txt index 5ecb90cb344..94986b5c974 100644 --- a/core/src/main/resources/com/graphhopper/util/ar.txt +++ b/core/src/main/resources/com/graphhopper/util/ar.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=انتقل الى %1$s web.start_label=البداية web.intermediate_label=نقطة عبور @@ -60,10 +65,16 @@ web.route=المسار web.add_to_route= web.delete_from_route=احذف من المسار web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ast.txt b/core/src/main/resources/com/graphhopper/util/ast.txt index 0230de4984a..3ea9794db37 100644 --- a/core/src/main/resources/com/graphhopper/util/ast.txt +++ b/core/src/main/resources/com/graphhopper/util/ast.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=cambia a %1$s web.start_label=Principiu web.intermediate_label=Intermediu @@ -60,10 +65,16 @@ web.route=Ruta web.add_to_route= web.delete_from_route=Quitar de la ruta web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -85,7 +96,7 @@ web.gpx_export_button=Esportar GPX web.gpx_button= web.hide_button= web.details_button= -web.to_hint=Fasta +web.to_hint= web.route_info=%1$s tardaràs %2$s web.search_button=Buscar web.more_button=más @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/az.txt b/core/src/main/resources/com/graphhopper/util/az.txt index 42634fa45c4..6b776943b5c 100644 --- a/core/src/main/resources/com/graphhopper/util/az.txt +++ b/core/src/main/resources/com/graphhopper/util/az.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=%1$s keçin web.start_label=Başlanğıc web.intermediate_label=Ara nöqtə @@ -60,10 +65,16 @@ web.route=Marşrut web.add_to_route= web.delete_from_route=Marşrutdan sil web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=%1$s mildə navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/bg.txt b/core/src/main/resources/com/graphhopper/util/bg.txt index d6e4a45e6a7..d4912f2c366 100644 --- a/core/src/main/resources/com/graphhopper/util/bg.txt +++ b/core/src/main/resources/com/graphhopper/util/bg.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=сменете на %1$s web.start_label=Начална точка web.intermediate_label=Междинна точка @@ -60,10 +65,16 @@ web.route=Маршрут web.add_to_route= web.delete_from_route=Премахване от маршрута web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=за %1$s мили navigate.warning=Внимание: Приложението е експериментално! Използвайте на свой риск! navigate.accept_risks_after_warning=Разбирам и се съгласявам navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/bn_BN.txt b/core/src/main/resources/com/graphhopper/util/bn_BN.txt index 0a32bfd0828..275c2f0b20f 100644 --- a/core/src/main/resources/com/graphhopper/util/bn_BN.txt +++ b/core/src/main/resources/com/graphhopper/util/bn_BN.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model=সাহায্য web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model=উদাহরণ @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ca.txt b/core/src/main/resources/com/graphhopper/util/ca.txt index 779afae4a29..7501bd65f7c 100644 --- a/core/src/main/resources/com/graphhopper/util/ca.txt +++ b/core/src/main/resources/com/graphhopper/util/ca.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=canvia a %1$s web.start_label=Punt d'inici web.intermediate_label=Punt intermig @@ -60,10 +65,16 @@ web.route=Ruta web.add_to_route= web.delete_from_route=Suprimeix el punt de la ruta web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=per %1$s milles navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/da_DK.txt b/core/src/main/resources/com/graphhopper/util/da_DK.txt index 1039fa59491..e74f4f3c0c6 100644 --- a/core/src/main/resources/com/graphhopper/util/da_DK.txt +++ b/core/src/main/resources/com/graphhopper/util/da_DK.txt @@ -49,6 +49,7 @@ web.steps=Trapper web.footways=Fortove web.steep_sections=Stejle sektioner web.private_sections= +web.trunk_roads_warn= web.get_off_bike_for=Føreren skal stige af og cyklen skal skubbes %1$s pt_transfer_to=omstigning til %1$s web.start_label=Start @@ -64,6 +65,7 @@ web.route=Rute web.add_to_route=Tilføj placering web.delete_from_route=Fjern fra rute web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model=Hjælp web.apply_custom_model= web.custom_model_enabled= @@ -72,6 +74,7 @@ web.settings_close= web.exclude_motorway_example=Eksludér motorvej web.limit_speed_example=Max hastighed web.cargo_bike_example=Ladcykel +web.prefer_bike_network= web.exclude_area_example=Eksludér område web.combined_example=Kombinerede eksempler web.examples_custom_model=Eksempler diff --git a/core/src/main/resources/com/graphhopper/util/de_DE.txt b/core/src/main/resources/com/graphhopper/util/de_DE.txt index b1e3663f21e..d106bc21b23 100644 --- a/core/src/main/resources/com/graphhopper/util/de_DE.txt +++ b/core/src/main/resources/com/graphhopper/util/de_DE.txt @@ -46,6 +46,11 @@ web.way_crosses_border=Route überquert Landesgrenzen web.way_contains=Auf der Route sind %1$s web.tracks=unbefestigte Feldwege web.steps=Treppen +web.footways=Fußwege +web.steep_sections=sehr steile Passagen +web.private_sections=private Abschnitte +web.trunk_roads_warn=Route beinhaltet potentiell gefährliche Fernstraßen +web.get_off_bike_for=Das Fahrrad muss für %1$s geschoben werden pt_transfer_to=umsteigen auf %1$s web.start_label=Start web.intermediate_label=Zwischenziel @@ -55,15 +60,21 @@ web.set_intermediate=Zwischenziel web.set_end=Bis hier web.center_map=Zentriere Karte web.show_coords=Zeige Koordinaten -web.query_osm=OSM Anfragen +web.query_osm=OSM anfragen web.route=Route web.add_to_route=Ziel hinzufügen web.delete_from_route=Lösche aus Route web.open_custom_model_box=Öffne custom model Kasten +web.draw_areas_enabled=Auf der Karte neue Gebiete einzeichnen und verändern web.help_custom_model=Hilfe web.apply_custom_model=Anwenden +web.custom_model_enabled=Custom Model aktiv +web.settings=Optionen +web.settings_close=Schließen web.exclude_motorway_example=Autobahn vermeiden web.limit_speed_example=Max. Geschwindigkeit +web.cargo_bike_example=Lastenfahrrad +web.prefer_bike_network=Radnetz bevorzugen web.exclude_area_example=Gebiet umfahren web.combined_example=Kombiniertes Bsp web.examples_custom_model=Beispiele @@ -82,7 +93,7 @@ web.searching_location_failed=Standortsuche fehlgeschlagen web.via_hint=Über web.from_hint=Von web.gpx_export_button=GPX Export -web.gpx_button= +web.gpx_button=GPX web.hide_button=Weniger web.details_button=Details web.to_hint=Nach @@ -117,6 +128,9 @@ navigate.in_mi_singular=In 1 Meile navigate.in_mi=In %1$s Meilen navigate.in_ft=In %1$s Fuß navigate.for_mi=für %1$s Meilen -navigate.warning=Achtung: diese Applikation ist experimentell! Benutzung auf eigene Gefahr! -navigate.accept_risks_after_warning=I verstehe und akzeptiere das Risiko -navigate.start_navigation=Navi +navigate.warning=ACHTUNG: Die Navigation ist höchst experimentell. Verwenden Sie diese auf eigene Gefahr, achten Sie auf den Straßenverkehr und berühren Sie das Gerät nicht während der Fahrt! +navigate.accept_risks_after_warning=Ich verstehe und akzeptiere +navigate.start_navigation=Navigation +navigate.vector_tiles_for_navigation=Nutze Vector Tiles +navigate.full_screen_for_navigation=Wechsle zum Vollbild +navigate.turn_navigation_settings_title=Navigation diff --git a/core/src/main/resources/com/graphhopper/util/el.txt b/core/src/main/resources/com/graphhopper/util/el.txt index d0cfb378c9b..704b2162917 100644 --- a/core/src/main/resources/com/graphhopper/util/el.txt +++ b/core/src/main/resources/com/graphhopper/util/el.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=αλλάξτε στο %1$s web.start_label=Αφετηρία web.intermediate_label=Ενδιάμεσο σημείο @@ -60,10 +65,16 @@ web.route=Διαδρομή web.add_to_route= web.delete_from_route=Αφαίρεση από διαδρομή web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=για %1$s μίλια navigate.warning=ΠΡΟΣΟΧΗ: Αυτή η εφαρμογή είναι πειραματική! Χρησιμοποιήστε την με δική σας ευθύνη! navigate.accept_risks_after_warning=Καταλαβαίνω και συμφωνώ navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/en_US.txt b/core/src/main/resources/com/graphhopper/util/en_US.txt index 254935c2824..5adb4e4a300 100644 --- a/core/src/main/resources/com/graphhopper/util/en_US.txt +++ b/core/src/main/resources/com/graphhopper/util/en_US.txt @@ -46,6 +46,11 @@ web.way_crosses_border=Route crosses a country border web.way_contains=Route includes %1$s web.tracks=unpaved dirt roads web.steps=steps +web.footways=footways +web.steep_sections=steep sections +web.private_sections=private sections +web.trunk_roads_warn=Route includes potentially dangerous trunk roads or worse +web.get_off_bike_for=Bike must be dismounted and pushed for %1$s pt_transfer_to=change to %1$s web.start_label=Start web.intermediate_label=Intermediate @@ -60,10 +65,16 @@ web.route=Route web.add_to_route=Add Location web.delete_from_route=Delete from Route web.open_custom_model_box=Open custom model box +web.draw_areas_enabled=Draw and modify areas on map web.help_custom_model=Help web.apply_custom_model=Apply +web.custom_model_enabled=Custom Model Active +web.settings=Settings +web.settings_close=Close web.exclude_motorway_example=Exclude Motorway web.limit_speed_example=Limit Speed +web.cargo_bike_example=Cargo Bike +web.prefer_bike_network=Prefer Cycle Routes web.exclude_area_example=Exclude Area web.combined_example=Combined Example web.examples_custom_model=Examples @@ -117,6 +128,9 @@ navigate.in_mi_singular=In 1 mile navigate.in_mi=In %1$s miles navigate.in_ft=In %1$s feet navigate.for_mi=for %1$s miles -navigate.warning=WARNING: This application is highly experimental! Use at your own risk! +navigate.warning=WARNING: The turn-by-turn navigation feature is highly experimental. Use it at your own risk, pay attention to the road and do not touch the device while driving! navigate.accept_risks_after_warning=I understand and agree -navigate.start_navigation=Navigate +navigate.start_navigation=Navigation +navigate.vector_tiles_for_navigation=Use vector tiles +navigate.full_screen_for_navigation=Set full screen +navigate.turn_navigation_settings_title=Turn-by-turn navigation diff --git a/core/src/main/resources/com/graphhopper/util/eo.txt b/core/src/main/resources/com/graphhopper/util/eo.txt index b13b378ed1f..27d61b1e76b 100644 --- a/core/src/main/resources/com/graphhopper/util/eo.txt +++ b/core/src/main/resources/com/graphhopper/util/eo.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=transveturiĝu al %1$s web.start_label=Komenco web.intermediate_label=Intercelo @@ -60,10 +65,16 @@ web.route=Kurso web.add_to_route= web.delete_from_route=Forigi el la kurso web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/es.txt b/core/src/main/resources/com/graphhopper/util/es.txt index ef61beac667..fbcf94b0878 100644 --- a/core/src/main/resources/com/graphhopper/util/es.txt +++ b/core/src/main/resources/com/graphhopper/util/es.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=cambia a %1$s web.start_label=Punto de partida web.intermediate_label=Punto intermedio @@ -60,10 +65,16 @@ web.route=Ruta web.add_to_route= web.delete_from_route=Borrar punto de ruta web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/fa.txt b/core/src/main/resources/com/graphhopper/util/fa.txt index 9e608b2809a..5bf83b7652c 100644 --- a/core/src/main/resources/com/graphhopper/util/fa.txt +++ b/core/src/main/resources/com/graphhopper/util/fa.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=مسیر را به %1$s تغییر دهید web.start_label=آغاز web.intermediate_label=نقطهٔ میانی @@ -60,10 +65,16 @@ web.route=مسیر web.add_to_route= web.delete_from_route=از مسیر حذف شود web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/fi.txt b/core/src/main/resources/com/graphhopper/util/fi.txt index 984035daf6d..d3d4cfa0161 100644 --- a/core/src/main/resources/com/graphhopper/util/fi.txt +++ b/core/src/main/resources/com/graphhopper/util/fi.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=vaihda %1$s web.start_label=Lähtöpaikka web.intermediate_label=Välikohde @@ -60,10 +65,16 @@ web.route=Reitti web.add_to_route= web.delete_from_route=Poista reitistä web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=kulje %1$s mailia navigate.warning=VAROITUS: Tämä sovellus on erittäin kokeellinen! Käytä omalla vastuullasi! navigate.accept_risks_after_warning=Ymmärrän ja hyväksyn navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/fil.txt b/core/src/main/resources/com/graphhopper/util/fil.txt index 25622231e7f..b0290a402e8 100644 --- a/core/src/main/resources/com/graphhopper/util/fil.txt +++ b/core/src/main/resources/com/graphhopper/util/fil.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/fr_CH.txt b/core/src/main/resources/com/graphhopper/util/fr_CH.txt index ba16f8eb136..980e056bb96 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_CH.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_CH.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=changez vers %1$s web.start_label=Départ web.intermediate_label=Point intermédiaire @@ -60,10 +65,16 @@ web.route=Itinéraire web.add_to_route=Ajouter un Emplacement web.delete_from_route=Supprimer ce point de l'itinéraire web.open_custom_model_box=Ouvrir la boîte du modèle personnalisé +web.draw_areas_enabled= web.help_custom_model=Aide web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/fr_FR.txt b/core/src/main/resources/com/graphhopper/util/fr_FR.txt index f76c8f30a44..31da6d33d54 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_FR.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_FR.txt @@ -46,6 +46,11 @@ web.way_crosses_border=L'itinéraire traverse une frontière nationale web.way_contains=L'itinéraire inclut %1$s web.tracks=chemins de terre non pavés web.steps=pas +web.footways=chemin pédestre +web.steep_sections=section raide +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=changez vers %1$s web.start_label=Départ web.intermediate_label=Point intermédiaire @@ -60,10 +65,16 @@ web.route=Itinéraire web.add_to_route=Ajouter un Emplacement web.delete_from_route=Supprimer ce point de l'itinéraire web.open_custom_model_box=Ouvrir la boîte du modèle personnalisé +web.draw_areas_enabled= web.help_custom_model=Aide web.apply_custom_model=Appliquer +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=Eviter les Autoroutes web.limit_speed_example=Vitesse Limite +web.cargo_bike_example=Vélo cargo +web.prefer_bike_network= web.exclude_area_example=Exclure Zone web.combined_example=Exemple Combiné web.examples_custom_model=Examples @@ -120,3 +131,6 @@ navigate.for_mi=Pendant %1$s miles navigate.warning=ATTENTION : Cette application est hautement expérimentale ! À utiliser à vos risques et périls ! navigate.accept_risks_after_warning=Je comprends et j'accepte navigate.start_navigation=Naviguer +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/gl.txt b/core/src/main/resources/com/graphhopper/util/gl.txt index 950fb8eb90d..e73fbe60b88 100644 --- a/core/src/main/resources/com/graphhopper/util/gl.txt +++ b/core/src/main/resources/com/graphhopper/util/gl.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/he.txt b/core/src/main/resources/com/graphhopper/util/he.txt index f344e0741ab..fe13dc41067 100644 --- a/core/src/main/resources/com/graphhopper/util/he.txt +++ b/core/src/main/resources/com/graphhopper/util/he.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=להחליף ל%1$s web.start_label=התחלה web.intermediate_label=אמצע @@ -60,10 +65,16 @@ web.route=דרך web.add_to_route= web.delete_from_route=מחיקה מהדרך web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/hr_HR.txt b/core/src/main/resources/com/graphhopper/util/hr_HR.txt index ea66ce48da1..28954e1afde 100644 --- a/core/src/main/resources/com/graphhopper/util/hr_HR.txt +++ b/core/src/main/resources/com/graphhopper/util/hr_HR.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label=Početak web.intermediate_label=Posrednik @@ -60,10 +65,16 @@ web.route=Ruta web.add_to_route= web.delete_from_route=Izbriši iz rute web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/hsb.txt b/core/src/main/resources/com/graphhopper/util/hsb.txt index 6a5656fa7df..680ff398d05 100644 --- a/core/src/main/resources/com/graphhopper/util/hsb.txt +++ b/core/src/main/resources/com/graphhopper/util/hsb.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/hu_HU.txt b/core/src/main/resources/com/graphhopper/util/hu_HU.txt index d281ebcc45f..6b563e16788 100644 --- a/core/src/main/resources/com/graphhopper/util/hu_HU.txt +++ b/core/src/main/resources/com/graphhopper/util/hu_HU.txt @@ -46,6 +46,11 @@ web.way_crosses_border=Az útvonal országhatárt keresztez web.way_contains=Az útvonalon előfordul %1$s web.tracks=burkolatlan földút web.steps=lépcső +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=szálljon át erre: %1$s web.start_label=Indulás web.intermediate_label=Köztes célpont @@ -60,10 +65,16 @@ web.route=Útvonal web.add_to_route=Hely hozzáadása web.delete_from_route=Eltávolítás az útvonalról web.open_custom_model_box=Egyedi modelldoboz megnyitása +web.draw_areas_enabled= web.help_custom_model=Súgó web.apply_custom_model=Alkalmazás +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=Autópálya nélkül web.limit_speed_example=Sebességkorlátozás +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example=Terület elkerülése web.combined_example=Kombinált példa web.examples_custom_model=Példák @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning=FIGYELEM! Ez az alkalmazás erősen kísérleti jellegű. Használat csak saját felelősségre! navigate.accept_risks_after_warning=Megértettem és elfogadom navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/in_ID.txt b/core/src/main/resources/com/graphhopper/util/in_ID.txt index 4458152889b..53e903354c6 100644 --- a/core/src/main/resources/com/graphhopper/util/in_ID.txt +++ b/core/src/main/resources/com/graphhopper/util/in_ID.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=berpindah ke jalur %1$s web.start_label=Mulai web.intermediate_label=Antara @@ -60,10 +65,16 @@ web.route=Rute web.add_to_route= web.delete_from_route=Hapus dari rute web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/it.txt b/core/src/main/resources/com/graphhopper/util/it.txt index 3f146fe6b37..e3507c1e138 100644 --- a/core/src/main/resources/com/graphhopper/util/it.txt +++ b/core/src/main/resources/com/graphhopper/util/it.txt @@ -46,6 +46,11 @@ web.way_crosses_border=Il percorso attraversa un confine di stato web.way_contains=Il percorso include %1$s web.tracks=strade sterrate web.steps=Passi +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=cambia con %1$s web.start_label=Partenza web.intermediate_label=Punto intermedio @@ -60,10 +65,16 @@ web.route=Itinerario web.add_to_route=Aggiungi destinazione web.delete_from_route=Elimina dall'itinerario web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model=Aiuto web.apply_custom_model=Applica +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=Escludi autostrada web.limit_speed_example=Limita velocità +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example=Escludi area web.combined_example=Esempio combinato web.examples_custom_model=Esempi @@ -120,3 +131,6 @@ navigate.for_mi=per %1$s miglia navigate.warning=ATTENZIONE: Questa applicazione è ancora sperimentale! Utilizzala a tuo rischio e pericolo! navigate.accept_risks_after_warning=Ho capito e accetto navigate.start_navigation=Naviga +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ja.txt b/core/src/main/resources/com/graphhopper/util/ja.txt index edd0d020515..7381f84941e 100644 --- a/core/src/main/resources/com/graphhopper/util/ja.txt +++ b/core/src/main/resources/com/graphhopper/util/ja.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route=経路 web.add_to_route= web.delete_from_route=経路から取り除く web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ko.txt b/core/src/main/resources/com/graphhopper/util/ko.txt index 539676d3359..0d6d2af7c5f 100644 --- a/core/src/main/resources/com/graphhopper/util/ko.txt +++ b/core/src/main/resources/com/graphhopper/util/ko.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=%1$s(으)로 환승 web.start_label=출발지 web.intermediate_label=경유지 @@ -60,10 +65,16 @@ web.route=경로 web.add_to_route= web.delete_from_route=경로에서 삭제 web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/kz.txt b/core/src/main/resources/com/graphhopper/util/kz.txt new file mode 100644 index 00000000000..24ae9bbae80 --- /dev/null +++ b/core/src/main/resources/com/graphhopper/util/kz.txt @@ -0,0 +1,136 @@ +# do not edit manually, instead use spreadsheet https://t.co/f086oJXAEI and script ./core/files/update-translations.sh + +continue=Жалғастырыңыз +continue_onto=%1$s бойынша жалғастырыңыз +finish=мәреге жеттіңіз +keep_left=сол жаққа шығыңыз +keep_right=оң жаққа шығыңыз +turn_onto= +turn_left=солға бұрылыңыз +turn_right=оңға бұрылыңыз +turn_slight_left=аздап солға бұрылыңыз +turn_slight_right=аздап оңға бұрылыңыз +turn_sharp_left=Қаттырақ солға бұрылыңыз +turn_sharp_right=Қаттырақ оңға бұрылыңыз +u_turn=артқа бұрылыңыз +toward_destination=%1$s және %2$s бағытында жүріңіз +toward_destination_ref_only= +toward_destination_with_ref= +unknown=белгісіз белгі '%1$s' +via=арқылы +hour_abbr=сағ. +day_abbr=күн +min_abbr=мин. +km_abbr=км +m_abbr=м +mi_abbr= +ft_abbr= +road=жол +off_bike=велосипедтен түсіңіз +cycleway=веложол +way=жол +small_way=тар жол +paved=асфальтталған +unpaved=жол төселмеген +stopover=%1$s аялдамасы +roundabout_enter=айналма жолға өтіңіз +roundabout_exit=%1$s-ші бұрылыстан бұрылыңыз +roundabout_exit_onto=Айналымда %1$s-ден %2$s-ге +web.total_ascend=%1$s көтерілу +web.total_descend=%1$s төмен түсу +web.way_contains_ford=Жолда өткел бар +web.way_contains_ferry= паромға отырыңыз +web.way_contains_private=жекеменшік жол +web.way_contains_toll=жол ақылы +web.way_crosses_border=жол ел шекарасын кесіп жатыр +web.way_contains=жолда %1$s бар +web.tracks=асфальтталмаған қара жолдар +web.steps=қадамдар +web.footways=жаяу жүргіншілер жолы +web.steep_sections=күрделі аялдамалар +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= +pt_transfer_to=%1$s-ған отырыңыз +web.start_label=бастапқы нүкте +web.intermediate_label=аралық нүкте +web.end_label=соңғы нүкте +web.set_start=бастапқы нүктені таңдау +web.set_intermediate=аралық нүктені қосу +web.set_end=соңғы нүктені таңдау +web.center_map= +web.show_coords=координаталарды көрсету +web.query_osm= +web.route=маршрут +web.add_to_route= +web.delete_from_route=маршруттан жою +web.open_custom_model_box=Арнайы модель қорабын ашыңыз +web.draw_areas_enabled= +web.help_custom_model=көмек +web.apply_custom_model=қолдану +web.custom_model_enabled= +web.settings= +web.settings_close= +web.exclude_motorway_example=Автомогистральді алып тастау +web.limit_speed_example=шектеулі жылдамдық +web.cargo_bike_example=жүк велосипеді +web.prefer_bike_network= +web.exclude_area_example=Аймақты алып тастау +web.combined_example= +web.examples_custom_model=мысалдар +web.marker=белгі +web.gh_offline_info= +web.refresh_button=бетті жаңартыңыз +web.server_status=жағдайы +web.zoom_in=үлкейту +web.zoom_out=кішірейту +web.drag_to_reorder=Ретін өзгерту үшін жылжытыңыз +web.route_timed_out=Маршрутты есептеу уақыты таусылды +web.route_request_failed=маршрут сұранысы орындалмады +web.current_location=қазіргі орныңыз +web.searching_location=орналасқан жерді іздеу +web.searching_location_failed=Қазіргі орныңызды іздеу сәтсіз аяқталды +web.via_hint=арқылы +web.from_hint=Бастауы +web.gpx_export_button=GPX Экспорты +web.gpx_button=GPX +web.hide_button=жасыру +web.details_button=толығырақ +web.to_hint=дейін +web.route_info=%1$s-ге дейін шамамен %2$s уақыт кетеді +web.search_button=іздеу +web.more_button=тағы +web.pt_route_info=%2$s-ден %1$s-ге пересадкамен бару (%3$s) +web.pt_route_info_walking=%1$s-ге дейін тек жаяу жүру (%2$s) +web.locations_not_found=Маршрут құру мүмкін болмады. Орын анықталмады. +web.search_with_nominatim=Nominatim арқылы іздеу +web.powered_by= +web.bike=велосипед +web.racingbike= +web.mtb=Таулы велосипед +web.car=көлік +web.foot=жаяу жүргінші +web.hike= +web.small_truck=Шағын жүк көлігі +web.bus=автобус +web.truck=үлкен жүк көлігі +web.staticlink= +web.motorcycle=мотоцикл +web.back_to_map=Қайту +web.distance_unit= +web.waiting_for_gps=GPS сигналын күтіңіз... +navigate.in_km_singular=1 км жерде +navigate.in_km=%1$s км жерде +navigate.in_m=%1$s метр жерде +navigate.for_km= +navigate.then=одан соң +navigate.in_mi_singular= +navigate.in_mi= +navigate.in_ft= +navigate.for_mi= +navigate.warning=Ескерту: бұрылыстан бұрылысқа навигация функциясы эксперименталды. Оны өз жауапкершілігіңізбен пайдаланыңыз, жолға назар аударыңыз және қозғалыс кезінде құрылғыға қол тигізбеңіз! +navigate.accept_risks_after_warning=мен түсіндім және келісемін +navigate.start_navigation=навигация +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/lt_LT.txt b/core/src/main/resources/com/graphhopper/util/lt_LT.txt index 81ebf6bf4a1..56255eac69b 100644 --- a/core/src/main/resources/com/graphhopper/util/lt_LT.txt +++ b/core/src/main/resources/com/graphhopper/util/lt_LT.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=persėskite į %1$s web.start_label=Pradėti web.intermediate_label= @@ -60,10 +65,16 @@ web.route=Maršrutas web.add_to_route= web.delete_from_route=Ištrinti iš maršruto web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/nb_NO.txt b/core/src/main/resources/com/graphhopper/util/nb_NO.txt index 9750a20cc3f..d5fc9a038c3 100644 --- a/core/src/main/resources/com/graphhopper/util/nb_NO.txt +++ b/core/src/main/resources/com/graphhopper/util/nb_NO.txt @@ -46,6 +46,11 @@ web.way_crosses_border=ruten krysser landegrense web.way_contains=ruten inneholder %1$s web.tracks=grusvei web.steps=trapper +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=bytt til %1$s web.start_label=Start web.intermediate_label=delmål @@ -60,11 +65,16 @@ web.route=Rute web.add_to_route=Legg til web.delete_from_route=Fjern fra ruten web.open_custom_model_box=Åpne tilpasser modellboks +web.draw_areas_enabled= web.help_custom_model=Hjelp web.apply_custom_model=Bekreft +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=Unngå motorvei web.limit_speed_example=Begrens hastighet web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example=Unngå område web.combined_example= web.examples_custom_model=Eksempler @@ -121,3 +131,6 @@ navigate.for_mi= navigate.warning=VARSEL: Denne appen er svært eksperimentell. Brukes på eget ansvar! navigate.accept_risks_after_warning=Jeg forstår og samtykker navigate.start_navigation=Start navigasjon +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ne.txt b/core/src/main/resources/com/graphhopper/util/ne.txt index a95acb66488..949a2dee4b0 100644 --- a/core/src/main/resources/com/graphhopper/util/ne.txt +++ b/core/src/main/resources/com/graphhopper/util/ne.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/nl.txt b/core/src/main/resources/com/graphhopper/util/nl.txt index 8e160bfbd98..204db0df29f 100644 --- a/core/src/main/resources/com/graphhopper/util/nl.txt +++ b/core/src/main/resources/com/graphhopper/util/nl.txt @@ -18,13 +18,13 @@ toward_destination_ref_only= toward_destination_with_ref= unknown=onbekende richtingaanwijzer '%1$s' via=via -hour_abbr=u -day_abbr=d -min_abbr=min +hour_abbr=uur +day_abbr=dag +min_abbr=minuut km_abbr=km -m_abbr=m -mi_abbr=mi -ft_abbr=ft +m_abbr=meter +mi_abbr=mijl +ft_abbr=voet road=weg off_bike=stap af cycleway=fietspad @@ -34,8 +34,8 @@ paved=verhard unpaved=onverhard stopover=marker %1$s roundabout_enter=ga de rotonde op -roundabout_exit=neem afslag %1$s op de rotonde -roundabout_exit_onto=neem afslag %1$s naar %2$s op de rotonde +roundabout_exit=neem afslag %1$s +roundabout_exit_onto=neem afslag %1$s naar %2$s web.total_ascend=%1$s totale klim web.total_descend=%1$s totale daling web.way_contains_ford=Er is een doorwaadbare plaats diff --git a/core/src/main/resources/com/graphhopper/util/pl_PL.txt b/core/src/main/resources/com/graphhopper/util/pl_PL.txt index c3d827f9280..3e7e0e057ac 100644 --- a/core/src/main/resources/com/graphhopper/util/pl_PL.txt +++ b/core/src/main/resources/com/graphhopper/util/pl_PL.txt @@ -46,6 +46,11 @@ web.way_crosses_border=Trasa przebiega przez granicę państwową web.way_contains=Trasa przez %1$s web.tracks=nieutwardzone drogi gruntowe web.steps=schody +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=przesiądź się na %1$s web.start_label=Początek web.intermediate_label=Punkt pośredni @@ -60,10 +65,16 @@ web.route=Trasa web.add_to_route=Dodaj punkt pośredni web.delete_from_route=Usuń z trasy web.open_custom_model_box=Otwórz okienko modelu niestandardowego +web.draw_areas_enabled= web.help_custom_model=Pomoc web.apply_custom_model=Zastosuj +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=Pomijaj autostrady web.limit_speed_example=Ogranicz prędkość +web.cargo_bike_example=Rower towarowy +web.prefer_bike_network= web.exclude_area_example=Wyklucz obszar web.combined_example=Przykład łączony web.examples_custom_model=Przykłady @@ -116,7 +127,10 @@ navigate.then=, potem navigate.in_mi_singular=Za 1 milę navigate.in_mi=Za %1$s mi navigate.in_ft=Za %1$s ft -navigate.for_mi= +navigate.for_mi=przez %1$s mil navigate.warning=OSTRZEŻENIE: Ta aplikacja jest wysoce eksperymentalna! Używaj na własne ryzyko! navigate.accept_risks_after_warning=Rozumiem i akceptuję navigate.start_navigation=Nawiguj +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/pt_BR.txt b/core/src/main/resources/com/graphhopper/util/pt_BR.txt index 89229e72c13..27f5e10553c 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_BR.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_BR.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=mude para %1$s web.start_label=Início web.intermediate_label=Intermediário @@ -60,10 +65,16 @@ web.route=Rota web.add_to_route= web.delete_from_route=Remover da rota web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/pt_PT.txt b/core/src/main/resources/com/graphhopper/util/pt_PT.txt index b81b6139cc5..99bf06f42f9 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_PT.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_PT.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label= web.intermediate_label= @@ -60,10 +65,16 @@ web.route= web.add_to_route= web.delete_from_route= web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ro.txt b/core/src/main/resources/com/graphhopper/util/ro.txt index 60eb4f1a9cf..c47c3412a0d 100644 --- a/core/src/main/resources/com/graphhopper/util/ro.txt +++ b/core/src/main/resources/com/graphhopper/util/ro.txt @@ -3,8 +3,8 @@ continue=continuă continue_onto=continuă pe %1$s finish=obiectiv atins -keep_left= -keep_right= +keep_left=Rămâneți pe banda stângă +keep_right=Rămâneți pe banda dreaptă turn_onto=%1$s pe %2$s turn_left=schimbați direcția la stânga turn_right=schimbați direcția la dreapta @@ -12,7 +12,7 @@ turn_slight_left=schimbați direcția la ușor la stânga turn_slight_right=schimbați direcția la ușor la dreapta turn_sharp_left=schimbați direcția la brusc la stânga turn_sharp_right=schimbați direcția la brusc la dreapta -u_turn= +u_turn=Întoarceţi-vă toward_destination= toward_destination_ref_only= toward_destination_with_ref= @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label=Pornire web.intermediate_label=Intermediar @@ -60,10 +65,16 @@ web.route=Intinerariu web.add_to_route= web.delete_from_route=Șterge din intinerariu web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/ru.txt b/core/src/main/resources/com/graphhopper/util/ru.txt index 7d305556e3d..60f319d4c9c 100644 --- a/core/src/main/resources/com/graphhopper/util/ru.txt +++ b/core/src/main/resources/com/graphhopper/util/ru.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=Пересядьте на %1$s web.start_label=Начало web.intermediate_label=Промежуточная точка @@ -60,10 +65,16 @@ web.route=Маршрут web.add_to_route= web.delete_from_route=Удалить из маршрута web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=В %1$s милях navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/sk.txt b/core/src/main/resources/com/graphhopper/util/sk.txt index 367aa92f559..e995beb35e9 100644 --- a/core/src/main/resources/com/graphhopper/util/sk.txt +++ b/core/src/main/resources/com/graphhopper/util/sk.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=prestúpte na linku %1$s web.start_label=Začiatok web.intermediate_label=Bod trasy @@ -60,10 +65,16 @@ web.route=Trasa web.add_to_route= web.delete_from_route=Odstrániť z trasy web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/sl_SI.txt b/core/src/main/resources/com/graphhopper/util/sl_SI.txt index c81bf065049..7c0d43043f5 100644 --- a/core/src/main/resources/com/graphhopper/util/sl_SI.txt +++ b/core/src/main/resources/com/graphhopper/util/sl_SI.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=Prestopite na %1$s web.start_label=Začetna točka web.intermediate_label=Vmesna točka @@ -60,10 +65,16 @@ web.route=Pot web.add_to_route= web.delete_from_route=Izbriši iz poti web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/sr_RS.txt b/core/src/main/resources/com/graphhopper/util/sr_RS.txt index 07e2b03c40f..069c3b44c90 100644 --- a/core/src/main/resources/com/graphhopper/util/sr_RS.txt +++ b/core/src/main/resources/com/graphhopper/util/sr_RS.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label=Početak web.intermediate_label=Prelazni @@ -60,10 +65,16 @@ web.route=Ruta web.add_to_route= web.delete_from_route=Izbriši iz rute web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/sv_SE.txt b/core/src/main/resources/com/graphhopper/util/sv_SE.txt index 3ee9a377510..eb83147ebdb 100644 --- a/core/src/main/resources/com/graphhopper/util/sv_SE.txt +++ b/core/src/main/resources/com/graphhopper/util/sv_SE.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains=Rutten inkluderar %1$s web.tracks= web.steps=steg +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=byt till %1$s web.start_label=Start web.intermediate_label=delmål @@ -60,11 +65,16 @@ web.route=Rutt web.add_to_route=Lägg till plats web.delete_from_route=Ta bort från rutt web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model=Hjälp web.apply_custom_model=Applicera +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model=Exempel @@ -121,3 +131,6 @@ navigate.for_mi=i %1$s mil navigate.warning=VARNING: Sväng-för-sväng-navigeringen är mycket experimentell! Använd på egen risk! navigate.accept_risks_after_warning=Jag förstår och godkänner navigate.start_navigation=Navigera +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/tr.txt b/core/src/main/resources/com/graphhopper/util/tr.txt index f7bbb0796e1..a96ae4ad67c 100644 --- a/core/src/main/resources/com/graphhopper/util/tr.txt +++ b/core/src/main/resources/com/graphhopper/util/tr.txt @@ -5,7 +5,7 @@ continue_onto=%1$s üstünde devam edin finish=hedefe ulaştınız keep_left=soldan ilerleyin keep_right=sağdan ilerleyin -turn_onto=%1$s üstünde %2$s +turn_onto=%2$s üstünde %1$s turn_left=sola dönün turn_right=sağa dönün turn_slight_left=hafif sola dönün @@ -46,6 +46,11 @@ web.way_crosses_border=Rota ülke sınırından geçmektedir web.way_contains=Rota %1$s içermektedir web.tracks=Asfaltsız toprak yol web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=%1$s geçiş yap web.start_label=Başlangıç web.intermediate_label=Ara nokta @@ -60,11 +65,16 @@ web.route=Rota web.add_to_route=Konum ekle web.delete_from_route=Rotadan kaldır web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model=Yardım web.apply_custom_model=Uygula +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example=Hız limiti web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model=Örnekler @@ -121,3 +131,6 @@ navigate.for_mi=%1$s mil boyunca navigate.warning= navigate.accept_risks_after_warning=Anladım ve kabul ediyorum navigate.start_navigation=Başla +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/uk.txt b/core/src/main/resources/com/graphhopper/util/uk.txt index 74aa932bb27..cc59a1d61bf 100644 --- a/core/src/main/resources/com/graphhopper/util/uk.txt +++ b/core/src/main/resources/com/graphhopper/util/uk.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=Пересядьте на %1$s web.start_label=Початок web.intermediate_label=Проміжна точка @@ -60,10 +65,16 @@ web.route=Маршрут web.add_to_route= web.delete_from_route=Вилучити з маршруту web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/vi_VN.txt b/core/src/main/resources/com/graphhopper/util/vi_VN.txt index 8d4cd8a1d20..32b04148547 100644 --- a/core/src/main/resources/com/graphhopper/util/vi_VN.txt +++ b/core/src/main/resources/com/graphhopper/util/vi_VN.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=chuyển sang tuyến %1$s web.start_label=Điểm bắt đầu web.intermediate_label=Điểm trung gian @@ -60,10 +65,16 @@ web.route=Lộ trình web.add_to_route= web.delete_from_route=Xóa khỏi tuyến đường web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi=Khoảng %1$s dặm navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/zh_CN.txt b/core/src/main/resources/com/graphhopper/util/zh_CN.txt index 54d02d0fae6..9374fb826a2 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_CN.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_CN.txt @@ -46,6 +46,11 @@ web.way_crosses_border=路径中跨越了国界 web.way_contains=路径中包含%1$s web.tracks=未铺设的土路 web.steps=台阶 +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to=换乘%1$s web.start_label=起点 web.intermediate_label=途经点 @@ -60,10 +65,16 @@ web.route=路线 web.add_to_route=增加位置 web.delete_from_route=从线路中移除 web.open_custom_model_box=打开自定义模型选项 +web.draw_areas_enabled= web.help_custom_model=帮助 web.apply_custom_model=应用 +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example=排除高速公路 web.limit_speed_example=限速 +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example=排除区域 web.combined_example=综合范例 web.examples_custom_model=范例 @@ -120,3 +131,6 @@ navigate.for_mi=行驶 %1$s 英里 navigate.warning=警告:该应用程序处于早期实验阶段,使用时风险自负! navigate.accept_risks_after_warning=我理解并同意 navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/zh_HK.txt b/core/src/main/resources/com/graphhopper/util/zh_HK.txt index a08ec249a49..ce1c492c3d6 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_HK.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_HK.txt @@ -46,6 +46,11 @@ web.way_crosses_border= web.way_contains= web.tracks= web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= pt_transfer_to= web.start_label=起點 web.intermediate_label=途經點 @@ -60,10 +65,16 @@ web.route=路線 web.add_to_route= web.delete_from_route=從路線移除 web.open_custom_model_box= +web.draw_areas_enabled= web.help_custom_model= web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= web.exclude_motorway_example= web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= web.exclude_area_example= web.combined_example= web.examples_custom_model= @@ -120,3 +131,6 @@ navigate.for_mi= navigate.warning= navigate.accept_risks_after_warning= navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= diff --git a/core/src/main/resources/com/graphhopper/util/zh_TW.txt b/core/src/main/resources/com/graphhopper/util/zh_TW.txt index 45b70dfbc52..5a09da7b79f 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_TW.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_TW.txt @@ -1,122 +1,136 @@ # do not edit manually, instead use spreadsheet https://t.co/f086oJXAEI and script ./core/files/update-translations.sh -continue=繼續 -continue_onto=繼續行駛到 %1$s -finish=抵達目的地 -keep_left=保持左側 -keep_right=保持右側 -turn_onto=%1$s 進入%2$s -turn_left=左轉 -turn_right=右轉 -turn_slight_left=微靠左轉 -turn_slight_right=微靠右轉 -turn_sharp_left=左急轉 -turn_sharp_right=右急轉 -u_turn=迴轉 -toward_destination= -toward_destination_ref_only= -toward_destination_with_ref= -unknown=未知指示標誌 '%1$s' -via=途經 -hour_abbr=小時 -day_abbr=天 -min_abbr=分鐘 -km_abbr=公里 -m_abbr=公尺 -mi_abbr=英里 -ft_abbr=英尺 -road=道路 -off_bike=下自行車 -cycleway=自行車道 -way=路 -small_way=小路 -paved=路面有鋪設 -unpaved=路面無鋪設 -stopover=中途點 %1$s -roundabout_enter=進入圓環 -roundabout_exit=於 %1$s 個出口離開圓環 -roundabout_exit_onto=於 %1$s 個出口離開圓環,進入 %2$s -web.total_ascend=總共上昇 %1$s -web.total_descend=總共下降 %1$s -web.way_contains_ford=路徑中含有淺灘 -web.way_contains_ferry=搭乘渡輪 -web.way_contains_private=私人道路 -web.way_contains_toll=收費道路 -web.way_crosses_border= -web.way_contains= -web.tracks= -web.steps= -pt_transfer_to=變換至 %1$s -web.start_label=出發點 -web.intermediate_label=途經點 -web.end_label=抵達點 -web.set_start=設為出發點 -web.set_intermediate=設為途經點 -web.set_end=設為抵達點 -web.center_map=設為地圖中心 -web.show_coords=顯示坐標 -web.query_osm= -web.route=路線 -web.add_to_route= -web.delete_from_route=從路線中移除 -web.open_custom_model_box= -web.help_custom_model= -web.apply_custom_model= -web.exclude_motorway_example= -web.limit_speed_example= -web.exclude_area_example= -web.combined_example= -web.examples_custom_model= -web.marker=標記 -web.gh_offline_info=GraphHopper API 離線狀態? -web.refresh_button=刷新頁面 -web.server_status=狀態 -web.zoom_in=放大 -web.zoom_out=縮小 -web.drag_to_reorder=拖曳排序 -web.route_timed_out= -web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= -web.via_hint=途經 -web.from_hint=起點 -web.gpx_export_button=匯出GPS -web.gpx_button= -web.hide_button= -web.details_button= -web.to_hint=迄點 -web.route_info=%1$s 需時 %2$s -web.search_button=搜尋 -web.more_button=更多 -web.pt_route_info=於 %1$s 抵達,%2$s 次轉乘 (%3$s) -web.pt_route_info_walking=於 %1$s 抵達,僅步行 (%2$s) -web.locations_not_found=無法進行規劃。無法在此區域內找到指定的地點 -web.search_with_nominatim= -web.powered_by= -web.bike=自行車 -web.racingbike=競技自行車 -web.mtb=登山車 -web.car=汽車 -web.foot=步行 -web.hike=健行 -web.small_truck=小貨車 -web.bus=公車 -web.truck=貨車 -web.staticlink=永久鏈結 -web.motorcycle=摩托車 -web.back_to_map= -web.distance_unit= -web.waiting_for_gps= -navigate.in_km_singular= -navigate.in_km= -navigate.in_m= -navigate.for_km= -navigate.then= -navigate.in_mi_singular= -navigate.in_mi= -navigate.in_ft= -navigate.for_mi= -navigate.warning= -navigate.accept_risks_after_warning= -navigate.start_navigation= +continue=繼續 +continue_onto=繼續行駛到 %1$s +finish=抵達目的地 +keep_left=保持左側 +keep_right=保持右側 +turn_onto=%1$s 進入%2$s +turn_left=左轉 +turn_right=右轉 +turn_slight_left=微靠左轉 +turn_slight_right=微靠右轉 +turn_sharp_left=左急轉 +turn_sharp_right=右急轉 +u_turn=迴轉 +toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= +unknown=未知指示標誌 '%1$s' +via=途經 +hour_abbr=小時 +day_abbr=天 +min_abbr=分鐘 +km_abbr=公里 +m_abbr=公尺 +mi_abbr=英里 +ft_abbr=英尺 +road=道路 +off_bike=下自行車 +cycleway=自行車道 +way=路 +small_way=小路 +paved=路面有鋪設 +unpaved=路面無鋪設 +stopover=中途點 %1$s +roundabout_enter=進入圓環 +roundabout_exit=於 %1$s 個出口離開圓環 +roundabout_exit_onto=於 %1$s 個出口離開圓環,進入 %2$s +web.total_ascend=總共上昇 %1$s +web.total_descend=總共下降 %1$s +web.way_contains_ford=路徑中含有淺灘 +web.way_contains_ferry=搭乘渡輪 +web.way_contains_private=私人道路 +web.way_contains_toll=收費道路 +web.way_crosses_border= +web.way_contains= +web.tracks= +web.steps= +web.footways= +web.steep_sections= +web.private_sections= +web.trunk_roads_warn= +web.get_off_bike_for= +pt_transfer_to=變換至 %1$s +web.start_label=出發點 +web.intermediate_label=途經點 +web.end_label=抵達點 +web.set_start=設為出發點 +web.set_intermediate=設為途經點 +web.set_end=設為抵達點 +web.center_map=設為地圖中心 +web.show_coords=顯示坐標 +web.query_osm= +web.route=路線 +web.add_to_route= +web.delete_from_route=從路線中移除 +web.open_custom_model_box= +web.draw_areas_enabled= +web.help_custom_model= +web.apply_custom_model= +web.custom_model_enabled= +web.settings= +web.settings_close= +web.exclude_motorway_example= +web.limit_speed_example= +web.cargo_bike_example= +web.prefer_bike_network= +web.exclude_area_example= +web.combined_example= +web.examples_custom_model= +web.marker=標記 +web.gh_offline_info=GraphHopper API 離線狀態? +web.refresh_button=刷新頁面 +web.server_status=狀態 +web.zoom_in=放大 +web.zoom_out=縮小 +web.drag_to_reorder=拖曳排序 +web.route_timed_out= +web.route_request_failed= +web.current_location= +web.searching_location= +web.searching_location_failed= +web.via_hint=途經 +web.from_hint=起點 +web.gpx_export_button=匯出GPS +web.gpx_button= +web.hide_button= +web.details_button= +web.to_hint=迄點 +web.route_info=%1$s 需時 %2$s +web.search_button=搜尋 +web.more_button=更多 +web.pt_route_info=於 %1$s 抵達,%2$s 次轉乘 (%3$s) +web.pt_route_info_walking=於 %1$s 抵達,僅步行 (%2$s) +web.locations_not_found=無法進行規劃。無法在此區域內找到指定的地點 +web.search_with_nominatim= +web.powered_by= +web.bike=自行車 +web.racingbike=競技自行車 +web.mtb=登山車 +web.car=汽車 +web.foot=步行 +web.hike=健行 +web.small_truck=小貨車 +web.bus=公車 +web.truck=貨車 +web.staticlink=永久鏈結 +web.motorcycle=摩托車 +web.back_to_map= +web.distance_unit= +web.waiting_for_gps= +navigate.in_km_singular= +navigate.in_km= +navigate.in_m= +navigate.for_km= +navigate.then= +navigate.in_mi_singular= +navigate.in_mi= +navigate.in_ft= +navigate.for_mi= +navigate.warning= +navigate.accept_risks_after_warning= +navigate.start_navigation= +navigate.vector_tiles_for_navigation= +navigate.full_screen_for_navigation= +navigate.turn_navigation_settings_title= From 547215973b5b66d082a6adb184f48ae71f790c9d Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Fri, 12 May 2023 10:22:33 -0700 Subject: [PATCH 072/165] differentiate travel time betas for access vs egress --- .../com/graphhopper/gtfs/GraphExplorer.java | 10 ++++---- .../com/graphhopper/gtfs/GraphHopperGtfs.java | 15 ++++++++++-- .../gtfs/PtRouterFreeWalkImpl.java | 6 ++++- .../com/graphhopper/gtfs/PtRouterImpl.java | 23 ++++++++++++++----- .../java/com/graphhopper/gtfs/Request.java | 18 +++++++++++++++ .../com/graphhopper/gtfs/TripFromLabel.java | 15 ++++++++---- .../graphhopper/GraphHopperMultimodalIT.java | 16 ++++++++----- .../resources/PtRouteResource.java | 6 ++++- .../com/graphhopper/maps/pt/data/Query.js | 4 ++++ .../com/graphhopper/maps/pt/view/App.js | 2 ++ .../maps/pt/view/sidebar/SearchInput.js | 12 ++++++++++ 11 files changed, 102 insertions(+), 25 deletions(-) diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphExplorer.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphExplorer.java index 13a381cadff..6665de10713 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphExplorer.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphExplorer.java @@ -42,7 +42,7 @@ public final class GraphExplorer { private final RealtimeFeed realtimeFeed; private final boolean reverse; private final Weighting accessEgressWeighting; - private final boolean walkOnly; + private final boolean streetOnly; private final boolean ptOnly; private final double walkSpeedKmH; private final boolean ignoreValidities; @@ -50,7 +50,7 @@ public final class GraphExplorer { private final PtGraph ptGraph; private final Graph graph; - public GraphExplorer(Graph graph, PtGraph ptGraph, Weighting accessEgressWeighting, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, boolean reverse, boolean walkOnly, boolean ptOnly, double walkSpeedKmh, boolean ignoreValidities, int blockedRouteTypes) { + public GraphExplorer(Graph graph, PtGraph ptGraph, Weighting accessEgressWeighting, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, boolean reverse, boolean streetOnly, boolean ptOnly, double walkSpeedKmh, boolean ignoreValidities, int blockedRouteTypes) { this.graph = graph; this.ptGraph = ptGraph; this.accessEgressWeighting = accessEgressWeighting; @@ -60,7 +60,7 @@ public GraphExplorer(Graph graph, PtGraph ptGraph, Weighting accessEgressWeighti this.gtfsStorage = gtfsStorage; this.realtimeFeed = realtimeFeed; this.reverse = reverse; - this.walkOnly = walkOnly; + this.streetOnly = streetOnly; this.ptOnly = ptOnly; this.walkSpeedKmH = walkSpeedKmh; } @@ -105,14 +105,14 @@ public boolean tryAdvance(Consumer action) { // off the priority queue. Additionally, when only walking, // don't bother finding the enterEdge, because we are not going to enter. if (edgeType == GtfsStorage.EdgeType.ENTER_TIME_EXPANDED_NETWORK) { - if (walkOnly) { + if (streetOnly) { return false; } else { action.accept(new MultiModalEdge(findEnterEdge(edge))); // fully consumes edgeIterator return true; } } - if (walkOnly && edgeType != (reverse ? GtfsStorage.EdgeType.EXIT_PT : GtfsStorage.EdgeType.ENTER_PT)) { + if (streetOnly && edgeType != (reverse ? GtfsStorage.EdgeType.EXIT_PT : GtfsStorage.EdgeType.ENTER_PT)) { continue; } if (!(ignoreValidities || isValidOn(edge, currentTime))) { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java index 05023b60fd8..1cda4a6f74d 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java @@ -21,6 +21,7 @@ import com.conveyal.gtfs.model.Transfer; import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperConfig; +import com.graphhopper.config.Profile; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; @@ -89,8 +90,16 @@ protected void importPublicTransit() { Transfers transfers = new Transfers(gtfsFeed); allTransfers.put(id, transfers); GtfsReader gtfsReader = new GtfsReader(id, ptGraph, ptGraph, getGtfsStorage(), getLocationIndex(), transfers, indexBuilder); - Weighting weighting = createWeighting(getProfile("foot"), new PMap()); - gtfsReader.connectStopsToStreetNetwork(new DefaultSnapFilter(weighting, getEncodingManager().getBooleanEncodedValue(Subnetwork.key("foot")))); + // Stops must be connected to the networks of all the modes + List snapFilters = getProfiles().stream().map(p -> + new DefaultSnapFilter(createWeighting(p, new PMap()), getEncodingManager().getBooleanEncodedValue(Subnetwork.key(p.getName())))).collect(Collectors.toList()); + gtfsReader.connectStopsToStreetNetwork(e -> { + for (DefaultSnapFilter snapFilter : snapFilters) { + if (!snapFilter.accept(e)) + return false; + } + return true; + }); LOGGER.info("Building transit graph for feed {}", gtfsFeed.feedId); gtfsReader.buildPtNetwork(); allReaders.put(id, gtfsReader); @@ -167,6 +176,8 @@ private boolean isValidPath(int[] edgeKeys) { if (edges.get(i).getBaseNode() != edges.get(i-1).getAdjNode()) return false; } + TripFromLabel tripFromLabel = new TripFromLabel(getBaseGraph(), getEncodingManager(), gtfsStorage, RealtimeFeed.empty(), getPathDetailsBuilderFactory(), 6.0); + tripFromLabel.transferPath(edgeKeys, createWeighting(getProfile("foot"), new PMap()), 0L); return true; } diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java index b6326417288..96ddcd195ab 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java @@ -141,6 +141,8 @@ private class RequestHandler { private final Profile accessProfile; private final EdgeFilter accessSnapFilter; private final Weighting accessWeighting; + private final Profile transferProfile; + private final Weighting transferWeighting; private final Profile egressProfile; private final EdgeFilter egressSnapFilter; private final Weighting egressWeighting; @@ -167,6 +169,8 @@ private class RequestHandler { accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getName()))); + transferProfile = config.getProfiles().stream().filter(p -> p.getName().equals("foot")).findFirst().get(); + transferWeighting = weightingFactory.createWeighting(transferProfile, new PMap(), false); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getName()))); @@ -195,7 +199,7 @@ GHResponse route() { private void parseSolutionsAndAddToResponse(List> solutions, PointList waypoints) { TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, encodingManager, gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); for (List solution : solutions) { - final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, solution, requestedPathDetails); + final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, transferWeighting, solution, requestedPathDetails); responsePath.setImpossible(solution.stream().anyMatch(t -> t.label.impossible)); responsePath.setTime((solution.get(solution.size() - 1).label.currentTime - solution.get(0).label.currentTime)); responsePath.setRouteWeight(router.weight(solution.get(solution.size() - 1).label)); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java index 5238727cc1a..8e573cc7ff2 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java @@ -121,7 +121,8 @@ private class RequestHandler { private final boolean arriveBy; private final boolean ignoreTransfers; private final double betaTransfers; - private final double betaStreetTime; + private final double betaAccessTime; + private final double betaEgressTime; private final double walkSpeedKmH; private final int blockedRouteTypes; private final Map transferPenaltiesByRouteType; @@ -140,6 +141,8 @@ private class RequestHandler { private final Profile accessProfile; private final EdgeFilter accessSnapFilter; private final Weighting accessWeighting; + private final Profile transferProfile; + private final Weighting transferWeighting; private final Profile egressProfile; private final EdgeFilter egressSnapFilter; private final Weighting egressWeighting; @@ -149,7 +152,8 @@ private class RequestHandler { profileQuery = request.isProfileQuery(); ignoreTransfers = Optional.ofNullable(request.getIgnoreTransfers()).orElse(request.isProfileQuery()); betaTransfers = request.getBetaTransfers(); - betaStreetTime = request.getBetaStreetTime(); + betaAccessTime = request.getBetaAccessTime(); + betaEgressTime = request.getBetaEgressTime(); limitSolutions = Optional.ofNullable(request.getLimitSolutions()).orElse(profileQuery ? 50 : ignoreTransfers ? 1 : Integer.MAX_VALUE); initialTime = request.getEarliestDepartureTime(); maxProfileDuration = request.getMaxProfileDuration().toMillis(); @@ -166,6 +170,8 @@ private class RequestHandler { accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); accessSnapFilter = new DefaultSnapFilter(accessWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getName()))); + transferProfile = config.getProfiles().stream().filter(p -> p.getName().equals("foot")).findFirst().get(); + transferWeighting = weightingFactory.createWeighting(transferProfile, new PMap(), false); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); egressSnapFilter = new DefaultSnapFilter(egressWeighting, encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getName()))); @@ -194,7 +200,7 @@ GHResponse route() { private void parseSolutionsAndAddToResponse(List> solutions, PointList waypoints) { TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, encodingManager, gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); for (List solution : solutions) { - final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, solution, requestedPathDetails); + final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, transferWeighting, solution, requestedPathDetails); responsePath.setImpossible(solution.stream().anyMatch(t -> t.label.impossible)); responsePath.setTime((solution.get(solution.size() - 1).label.currentTime - solution.get(0).label.currentTime)); responsePath.setRouteWeight(router.weight(solution.get(solution.size() - 1).label)); @@ -211,7 +217,7 @@ private List> findPaths(Label.NodeId startNode, Label.Nod final GraphExplorer accessEgressGraphExplorer = new GraphExplorer(queryGraph, ptGraph, isEgress ? egressWeighting : accessWeighting, gtfsStorage, realtimeFeed, isEgress, true, false, walkSpeedKmH, false, blockedRouteTypes); GtfsStorage.EdgeType edgeType = isEgress ? GtfsStorage.EdgeType.EXIT_PT : GtfsStorage.EdgeType.ENTER_PT; MultiCriteriaLabelSetting stationRouter = new MultiCriteriaLabelSetting(accessEgressGraphExplorer, isEgress, false, false, maxProfileDuration, new ArrayList<>()); - stationRouter.setBetaStreetTime(betaStreetTime); + stationRouter.setBetaStreetTime(isEgress ? betaEgressTime : betaAccessTime); stationRouter.setLimitStreetTime(limitStreetTime); List