Repository: graphhopper/graphhopper
Pull request #2713 (2023-01-03 11:02:58)

Remove name and turn cost encoded value from vehicle tag parsers
With this PR the VehicleTagParsers no longer have a special role in OSMParsers and are treated like ordinary WayTagParsers. VehicleTagParser is now just a common base class for the different vehicles and the 'name' is derived from the prefix of the `xyz_access` encoded value. The turn cost encoded value is handled separately and the abstract `WayAccess getAccess(ReaderWay way);` method is gone.


Patch:
diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh
index 0b1794ba6..b59845563 100755
--- a/benchmark/benchmark.sh
+++ b/benchmark/benchmark.sh
@@ -35,7 +35,7 @@ mkdir -p ${RESULTS_DIR}
 mkdir -p ${SUMMARY_DIR}
 
 # actually run the benchmarks:
-echo "1 - small map: node- and edge-based CH + slow routing"
+echo "1 - small map: node- and edge-based CH + landmarks (edge- & node-based for LM) + slow routing"
 java -cp tools/target/graphhopper-tools-*-jar-with-dependencies.jar \
 -XX:+UseParallelGC -Xmx20g -Xms20g \
 com.graphhopper.tools.Measurement \
@@ -51,7 +51,9 @@ measurement.run_slow_routing=true \
 measurement.weighting=fastest \
 measurement.ch.node=true \
 measurement.ch.edge=true \
-measurement.lm=false \
+measurement.lm=true \
+"measurement.lm.active_counts=[4,8,12]" \
+measurement.lm.edge_based=true \
 measurement.vehicle=car \
 import.osm.ignored_highways=footway,cycleway,path,pedestrian,bridleway \
 measurement.turn_costs=true \
@@ -62,7 +64,7 @@ measurement.count=5000 \
 measurement.use_measurement_time_as_ref_time=${USE_MEASUREMENT_TIME_AS_REF_TIME} \
 "measurement.block_area=49.394664,11.144428,49.348388,11.144943,49.355768,11.227169,49.411643,11.227512"
 
-echo "2 - big map: node-based CH + landmarks (edge- & node-based for LM)"
+echo "2 - big map: node-based CH + landmarks (edge- & node-based for LM) + slow routing"
 java -cp tools/target/graphhopper-tools-*-jar-with-dependencies.jar \
 -XX:+UseParallelGC -Xmx20g -Xms20g \
 com.graphhopper.tools.Measurement \
@@ -74,7 +76,7 @@ measurement.clean=true \
 measurement.stop_on_error=true \
 measurement.summaryfile=${SUMMARY_DIR}summary_big.dat \
 measurement.repeats=1 \
-measurement.run_slow_routing=false \
+measurement.run_slow_routing=true \
 measurement.weighting=fastest \
 measurement.ch.node=true \
 measurement.ch.edge=false \
diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java
index b146bfa0f..5412eabd9 100644
--- a/core/src/main/java/com/graphhopper/GraphHopper.java
+++ b/core/src/main/java/com/graphhopper/GraphHopper.java
@@ -24,6 +24,7 @@ import com.graphhopper.config.LMProfile;
 import com.graphhopper.config.Profile;
 import com.graphhopper.reader.dem.*;
 import com.graphhopper.reader.osm.OSMReader;
+import com.graphhopper.reader.osm.RestrictionTagParser;
 import com.graphhopper.reader.osm.conditional.DateRangeParser;
 import com.graphhopper.routing.*;
 import com.graphhopper.routing.ch.CHPreparationHandler;
@@ -669,7 +670,10 @@ public class GraphHopper {
                 if (encodingManager.hasEncodedValue(FootNetwork.KEY))
                     osmParsers.addRelationTagParser(relConfig -> new OSMFootNetworkTagParser(encodingManager.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), relConfig));
             }
-            osmParsers.addVehicleTagParser(vehicleTagParser);
+            osmParsers.addWayTagParser(vehicleTagParser);
+            String turnCostKey = TurnCost.key(new PMap(vehicleStr).getString("name", name));
+            if (encodingManager.hasEncodedValue(turnCostKey))
+                osmParsers.addRestrictionTagParser(new RestrictionTagParser(vehicleTagParser.getRestrictions(), encodingManager.getDecimalEncodedValue(turnCostKey)));
         });
         return osmParsers;
     }
@@ -691,15 +695,15 @@ public class GraphHopper {
                 throw new IllegalArgumentException("Duplicate flag encoder: " + name + " in: " + encoderStr);
             vehiclesMap.put(name, encoderStr);
         }
-        Map<String, String> flagEncodersFromProfilesMap = new LinkedHashMap<>();
+        Map<String, String> vehiclesFromProfiles = new LinkedHashMap<>();
         for (Profile profile : profiles) {
-            // if a profile uses a flag encoder with turn costs make sure we add that flag encoder with turn costs
+            // if a profile uses a vehicle with turn costs make sure we add that vehicle with turn costs
             String vehicle = profile.getVehicle().trim();
-            if (!flagEncodersFromProfilesMap.containsKey(vehicle) || profile.isTurnCosts())
-                flagEncodersFromProfilesMap.put(vehicle, vehicle + (profile.isTurnCosts() ? "|turn_costs=true" : ""));
+            if (!vehiclesFromProfiles.containsKey(vehicle) || profile.isTurnCosts())
+                vehiclesFromProfiles.put(vehicle, vehicle + (profile.isTurnCosts() ? "|turn_costs=true" : ""));
         }
-        // flag encoders from profiles are only taken into account when they were not given explicitly
-        flagEncodersFromProfilesMap.forEach(vehiclesMap::putIfAbsent);
+        // vehicles from profiles are only taken into account when they were not given explicitly
+        vehiclesFromProfiles.forEach(vehiclesMap::putIfAbsent);
         return vehiclesMap;
     }
 
diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java
index 2421ad541..1a6a467d9 100644
--- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java
@@ -61,8 +61,8 @@ abstract public class BikeCommonTagParser extends VehicleTagParser {
 
     protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
                                   EnumEncodedValue<RouteNetwork> bikeRouteEnc, EnumEncodedValue<Smoothness> smoothnessEnc,
-                                  String name, BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) {
-        super(accessEnc, speedEnc, name, roundaboutEnc, turnCostEnc, TransportationMode.BIKE, speedEnc.getNextStorableValue(MAX_SPEED));
+                                  BooleanEncodedValue roundaboutEnc) {
+        super(accessEnc, speedEnc, roundaboutEnc, TransportationMode.BIKE, speedEnc.getNextStorableValue(MAX_SPEED));
         this.bikeRouteEnc = bikeRouteEnc;
         this.smoothnessEnc = smoothnessEnc;
         this.priorityEnc = priorityEnc;
@@ -191,7 +191,6 @@ abstract public class BikeCommonTagParser extends VehicleTagParser {
         setAvoidSpeedLimit(71);
     }
 
-    @Override
     public WayAccess getAccess(ReaderWay way) {
         String highwayValue = way.getTag("highway");
         if (highwayValue == null) {
diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java
index 05fcf491c..12a630274 100644
--- a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java
@@ -20,8 +20,6 @@ package com.graphhopper.routing.util;
 import com.graphhopper.routing.ev.*;
 import com.graphhopper.util.PMap;
 
-import static com.graphhopper.routing.ev.Smoothness.*;
-
 /**
  * Specifies the settings for cycletouring/trekking
  *
@@ -37,9 +35,7 @@ public class BikeTagParser extends BikeCommonTagParser {
                 lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "bike"))),
                 lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class),
                 lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class),
-                properties.getString("name", "bike"),
-                lookup.getBooleanEncodedValue(Roundabout.KEY),
-                lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "bike"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "bike"))) : null
+                lookup.getBooleanEncodedValue(Roundabout.KEY)
         );
         blockPrivate(properties.getBool("block_private", true));
         blockFords(properties.getBool("block_fords", false));
@@ -47,8 +43,8 @@ public class BikeTagParser extends BikeCommonTagParser {
 
     public BikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
                          EnumEncodedValue<RouteNetwork> bikeRouteEnc, EnumEncodedValue<Smoothness> smoothnessEnc,
-                         String name, BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) {
-        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, name, roundaboutEnc, turnCostEnc);
+                         BooleanEncodedValue roundaboutEnc) {
+        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, roundaboutEnc);
         addPushingSection("path");
         addPushingSection("footway");
         addPushingSection("pedestrian");
diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java
index e2b670163..99693c062 100644
--- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java
@@ -53,7 +53,6 @@ public class CarTagParser extends VehicleTagParser {
         this(
                 lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car"))),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "car"))),
-                lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car"))) : null,
                 lookup.getBooleanEncodedValue(Roundabout.KEY),
                 properties,
                 TransportationMode.CAR,
@@ -61,12 +60,10 @@ public class CarTagParser extends VehicleTagParser {
         );
     }
 
-    public CarTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc,
+    public CarTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc,
                         BooleanEncodedValue roundaboutEnc, PMap properties,
                         TransportationMode transportationMode, double maxPossibleSpeed) {
-        super(accessEnc, speedEnc,
-                properties.getString("name", "car"), roundaboutEnc,
-                turnCostEnc, transportationMode, maxPossibleSpeed);
+        super(accessEnc, speedEnc, roundaboutEnc, transportationMode, maxPossibleSpeed);
         restrictedValues.add("agricultural");
         restrictedValues.add("forestry");
         restrictedValues.add("no");
@@ -158,7 +155,6 @@ public class CarTagParser extends VehicleTagParser {
         return speed;
     }
 
-    @Override
     public WayAccess getAccess(ReaderWay way) {
         // TODO: Ferries have conditionals, like opening hours or are closed during some time in the year
         String highwayValue = way.getTag("highway");
@@ -174,7 +170,7 @@ public class CarTagParser extends VehicleTagParser {
             }
             return WayAccess.CAN_SKIP;
         }
-        
+
         if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) {
             return WayAccess.CAN_SKIP;
         }
@@ -192,7 +188,7 @@ public class CarTagParser extends VehicleTagParser {
         if (!firstValue.isEmpty()) {
             String[] restrict = firstValue.split(";");
             boolean notConditionalyPermitted = !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way);
-            for (String value: restrict) {
+            for (String value : restrict) {
                 if (restrictedValues.contains(value) && notConditionalyPermitted)
                     return WayAccess.CAN_SKIP;
                 if (intendedValues.contains(value))
diff --git a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java
index d3fb6218b..ee8d87c01 100644
--- a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java
@@ -57,16 +57,15 @@ public class FootTagParser extends VehicleTagParser {
                 lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "foot"))),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "foot"))),
                 lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "foot"))),
-                lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class),
-                "foot"
+                lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class)
         );
         blockPrivate(properties.getBool("block_private", true));
         blockFords(properties.getBool("block_fords", false));
     }
 
     protected FootTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
-                            EnumEncodedValue<RouteNetwork> footRouteEnc, String name) {
-        super(accessEnc, speedEnc, name, null, null, TransportationMode.FOOT, speedEnc.getNextStorableValue(FERRY_SPEED));
+                            EnumEncodedValue<RouteNetwork> footRouteEnc) {
+        super(accessEnc, speedEnc, null, TransportationMode.FOOT, speedEnc.getNextStorableValue(FERRY_SPEED));
         this.footRouteEnc = footRouteEnc;
         priorityWayEncoder = priorityEnc;
 
@@ -133,7 +132,6 @@ public class FootTagParser extends VehicleTagParser {
     /**
      * Some ways are okay but not separate for pedestrians.
      */
-    @Override
     public WayAccess getAccess(ReaderWay way) {
         String highwayValue = way.getTag("highway");
         if (highwayValue == null) {
diff --git a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java
index b275f69fa..4f48e9f5d 100644
--- a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java
@@ -41,16 +41,15 @@ public class HikeTagParser extends FootTagParser {
                 lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "hike"))),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "hike"))),
                 lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "hike"))),
-                lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class),
-                properties.getString("name", "hike")
+                lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class)
         );
         blockPrivate(properties.getBool("block_private", true));
         blockFords(properties.getBool("block_fords", false));
     }
 
     protected HikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
