Repository: graphhopper/graphhopper (java)

Issue:
Initialization with example config should work like the default Java settings
I am author of https://graphhopper.develar.org/ and contributor of [locus-addon-graphhopper](https://github.com/asamm/locus-addon-graphhopper).

I working on updating to `1.0-pre18`, as latest release 0.13 version is not usable (see https://github.com/asamm/locus-addon-graphhopper/pull/4#issuecomment-577033241)

I regenerated all maps, but now I get error  ""Encoded values do not match:"" 
![image](https://user-images.githubusercontent.com/350686/72975013-595d4c80-3dd0-11ea-8cc1-9184e092d91c.png)

problem is that last shift `24` (config) is not equal to `27` (27).

I do not understand the error and what I should do to fix it. Looks like that check is too strict.

Android version: 8.1.0
Java version to generate routing data: 13.0.1+9-jre
gh config to build routing data: https://github.com/develar/gh-routing-data/blob/c0fe3f5a396c5a03a47bd8268c2691460291f56c/internal/builder/builder.go#L158

Android java code to create is very simple  (and it worked for 0.11):

```
GraphHopper gh = new GraphHopper().forMobile();
gh.setAllowWrites(false);
gh.setCHEnabled(true);
gh.setElevation(true);
boolean load = gh.load(routingItem.getAbsolutePath());
```


Pull request:
Improve picking up default graph
fixes #1862 

Done:

 - RouteNetwork.EV_SUFFIX is replaced via the simpler RouteNetwork.key() method that enforces the parameter. Same for TurnCost.EV_SUFFIX.
 - Made bike_network a shared EncodedValue (before it was in `bike` namespace and associated to a specific bike encoder which does not make much sense as it is valid for all BikeFlagEncoders)
 - force separating shared encoded values (come first) and encoded values of FlagEncoders (later)
 - default config.yml is now loadable via `new GraphHopper().load(graph-cache)`
 - bug fix in PathTest that used the wrong encoder
 - bug fix in EnumEncodedValue that calculated the size wrong and wasted a bit space

Patch:
diff --git a/config-example.yml b/config-example.yml
index 66a2b8062..f110de031 100644
--- a/config-example.yml
+++ b/config-example.yml
@@ -13,10 +13,10 @@ graphhopper:
   # Enable turn restrictions for car or motorcycle.
   # graph.flag_encoders: car|turn_costs=true
 
-  # Add additional information to every edge. Used for path details.
-  # If road_environment is added and elevation is enabled then also a tunnel and bridge interpolation is done, see #798.
-  # More options are: surface,max_width,max_height,max_weight,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type
-  graph.encoded_values: road_class,road_class_link,road_environment,max_speed,road_access
+  # Add additional information to every edge. Used for path details (#1548), better instructions (#1844) and tunnel/bridge interpolation (#798).
+  # Default values are: road_class,road_class_link,road_environment,max_speed,road_access (since #1805)
+  # More are: surface,max_width,max_height,max_weight,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type
+  # graph.encoded_values: surface,toll,track_type
 
   ##### Elevation #####
 
diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
index 1d23f95d3..995d747cd 100644
--- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
+++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
@@ -100,7 +100,7 @@ public class InstructionsFromEdges implements Path.EdgeVisitor {
         this.roundaboutEnc = evLookup.getBooleanEncodedValue(Roundabout.KEY);
 
         // both EncodedValues are optional; And return annotation only when instructions for bike encoder is requested
-        String key = getKey("bike", RouteNetwork.EV_SUFFIX);
+        String key = RouteNetwork.key("bike");
         this.bikeRouteEnc = evLookup.hasEncodedValue(key) ? evLookup.getEnumEncodedValue(key, RouteNetwork.class) : null;
         this.getOffBikeEnc = encoder instanceof BikeCommonFlagEncoder && evLookup.hasEncodedValue(GetOffBike.KEY)
                 ? evLookup.getBooleanEncodedValue(GetOffBike.KEY) : null;
diff --git a/core/src/main/java/com/graphhopper/routing/Path.java b/core/src/main/java/com/graphhopper/routing/Path.java
index 01634e842..281d60ab0 100644
--- a/core/src/main/java/com/graphhopper/routing/Path.java
+++ b/core/src/main/java/com/graphhopper/routing/Path.java
@@ -40,10 +40,10 @@ import java.util.List;
  * @author easbar
  */
 public class Path {
-    protected Graph graph;
-    protected double distance;
-    protected long time;
-    protected int endNode = -1;
+    Graph graph;
+    double distance;
+    long time;
+    int endNode = -1;
     private boolean reverseOrder = true;
     private List<String> description;
     private boolean found;
diff --git a/core/src/main/java/com/graphhopper/routing/profiles/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/profiles/DefaultEncodedValueFactory.java
index a36fbfbd8..8a90dac4b 100644
--- a/core/src/main/java/com/graphhopper/routing/profiles/DefaultEncodedValueFactory.java
+++ b/core/src/main/java/com/graphhopper/routing/profiles/DefaultEncodedValueFactory.java
@@ -17,7 +17,6 @@
  */
 package com.graphhopper.routing.profiles;
 
-import com.graphhopper.routing.util.EncodingManager;
 import com.graphhopper.util.Helper;
 
 public class DefaultEncodedValueFactory implements EncodedValueFactory {
@@ -62,8 +61,8 @@ public class DefaultEncodedValueFactory implements EncodedValueFactory {
             enc = new EnumEncodedValue<>(Toll.KEY, Toll.class);
         } else if (TrackType.KEY.equals(name)) {
             enc = new EnumEncodedValue<>(TrackType.KEY, TrackType.class);
-        } else if (name.endsWith(EncodingManager.getKey("", RouteNetwork.EV_SUFFIX))) {
-            enc = new EnumEncodedValue<>(EncodingManager.getKey(name, RouteNetwork.EV_SUFFIX), RouteNetwork.class);
+        } else if (name.endsWith(RouteNetwork.key(""))) {
+            enc = new EnumEncodedValue<>(name, RouteNetwork.class);
         } else if (Hazmat.KEY.equals(name)) {
             enc = new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class);
         } else if (HazmatTunnel.KEY.equals(name)) {
diff --git a/core/src/main/java/com/graphhopper/routing/profiles/EnumEncodedValue.java b/core/src/main/java/com/graphhopper/routing/profiles/EnumEncodedValue.java
index 6f689ae3f..0f7cbfe68 100644
--- a/core/src/main/java/com/graphhopper/routing/profiles/EnumEncodedValue.java
+++ b/core/src/main/java/com/graphhopper/routing/profiles/EnumEncodedValue.java
@@ -33,7 +33,7 @@ public final class EnumEncodedValue<E extends Enum> extends UnsignedIntEncodedVa
     }
 
     public EnumEncodedValue(String name, Class<E> enumType, boolean storeTwoDirections) {
-        super(name, 32 - Integer.numberOfLeadingZeros(enumType.getEnumConstants().length), storeTwoDirections);
+        super(name, 32 - Integer.numberOfLeadingZeros(enumType.getEnumConstants().length - 1), storeTwoDirections);
         arr = enumType.getEnumConstants();
     }
 
diff --git a/core/src/main/java/com/graphhopper/routing/profiles/RouteNetwork.java b/core/src/main/java/com/graphhopper/routing/profiles/RouteNetwork.java
index 0d421c7b0..e0576dabc 100644
--- a/core/src/main/java/com/graphhopper/routing/profiles/RouteNetwork.java
+++ b/core/src/main/java/com/graphhopper/routing/profiles/RouteNetwork.java
@@ -24,10 +24,9 @@ public enum RouteNetwork {
     OTHER("other"), INTERNATIONAL("international"), NATIONAL("national"), REGIONAL("regional"),
     LOCAL("local");
 
-    /**
-     * You need to call EncodingManager.getKey(prefix, EV_SUFFIX) as this EncodedValue can be used for e.g. bike and hike
-     */
-    public static final String EV_SUFFIX = "network";
+    public static String key(String prefix) {
+        return prefix + "_network";
+    }
 
     private final String name;
 
diff --git a/core/src/main/java/com/graphhopper/routing/profiles/TurnCost.java b/core/src/main/java/com/graphhopper/routing/profiles/TurnCost.java
index a93537248..d3c6b9b79 100644
--- a/core/src/main/java/com/graphhopper/routing/profiles/TurnCost.java
+++ b/core/src/main/java/com/graphhopper/routing/profiles/TurnCost.java
@@ -6,17 +6,17 @@ import com.graphhopper.util.Helper;
 import static com.graphhopper.routing.util.EncodingManager.getKey;
 
 public class TurnCost {
-    /**
-     * You need to call EncodingManager.getKey(prefix, EV_SUFFIX) as this EncodedValue can be used for e.g. car and bike
-     */
-    public final static String EV_SUFFIX = "turn_cost";
+
+    public static String key(String prefix) {
+        return getKey(prefix, "turn_cost");
+    }
 
     /**
      * This creates an EncodedValue specifically for the turn costs
      */
     public static DecimalEncodedValue create(String name, int maxTurnCosts) {
         int turnBits = Helper.countBitValue(maxTurnCosts);
-        return new UnsignedDecimalEncodedValue(getKey(name, EV_SUFFIX), turnBits, 1, 0, false, true);
+        return new UnsignedDecimalEncodedValue(key(name), turnBits, 1, 0, false, true);
     }
 
     public static IntsRef createFlags() {
diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java
index abdc8ba04..efb50d354 100644
--- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java
+++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java
@@ -207,7 +207,7 @@ abstract public class BikeCommonFlagEncoder extends AbstractFlagEncoder {
         registerNewEncodedValue.add(avgSpeedEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "average_speed"), speedBits, speedFactor, speedTwoDirections));
         registerNewEncodedValue.add(priorityEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 3, PriorityCode.getFactor(1), false));
 
-        bikeRouteEnc = getEnumEncodedValue(getKey("bike", EV_SUFFIX), RouteNetwork.class);
+        bikeRouteEnc = getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class);
     }
 
     @Override
@@ -474,7 +474,7 @@ abstract public class BikeCommonFlagEncoder extends AbstractFlagEncoder {
         if (pushingSectionsHighways.contains(highway)
                 || "parking_aisle".equals(service)) {
             int pushingSectionPrio = AVOID_IF_POSSIBLE.getValue();
-            if (way.hasTag("bicycle", "use_sidepath"))  {
+            if (way.hasTag("bicycle", "use_sidepath")) {
                 pushingSectionPrio = PREFER.getValue();
             }
             if (way.hasTag("bicycle", "yes") || way.hasTag("bicycle", "permissive"))
diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
index f7ffdbf73..f0a634958 100644
--- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
+++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
@@ -251,6 +251,9 @@ public class EncodingManager implements EncodedValueLookup {
         }
 
         private void _addEdgeTagParser(TagParser tagParser, boolean withNamespace, boolean insert) {
+            if (!em.edgeEncoders.isEmpty())
+                throw new IllegalStateException("Avoid mixing encoded values from FlagEncoder with shared encoded values until we have a more clever mechanism, see #1862");
+
             List<EncodedValue> list = new ArrayList<>();
             tagParser.createEncodedValues(em, list);
             for (EncodedValue ev : list) {
@@ -270,8 +273,7 @@ public class EncodingManager implements EncodedValueLookup {
             }
             em.relationTagParsers.add(tagParser);
 
-            // for simplicity add into edge-EncodedValue
-            _addEdgeTagParser(tagParser, true, false);
+            _addEdgeTagParser(tagParser, false, false);
         }
 
         private void _addTurnCostParser(TurnCostParser parser) {
@@ -307,23 +309,24 @@ public class EncodingManager implements EncodedValueLookup {
                 em.addEncodedValue(ev, false);
             }
 
-            if (!em.encodedValueMap.containsKey(RoadAccess.KEY))
-                _addEdgeTagParser(new OSMRoadAccessParser(), false, true);
-            if (!em.encodedValueMap.containsKey(MaxSpeed.KEY))
-                _addEdgeTagParser(new OSMMaxSpeedParser(), false, true);
-            if (!em.encodedValueMap.containsKey(RoadEnvironment.KEY))
-                _addEdgeTagParser(new OSMRoadEnvironmentParser(), false, true);
-            if (!em.encodedValueMap.containsKey(RoadClassLink.KEY))
-                _addEdgeTagParser(new OSMRoadClassLinkParser(), false, true);
-            if (!em.encodedValueMap.containsKey(RoadClass.KEY))
-                _addEdgeTagParser(new OSMRoadClassParser(), false, true);
-            if (!em.encodedValueMap.containsKey(Roundabout.KEY))
-                _addEdgeTagParser(new OSMRoundaboutParser(), false, true);
-
+            if (!em.hasEncodedValue(Roundabout.KEY))
+                _addEdgeTagParser(new OSMRoundaboutParser(), false, false);
+            if (!em.hasEncodedValue(RoadClass.KEY))
+                _addEdgeTagParser(new OSMRoadClassParser(), false, false);
+            if (!em.hasEncodedValue(RoadClassLink.KEY))
+                _addEdgeTagParser(new OSMRoadClassLinkParser(), false, false);
+            if (!em.hasEncodedValue(RoadEnvironment.KEY))
+                _addEdgeTagParser(new OSMRoadEnvironmentParser(), false, false);
+            if (!em.hasEncodedValue(MaxSpeed.KEY))
+                _addEdgeTagParser(new OSMMaxSpeedParser(), false, false);
+            if (!em.hasEncodedValue(RoadAccess.KEY))
+                _addEdgeTagParser(new OSMRoadAccessParser(), false, false);
+
+            // ensure that SpatialRuleParsers come after required EncodedValues like max_speed or road_access
             // TODO can we avoid this hack without complex dependency management?
-            // ensure that SpatialRuleParser come after required EncodedValues like max_speed or road_access
+            boolean insert = true;
             for (SpatialRuleParser srp : insertLater) {
-                _addEdgeTagParser(srp, false, true);
+                _addEdgeTagParser(srp, false, insert);
             }
 
             if (dateRangeParser == null)
@@ -331,16 +334,18 @@ public class EncodingManager implements EncodedValueLookup {
 
             for (AbstractFlagEncoder encoder : flagEncoderList) {
                 if (encoder instanceof BikeCommonFlagEncoder) {
-                    if (!em.hasEncodedValue(getKey("bike", RouteNetwork.EV_SUFFIX)))
+                    if (!em.hasEncodedValue(RouteNetwork.key("bike")))
                         _addRelationTagParser(new OSMBikeNetworkTagParser());
-                    if (!em.encodedValueMap.containsKey(GetOffBike.KEY))
+                    if (!em.hasEncodedValue(GetOffBike.KEY))
                         _addEdgeTagParser(new OSMGetOffBikeParser(), false, false);
 
                 } else if (encoder instanceof FootFlagEncoder) {
-                    if (!em.hasEncodedValue(getKey("foot", RouteNetwork.EV_SUFFIX)))
+                    if (!em.hasEncodedValue(RouteNetwork.key("foot")))
                         _addRelationTagParser(new OSMFootNetworkTagParser());
                 }
+            }
 
+            for (AbstractFlagEncoder encoder : flagEncoderList) {
                 encoder.init(dateRangeParser);
                 em.addEncoder(encoder);
             }
@@ -469,7 +474,7 @@ public class EncodingManager implements EncodedValueLookup {
     }
 
     private void addEncodedValue(EncodedValue ev, boolean withNamespace) {
-        if (encodedValueMap.containsKey(ev.getName()))
+        if (hasEncodedValue(ev.getName()))
             throw new IllegalStateException("EncodedValue " + ev.getName() + " already exists " + encodedValueMap.get(ev.getName()) + " vs " + ev);
         if (!withNamespace && ev.getName().contains(SPECIAL_SEPARATOR))
             throw new IllegalArgumentException("EncodedValue " + ev.getName() + " must not contain namespace character '" + SPECIAL_SEPARATOR + "'");
diff --git a/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java
index 33a5eacbb..8dbe63673 100644
--- a/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java
+++ b/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java
@@ -156,7 +156,7 @@ public class FootFlagEncoder extends AbstractFlagEncoder {
         registerNewEncodedValue.add(avgSpeedEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "average_speed"), speedBits, speedFactor, speedTwoDirections));
         registerNewEncodedValue.add(priorityWayEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 3, PriorityCode.getFactor(1), speedTwoDirections));
 
-        footRouteEnc = getEnumEncodedValue(getKey("foot", EV_SUFFIX), RouteNetwork.class);
+        footRouteEnc = getEnumEncodedValue(RouteNetwork.key("foot"), RouteNetwork.class);
     }
 
     /**
diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMBikeNetworkTagParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMBikeNetworkTagParser.java
index e8ed456dd..be1624671 100644
--- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMBikeNetworkTagParser.java
+++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMBikeNetworkTagParser.java
@@ -64,7 +64,7 @@ public class OSMBikeNetworkTagParser implements RelationTagParser {
 
     @Override
     public void createEncodedValues(EncodedValueLookup lookup, List<EncodedValue> registerNewEncodedValue) {
-        registerNewEncodedValue.add(bikeRouteEnc = new EnumEncodedValue<>(getKey("bike", RouteNetwork.EV_SUFFIX), RouteNetwork.class));
+        registerNewEncodedValue.add(bikeRouteEnc = new EnumEncodedValue<>(RouteNetwork.key("bike"), RouteNetwork.class));
     }
 
     @Override
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 07d6e7033..7839ace2c 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
@@ -64,7 +64,7 @@ public class OSMFootNetworkTagParser implements RelationTagParser {
 
     @Override
     public void createEncodedValues(EncodedValueLookup lookup, List<EncodedValue> registerNewEncodedValue) {
-        registerNewEncodedValue.add(footRouteEnc = new EnumEncodedValue<>(getKey("foot", RouteNetwork.EV_SUFFIX), RouteNetwork.class));
+        registerNewEncodedValue.add(footRouteEnc = new EnumEncodedValue<>(RouteNetwork.key("foot"), RouteNetwork.class));
     }
 
     @Override
diff --git a/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java b/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java
index 41e45f19c..936215203 100644
--- a/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java
+++ b/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java
@@ -25,8 +25,6 @@ import com.graphhopper.storage.IntsRef;
 import com.graphhopper.storage.TurnCostStorage;
 import com.graphhopper.util.EdgeIterator;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
-import static com.graphhopper.routing.util.EncodingManager.getKey;
 import static com.graphhopper.routing.weighting.Weighting.INFINITE_U_TURN_COSTS;
 
 public class DefaultTurnCostProvider implements TurnCostProvider {
@@ -53,7 +51,7 @@ public class DefaultTurnCostProvider implements TurnCostProvider {
         if (turnCostStorage == null) {
             throw new IllegalArgumentException("No storage set to calculate turn weight");
         }
-        String key = getKey(encoder.toString(), EV_SUFFIX);
+        String key = TurnCost.key(encoder.toString());
         // if null the TurnCostProvider can be still useful for edge-based routing
         this.turnCostEnc = encoder.hasEncodedValue(key) ? encoder.getDecimalEncodedValue(key) : null;
         this.turnCostStorage = turnCostStorage;
diff --git a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
index cfd49d0d5..c90c28075 100644
--- a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
+++ b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
@@ -22,7 +22,6 @@ import com.graphhopper.routing.profiles.EncodedValueLookup;
 import com.graphhopper.routing.profiles.TurnCost;
 import com.graphhopper.util.EdgeIterator;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
 import static com.graphhopper.routing.util.EncodingManager.getKey;
 
 /**
@@ -100,7 +99,7 @@ public class TurnCostStorage implements Storable<TurnCostStorage> {
      * This is a convenient setter method and should not be used in loops or where speed is important.
      */
     public void setExpensive(String name, EncodedValueLookup lookup, int fromEdge, int viaNode, int toEdge, double cost) {
-        set(lookup.getDecimalEncodedValue(getKey(name, EV_SUFFIX)), TurnCost.createFlags(), fromEdge, viaNode, toEdge, cost);
+        set(lookup.getDecimalEncodedValue(TurnCost.key(name)), TurnCost.createFlags(), fromEdge, viaNode, toEdge, cost);
     }
 
     /**
@@ -192,7 +191,7 @@ public class TurnCostStorage implements Storable<TurnCostStorage> {
      * This is a convenient getter method and should not be used in loops or where speed is important.
      */
     public double getExpensive(String name, EncodedValueLookup lookup, int fromEdge, int viaNode, int toEdge) {
-        return get(lookup.getDecimalEncodedValue(getKey(name, EV_SUFFIX)), TurnCost.createFlags(), fromEdge, viaNode, toEdge);
+        return get(lookup.getDecimalEncodedValue(TurnCost.key(name)), TurnCost.createFlags(), fromEdge, viaNode, toEdge);
     }
 
     /**
diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java
index 7c4f2de2f..4a69337f1 100644
--- a/core/src/main/java/com/graphhopper/util/GHUtility.java
+++ b/core/src/main/java/com/graphhopper/util/GHUtility.java
@@ -33,8 +33,6 @@ import org.slf4j.LoggerFactory;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
-import static com.graphhopper.routing.util.EncodingManager.getKey;
 import static com.graphhopper.util.Helper.DIST_EARTH;
 
 /**
@@ -233,7 +231,7 @@ public class GHUtility {
         double pEdgePairHasTurnCosts = 0.6;
         double pCostIsRestriction = 0.1;
 
-        DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(getKey(encoder.toString(), EV_SUFFIX));
+        DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString()));
         EdgeExplorer inExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.inEdges(encoder));
         EdgeExplorer outExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.outEdges(encoder));
         IntsRef tcFlags = TurnCost.createFlags();


Test patch:
diff --git a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java
index 3d88767b5..0871a4199 100644
--- a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java
+++ b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java
@@ -85,8 +85,7 @@ public class BridgeElevationInterpolatorTest extends EdgeElevationInterpolatorTe
         EdgeIteratorState edge17 = graph.edge(1, 7, 10, true);
         EdgeIteratorState edge27 = graph.edge(2, 7, 10, true);
         EdgeIteratorState edge37 = graph.edge(3, 7, 10, true);
-        edge17.setWayGeometry(
-                Helper.createPointList3D(12, 2, 200, 14, 4, 400, 16, 6, 600, 18, 8, 800));
+        edge17.setWayGeometry(Helper.createPointList3D(12, 2, 200, 14, 4, 400, 16, 6, 600, 18, 8, 800));
 
         IntsRef relFlags = encodingManager.createRelationFlags();
         edge01.setFlags(encodingManager.handleWayTags(normalWay, ACCEPT_WAY, relFlags));
diff --git a/core/src/test/java/com/graphhopper/routing/BidirPathExtractorTest.java b/core/src/test/java/com/graphhopper/routing/BidirPathExtractorTest.java
index 06ec0e2a4..773b85a7d 100644
--- a/core/src/test/java/com/graphhopper/routing/BidirPathExtractorTest.java
+++ b/core/src/test/java/com/graphhopper/routing/BidirPathExtractorTest.java
@@ -29,8 +29,6 @@ import com.graphhopper.storage.*;
 import com.graphhopper.util.EdgeIterator;
 import org.junit.Test;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
-import static com.graphhopper.routing.util.EncodingManager.getKey;
 import static org.junit.Assert.assertEquals;
 
 /**
@@ -66,7 +64,7 @@ public class BidirPathExtractorTest {
         // add some turn costs at node 2 where fwd&bwd searches meet. these costs have to be included in the
         // weight and the time of the path
         TurnCostStorage turnCostStorage = g.getTurnCostStorage();
-        DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(getKey(carEncoder.toString(), EV_SUFFIX));
+        DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(carEncoder.toString()));
         IntsRef tcFlags = TurnCost.createFlags();
         turnCostEnc.setDecimal(false, tcFlags, 5);
         turnCostStorage.setTurnCost(tcFlags, 0, 2, 1);
diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java
index 66f5bb152..b40748f81 100644
--- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java
+++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java
@@ -23,8 +23,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Random;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
-import static com.graphhopper.routing.util.EncodingManager.getKey;
 import static com.graphhopper.util.EdgeIterator.ANY_EDGE;
 import static com.graphhopper.util.EdgeIterator.NO_EDGE;
 import static org.junit.Assert.*;
@@ -57,7 +55,7 @@ public class DirectedBidirectionalDijkstraTest {
         graph = new GraphHopperStorage(dir, encodingManager, false, true).create(1000);
         turnCostStorage = graph.getTurnCostStorage();
         weighting = createWeighting(Weighting.INFINITE_U_TURN_COSTS);
-        turnCostEnc = encodingManager.getDecimalEncodedValue(getKey(encoder.toString(), EV_SUFFIX));
+        turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(encoder.toString()));
     }
 
     private Weighting createWeighting(int uTurnCosts) {
diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java
index 51fb890ae..535505cee 100644
--- a/core/src/test/java/com/graphhopper/routing/PathTest.java
+++ b/core/src/test/java/com/graphhopper/routing/PathTest.java
@@ -52,17 +52,16 @@ public class PathTest {
 
     @Test
     public void testFound() {
-        GraphHopperStorage g = new GraphBuilder(carManager).create();
+        Graph g = new GraphBuilder(carManager).create();
         Path p = new Path(g);
         assertFalse(p.isFound());
         assertEquals(0, p.getDistance(), 1e-7);
         assertEquals(0, p.calcNodes().size());
-        g.close();
     }
 
     @Test
     public void testWayList() {
-        GraphHopperStorage g = new GraphBuilder(carManager).create();
+        Graph g = new GraphBuilder(carManager).create();
         NodeAccess na = g.getNodeAccess();
         na.setNode(0, 0.0, 0.1);
         na.setNode(1, 1.0, 0.1);
@@ -171,7 +170,6 @@ public class PathTest {
         na.setNode(4, 7.5, 0.25);
         na.setNode(5, 5.0, 1.0);
 
-
         EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true).setReverse(carAccessEnc, true).set(carAvSpeedEnv, 50.0);
         edge1.setWayGeometry(Helper.createPointList());
         edge1.setName("Street 1");
@@ -257,12 +255,9 @@ public class PathTest {
         }
     }
 
-    /**
-     * case starting in Roundabout
-     */
     @Test
     public void testCalcInstructionsRoundaboutBegin() {
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(2, 8);
         assertTrue(p.isFound());
@@ -273,13 +268,10 @@ public class PathTest {
                 tmpList);
     }
 
-    /**
-     * case with one node being containig already exit
-     */
     @Test
     public void testCalcInstructionsRoundaboutDirectExit() {
         roundaboutGraph.inverse3to9();
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(6, 8);
         assertTrue(p.isFound());
@@ -436,7 +428,7 @@ public class PathTest {
     @Test
     public void testCalcInstructionsRoundabout2() {
         roundaboutGraph.inverse3to6();
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(1, 8);
         assertTrue(p.isFound());
@@ -527,13 +519,10 @@ public class PathTest {
                 tmpList);
     }
 
-    /**
-     * clockwise roundabout
-     */
     @Test
     public void testCalcInstructionsRoundaboutClockwise() {
         roundaboutGraph.setRoundabout(true);
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(1, 8);
         assertTrue(p.isFound());
@@ -552,7 +541,7 @@ public class PathTest {
     @Test
     public void testCalcInstructionsIgnoreContinue() {
         // Follow a couple of straight edges, including a name change
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(4, 11);
         assertTrue(p.isFound());
@@ -565,7 +554,7 @@ public class PathTest {
     @Test
     public void testCalcInstructionsIgnoreTurnIfNoAlternative() {
         // The street turns left, but there is not turn
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(10, 12);
         assertTrue(p.isFound());
@@ -640,7 +629,7 @@ public class PathTest {
     }
 
     @Test
-    public void testCalcInstructionsEnterMotoway() {
+    public void testCalcInstructionsEnterMotorway() {
         final Graph g = new GraphBuilder(carManager).create();
         final NodeAccess na = g.getNodeAccess();
 
@@ -669,7 +658,7 @@ public class PathTest {
     }
 
     @Test
-    public void testCalcInstructionsMotowayJunction() {
+    public void testCalcInstructionsMotorwayJunction() {
         final Graph g = new GraphBuilder(carManager).create();
         final NodeAccess na = g.getNodeAccess();
 
@@ -860,7 +849,7 @@ public class PathTest {
     @Test
     public void testCalcInstructionsForTurn() {
         // The street turns left, but there is not turn
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(11, 13);
         assertTrue(p.isFound());
@@ -875,7 +864,7 @@ public class PathTest {
     @Test
     public void testCalcInstructionsForSlightTurnWithOtherSlightTurn() {
         // Test for a fork with two sligh turns. Since there are two sligh turns, show the turn instruction
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(12, 16);
         assertTrue(p.isFound());
@@ -919,7 +908,7 @@ public class PathTest {
     @Test
     public void testIgnoreInstructionsForSlightTurnWithOtherTurn() {
         // Test for a fork with one sligh turn and one actual turn. We are going along the slight turn. No turn instruction needed in this case
-        ShortestWeighting weighting = new ShortestWeighting(encoder);
+        ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car"));
         Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED)
                 .calcPath(16, 19);
         assertTrue(p.isFound());
diff --git a/core/src/test/java/com/graphhopper/routing/profiles/EnumEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/profiles/EnumEncodedValueTest.java
index f3c18da93..6ae5fcc73 100644
--- a/core/src/test/java/com/graphhopper/routing/profiles/EnumEncodedValueTest.java
+++ b/core/src/test/java/com/graphhopper/routing/profiles/EnumEncodedValueTest.java
@@ -11,8 +11,8 @@ public class EnumEncodedValueTest {
     public void testInit() {
         EnumEncodedValue<RoadClass> prop = new EnumEncodedValue<>("road_class", RoadClass.class);
         EncodedValue.InitializerConfig init = new EncodedValue.InitializerConfig();
-        assertEquals(5, prop.init(init));
-        assertEquals(5, prop.bits);
+        assertEquals(4, prop.init(init));
+        assertEquals(4, prop.bits);
         assertEquals(0, init.dataIndex);
         assertEquals(0, init.shift);
         IntsRef ref = new IntsRef(1);
@@ -23,4 +23,13 @@ public class EnumEncodedValueTest {
         prop.setEnum(false, ref, RoadClass.SECONDARY);
         assertEquals(RoadClass.SECONDARY, prop.getEnum(false, ref));
     }
+
+    @Test
+    public void testSize() {
+        assertEquals(3, 32 - Integer.numberOfLeadingZeros(7 - 1));
+        assertEquals(3, 32 - Integer.numberOfLeadingZeros(8 - 1));
+        assertEquals(4, 32 - Integer.numberOfLeadingZeros(9 - 1));
+        assertEquals(4, 32 - Integer.numberOfLeadingZeros(16 - 1));
+        assertEquals(5, 32 - Integer.numberOfLeadingZeros(17 - 1));
+    }
 }
\ No newline at end of file
diff --git a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java
index a8e309732..ad067fbc1 100644
--- a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java
+++ b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java
@@ -40,7 +40,6 @@ import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
 import static com.graphhopper.storage.index.QueryResult.Position.*;
 import static com.graphhopper.util.GHUtility.updateDistancesFor;
 import static org.junit.Assert.*;
@@ -498,7 +497,7 @@ public class QueryGraphTest {
                 create(100);
         TurnCostStorage turnExt = graphWithTurnCosts.getTurnCostStorage();
         IntsRef tcFlags = TurnCost.createFlags();
-        DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(EncodingManager.getKey(encoder.toString(), EV_SUFFIX));
+        DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString()));
         NodeAccess na = graphWithTurnCosts.getNodeAccess();
         na.setNode(0, .00, .00);
         na.setNode(1, .00, .01);
diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java
index 25976bfb4..7dbd49e8d 100644
--- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java
+++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java
@@ -230,7 +230,7 @@ public abstract class AbstractBikeFlagEncoderTester {
         // Example https://www.openstreetmap.org/way/213492914 => two hike 84544, 2768803 and two bike relations 3162932, 5254650
         IntsRef relFlags = encodingManager.handleRelationTags(rel2, encodingManager.handleRelationTags(rel, encodingManager.createRelationFlags()));
         IntsRef edgeFlags = encodingManager.handleWayTags(way, new EncodingManager.AcceptWay().put(encoder.toString(), WAY), relFlags);
-        EnumEncodedValue<RouteNetwork> enc = encodingManager.getEnumEncodedValue(getKey("bike", RouteNetwork.EV_SUFFIX), RouteNetwork.class);
+        EnumEncodedValue<RouteNetwork> enc = encodingManager.getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class);
         assertEquals(RouteNetwork.REGIONAL, enc.getEnum(false, edgeFlags));
     }
 
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 8ec0bbde2..1f96b7c08 100644
--- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java
@@ -144,7 +144,7 @@ public class EncodingManagerTest {
         manager.acceptWay(osmWay, map);
         IntsRef edgeFlags = manager.handleWayTags(osmWay, map, relFlags);
 
-        EnumEncodedValue enc = manager.getEnumEncodedValue(EncodingManager.getKey("bike", RouteNetwork.EV_SUFFIX), RouteNetwork.class);
+        EnumEncodedValue enc = manager.getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class);
 
         assertTrue(defaultBike.priorityEnc.getDecimal(false, edgeFlags)
                 > lessRelationCodes.priorityEnc.getDecimal(false, edgeFlags));
diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
index a25d53550..d2ff0ddba 100644
--- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
+++ b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
@@ -23,6 +23,7 @@ import com.graphhopper.routing.querygraph.QueryGraph;
 import com.graphhopper.routing.util.*;
 import com.graphhopper.routing.weighting.DefaultTurnCostProvider;
 import com.graphhopper.routing.weighting.FastestWeighting;
+import com.graphhopper.routing.weighting.TurnCostProvider;
 import com.graphhopper.storage.index.QueryResult;
 import com.graphhopper.util.*;
 import com.graphhopper.util.shapes.BBox;
@@ -41,7 +42,7 @@ import static org.junit.Assert.*;
  */
 public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
     private CHGraph getGraph(GraphHopperStorage ghStorage) {
-        return ghStorage.getCHGraph();
+        return ghStorage.getCHGraph(ghStorage.getCHProfiles().get(0));
     }
 
     @Override
@@ -61,8 +62,13 @@ public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
     private GraphHopperStorage newGHStorage(Directory dir, boolean is3D, boolean forEdgeBasedTraversal, int segmentSize) {
         GraphHopperStorage graph = new GraphBuilder(encodingManager)
                 .setDir(dir).set3D(is3D).withTurnCosts(true).setSegmentSize(segmentSize).build();
-        FastestWeighting weighting = new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder, graph.getTurnCostStorage()));
-        graph.addCHGraph(new CHProfile(weighting, forEdgeBasedTraversal));
+        for (FlagEncoder encoder : encodingManager.fetchEdgeEncoders()) {
+            TurnCostProvider turnCostProvider = forEdgeBasedTraversal
+                    ? new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())
+                    : TurnCostProvider.NO_TURN_COST_PROVIDER;
+            FastestWeighting weighting = new FastestWeighting(encoder, turnCostProvider);
+            graph.addCHGraph(new CHProfile(weighting, forEdgeBasedTraversal));
+        }
         return graph;
     }
 
@@ -364,7 +370,7 @@ public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
         graph.edge(3, 4, 10, true);
         graph.freeze();
 
-        CHGraph lg = graph.getCHGraph();
+        CHGraph lg = getGraph(graph);
         lg.shortcut(1, 4, PrepareEncoder.getScFwdDir(), 3, NO_EDGE, NO_EDGE);
 
         EdgeExplorer vehicleOutExplorer = lg.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder));
@@ -380,7 +386,7 @@ public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
         final EdgeIteratorState edge2 = graph.edge(3, 4, 10, true);
         graph.freeze();
 
-        CHGraph lg = graph.getCHGraph();
+        CHGraph lg = getGraph(graph);
         lg.shortcut(1, 4, PrepareEncoder.getScDirMask(), 10, NO_EDGE, NO_EDGE);
 
         AllCHEdgesIterator iter = lg.getAllEdges();
@@ -400,7 +406,7 @@ public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
         final EdgeIteratorState edge2 = graph.edge(3, 4, 10, true);
         graph.freeze();
 
-        CHGraph lg = graph.getCHGraph();
+        CHGraph lg = getGraph(graph);
         lg.shortcut(1, 4, PrepareEncoder.getScDirMask(), 10, edge1.getEdge(), edge2.getEdge());
 
         AllCHEdgesIterator iter = lg.getAllEdges();
diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
index 5dd0c1057..27e737a89 100644
--- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
+++ b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
@@ -17,10 +17,14 @@
  */
 package com.graphhopper.storage;
 
+import com.graphhopper.GraphHopper;
+import com.graphhopper.routing.util.BikeFlagEncoder;
+import com.graphhopper.routing.util.EncodingManager;
 import com.graphhopper.util.*;
 import com.graphhopper.util.shapes.BBox;
 import org.junit.Test;
 
+import java.io.File;
 import java.io.IOException;
 
 import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE;
@@ -59,7 +63,7 @@ public class GraphHopperStorageTest extends AbstractGraphStorageTester {
     }
 
     @Test
-    public void testSave_and_fileFormat() throws IOException {
+    public void testSave_and_fileFormat() {
         graph = newGHStorage(new RAMDirectory(defaultGraphLoc, true), true).create(defaultSize);
         NodeAccess na = graph.getNodeAccess();
         assertTrue(na.is3D());
@@ -280,4 +284,41 @@ public class GraphHopperStorageTest extends AbstractGraphStorageTester {
         assertEquals(13, edge1.getFlags().ints[0]);
     }
 
+    @Test
+    public void testLoadGraph_implicitEncodedValues_issue1862() {
+        Helper.removeDir(new File(defaultGraphLoc));
+        encodingManager = new EncodingManager.Builder().add(createCarFlagEncoder()).add(new BikeFlagEncoder()).build();
+        graph = newGHStorage(new RAMDirectory(defaultGraphLoc, true), false).create(defaultSize);
+        NodeAccess na = graph.getNodeAccess();
+        na.setNode(0, 12, 23);
+        na.setNode(1, 8, 13);
+        na.setNode(2, 2, 10);
+        na.setNode(3, 5, 9);
+        graph.edge(1, 2, 10, true);
+        graph.edge(1, 3, 10, true);
+        int nodes = graph.getNodes();
+        int edges = graph.getAllEdges().length();
+        graph.flush();
+        boolean ch = graph.isCHPossible();
+        Helper.close(graph);
+
+        // load without configured FlagEncoders
+        GraphHopper hopper = new GraphHopper().setCHEnabled(ch);
+        assertTrue(hopper.load(defaultGraphLoc));
+        graph = hopper.getGraphHopperStorage();
+        assertEquals(nodes, graph.getNodes());
+        assertEquals(edges, graph.getAllEdges().length());
+        Helper.close(graph);
+
+        // load via explicitly configured FlagEncoders
+        hopper = new GraphHopper().setCHEnabled(ch).setEncodingManager(encodingManager);
+        assertTrue(hopper.load(defaultGraphLoc));
+        graph = hopper.getGraphHopperStorage();
+        assertEquals(nodes, graph.getNodes());
+        assertEquals(edges, graph.getAllEdges().length());
+        Helper.close(graph);
+
+        Helper.removeDir(new File(defaultGraphLoc));
+    }
+
 }
diff --git a/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
index b05706927..307c65eef 100644
--- a/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
@@ -48,8 +48,6 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.*;
 
-import static com.graphhopper.routing.profiles.TurnCost.EV_SUFFIX;
-import static com.graphhopper.routing.util.EncodingManager.getKey;
 import static org.junit.Assert.*;
 
 /**
@@ -520,7 +518,7 @@ public class OSMReaderTest {
         // (2-3)->(3-4) only_straight_on = (2-3)->(3-8) restricted
         // (4-3)->(3-8) no_right_turn = (4-3)->(3-8) restricted
         IntsRef tcFlags = TurnCost.createFlags();
-        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("car", EV_SUFFIX));
+        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("car"));
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_8)) > 0);
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_3, n3, edge3_8)) > 0);
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_4)) == 0);
@@ -541,7 +539,7 @@ public class OSMReaderTest {
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_5, n5, edge5_6)) == 0);
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_5, n5, edge5_1)) > 0);
 
-        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("bike", EV_SUFFIX));
+        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("bike"));
         assertTrue(bikeTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_5, n5, edge5_6)) == 0);
 
         int n10 = AbstractGraphStorageTester.getIdOf(graph, 40, 10);
@@ -736,9 +734,9 @@ public class OSMReaderTest {
                 setOSMFile(getClass().getResource("test-multi-profile-turn-restrictions.xml").getFile()).
                 setGraphHopperLocation(dir).setEncodingManager(manager).importOrLoad();
 
-        DecimalEncodedValue carTCEnc = manager.getDecimalEncodedValue(getKey("car", EV_SUFFIX));
-        DecimalEncodedValue truckTCEnc = manager.getDecimalEncodedValue(getKey("truck", EV_SUFFIX));
-        DecimalEncodedValue bikeTCEnc = manager.getDecimalEncodedValue(getKey("bike", EV_SUFFIX));
+        DecimalEncodedValue carTCEnc = manager.getDecimalEncodedValue(TurnCost.key("car"));
+        DecimalEncodedValue truckTCEnc = manager.getDecimalEncodedValue(TurnCost.key("truck"));
+        DecimalEncodedValue bikeTCEnc = manager.getDecimalEncodedValue(TurnCost.key("bike"));
 
         Graph graph = hopper.getGraphHopperStorage();
         TurnCostStorage tcStorage = graph.getTurnCostStorage();
@@ -798,7 +796,7 @@ public class OSMReaderTest {
         // (4-3)->(3-8) no_right_turn dedicated to motorcar = (4-3)->(3-8) restricted for car
 
         IntsRef tcFlags = TurnCost.createFlags();
-        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("car", EV_SUFFIX));
+        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("car"));
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_8)) > 0);
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_3, n3, edge3_8)) > 0);
         assertEquals(0, carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_4)), .1);
@@ -807,7 +805,7 @@ public class OSMReaderTest {
         assertEquals(0, carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_3, n3, edge3_2)), .1);
         assertEquals(0, carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge8_3, n3, edge3_2)), .1);
 
-        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("bike", EV_SUFFIX));
+        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("bike"));
         assertEquals(0, bikeTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_8)), .1);
         assertEquals(0, bikeTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge4_3, n3, edge3_8)), .1);
         assertEquals(0, bikeTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge2_3, n3, edge3_4)), .1);
@@ -855,8 +853,8 @@ public class OSMReaderTest {
         int edge5_1 = GHUtility.getEdge(graph, n5, n1).getEdge();
 
         IntsRef tcFlags = TurnCost.createFlags();
-        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("car", EV_SUFFIX));
-        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(getKey("bike", EV_SUFFIX));
+        DecimalEncodedValue carTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("car"));
+        DecimalEncodedValue bikeTCEnc = hopper.getEncodingManager().getDecimalEncodedValue(TurnCost.key("bike"));
 
         // (1-2)->(2-3) no_right_turn for motorcar and bus
         assertTrue(carTCEnc.getDecimal(false, tcStorage.readFlags(tcFlags, edge1_2, n2, edge2_3)) > 0);