Repository: graphhopper/graphhopper
Pull request #1563 (2019-03-04 19:43:49)

Allow to retrieve SpatialRule by Id
With this PR it's possible to retrieve a SpatialRule from the Lookup using the id. This can be especially helpful when one wants to store the id in the graph and retrieve the SpatialRule from that id.

One thing to consider is that if you change the SpatialRules (add one or change the the order), this will fail. Currently, we don't save the version of the SpatialRuleLookup.

karussell: Thanks!

Patch:
diff --git a/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookup.java b/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookup.java
index 4f66a68b3..c5b9ff85f 100644
--- a/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookup.java
+++ b/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookup.java
@@ -49,6 +49,12 @@ public interface SpatialRuleLookup {
      */
     int getSpatialId(SpatialRule rule);
 
+    /**
+     * This method returns the SpatialRule for a given Spatial Id. This can be used when retrieving SpatialRules from
+     * a Spatial Id stored in the graph.
+     */
+    SpatialRule getSpatialRule(int spatialId);
+
     /**
      * @return the number of rules added to this lookup.
      */
@@ -75,6 +81,11 @@ public interface SpatialRuleLookup {
             return 0;
         }
 
+        @Override
+        public SpatialRule getSpatialRule(int spatialId) {
+            return SpatialRule.EMPTY;
+        }
+
         @Override
         public int size() {
             return 1;
diff --git a/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArray.java b/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArray.java
index d40b57be6..4320767b4 100644
--- a/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArray.java
+++ b/core/src/main/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArray.java
@@ -212,7 +212,7 @@ public class SpatialRuleLookupArray implements SpatialRuleLookup {
         singleRules.add(rule);
     }
 
-    SpatialRule getSpatialRule(int id) {
+    public SpatialRule getSpatialRule(int id) {
         if (id < 0 || id >= ruleContainers.size())
             throw new IllegalArgumentException("SpatialRuleId " + id + " is illegal");
 


Test patch:
diff --git a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java
index ad508969f..41d97b5e6 100644
--- a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java
+++ b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java
@@ -227,6 +227,11 @@ public class LandmarkStorageTest {
                 throw new IllegalStateException();
             }
 
+            @Override
+            public SpatialRule getSpatialRule(int spatialId) {
+                throw new IllegalStateException();
+            }
+
             @Override
             public int size() {
                 return 2;
diff --git a/core/src/test/java/com/graphhopper/routing/util/DataFlagEncoderTest.java b/core/src/test/java/com/graphhopper/routing/util/DataFlagEncoderTest.java
index 4817d8830..e8abdf898 100644
--- a/core/src/test/java/com/graphhopper/routing/util/DataFlagEncoderTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/DataFlagEncoderTest.java
@@ -364,6 +364,11 @@ public class DataFlagEncoderTest {
                 }
             }
 
+            @Override
+            public SpatialRule getSpatialRule(int spatialId) {
+                return SpatialRule.EMPTY;
+            }
+
             @Override
             public int size() {
                 return 2;
diff --git a/core/src/test/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArrayTest.java b/core/src/test/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArrayTest.java
index 525bbfa34..1a9437a42 100644
--- a/core/src/test/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArrayTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/spatialrules/SpatialRuleLookupArrayTest.java
@@ -83,7 +83,7 @@ public class SpatialRuleLookupArrayTest {
         String germanPolygonJson = "[9.921906,54.983104],[9.93958,54.596642],[10.950112,54.363607],[10.939467,54.008693],[11.956252,54.196486],[12.51844,54.470371],[13.647467,54.075511],[14.119686,53.757029],[14.353315,53.248171],[14.074521,52.981263],[14.4376,52.62485],[14.685026,52.089947],[14.607098,51.745188],[15.016996,51.106674],[14.570718,51.002339],[14.307013,51.117268],[14.056228,50.926918],[13.338132,50.733234],[12.966837,50.484076],[12.240111,50.266338],[12.415191,49.969121],[12.521024,49.547415],[13.031329,49.307068],[13.595946,48.877172],[13.243357,48.416115],[12.884103,48.289146],[13.025851,47.637584],[12.932627,47.467646],[12.62076,47.672388],[12.141357,47.703083],[11.426414,47.523766],[10.544504,47.566399],[10.402084,47.302488],[9.896068,47.580197],[9.594226,47.525058],[8.522612,47.830828],[8.317301,47.61358],[7.466759,47.620582],[7.593676,48.333019],[8.099279,49.017784],[6.65823,49.201958],[6.18632,49.463803],[6.242751,49.902226],[6.043073,50.128052],[6.156658,50.803721],[5.988658,51.851616],[6.589397,51.852029],[6.84287,52.22844],[7.092053,53.144043],[6.90514,53.482162],[7.100425,53.693932],[7.936239,53.748296],[8.121706,53.527792],[8.800734,54.020786],[8.572118,54.395646],[8.526229,54.962744],[9.282049,54.830865],[9.921906,54.983104]";
         Polygon germanPolygon = parsePolygonString(germanPolygonJson);
 
-        spatialRules.add(new DefaultSpatialRule(){
+        spatialRules.add(new DefaultSpatialRule() {
             @Override
             public String getId() {
                 return "DEU";
@@ -135,6 +135,21 @@ public class SpatialRuleLookupArrayTest {
         assertEquals("big", spatialRuleLookup.lookupRule(1.5, 1.5).getId());
     }
 
+    @Test
+    public void testSpatialRuleForId() {
+        List<SpatialRule> spatialRules = new ArrayList<>();
+        spatialRules.add(getSpatialRule(new Polygon(new double[]{1, 1, 1.5, 1.5}, new double[]{1, 2, 2, 1}), "1"));
+        spatialRules.add(getSpatialRule(new Polygon(new double[]{1.5, 1.5, 2, 2}, new double[]{1, 2, 2, 1}), "2"));
+        spatialRules.add(getSpatialRule(new Polygon(new double[]{1.5, 1.5, 2, 2}, new double[]{1, 2, 2, 1}), "3"));
+        spatialRules.add(getSpatialRule(new Polygon(new double[]{1.5, 1.5, 2, 2}, new double[]{1, 2, 2, 1}), "4"));
+
+        SpatialRuleLookup spatialRuleLookup = new SpatialRuleLookupArray(spatialRules, .1, false, new BBox(1, 2, 1, 2));
+
+        // Note index=0 is the EMPTY rule
+        assertEquals("1", spatialRuleLookup.getSpatialRule(1).getId());
+        assertEquals("4", spatialRuleLookup.getSpatialRule(4).getId());
+    }
+
     private Polygon parsePolygonString(String polygonString) {
         String[] germanPolygonArr = polygonString.split("\\],\\[");
         double[] lats = new double[germanPolygonArr.length];