Browse Source

Move the spherical H3 LatLonGeometry under the common package (#93028)

This commit just repackage the class H3LatLonGeometry under the common package with the name H3SphericalGeometry
Ignacio Vera 2 years ago
parent
commit
07f6bbce17

+ 15 - 33
x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/query/H3LatLonGeometry.java → x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/common/H3SphericalGeometry.java

@@ -5,7 +5,7 @@
  * 2.0.
  */
 
-package org.elasticsearch.xpack.spatial.index.query;
+package org.elasticsearch.xpack.spatial.common;
 
 import org.apache.lucene.geo.Component2D;
 import org.apache.lucene.geo.GeoUtils;
@@ -13,46 +13,38 @@ import org.apache.lucene.geo.LatLonGeometry;
 import org.apache.lucene.index.PointValues;
 import org.apache.lucene.spatial3d.geom.GeoArea;
 import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
-import org.apache.lucene.spatial3d.geom.GeoPoint;
 import org.apache.lucene.spatial3d.geom.GeoPolygon;
-import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
 import org.apache.lucene.spatial3d.geom.LatLonBounds;
 import org.apache.lucene.spatial3d.geom.PlanetModel;
-import org.elasticsearch.h3.CellBoundary;
 import org.elasticsearch.h3.H3;
-import org.elasticsearch.h3.LatLng;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
 
 /** Implementation of a lucene {@link LatLonGeometry} that covers the extent of a provided H3 bin. Note that
  * H3 bin are polygons on the sphere. */
-class H3LatLonGeometry extends LatLonGeometry {
+class H3SphericalGeometry extends LatLonGeometry {
 
-    private final String h3Address;
+    private final long h3;
 
-    H3LatLonGeometry(String h3Address) {
-        this.h3Address = h3Address;
+    H3SphericalGeometry(long h3) {
+        this.h3 = h3;
     }
 
     @Override
     protected Component2D toComponent2D() {
-        return new H3Polygon2D(h3Address);
+        return new H3Polygon2D(h3);
     }
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o instanceof H3LatLonGeometry h3) {
-            return Objects.equals(h3Address, h3.h3Address);
+        if (o instanceof H3SphericalGeometry geom) {
+            return h3 == geom.h3;
         }
         return false;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(h3Address);
+        return Long.hashCode(h3);
     }
 
     @Override
@@ -60,7 +52,7 @@ class H3LatLonGeometry extends LatLonGeometry {
         StringBuilder sb = new StringBuilder();
         sb.append("H3 : ");
         sb.append("\"");
-        sb.append(h3Address);
+        sb.append(h3);
         sb.append("\"");
         return sb.toString();
     }
@@ -75,13 +67,12 @@ class H3LatLonGeometry extends LatLonGeometry {
         private final GeoPolygon hexagon;
         private final double minX, maxX, minY, maxY;
 
-        private H3Polygon2D(String h3Address) {
-            h3 = H3.stringToH3(h3Address);
-            res = H3.getResolution(h3Address);
-            final CellBoundary cellBoundary = H3.h3ToGeoBoundary(h3Address);
-            hexagon = getGeoPolygon(cellBoundary);
+        private H3Polygon2D(long h3) {
+            this.h3 = h3;
+            this.res = H3.getResolution(h3);
+            this.hexagon = H3SphericalUtil.toGeoPolygon(h3);
             final LatLonBounds bounds = new LatLonBounds();
-            hexagon.getBounds(bounds);
+            this.hexagon.getBounds(bounds);
             final double minY = bounds.checkNoBottomLatitudeBound() ? GeoUtils.MIN_LAT_INCL : Math.toDegrees(bounds.getMinLatitude());
             final double maxY = bounds.checkNoTopLatitudeBound() ? GeoUtils.MAX_LAT_INCL : Math.toDegrees(bounds.getMaxLatitude());
             final double minX;
@@ -102,15 +93,6 @@ class H3LatLonGeometry extends LatLonGeometry {
 
         }
 
-        private GeoPolygon getGeoPolygon(CellBoundary cellBoundary) {
-            final List<GeoPoint> points = new ArrayList<>(cellBoundary.numPoints());
-            for (int i = 0; i < cellBoundary.numPoints(); i++) {
-                final LatLng latLng = cellBoundary.getLatLon(i);
-                points.add(new GeoPoint(PlanetModel.SPHERE, latLng.getLatRad(), latLng.getLonRad()));
-            }
-            return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
-        }
-
         @Override
         public double getMinX() {
             return minX;

+ 6 - 0
x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/common/H3SphericalUtil.java

@@ -7,6 +7,7 @@
 
 package org.elasticsearch.xpack.spatial.common;
 
+import org.apache.lucene.geo.LatLonGeometry;
 import org.apache.lucene.spatial3d.geom.GeoPoint;
 import org.apache.lucene.spatial3d.geom.GeoPolygon;
 import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
@@ -126,4 +127,9 @@ public final class H3SphericalUtil {
         }
         return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
     }
+
+    /** Return the {@link LatLonGeometry} representing the provided H3 bin */
+    public static LatLonGeometry getLatLonGeometry(long h3) {
+        return new H3SphericalGeometry(h3);
+    }
 }

+ 4 - 2
x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/query/GeoGridQueryBuilder.java

@@ -32,6 +32,7 @@ import org.elasticsearch.xcontent.ParseField;
 import org.elasticsearch.xcontent.XContentBuilder;
 import org.elasticsearch.xcontent.XContentParser;
 import org.elasticsearch.xpack.spatial.common.H3CartesianUtil;
+import org.elasticsearch.xpack.spatial.common.H3SphericalUtil;
 import org.elasticsearch.xpack.spatial.index.mapper.GeoShapeWithDocValuesFieldMapper;
 
 import java.io.IOException;
@@ -105,13 +106,14 @@ public class GeoGridQueryBuilder extends AbstractQueryBuilder<GeoGridQueryBuilde
 
             @Override
             protected Query toQuery(SearchExecutionContext context, String fieldName, MappedFieldType fieldType, String id) {
+                final long h3 = H3.stringToH3(id);
                 if (fieldType instanceof GeoShapeWithDocValuesFieldMapper.GeoShapeWithDocValuesFieldType geoShapeFieldType) {
                     // shapes are solved on the cartesian geometry
-                    final LatLonGeometry geometry = H3CartesianUtil.getLatLonGeometry(H3.stringToH3(id));
+                    final LatLonGeometry geometry = H3CartesianUtil.getLatLonGeometry(h3);
                     return geoShapeFieldType.geoShapeQuery(context, fieldName, ShapeRelation.INTERSECTS, geometry);
                 } else {
                     // points are solved on the spherical geometry
-                    final H3LatLonGeometry geometry = new H3LatLonGeometry(id);
+                    final LatLonGeometry geometry = H3SphericalUtil.getLatLonGeometry(h3);
                     if (fieldType instanceof GeoPointFieldMapper.GeoPointFieldType pointFieldType) {
                         return pointFieldType.geoShapeQuery(context, fieldName, ShapeRelation.INTERSECTS, geometry);
                     } else if (fieldType instanceof GeoPointScriptFieldType scriptType) {

+ 8 - 8
x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/query/H3LatLonGeometryTests.java → x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/common/H3SphericalGeometryTests.java

@@ -5,7 +5,7 @@
  * 2.0.
  */
 
-package org.elasticsearch.xpack.spatial.index.query;
+package org.elasticsearch.xpack.spatial.common;
 
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.LatLonPoint;
@@ -27,15 +27,15 @@ import org.elasticsearch.h3.H3;
 import org.elasticsearch.h3.LatLng;
 import org.elasticsearch.test.ESTestCase;
 
-public class H3LatLonGeometryTests extends ESTestCase {
+public class H3SphericalGeometryTests extends ESTestCase {
 
     private static final String FIELD_NAME = "field";
 
     public void testIndexPoints() throws Exception {
         Point queryPoint = GeometryTestUtils.randomPoint();
-        String[] hexes = new String[H3.MAX_H3_RES + 1];
+        long[] hexes = new long[H3.MAX_H3_RES + 1];
         for (int res = 0; res < hexes.length; res++) {
-            hexes[res] = H3.geoToH3Address(queryPoint.getLat(), queryPoint.getLon(), res);
+            hexes[res] = H3.geoToH3(queryPoint.getLat(), queryPoint.getLon(), res);
         }
         IndexWriterConfig iwc = newIndexWriterConfig();
         // Else seeds may not reproduce:
@@ -46,7 +46,7 @@ public class H3LatLonGeometryTests extends ESTestCase {
         // RandomIndexWriter is too slow here:
         int[] counts = new int[H3.MAX_H3_RES + 1];
         IndexWriter w = new IndexWriter(dir, iwc);
-        for (String hex : hexes) {
+        for (long hex : hexes) {
             CellBoundary cellBoundary = H3.h3ToGeoBoundary(hex);
             for (int i = 0; i < cellBoundary.numPoints(); i++) {
                 Document doc = new Document();
@@ -74,18 +74,18 @@ public class H3LatLonGeometryTests extends ESTestCase {
 
         IndexSearcher s = newSearcher(r);
         for (int i = 0; i < H3.MAX_H3_RES + 1; i++) {
-            H3LatLonGeometry geometry = new H3LatLonGeometry(hexes[i]);
+            H3SphericalGeometry geometry = new H3SphericalGeometry(hexes[i]);
             Query indexQuery = LatLonPoint.newGeometryQuery(FIELD_NAME, ShapeField.QueryRelation.INTERSECTS, geometry);
             assertEquals(counts[i], s.count(indexQuery));
         }
         IOUtils.close(r, dir);
     }
 
-    private void computeCounts(String[] hexes, double lon, double lat, int[] counts) {
+    private void computeCounts(long[] hexes, double lon, double lat, int[] counts) {
         double qLat = GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(lat));
         double qLon = GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(lon));
         for (int res = 0; res < hexes.length; res++) {
-            if (hexes[res].equals(H3.geoToH3Address(qLat, qLon, res))) {
+            if (hexes[res] == H3.geoToH3(qLat, qLon, res)) {
                 counts[res]++;
             }
         }