-                            EnumEncodedValue<RouteNetwork> footRouteEnc, String name) {
-        super(accessEnc, speedEnc, priorityEnc, footRouteEnc, name);
+                            EnumEncodedValue<RouteNetwork> footRouteEnc) {
+        super(accessEnc, speedEnc, priorityEnc, footRouteEnc);
 
         routeMap.put(INTERNATIONAL, BEST.getValue());
         routeMap.put(NATIONAL, BEST.getValue());
diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java
index ee71ad086..1d94859f3 100644
--- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java
@@ -21,15 +21,10 @@ import com.graphhopper.reader.ReaderWay;
 import com.graphhopper.routing.ev.*;
 import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor;
 import com.graphhopper.storage.IntsRef;
-import com.graphhopper.util.DistanceCalcEarth;
-import com.graphhopper.util.EdgeIteratorState;
 import com.graphhopper.util.PMap;
-import com.graphhopper.util.PointList;
 
 import java.util.HashSet;
 
-import static com.graphhopper.routing.util.EncodingManager.getKey;
-
 /**
  * Defines bit layout for motorbikes
  * <p>
@@ -47,7 +42,6 @@ public class MotorcycleTagParser extends CarTagParser {
         this(
                 lookup.getBooleanEncodedValue(VehicleAccess.key("motorcycle")),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key("motorcycle")),
-                lookup.hasEncodedValue(TurnCost.key("motorcycle")) ? lookup.getDecimalEncodedValue(TurnCost.key("motorcycle")) : null,
                 lookup.getBooleanEncodedValue(Roundabout.KEY),
                 lookup.getDecimalEncodedValue(VehiclePriority.key("motorcycle")),
                 new PMap(properties).putObject("name", "motorcycle"),
@@ -55,10 +49,10 @@ public class MotorcycleTagParser extends CarTagParser {
         );
     }
 
-    public MotorcycleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc,
+    public MotorcycleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc,
                                BooleanEncodedValue roundaboutEnc,
                                DecimalEncodedValue priorityWayEncoder, PMap properties, TransportationMode transportationMode) {
-        super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", "motorcycle"),
+        super(accessEnc, speedEnc, roundaboutEnc, new PMap(properties).putObject("name", "motorcycle"),
                 transportationMode, speedEnc.getNextStorableValue(MOTOR_CYCLE_MAX_SPEED));
         this.priorityWayEncoder = priorityWayEncoder;
 
diff --git a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java
index ef38bec1c..2a2b32d90 100644
--- a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java
@@ -42,8 +42,7 @@ public class MountainBikeTagParser extends BikeCommonTagParser {
                 lookup.getDecimalEncodedValue(VehiclePriority.key("mtb")),
                 lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class),
                 lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class),
-                lookup.getBooleanEncodedValue(Roundabout.KEY),
-                lookup.hasEncodedValue(TurnCost.key("mtb")) ? lookup.getDecimalEncodedValue(TurnCost.key("mtb")) : null
+                lookup.getBooleanEncodedValue(Roundabout.KEY)
         );
         blockPrivate(properties.getBool("block_private", true));
         blockFords(properties.getBool("block_fords", false));
@@ -51,9 +50,8 @@ public class MountainBikeTagParser extends BikeCommonTagParser {
 
     protected MountainBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
                                     EnumEncodedValue<RouteNetwork> bikeRouteEnc, EnumEncodedValue<Smoothness> smoothnessEnc,
-                                    BooleanEncodedValue roundaboutEnc,
-                                    DecimalEncodedValue turnCostEnc) {
-        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, "mtb", roundaboutEnc, turnCostEnc);
+                                    BooleanEncodedValue roundaboutEnc) {
+        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, roundaboutEnc);
         setTrackTypeSpeed("grade1", 18); // paved
         setTrackTypeSpeed("grade2", 16); // now unpaved ...
         setTrackTypeSpeed("grade3", 12);
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 efbd4e01f..d0d5fd3a4 100644
--- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java
+++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java
@@ -33,20 +33,18 @@ import java.util.function.Function;
 public class OSMParsers {
     private final List<String> ignoredHighways;
     private final List<TagParser> wayTagParsers;
-    private final List<VehicleTagParser> vehicleTagParsers;
     private final List<RelationTagParser> relationTagParsers;
     private final List<RestrictionTagParser> restrictionTagParsers;
     private final EncodedValue.InitializerConfig relConfig = new EncodedValue.InitializerConfig();
 
     public OSMParsers() {
-        this(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+        this(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
     }
 
-    public OSMParsers(List<String> ignoredHighways, List<TagParser> wayTagParsers, List<VehicleTagParser> vehicleTagParsers,
+    public OSMParsers(List<String> ignoredHighways, List<TagParser> wayTagParsers,
                       List<RelationTagParser> relationTagParsers, List<RestrictionTagParser> restrictionTagParsers) {
         this.ignoredHighways = ignoredHighways;
         this.wayTagParsers = wayTagParsers;
-        this.vehicleTagParsers = vehicleTagParsers;
         this.relationTagParsers = relationTagParsers;
         this.restrictionTagParsers = restrictionTagParsers;
     }
@@ -61,14 +59,6 @@ public class OSMParsers {
         return this;
     }
 
-    public OSMParsers addVehicleTagParser(VehicleTagParser vehicleTagParser) {
-        vehicleTagParsers.add(vehicleTagParser);
-        if (vehicleTagParser.supportsTurnCosts()) {
-            restrictionTagParsers.add(new RestrictionTagParser(vehicleTagParser.getRestrictions(), vehicleTagParser.getTurnCostEnc()));
-        }
-        return this;
-    }
-
     public OSMParsers addRelationTagParser(Function<EncodedValue.InitializerConfig, RelationTagParser> createRelationTagParser) {
         relationTagParsers.add(createRelationTagParser.apply(relConfig));
         return this;
@@ -108,8 +98,6 @@ public class OSMParsers {
             relParser.handleWayTags(edgeFlags, way, relationFlags);
         for (TagParser parser : wayTagParsers)
             parser.handleWayTags(edgeFlags, way, relationFlags);
-        for (VehicleTagParser vehicleTagParser : vehicleTagParsers)
-            vehicleTagParser.handleWayTags(edgeFlags, way, relationFlags);
         return edgeFlags;
     }
 
@@ -124,8 +112,12 @@ public class OSMParsers {
         return ignoredHighways;
     }
 
-    public List<VehicleTagParser> getVehicleTagParsers() {
-        return vehicleTagParsers;
+    public List<TagParser> getWayTagParsers() {
+        return wayTagParsers;
+    }
+
+    public List<RelationTagParser> getRelationTagParsers() {
+        return relationTagParsers;
     }
 
     public List<RestrictionTagParser> getRestrictionTagParsers() {
diff --git a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java
index 63097b67b..25ec8eee5 100644
--- a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java
@@ -41,8 +41,7 @@ public class RacingBikeTagParser extends BikeCommonTagParser {
                 lookup.getDecimalEncodedValue(VehiclePriority.key("racingbike")),
                 lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class),
                 lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class),
-                lookup.getBooleanEncodedValue(Roundabout.KEY),
-                lookup.hasEncodedValue(TurnCost.key("racingbike")) ? lookup.getDecimalEncodedValue(TurnCost.key("racingbike")) : null
+                lookup.getBooleanEncodedValue(Roundabout.KEY)
         );
         blockPrivate(properties.getBool("block_private", true));
         blockFords(properties.getBool("block_fords", false));
@@ -50,8 +49,8 @@ public class RacingBikeTagParser extends BikeCommonTagParser {
 
     protected RacingBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
                                   EnumEncodedValue<RouteNetwork> bikeRouteEnc, EnumEncodedValue<Smoothness> smoothnessEnc,
-                                  BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) {
-        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, "racingbike", roundaboutEnc, turnCostEnc);
+                                  BooleanEncodedValue roundaboutEnc) {
+        super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, roundaboutEnc);
         preferHighwayTags.add("road");
         preferHighwayTags.add("secondary");
         preferHighwayTags.add("secondary_link");
diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java
index f92d8f597..13f19c783 100644
--- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java
@@ -14,16 +14,14 @@ public class RoadsTagParser extends VehicleTagParser {
         super(
                 lookup.getBooleanEncodedValue(VehicleAccess.key("roads")),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key("roads")),
-                "roads",
                 lookup.getBooleanEncodedValue(Roundabout.KEY),
-                lookup.hasEncodedValue(TurnCost.key("roads")) ? lookup.getDecimalEncodedValue(TurnCost.key("roads")) : null,
                 TransportationMode.valueOf(properties.getString("transportation_mode", "VEHICLE")),
                 lookup.getDecimalEncodedValue(VehicleSpeed.key("roads")).getNextStorableValue(ROADS_MAX_SPEED)
         );
     }
 
-    public RoadsTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc) {
-        super(accessEnc, speedEnc, "roads", null, turnCostEnc, TransportationMode.VEHICLE, speedEnc.getNextStorableValue(ROADS_MAX_SPEED));
+    public RoadsTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) {
+        super(accessEnc, speedEnc, null, TransportationMode.VEHICLE, speedEnc.getNextStorableValue(ROADS_MAX_SPEED));
     }
 
     @Override
@@ -38,13 +36,6 @@ public class RoadsTagParser extends VehicleTagParser {
         return edgeFlags;
     }
 
-    @Override
-    public WayAccess getAccess(ReaderWay way) {
-        if (way.getTag("highway", "").isEmpty())
-            return WayAccess.CAN_SKIP;
-        return WayAccess.WAY;
-    }
-
     @Override
     public boolean isBarrier(ReaderNode node) {
         return false;
diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java
index 365660a11..9670463f2 100644
--- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java
@@ -24,6 +24,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.DecimalEncodedValue;
+import com.graphhopper.routing.ev.VehicleAccess;
 import com.graphhopper.routing.util.parsers.OSMRoadAccessParser;
 import com.graphhopper.routing.util.parsers.TagParser;
 import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor;
@@ -42,7 +43,6 @@ import static java.util.Collections.emptyMap;
  * @see EncodingManager
  */
 public abstract class VehicleTagParser implements TagParser {
-    private final String name;
     protected final Set<String> intendedValues = new HashSet<>(5);
     // order is important
     protected final List<String> restrictions = new ArrayList<>(5);
@@ -53,7 +53,6 @@ public abstract class VehicleTagParser implements TagParser {
     protected final Set<String> barriers = new HashSet<>(5);
     protected final BooleanEncodedValue accessEnc;
     protected final DecimalEncodedValue avgSpeedEnc;
-    private final DecimalEncodedValue turnCostEnc;
     protected final BooleanEncodedValue roundaboutEnc;
     // This value determines the maximal possible speed of any road regardless of the maxspeed value
     // lower values allow more compact representation of the routing graph
@@ -62,15 +61,12 @@ public abstract class VehicleTagParser implements TagParser {
     private ConditionalTagInspector conditionalTagInspector;
     protected final FerrySpeedCalculator ferrySpeedCalc;
 
-    protected VehicleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, String name,
-                               BooleanEncodedValue roundaboutEnc,
-                               DecimalEncodedValue turnCostEnc, TransportationMode transportationMode, double maxPossibleSpeed) {
-        this.name = name;
+    protected VehicleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, BooleanEncodedValue roundaboutEnc,
+                               TransportationMode transportationMode, double maxPossibleSpeed) {
         this.maxPossibleSpeed = maxPossibleSpeed;
 
         this.accessEnc = accessEnc;
         this.avgSpeedEnc = speedEnc;
-        this.turnCostEnc = turnCostEnc;
         this.roundaboutEnc = roundaboutEnc;
 
         oneways.add("yes");
@@ -147,14 +143,6 @@ public abstract class VehicleTagParser implements TagParser {
         return edgeFlags;
     }
 
-    /**
-     * Decide whether a way is routable for a given mode of travel. This skips some ways before
-     * handleWayTags is called.
-     *
-     * @return the encoded value to indicate if this encoder allows travel or not.
-     */
-    public abstract WayAccess getAccess(ReaderWay way);
-
     /**
      * @return true if the given OSM node blocks access for this vehicle, false otherwise
      */
@@ -215,19 +203,16 @@ public abstract class VehicleTagParser implements TagParser {
         }
     }
 
-    public boolean supportsTurnCosts() {
-        return turnCostEnc != null;
-    }
-
-    public DecimalEncodedValue getTurnCostEnc() {
-        return turnCostEnc;
-    }
-
     public final List<String> getRestrictions() {
         return restrictions;
     }
 
     public final String getName() {
+        String name = accessEnc.getName().replaceAll("_access", "");
+        // safety check for the time being
+        String expectedKey = VehicleAccess.key(name);
+        if (!accessEnc.getName().equals(expectedKey))
+            throw new IllegalStateException("Expected access key '" + expectedKey + "', but got: " + accessEnc.getName());
         return name;
     }
 
diff --git a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java
index 99c7deb27..ca85483d3 100644
--- a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java
@@ -53,7 +53,7 @@ public class WheelchairTagParser extends FootTagParser {
 
     protected WheelchairTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc,
                                   EnumEncodedValue<RouteNetwork> footRouteEnc) {
-        super(accessEnc, speedEnc, priorityEnc, footRouteEnc, "wheelchair");
+        super(accessEnc, speedEnc, priorityEnc, footRouteEnc);
 
         restrictions.add("wheelchair");
 


Test patch:
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 2faa90412..91b577a7c 100644
--- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
+++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
@@ -667,7 +667,6 @@ public class OSMReaderTest {
                 return new CarTagParser(
                         lookup.getBooleanEncodedValue(VehicleAccess.key("truck")),
                         lookup.getDecimalEncodedValue(VehicleSpeed.key("truck")),
-                        lookup.hasEncodedValue(TurnCost.key("truck")) ? lookup.getDecimalEncodedValue(TurnCost.key("truck")) : null,
                         lookup.getBooleanEncodedValue(Roundabout.KEY),
                         config,
                         TransportationMode.HGV,
@@ -906,7 +905,7 @@ public class OSMReaderTest {
         osmParsers.addWayTagParser(new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)));
         CarTagParser parser = new CarTagParser(em, new PMap());
         parser.init(new DateRangeParser());
-        osmParsers.addVehicleTagParser(parser);
+        osmParsers.addWayTagParser(parser);
         BaseGraph graph = new BaseGraph.Builder(em).create();
         OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig());
         reader.setCountryRuleFactory(new CountryRuleFactory());
@@ -942,7 +941,7 @@ public class OSMReaderTest {
         carParser.init(new DateRangeParser());
         OSMParsers osmParsers = new OSMParsers()
                 .addWayTagParser(new CountryParser(countryEnc))
-                .addVehicleTagParser(carParser);
+                .addWayTagParser(carParser);
         BaseGraph graph = new BaseGraph.Builder(em).create();
         OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig());
         reader.setCountryRuleFactory(new CountryRuleFactory());
diff --git a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java
index 1a66c9db2..bcab4c30f 100644
--- a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java
+++ b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java
@@ -64,7 +64,7 @@ public class TrafficChangeWithNodeOrderingReusingTest {
             CarTagParser carParser = new CarTagParser(em, new PMap());
             carParser.init(new DateRangeParser());
             osmParsers = new OSMParsers()
-                    .addVehicleTagParser(carParser);
+                    .addWayTagParser(carParser);
             baseCHConfig = CHConfig.nodeBased("base", new FastestWeighting(accessEnc, speedEnc));
             trafficCHConfig = CHConfig.nodeBased("traffic", new RandomDeviationWeighting(baseCHConfig.getWeighting(), accessEnc, speedEnc, maxDeviationPercentage));
             graph = new BaseGraph.Builder(em).create();
diff --git a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java
index 7337545a4..0a4403a39 100644
--- a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java
@@ -59,7 +59,7 @@ public class BikeTagParserTest extends AbstractBikeTagParserTester {
         return new OSMParsers()
                 .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig))
                 .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class)))
-                .addVehicleTagParser(parser);
+                .addWayTagParser(parser);
     }
 
     @Test
