diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 909d3edadee..16550c6b06b 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -125,6 +125,9 @@ API Changes * LUCENE-7064: MultiPhraseQuery is now immutable and should be constructed with MultiPhraseQuery.Builder. (Luc Vanlerberghe via Adrien Grand) +* LUCENE-7072: Geo3DPoint always uses WGS84 planet model. + (Robert Muir, Mike McCandless) + Optimizations * LUCENE-6891: Use prefix coding when writing points in diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java index b5e3d286adb..c64b974fd1f 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java @@ -34,6 +34,11 @@ public abstract class BasePlanetObject { public BasePlanetObject(final PlanetModel planetModel) { this.planetModel = planetModel; } + + /** Returns the {@link PlanetModel} provided when this shape was created. */ + public PlanetModel getPlanetModel() { + return planetModel; + } @Override public int hashCode() { diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java index fbdb00d7a3c..cde87f3c77b 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java @@ -36,8 +36,6 @@ import org.apache.lucene.util.RamUsageEstimator; * @lucene.experimental */ public final class Geo3DPoint extends Field { - private final PlanetModel planetModel; - /** Indexing {@link FieldType}. */ public static final FieldType TYPE = new FieldType(); static { @@ -46,16 +44,15 @@ public final class Geo3DPoint extends Field { } /** - * Creates a new Geo3DPoint field with the specified lat, lon (in radians), given a planet model. + * Creates a new Geo3DPoint field with the specified lat, lon (in radians). * * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds */ - public Geo3DPoint(String name, PlanetModel planetModel, double lat, double lon) { + public Geo3DPoint(String name, double lat, double lon) { super(name, TYPE); - this.planetModel = planetModel; // Translate lat/lon to x,y,z: - final GeoPoint point = new GeoPoint(planetModel, lat, lon); - fillFieldsData(planetModel, point.x, point.y, point.z); + final GeoPoint point = new GeoPoint(PlanetModel.WGS84, lat, lon); + fillFieldsData(point.x, point.y, point.z); } /** @@ -63,40 +60,38 @@ public final class Geo3DPoint extends Field { * * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds */ - public Geo3DPoint(String name, PlanetModel planetModel, double x, double y, double z) { + public Geo3DPoint(String name, double x, double y, double z) { super(name, TYPE); - this.planetModel = planetModel; - fillFieldsData(planetModel, x, y, z); + fillFieldsData(x, y, z); } - private void fillFieldsData(PlanetModel planetModel, double x, double y, double z) { + private void fillFieldsData(double x, double y, double z) { byte[] bytes = new byte[12]; - encodeDimension(planetModel, x, bytes, 0); - encodeDimension(planetModel, y, bytes, Integer.BYTES); - encodeDimension(planetModel, z, bytes, 2*Integer.BYTES); + encodeDimension(x, bytes, 0); + encodeDimension(y, bytes, Integer.BYTES); + encodeDimension(z, bytes, 2*Integer.BYTES); fieldsData = new BytesRef(bytes); } // public helper methods (e.g. for queries) /** Encode single dimension */ - public static void encodeDimension(PlanetModel planetModel, double value, byte bytes[], int offset) { - NumericUtils.intToSortableBytes(Geo3DUtil.encodeValue(planetModel.getMaximumMagnitude(), value), bytes, offset); + public static void encodeDimension(double value, byte bytes[], int offset) { + NumericUtils.intToSortableBytes(Geo3DUtil.encodeValue(PlanetModel.WGS84.getMaximumMagnitude(), value), bytes, offset); } /** Decode single dimension */ - public static double decodeDimension(PlanetModel planetModel, byte value[], int offset) { - return Geo3DUtil.decodeValueCenter(planetModel.getMaximumMagnitude(), NumericUtils.sortableBytesToInt(value, offset)); + public static double decodeDimension(byte value[], int offset) { + return Geo3DUtil.decodeValueCenter(PlanetModel.WGS84.getMaximumMagnitude(), NumericUtils.sortableBytesToInt(value, offset)); } /** Returns a query matching all points inside the provided shape. * - * @param planetModel The {@link PlanetModel} to use, which must match what was used during indexing * @param field field name. must not be {@code null}. * @param shape Which {@link GeoShape} to match */ - public static Query newShapeQuery(PlanetModel planetModel, String field, GeoShape shape) { - return new PointInGeo3DShapeQuery(planetModel, field, shape); + public static Query newShapeQuery(String field, GeoShape shape) { + return new PointInGeo3DShapeQuery(field, shape); } @Override @@ -108,9 +103,9 @@ public final class Geo3DPoint extends Field { result.append(':'); BytesRef bytes = (BytesRef) fieldsData; - result.append(" x=" + decodeDimension(planetModel, bytes.bytes, bytes.offset)); - result.append(" y=" + decodeDimension(planetModel, bytes.bytes, bytes.offset + Integer.BYTES)); - result.append(" z=" + decodeDimension(planetModel, bytes.bytes, bytes.offset + 2*Integer.BYTES)); + result.append(" x=" + decodeDimension(bytes.bytes, bytes.offset)); + result.append(" y=" + decodeDimension(bytes.bytes, bytes.offset + Integer.BYTES)); + result.append(" z=" + decodeDimension(bytes.bytes, bytes.offset + 2*Integer.BYTES)); result.append('>'); return result.toString(); } diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java index 4d816963080..9e2132d680d 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java @@ -40,14 +40,19 @@ import org.apache.lucene.util.NumericUtils; class PointInGeo3DShapeQuery extends Query { final String field; - final PlanetModel planetModel; final GeoShape shape; /** The lats/lons must be clockwise or counter-clockwise. */ - public PointInGeo3DShapeQuery(PlanetModel planetModel, String field, GeoShape shape) { + public PointInGeo3DShapeQuery(String field, GeoShape shape) { this.field = field; - this.planetModel = planetModel; this.shape = shape; + + if (shape instanceof BasePlanetObject) { + BasePlanetObject planetObject = (BasePlanetObject) shape; + if (planetObject.getPlanetModel().equals(PlanetModel.WGS84) == false) { + throw new IllegalArgumentException("this qurey requires PlanetModel.WGS84, but got: " + planetObject.getPlanetModel()); + } + } } @Override @@ -88,7 +93,7 @@ class PointInGeo3DShapeQuery extends Query { assert xyzSolid.getRelationship(shape) == GeoArea.WITHIN || xyzSolid.getRelationship(shape) == GeoArea.OVERLAPS: "expected WITHIN (1) or OVERLAPS (2) but got " + xyzSolid.getRelationship(shape) + "; shape="+shape+"; XYZSolid="+xyzSolid; */ - double planetMax = planetModel.getMaximumMagnitude(); + double planetMax = PlanetModel.WGS84.getMaximumMagnitude(); DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc()); @@ -103,9 +108,9 @@ class PointInGeo3DShapeQuery extends Query { @Override public void visit(int docID, byte[] packedValue) { assert packedValue.length == 12; - double x = Geo3DPoint.decodeDimension(planetModel, packedValue, 0); - double y = Geo3DPoint.decodeDimension(planetModel, packedValue, Integer.BYTES); - double z = Geo3DPoint.decodeDimension(planetModel, packedValue, 2 * Integer.BYTES); + double x = Geo3DPoint.decodeDimension(packedValue, 0); + double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES); + double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES); if (shape.isWithin(x, y, z)) { result.add(docID); } @@ -129,7 +134,7 @@ class PointInGeo3DShapeQuery extends Query { assert yMin <= yMax; assert zMin <= zMax; - GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel, xMin, xMax, yMin, yMax, zMin, zMax); + GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax); switch(xyzSolid.getRelationship(shape)) { case GeoArea.CONTAINS: @@ -165,10 +170,6 @@ class PointInGeo3DShapeQuery extends Query { return field; } - public PlanetModel getPlanetModel() { - return planetModel; - } - public GeoShape getShape() { return shape; } @@ -182,13 +183,12 @@ class PointInGeo3DShapeQuery extends Query { PointInGeo3DShapeQuery that = (PointInGeo3DShapeQuery) o; - return planetModel.equals(that.planetModel) && shape.equals(that.shape); + return shape.equals(that.shape); } @Override public final int hashCode() { int result = super.hashCode(); - result = 31 * result + planetModel.hashCode(); result = 31 * result + shape.hashCode(); return result; } @@ -203,8 +203,6 @@ class PointInGeo3DShapeQuery extends Query { sb.append(this.field); sb.append(':'); } - sb.append(" PlanetModel: "); - sb.append(planetModel); sb.append(" Shape: "); sb.append(shape); return sb.toString(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java index 9d00d3e6ccb..17a40755d2f 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java @@ -106,13 +106,12 @@ public class TestGeo3DPoint extends LuceneTestCase { iwc.setCodec(getCodec()); IndexWriter w = new IndexWriter(dir, iwc); Document doc = new Document(); - doc.add(new Geo3DPoint("field", PlanetModel.WGS84, toRadians(50.7345267), toRadians(-97.5303555))); + doc.add(new Geo3DPoint("field", toRadians(50.7345267), toRadians(-97.5303555))); w.addDocument(doc); IndexReader r = DirectoryReader.open(w); // We can't wrap with "exotic" readers because the query must see the BKD3DDVFormat: IndexSearcher s = newSearcher(r, false); - assertEquals(1, s.search(Geo3DPoint.newShapeQuery(PlanetModel.WGS84, - "field", + assertEquals(1, s.search(Geo3DPoint.newShapeQuery("field", GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(50), toRadians(-97), Math.PI/180.)), 1).totalHits); w.close(); r.close(); @@ -640,8 +639,6 @@ public class TestGeo3DPoint extends LuceneTestCase { private static void verify(double[] lats, double[] lons) throws Exception { IndexWriterConfig iwc = newIndexWriterConfig(); - PlanetModel planetModel = getPlanetModel(); - // Else we can get O(N^2) merging: int mbd = iwc.getMaxBufferedDocs(); if (mbd != -1 && mbd < lats.length/100) { @@ -662,7 +659,7 @@ public class TestGeo3DPoint extends LuceneTestCase { doc.add(newStringField("id", ""+id, Field.Store.NO)); doc.add(new NumericDocValuesField("id", id)); if (Double.isNaN(lats[id]) == false) { - doc.add(new Geo3DPoint("point", planetModel, lats[id], lons[id])); + doc.add(new Geo3DPoint("point", lats[id], lons[id])); } w.addDocument(doc); if (id > 0 && random().nextInt(100) == 42) { @@ -710,13 +707,13 @@ public class TestGeo3DPoint extends LuceneTestCase { for (int iter=0;iter", point.toString()); + Geo3DPoint point = new Geo3DPoint("point", toRadians(44.244272), toRadians(7.769736)); + assertEquals("Geo3DPoint ", point.toString()); } public void testShapeQueryToString() { - assertEquals("PointInGeo3DShapeQuery: field=point: PlanetModel: PlanetModel.SPHERE Shape: GeoStandardCircle: {planetmodel=PlanetModel.SPHERE, center=[lat=0.3861041107739683, lon=0.06780373760536706], radius=0.1(5.729577951308232)}", - Geo3DPoint.newShapeQuery(PlanetModel.SPHERE, "point", GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, toRadians(44.244272), toRadians(7.769736), 0.1)).toString()); + assertEquals("PointInGeo3DShapeQuery: field=point: Shape: GeoStandardCircle: {planetmodel=PlanetModel.WGS84, center=[lat=0.3861041107739683, lon=0.06780373760536706], radius=0.1(5.729577951308232)}", + Geo3DPoint.newShapeQuery("point", GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(44.244272), toRadians(7.769736), 0.1)).toString()); } private static Directory getDirectory() {