diff --git a/src/main/java/com/esri/core/geometry/Geohash.java b/src/main/java/com/esri/core/geometry/Geohash.java index 87070786..33987207 100644 --- a/src/main/java/com/esri/core/geometry/Geohash.java +++ b/src/main/java/com/esri/core/geometry/Geohash.java @@ -187,7 +187,7 @@ public static String containingGeohash(Envelope2D envelope) { double deltaLon = 360; double deltaLat = 180; - while (xmin == xmax && ymin == ymax && chars < 25) { + while (xmin == xmax && ymin == ymax && chars < 7) { if (chars % 2 == 0) { deltaLon = deltaLon / 8; deltaLat = deltaLat / 4; @@ -215,6 +215,38 @@ public static String containingGeohash(Envelope2D envelope) { * @return up to four geohashes that completely cover given envelope */ public static String[] coveringGeohash(Envelope2D envelope) { - return new String[] {}; + double xmin = envelope.xmin; + double ymin = envelope.ymin; + double xmax = envelope.xmax; + double ymax = envelope.ymax; + + if (NumberUtils.isNaN(xmax)) { + return new String[] {""}; + } + String[] geoHash = {containingGeohash(envelope)}; + if (geoHash[0] != ""){ + return geoHash; + } + + int grid = 45; + int gridMaxLon = (int)Math.floor(xmax/grid); + int gridMinLon = (int)Math.floor(xmin/grid); + int gridMaxLat = (int)Math.floor(ymax/grid); + int gridMinLat = (int)Math.floor(ymin/grid); + int deltaLon = gridMaxLon - gridMinLon + 1; + int deltaLat = gridMaxLat - gridMinLat + 1; + String[] geoHashes = new String[deltaLon * deltaLat]; + + if (deltaLon * deltaLat > 4){ + return new String[] {""}; + } else { + for (int i = 0; i < deltaLon; i++){ + for (int j = 0; j < deltaLat; j++){ + Point2D p = new Point2D(xmin + i * grid, ymin + j * grid); + geoHashes[i*deltaLat + j] = toGeohash(p, 1); + } + } + } + return geoHashes; } } diff --git a/src/test/java/com/esri/core/geometry/TestGeohash.java b/src/test/java/com/esri/core/geometry/TestGeohash.java index 662e65df..ab09d327 100644 --- a/src/test/java/com/esri/core/geometry/TestGeohash.java +++ b/src/test/java/com/esri/core/geometry/TestGeohash.java @@ -129,7 +129,54 @@ public void testContainingGeohash() { @Test public void testContainingGeohash2() { - Envelope2D envelope = new Envelope2D(18.078, 59.3564, 18.1, 59.3344); - assertEquals("u6sce", Geohash.containingGeohash(envelope)); + Envelope2D envelope = new Envelope2D(18.078, 59.3564, 18.1, 59.3344); + assertEquals("u6sce", Geohash.containingGeohash(envelope)); } -} + + @Test + public void testCoveringGeohashEmptyEnvelope() { + Envelope2D emptyEnv = new Envelope2D(); + String [] coverage = Geohash.coveringGeohash(emptyEnv); + } + + @Test + public void testCoveringGeohashOneGeohash() { + Envelope2D env = new Envelope2D(-180, -90, -149, -49); + String [] coverage = Geohash.coveringGeohash(env); + assertEquals("0", coverage[0]); + } + + @Test + public void testCoveringGeohashPoint() { + Envelope2D env = new Envelope2D(180,90,180,90); + String [] coverage = Geohash.coveringGeohash(env); + assertEquals("zzzzzz", coverage[0]); + } + + @Test + public void testCoveringGeohashTwoGeohashes() { + Envelope2D env = new Envelope2D(-180, -90, -180, -35); + String [] coverage = Geohash.coveringGeohash(env); + assertEquals("0", coverage[0]); + assertEquals("2", coverage[1]); + } + + @Test + public void testCoveringGeohashThreeGeohashes() { + Envelope2D env = new Envelope2D(-180, -90, -180, 5); + String [] coverage = Geohash.coveringGeohash(env); + assertEquals("0", coverage[0]); + assertEquals("2", coverage[1]); + assertEquals("8", coverage[2]); + } + + @Test + public void testCoveringGeohashFourGeohashes() { + Envelope2D env = new Envelope2D(-180, -90, -130, -40); + String [] coverage = Geohash.coveringGeohash(env); + assertEquals("0", coverage[0]); + assertEquals("2", coverage[1]); + assertEquals("1", coverage[2]); + assertEquals("3", coverage[3]); + } +} \ No newline at end of file