diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtils.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtils.java index f4f9821d926c1..718f20a7400fc 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtils.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtils.java @@ -266,11 +266,13 @@ private static double tileToLon(double xTile, double tiles) { */ public static double tileToLat(int yTile, int tiles) { final double lat = tileToLat((double) yTile, tiles); + // need to quantize to keep it consistent with the adjusted values + final double qLat = GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(lat)); if (tiles < MAX_TILES_FULL_PRECISION || yTile == 0 || yTile == tiles) { - return lat; // precise case, don't need to do more work + return qLat; // precise case, don't need to do more work } // Maybe adjust latitude due to numerical errors - final double qLat = GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(lat)); + final int computedYTile = getYTile(qLat, tiles); // the idea here is that the latitude returned belongs to the tile and the next latitude up belongs to the next tile // therefore we can be in the current tile and we need to find the point up just before the next tile, diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtilsTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtilsTests.java index f76d8a9daa0d5..c929322031bdd 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtilsTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoTileUtilsTests.java @@ -233,8 +233,8 @@ public void testPointToTile() { // check corners assertThat(GeoTileUtils.getXTile(rectangle.getMinX(), tiles), equalTo(xTile)); assertThat(GeoTileUtils.getXTile(rectangle.getMaxX(), tiles), equalTo(Math.min(tiles - 1, xTile + 1))); - assertThat(GeoTileUtils.getYTile(rectangle.getMaxY(), tiles), anyOf(equalTo(yTile - 1), equalTo(yTile))); - assertThat(GeoTileUtils.getYTile(rectangle.getMinY(), tiles), anyOf(equalTo(yTile + 1), equalTo(yTile))); + assertThat(GeoTileUtils.getYTile(rectangle.getMaxY(), tiles), equalTo(yTile)); + assertThat(GeoTileUtils.getYTile(rectangle.getMinY(), tiles), equalTo(Math.min(tiles - 1, yTile + 1))); // check point inside double x = randomDoubleBetween(rectangle.getMinX(), rectangle.getMaxX(), false); double y = randomDoubleBetween(rectangle.getMinY(), rectangle.getMaxY(), false);