From 15db5b98d200acf492068dcfbc404997a3f69542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Tourri=C3=A8re?= Date: Tue, 18 Nov 2014 10:39:37 +0100 Subject: [PATCH] Fix for geohash neighbors when geohash length is even. We don't have to set XLimit and YLimit depending on the level (even or odd), since semantics of x and y are already swapped on each level. XLimit is always 7 and YLimit is always 3. Close #8526 --- .../common/geo/GeoHashUtils.java | 8 ++--- .../index/search/geo/GeoHashUtilsTests.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java b/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java index 15aca20e23a..d679d2dd943 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java @@ -159,15 +159,13 @@ public class GeoHashUtils { final int nx = ((level % 2) == 1) ? (x + dx) : (x + dy); final int ny = ((level % 2) == 1) ? (y + dy) : (y + dx); - // define grid limits for current level - final int xLimit = ((level % 2) == 0) ? 7 : 3; - final int yLimit = ((level % 2) == 0) ? 3 : 7; - // if the defined neighbor has the same parent a the current cell // encode the cell directly. Otherwise find the cell next to this // cell recursively. Since encoding wraps around within a cell // it can be encoded here. - if (nx >= 0 && nx <= xLimit && ny >= 0 && ny <= yLimit) { + // xLimit and YLimit must always be respectively 7 and 3 + // since x and y semantics are swapping on each level. + if (nx >= 0 && nx <= 7 && ny >= 0 && ny <= 3) { return geohash.substring(0, level - 1) + encode(nx, ny); } else { String neighbor = neighbor(geohash, level - 1, dx, dy); diff --git a/src/test/java/org/elasticsearch/index/search/geo/GeoHashUtilsTests.java b/src/test/java/org/elasticsearch/index/search/geo/GeoHashUtilsTests.java index 60842b51ed4..72b86a269cf 100644 --- a/src/test/java/org/elasticsearch/index/search/geo/GeoHashUtilsTests.java +++ b/src/test/java/org/elasticsearch/index/search/geo/GeoHashUtilsTests.java @@ -104,5 +104,35 @@ public class GeoHashUtilsTests extends ElasticsearchTestCase { Collection neighbors = new ArrayList<>(); GeoHashUtils.addNeighbors(geohash, neighbors ); assertEquals(expectedNeighbors, neighbors); + + // Border odd geohash + geohash = "u09x"; + expectedNeighbors = new ArrayList<>(); + expectedNeighbors.add("u0c2"); + expectedNeighbors.add("u0c8"); + expectedNeighbors.add("u0cb"); + expectedNeighbors.add("u09r"); + expectedNeighbors.add("u09z"); + expectedNeighbors.add("u09q"); + expectedNeighbors.add("u09w"); + expectedNeighbors.add("u09y"); + neighbors = new ArrayList<>(); + GeoHashUtils.addNeighbors(geohash, neighbors ); + assertEquals(expectedNeighbors, neighbors); + + // Border even geohash + geohash = "u09tv"; + expectedNeighbors = new ArrayList<>(); + expectedNeighbors.add("u09wh"); + expectedNeighbors.add("u09wj"); + expectedNeighbors.add("u09wn"); + expectedNeighbors.add("u09tu"); + expectedNeighbors.add("u09ty"); + expectedNeighbors.add("u09ts"); + expectedNeighbors.add("u09tt"); + expectedNeighbors.add("u09tw"); + neighbors = new ArrayList<>(); + GeoHashUtils.addNeighbors(geohash, neighbors ); + assertEquals(expectedNeighbors, neighbors); } }