diff --git a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java
index 5bd6d6a27..41dc53872 100644
--- a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java
@@ -53,7 +53,7 @@ public class MountainBikeTagParserTest extends AbstractBikeTagParserTester {
         return new OSMParsers()
                 .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig))
                 .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class)))
-                .addVehicleTagParser(parser);
+                .addWayTagParser(parser);
     }
 
     @Test
diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java
index e36f71772..78b49244a 100644
--- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java
@@ -56,7 +56,7 @@ public class RacingBikeTagParserTest extends AbstractBikeTagParserTester {
         return new OSMParsers()
                 .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig))
                 .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class)))
-                .addVehicleTagParser(parser);
+                .addWayTagParser(parser);
     }
 
     @Test
diff --git a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java
index 07836bef6..6e63cebff 100644
--- a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java
@@ -19,17 +19,6 @@ class RoadsTagParserTest {
         parser.init(new DateRangeParser());
     }
 
-    @Test
-    public void testAccess() {
-        ReaderWay way = new ReaderWay(1);
-        assertTrue(parser.getAccess(way).canSkip());
-
-        way.setTag("highway", "motorway");
-        assertTrue(parser.getAccess(way).isWay());
-        way.setTag("highway", "footway");
-        assertTrue(parser.getAccess(way).isWay());
-    }
-
     @Test
     public void testSpeed() {
         ReaderWay way = new ReaderWay(1);