From 5c0273791865109be8495ecec385aeedf043bc89 Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Tue, 3 Nov 2020 09:21:03 +0100 Subject: [PATCH] LUCENE-9553: Adds a XYPoint query that accepts an array of XYGeometries (#1939) --- lucene/CHANGES.txt | 2 + .../lucene/document/XYDocValuesField.java | 22 +- .../apache/lucene/document/XYPointField.java | 15 +- .../lucene/search/TestXYDocValuesQueries.java | 6 + .../lucene/search/TestXYPointQueries.java | 6 + .../lucene/geo/BaseXYPointTestCase.java | 408 ++++++++---------- 6 files changed, 239 insertions(+), 220 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index d049e55645b..163c09c3db2 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -214,6 +214,8 @@ New Features * LUCENE-9552: New LatLonPoint query that accepts an array of LatLonGeometries. (Ignacio Vera) +* LUCENE-9553: New XYPoint query that accepts an array of XYGeometries. (Ignacio Vera) + Improvements --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/document/XYDocValuesField.java b/lucene/core/src/java/org/apache/lucene/document/XYDocValuesField.java index 3f1bb66c086..1310159200d 100644 --- a/lucene/core/src/java/org/apache/lucene/document/XYDocValuesField.java +++ b/lucene/core/src/java/org/apache/lucene/document/XYDocValuesField.java @@ -18,6 +18,7 @@ package org.apache.lucene.document; import org.apache.lucene.geo.XYCircle; import org.apache.lucene.geo.XYEncodingUtils; +import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.XYPolygon; import org.apache.lucene.geo.XYRectangle; import org.apache.lucene.index.DocValuesType; @@ -36,6 +37,10 @@ import org.apache.lucene.search.SortField; *

* This field defines static factory methods for common operations: *

*

@@ -173,6 +178,21 @@ public class XYDocValuesField extends Field { * @throws IllegalArgumentException if {@code field} is null or polygons is empty or contain a null polygon. */ public static Query newSlowPolygonQuery(String field, XYPolygon... polygons) { - return new XYDocValuesPointInGeometryQuery(field, polygons); + return newSlowGeometryQuery(field, polygons); + } + + /** + * Create a query for matching points within the supplied geometries. XYLine geometries are not supported. + * This query is usually slow as it does not use an index structure and needs + * to verify documents one-by-one in order to know whether they match. It is + * best used wrapped in an {@link IndexOrDocValuesQuery} alongside a + * {@link XYPointField#newGeometryQuery(String, XYGeometry...)}. + * @param field field name. must not be null. + * @param geometries array of XY geometries. must not be null or empty. + * @return query matching points within the given geometries. + * @throws IllegalArgumentException if {@code field} is null, {@code polygons} is null, empty or contains a null or XYLine geometry. + */ + public static Query newSlowGeometryQuery(String field, XYGeometry... geometries) { + return new XYDocValuesPointInGeometryQuery(field, geometries); } } diff --git a/lucene/core/src/java/org/apache/lucene/document/XYPointField.java b/lucene/core/src/java/org/apache/lucene/document/XYPointField.java index 1c43774fc40..6c4e0bb9d2c 100644 --- a/lucene/core/src/java/org/apache/lucene/document/XYPointField.java +++ b/lucene/core/src/java/org/apache/lucene/document/XYPointField.java @@ -19,6 +19,7 @@ package org.apache.lucene.document; import org.apache.lucene.geo.Polygon; import org.apache.lucene.geo.XYCircle; import org.apache.lucene.geo.XYEncodingUtils; +import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.XYPolygon; import org.apache.lucene.geo.XYRectangle; import org.apache.lucene.index.FieldInfo; @@ -40,6 +41,7 @@ import org.apache.lucene.util.NumericUtils; *

  • {@link #newBoxQuery newBoxQuery()} for matching points within a bounding box. *
  • {@link #newDistanceQuery newDistanceQuery()} for matching points within a specified distance. *
  • {@link #newPolygonQuery newPolygonQuery()} for matching points within an arbitrary polygon. + *
  • {@link #newGeometryQuery newGeometryQuery()} for matching points within an arbitrary geometry collection. * *

    * If you also need per-document operations such as sort by distance, add a separate {@link XYDocValuesField} instance. @@ -167,6 +169,17 @@ public class XYPointField extends Field { * @see Polygon */ public static Query newPolygonQuery(String field, XYPolygon... polygons) { - return new XYPointInGeometryQuery(field, polygons); + return newGeometryQuery(field, polygons); + } + + /** create a query to find all indexed shapes that intersect a provided geometry collection. XYLine geometries are not supported. + * @param field field name. must not be null. + * @param xyGeometries array of geometries. must not be null or empty. + * @return query matching points within this geometry collection. + * @throws IllegalArgumentException if {@code field} is null, {@code polygons} is null, empty or contains a null or XYLine geometry. + * @see XYGeometry + **/ + public static Query newGeometryQuery(String field, XYGeometry... xyGeometries) { + return new XYPointInGeometryQuery(field, xyGeometries); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestXYDocValuesQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestXYDocValuesQueries.java index 4ca1e5e2a96..8a7c8f75a26 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestXYDocValuesQueries.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestXYDocValuesQueries.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.Document; import org.apache.lucene.document.XYDocValuesField; import org.apache.lucene.geo.BaseXYPointTestCase; +import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.XYPolygon; public class TestXYDocValuesQueries extends BaseXYPointTestCase { @@ -42,4 +43,9 @@ public class TestXYDocValuesQueries extends BaseXYPointTestCase { protected Query newPolygonQuery(String field, XYPolygon... polygons) { return XYDocValuesField.newSlowPolygonQuery(field, polygons); } + + @Override + protected Query newGeometryQuery(String field, XYGeometry... geometries) { + return XYDocValuesField.newSlowGeometryQuery(field, geometries); + } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestXYPointQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestXYPointQueries.java index 208c3bd01bb..faff88f89d6 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestXYPointQueries.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestXYPointQueries.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.Document; import org.apache.lucene.document.XYPointField; import org.apache.lucene.geo.BaseXYPointTestCase; +import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.XYPolygon; public class TestXYPointQueries extends BaseXYPointTestCase { @@ -42,4 +43,9 @@ public class TestXYPointQueries extends BaseXYPointTestCase { protected Query newPolygonQuery(String field, XYPolygon... polygons) { return XYPointField.newPolygonQuery(field, polygons); } + + @Override + protected Query newGeometryQuery(String field, XYGeometry... geometries) { + return XYPointField.newGeometryQuery(field, geometries); + } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/geo/BaseXYPointTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/geo/BaseXYPointTestCase.java index c9240d7e7ae..e31134ca7ea 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/geo/BaseXYPointTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/geo/BaseXYPointTestCase.java @@ -24,6 +24,7 @@ import java.util.BitSet; import java.util.HashSet; import java.util.Locale; import java.util.Set; +import java.util.function.Consumer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.codecs.Codec; @@ -91,9 +92,23 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { return ShapeTestUtil.nextPolygon(); } - /** Whether this impl supports polygons. */ - protected boolean supportsPolygons() { - return true; + protected XYGeometry[] nextGeometry() { + final int len = random().nextInt(4) + 1; + XYGeometry[] geometries = new XYGeometry[len]; + for (int i = 0; i < len; i++) { + switch (random().nextInt(3)) { + case 0: + geometries[i] = new XYPoint(nextX(), nextY()); + break; + case 1: + geometries[i] = nextBox(); + break; + default: + geometries[i] = nextPolygon(); + break; + } + } + return geometries; } /** Valid values that should not cause exception */ @@ -253,7 +268,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { /** test we can search for a polygon */ public void testPolygonBasics() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); Directory dir = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random(), dir); @@ -276,7 +290,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { /** test we can search for a polygon with a hole (but still includes the doc) */ public void testPolygonHole() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); Directory dir = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random(), dir); @@ -301,7 +314,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { /** test we can search for a polygon with a hole (that excludes the doc) */ public void testPolygonHoleExcludes() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); Directory dir = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random(), dir); @@ -326,7 +338,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { /** test we can search for a multi-polygon */ public void testMultiPolygonBasics() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); Directory dir = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random(), dir); @@ -351,7 +362,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { /** null field name not allowed */ public void testPolygonNullField() { - assumeTrue("Impl does not support polygons", supportsPolygons()); IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> { newPolygonQuery(null, new XYPolygon( new float[] { 18, 18, 19, 19, 18 }, @@ -542,26 +552,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { Query query = newRectQuery(FIELD_NAME, rect.minX, rect.maxX, rect.minY, rect.maxY); - final FixedBitSet hits = new FixedBitSet(r.maxDoc()); - s.search(query, new SimpleCollector() { - - private int docBase; - - @Override - public ScoreMode scoreMode() { - return ScoreMode.COMPLETE_NO_SCORES; - } - - @Override - protected void doSetNextReader(LeafReaderContext context) throws IOException { - docBase = context.docBase; - } - - @Override - public void collect(int doc) { - hits.set(docBase+doc); - } - }); + final FixedBitSet hits = searchIndex(s, query, r.maxDoc()); boolean fail = false; @@ -570,7 +561,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { float xDoc1 = xs[2*docID]; float yDoc2 = ys[2*docID+1]; float xDoc2 = xs[2*docID+1]; - + boolean result1 = rectContainsPoint(rect, xDoc1, yDoc1); boolean result2 = rectContainsPoint(rect, xDoc2, yDoc2); @@ -691,6 +682,8 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { protected abstract Query newPolygonQuery(String field, XYPolygon... polygon); + protected abstract Query newGeometryQuery(String field, XYGeometry... geometries); + static final boolean rectContainsPoint(XYRectangle rect, double x, double y) { if (y < rect.minY || y > rect.maxY) { return false; @@ -708,9 +701,8 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { // NaN means missing for the doc!!!!! verifyRandomRectangles(xs, ys); verifyRandomDistances(xs, ys); - if (supportsPolygons()) { - verifyRandomPolygons(xs, ys); - } + verifyRandomPolygons(xs, ys); + verifyRandomGeometries(xs, ys); } protected void verifyRandomRectangles(float[] xs, float[] ys) throws Exception { @@ -732,27 +724,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { Set deleted = new HashSet<>(); // RandomIndexWriter is too slow here: IndexWriter w = new IndexWriter(dir, iwc); - for(int id=0;id 0 && random().nextInt(100) == 42) { - int idToDelete = random().nextInt(id); - w.deleteDocuments(new Term("id", ""+idToDelete)); - deleted.add(idToDelete); - if (VERBOSE) { - System.out.println(" delete id=" + idToDelete); - } - } - } - - if (random().nextBoolean()) { - w.forceMerge(1); - } + indexPoints(xs, ys, deleted, w); final IndexReader r = DirectoryReader.open(w); w.close(); @@ -777,26 +749,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { System.out.println(" query=" + query); } - final FixedBitSet hits = new FixedBitSet(maxDoc); - s.search(query, new SimpleCollector() { - - private int docBase; - - @Override - public ScoreMode scoreMode() { - return ScoreMode.COMPLETE_NO_SCORES; - } - - @Override - protected void doSetNextReader(LeafReaderContext context) { - docBase = context.docBase; - } - - @Override - public void collect(int doc) { - hits.set(docBase+doc); - } - }); + final FixedBitSet hits = searchIndex(s, query, maxDoc); boolean fail = false; NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id"); @@ -814,24 +767,8 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { } if (hits.get(docID) != expected) { - StringBuilder b = new StringBuilder(); - b.append("docID=(").append(docID).append(")\n"); - - if (expected) { - b.append("FAIL: id=").append(id).append(" should match but did not\n"); - } else { - b.append("FAIL: id=").append(id).append(" should not match but did\n"); - } - b.append(" box=").append(rect).append("\n"); - b.append(" query=").append(query).append(" docID=").append(docID).append("\n"); - b.append(" x=").append(xs[id]).append(" y=").append(ys[id]).append("\n"); - b.append(" deleted?=").append(liveDocs != null && liveDocs.get(docID) == false); - if (true) { - fail("wrong hit (first of possibly more):\n\n" + b); - } else { - System.out.println(b.toString()); - fail = true; - } + buildError(docID, expected, id, xs, ys, query, liveDocs, (b) -> b.append(" rect=").append(rect)); + fail = true; } } if (fail) { @@ -861,27 +798,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { Set deleted = new HashSet<>(); // RandomIndexWriter is too slow here: IndexWriter w = new IndexWriter(dir, iwc); - for(int id=0;id 0 && random().nextInt(100) == 42) { - int idToDelete = random().nextInt(id); - w.deleteDocuments(new Term("id", ""+idToDelete)); - deleted.add(idToDelete); - if (VERBOSE) { - System.out.println(" delete id=" + idToDelete); - } - } - } - - if (random().nextBoolean()) { - w.forceMerge(1); - } + indexPoints(xs, ys, deleted, w); final IndexReader r = DirectoryReader.open(w); w.close(); @@ -916,26 +833,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { System.out.println(" query=" + query); } - final FixedBitSet hits = new FixedBitSet(maxDoc); - s.search(query, new SimpleCollector() { - - private int docBase; - - @Override - public ScoreMode scoreMode() { - return ScoreMode.COMPLETE_NO_SCORES; - } - - @Override - protected void doSetNextReader(LeafReaderContext context) throws IOException { - docBase = context.docBase; - } - - @Override - public void collect(int doc) { - hits.set(docBase+doc); - } - }); + final FixedBitSet hits = searchIndex(s, query, maxDoc); boolean fail = false; NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id"); @@ -953,26 +851,15 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { } if (hits.get(docID) != expected) { - StringBuilder b = new StringBuilder(); - - if (expected) { - b.append("FAIL: id=").append(id).append(" should match but did not\n"); - } else { - b.append("FAIL: id=").append(id).append(" should not match but did\n"); - } - b.append(" query=").append(query).append(" docID=").append(docID).append("\n"); - b.append(" x=").append(xs[id]).append(" y=").append(ys[id]).append("\n"); - b.append(" deleted?=").append(liveDocs != null && liveDocs.get(docID) == false); - if (Double.isNaN(xs[id]) == false) { - double distance = cartesianDistance(centerX, centerY, xs[id], ys[id]); - b.append(" centerX=").append(centerX).append(" centerY=").append(centerY).append(" distance=").append(distance).append(" vs radius=").append(radius); - } - if (true) { - fail("wrong hit (first of possibly more):\n\n" + b); - } else { - System.out.println(b.toString()); - fail = true; - } + Consumer explain = (b) -> { + if (Double.isNaN(xs[id]) == false) { + double distance = cartesianDistance(centerX, centerY, xs[id], ys[id]); + b.append(" centerX=").append(centerX).append(" centerY=").append(centerY).append(" distance=") + .append(distance).append(" vs radius=").append(radius); + } + }; + buildError(docID, expected, id, xs, ys, query, liveDocs, explain); + fail = true; } } if (fail) { @@ -1002,27 +889,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { Set deleted = new HashSet<>(); // RandomIndexWriter is too slow here: IndexWriter w = new IndexWriter(dir, iwc); - for(int id=0;id 0 && random().nextInt(100) == 42) { - int idToDelete = random().nextInt(id); - w.deleteDocuments(new Term("id", ""+idToDelete)); - deleted.add(idToDelete); - if (VERBOSE) { - System.out.println(" delete id=" + idToDelete); - } - } - } - - if (random().nextBoolean()) { - w.forceMerge(1); - } + indexPoints(xs, ys, deleted, w); final IndexReader r = DirectoryReader.open(w); w.close(); @@ -1048,26 +915,7 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { System.out.println(" query=" + query); } - final FixedBitSet hits = new FixedBitSet(maxDoc); - s.search(query, new SimpleCollector() { - - private int docBase; - - @Override - public ScoreMode scoreMode() { - return ScoreMode.COMPLETE_NO_SCORES; - } - - @Override - protected void doSetNextReader(LeafReaderContext context) throws IOException { - docBase = context.docBase; - } - - @Override - public void collect(int doc) { - hits.set(docBase+doc); - } - }); + final FixedBitSet hits = searchIndex(s, query, maxDoc); boolean fail = false; NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id"); @@ -1085,23 +933,8 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { } if (hits.get(docID) != expected) { - StringBuilder b = new StringBuilder(); - - if (expected) { - b.append("FAIL: id=").append(id).append(" should match but did not\n"); - } else { - b.append("FAIL: id=").append(id).append(" should not match but did\n"); - } - b.append(" query=").append(query).append(" docID=").append(docID).append("\n"); - b.append(" x=").append(xs[id]).append(" y=").append(ys[id]).append("\n"); - b.append(" deleted?=").append(liveDocs != null && liveDocs.get(docID) == false); - b.append(" polygon=").append(polygon); - if (true) { - fail("wrong hit (first of possibly more):\n\n" + b); - } else { - System.out.println(b.toString()); - fail = true; - } + buildError(docID, expected, id, xs, ys, query, liveDocs, (b) -> b.append(" polygon=").append(polygon)); + fail = true; } } if (fail) { @@ -1112,6 +945,149 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { IOUtils.close(r, dir); } + protected void verifyRandomGeometries(float[] xs, float[] ys) throws Exception { + IndexWriterConfig iwc = newIndexWriterConfig(); + // Else seeds may not reproduce: + iwc.setMergeScheduler(new SerialMergeScheduler()); + // Else we can get O(N^2) merging: + int mbd = iwc.getMaxBufferedDocs(); + if (mbd != -1 && mbd < xs.length/100) { + iwc.setMaxBufferedDocs(xs.length/100); + } + Directory dir; + if (xs.length > 100000) { + dir = newFSDirectory(createTempDir(getClass().getSimpleName())); + } else { + dir = newDirectory(); + } + + Set deleted = new HashSet<>(); + // RandomIndexWriter is too slow here: + IndexWriter w = new IndexWriter(dir, iwc); + indexPoints(xs, ys, deleted, w); + final IndexReader r = DirectoryReader.open(w); + w.close(); + + // We can't wrap with "exotic" readers because points needs to work: + IndexSearcher s = newSearcher(r); + + final int iters = atLeast(75); + + Bits liveDocs = MultiBits.getLiveDocs(s.getIndexReader()); + int maxDoc = s.getIndexReader().maxDoc(); + + for (int iter=0;iter b.append(" geometry=").append(Arrays.toString(geometries))); + fail = true; + } + } + if (fail) { + fail("some hits were wrong"); + } + } + + IOUtils.close(r, dir); + } + + private void indexPoints(float[] xs, float[] ys, Set deleted, IndexWriter w) throws IOException { + for(int id=0;id 0 && random().nextInt(100) == 42) { + int idToDelete = random().nextInt(id); + w.deleteDocuments(new Term("id", ""+idToDelete)); + deleted.add(idToDelete); + if (VERBOSE) { + System.out.println(" delete id=" + idToDelete); + } + } + } + + if (random().nextBoolean()) { + w.forceMerge(1); + } + } + + private FixedBitSet searchIndex(IndexSearcher s, Query query, int maxDoc) throws IOException { + final FixedBitSet hits = new FixedBitSet(maxDoc); + s.search(query, new SimpleCollector() { + + private int docBase; + + @Override + public ScoreMode scoreMode() { + return ScoreMode.COMPLETE_NO_SCORES; + } + + @Override + protected void doSetNextReader(LeafReaderContext context) { + docBase = context.docBase; + } + + @Override + public void collect(int doc) { + hits.set(docBase+doc); + } + }); + return hits; + } + + private void buildError(int docID, boolean expected, int id, float[] xs, float[] ys, Query query, + Bits liveDocs, Consumer explain) { + StringBuilder b = new StringBuilder(); + if (expected) { + b.append("FAIL: id=").append(id).append(" should match but did not\n"); + } else { + b.append("FAIL: id=").append(id).append(" should not match but did\n"); + } + b.append(" query=").append(query).append(" docID=").append(docID).append("\n"); + b.append(" x=").append(xs[id]).append(" y=").append(ys[id]).append("\n"); + b.append(" deleted?=").append(liveDocs != null && liveDocs.get(docID) == false); + explain.accept(b); + if (true) { + fail("wrong hit (first of possibly more):\n\n" + b); + } else { + System.out.println(b.toString()); + } + } + public void testRectBoundariesAreInclusive() throws Exception { XYRectangle rect = ShapeTestUtil.nextBox(random()); Directory dir = newDirectory(); @@ -1292,12 +1268,10 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { ys[3] = rect.maxY; xs[4] = rect.minX; ys[4] = rect.minY; - if (supportsPolygons()) { - q1 = newPolygonQuery("field", new XYPolygon(xs, ys)); - q2 = newPolygonQuery("field", new XYPolygon(xs, ys)); - assertEquals(q1, q2); - assertFalse(q1.equals(newPolygonQuery("field2", new XYPolygon(xs, ys)))); - } + q1 = newPolygonQuery("field", new XYPolygon(xs, ys)); + q2 = newPolygonQuery("field", new XYPolygon(xs, ys)); + assertEquals(q1, q2); + assertFalse(q1.equals(newPolygonQuery("field2", new XYPolygon(xs, ys)))); } /** return topdocs over a small set of points in field "point" */ @@ -1385,7 +1359,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { } public void testSmallSetPoly() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); TopDocs td = searchSmallSet(newPolygonQuery("point", new XYPolygon( new float[]{33.073130f, 32.9942669f, 32.938386f, 33.0374494f, @@ -1397,7 +1370,6 @@ public abstract class BaseXYPointTestCase extends LuceneTestCase { } public void testSmallSetPolyWholeSpace() throws Exception { - assumeTrue("Impl does not support polygons", supportsPolygons()); TopDocs td = searchSmallSet(newPolygonQuery("point", new XYPolygon( new float[] {-Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE},