LUCENE-9637: Removes some unused code and replaces the Point implementation on ShapeField/ShapeQuery random tests

This commit is contained in:
Ignacio Vera 2020-12-16 12:08:23 +01:00 committed by GitHub
parent bf7b438f12
commit 6f56a3cd73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 154 additions and 554 deletions

View File

@ -283,6 +283,8 @@ Other
* SOLR-14995: Update Jetty to 9.4.34 (Mike Drob) * SOLR-14995: Update Jetty to 9.4.34 (Mike Drob)
* LUCENE-9637: Removes some unused code and replaces the Point implementation on ShapeField/ShapeQuery
random tests. (Ignacio Vera)
======================= Lucene 8.7.0 ======================= ======================= Lucene 8.7.0 =======================

View File

@ -25,8 +25,10 @@ import org.apache.lucene.geo.GeoTestUtil;
import org.apache.lucene.geo.GeoUtils; import org.apache.lucene.geo.GeoUtils;
import org.apache.lucene.geo.LatLonGeometry; import org.apache.lucene.geo.LatLonGeometry;
import org.apache.lucene.geo.Line; import org.apache.lucene.geo.Line;
import org.apache.lucene.geo.Point;
import org.apache.lucene.geo.Polygon; import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Rectangle; import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.geo.Tessellator;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
@ -88,6 +90,11 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
return LatLonGeometry.create(Arrays.stream(polygons).toArray(Polygon[]::new)); return LatLonGeometry.create(Arrays.stream(polygons).toArray(Polygon[]::new));
} }
@Override
protected Component2D toRectangle2D(double minX, double maxX, double minY, double maxY) {
return LatLonGeometry.create(new Rectangle(minY, maxY, minX, maxX));
}
@Override @Override
protected Component2D toPoint2D(Object... points) { protected Component2D toPoint2D(Object... points) {
double[][] p = Arrays.stream(points).toArray(double[][]::new); double[][] p = Arrays.stream(points).toArray(double[][]::new);
@ -251,11 +258,6 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
return LatLonShape.newPolygonQuery(field, queryRelation, polygons); return LatLonShape.newPolygonQuery(field, queryRelation, polygons);
} }
/** factory method to create a new point query */
protected Query newPointQuery(String field, QueryRelation queryRelation, double[]... points) {
return LatLonShape.newPointQuery(field, queryRelation, points);
}
public void testPolygonQueryEqualsAndHashcode() { public void testPolygonQueryEqualsAndHashcode() {
Polygon polygon = GeoTestUtil.nextPolygon(); Polygon polygon = GeoTestUtil.nextPolygon();
QueryRelation queryRelation = RandomPicks.randomFrom(random(), QueryRelation.values()); QueryRelation queryRelation = RandomPicks.randomFrom(random(), QueryRelation.values());
@ -293,21 +295,10 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
protected boolean rectCrossesDateline(Object rect) { protected boolean rectCrossesDateline(Object rect) {
return ((Rectangle)rect).crossesDateline(); return ((Rectangle)rect).crossesDateline();
} }
/** use {@link GeoTestUtil#nextPolygon()} to create a random line; TODO: move to GeoTestUtil */
@Override @Override
public Line nextLine() { public Line nextLine() {
return getNextLine(); return GeoTestUtil.nextLine();
}
public static Line getNextLine() {
Polygon poly = GeoTestUtil.nextPolygon();
double[] lats = new double[poly.numPoints() - 1];
double[] lons = new double[lats.length];
System.arraycopy(poly.getPolyLats(), 0, lats, 0, lats.length);
System.arraycopy(poly.getPolyLons(), 0, lons, 0, lons.length);
return new Line(lats, lons);
} }
@Override @Override
@ -347,41 +338,6 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
double quantizeYCeil(double raw) { double quantizeYCeil(double raw) {
return decodeLatitude(encodeLatitudeCeil(raw)); return decodeLatitude(encodeLatitudeCeil(raw));
} }
/** quantizes a latitude value to be consistent with index encoding */
protected double quantizeLat(double rawLat) {
return quantizeY(rawLat);
}
/** quantizes a provided latitude value rounded up to the nearest encoded integer */
protected double quantizeLatCeil(double rawLat) {
return quantizeYCeil(rawLat);
}
/** quantizes a longitude value to be consistent with index encoding */
protected double quantizeLon(double rawLon) {
return quantizeX(rawLon);
}
/** quantizes a provided longitude value rounded up to the nearest encoded integer */
protected double quantizeLonCeil(double rawLon) {
return quantizeXCeil(rawLon);
}
@Override
double[] quantizeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca) {
ShapeField.DecodedTriangle decoded = encodeDecodeTriangle(ax, ay, ab, bx, by, bc, cx, cy, ca);
return new double[]{decodeLatitude(decoded.aY), decodeLongitude(decoded.aX), decodeLatitude(decoded.bY), decodeLongitude(decoded.bX), decodeLatitude(decoded.cY), decodeLongitude(decoded.cX)};
}
@Override
ShapeField.DecodedTriangle encodeDecodeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca) {
byte[] encoded = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(encoded, encodeLatitude(ay), encodeLongitude(ax), ab, encodeLatitude(by), encodeLongitude(bx), bc, encodeLatitude(cy), encodeLongitude(cx), ca);
ShapeField.DecodedTriangle triangle = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(encoded, triangle);
return triangle;
}
}; };
} }
@ -389,24 +345,25 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
protected enum ShapeType { protected enum ShapeType {
POINT() { POINT() {
public Point nextShape() { public Point nextShape() {
return new Point(nextLongitude(), nextLatitude()); return GeoTestUtil.nextPoint();
} }
}, },
LINE() { LINE() {
public Line nextShape() { public Line nextShape() {
Polygon p = GeoTestUtil.nextPolygon(); return GeoTestUtil.nextLine();
double[] lats = new double[p.numPoints() - 1];
double[] lons = new double[lats.length];
for (int i = 0; i < lats.length; ++i) {
lats[i] = p.getPolyLat(i);
lons[i] = p.getPolyLon(i);
}
return new Line(lats, lons);
} }
}, },
POLYGON() { POLYGON() {
public Polygon nextShape() { public Polygon nextShape() {
return GeoTestUtil.nextPolygon(); while (true) {
Polygon p = GeoTestUtil.nextPolygon();
try {
Tessellator.tessellate(p);
return p;
} catch (IllegalArgumentException e) {
// if we can't tessellate; then random polygon generator created a malformed shape
}
}
} }
}, },
MIXED() { MIXED() {
@ -421,37 +378,5 @@ public abstract class BaseLatLonShapeTestCase extends BaseShapeTestCase {
} }
public abstract Object nextShape(); public abstract Object nextShape();
static ShapeType fromObject(Object shape) {
if (shape instanceof Point) {
return POINT;
} else if (shape instanceof Line) {
return LINE;
} else if (shape instanceof Polygon) {
return POLYGON;
}
throw new IllegalArgumentException("invalid shape type from " + shape.toString());
}
}
/** internal lat lon point class for testing point shapes */
protected static class Point {
double lon;
double lat;
public Point(double lon, double lat) {
this.lon = lon;
this.lat = lat;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("POINT(");
sb.append(lon);
sb.append(',');
sb.append(lat);
sb.append(')');
return sb.toString();
}
} }
} }

View File

@ -212,6 +212,8 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
protected abstract Component2D toCircle2D(Object circle); protected abstract Component2D toCircle2D(Object circle);
protected abstract Component2D toRectangle2D(double minX, double maxX, double minY, double maxY);
private void verify(Object... shapes) throws Exception { private void verify(Object... shapes) throws Exception {
IndexWriterConfig iwc = newIndexWriterConfig(); IndexWriterConfig iwc = newIndexWriterConfig();
iwc.setMergeScheduler(new SerialMergeScheduler()); iwc.setMergeScheduler(new SerialMergeScheduler());
@ -299,37 +301,18 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
System.out.println(" query=" + query + ", relation=" + queryRelation); System.out.println(" query=" + query + ", relation=" + queryRelation);
} }
final FixedBitSet hits = new FixedBitSet(maxDoc); final FixedBitSet hits = searchIndex(s, query, 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) throws IOException {
hits.set(docBase+doc);
}
});
boolean fail = false; boolean fail = false;
NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id"); NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id");
for (int docID = 0; docID < maxDoc; ++docID) { for (int docID = 0; docID < maxDoc; ++docID) {
assertEquals(docID, docIDToID.nextDoc()); assertEquals(docID, docIDToID.nextDoc());
int id = (int) docIDToID.longValue(); int id = (int) docIDToID.longValue();
boolean expected; boolean expected;
double minLon = rectMinX(rect); double minX = rectMinX(rect);
double maxLon = rectMaxX(rect); double maxX = rectMaxX(rect);
double minLat = rectMinY(rect); double minY = rectMinY(rect);
double maxLat = rectMaxY(rect); double maxY = rectMaxY(rect);
if (liveDocs != null && liveDocs.get(docID) == false) { if (liveDocs != null && liveDocs.get(docID) == false) {
// document is deleted // document is deleted
expected = false; expected = false;
@ -339,10 +322,13 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
if (queryRelation == QueryRelation.CONTAINS && rectCrossesDateline(rect)) { if (queryRelation == QueryRelation.CONTAINS && rectCrossesDateline(rect)) {
// For contains we need to call the validator for each section. // For contains we need to call the validator for each section.
// It is only expected if both sides are contained. // It is only expected if both sides are contained.
expected = VALIDATOR.setRelation(queryRelation).testBBoxQuery(minLat, maxLat, minLon, GeoUtils.MAX_LON_INCL, shapes[id]) && Component2D left = toRectangle2D(minX, GeoUtils.MAX_LON_INCL, minY, maxY);
VALIDATOR.setRelation(queryRelation).testBBoxQuery(minLat, maxLat, GeoUtils.MIN_LON_INCL, maxLon, shapes[id]); Component2D right = toRectangle2D(GeoUtils.MIN_LON_INCL, maxX, minY, maxY);
expected = VALIDATOR.setRelation(queryRelation).testComponentQuery(left, shapes[id]) &&
VALIDATOR.setRelation(queryRelation).testComponentQuery(right, shapes[id]);
} else { } else {
expected = VALIDATOR.setRelation(queryRelation).testBBoxQuery(minLat, maxLat, minLon, maxLon, shapes[id]); Component2D component2D = toRectangle2D(minX, maxX, minY, maxY);
expected = VALIDATOR.setRelation(queryRelation).testComponentQuery(component2D, shapes[id]);
} }
} }
@ -362,7 +348,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
b.append(" shape=" + shapes[id] + "\n"); b.append(" shape=" + shapes[id] + "\n");
} }
b.append(" deleted?=" + (liveDocs != null && liveDocs.get(docID) == false)); b.append(" deleted?=" + (liveDocs != null && liveDocs.get(docID) == false));
b.append(" rect=Rectangle(lat=" + ENCODER.quantizeYCeil(rectMinY(rect)) + " TO " + ENCODER.quantizeY(rectMaxY(rect)) + " lon=" + minLon + " TO " + ENCODER.quantizeX(rectMaxX(rect)) + ")\n"); b.append(" rect=Rectangle(lat=" + ENCODER.quantizeYCeil(rectMinY(rect)) + " TO " + ENCODER.quantizeY(rectMaxY(rect)) + " lon=" + minX + " TO " + ENCODER.quantizeX(rectMaxX(rect)) + ")\n");
if (true) { if (true) {
fail("wrong hit (first of possibly more):\n\n" + b); fail("wrong hit (first of possibly more):\n\n" + b);
} else { } else {
@ -401,26 +387,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
System.out.println(" query=" + query + ", relation=" + queryRelation); System.out.println(" query=" + query + ", relation=" + queryRelation);
} }
final FixedBitSet hits = new FixedBitSet(maxDoc); final FixedBitSet hits = searchIndex(s, query, 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) throws IOException {
hits.set(docBase+doc);
}
});
boolean fail = false; boolean fail = false;
NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id"); NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id");
@ -492,26 +459,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
System.out.println(" query=" + query + ", relation=" + queryRelation); System.out.println(" query=" + query + ", relation=" + queryRelation);
} }
final FixedBitSet hits = new FixedBitSet(maxDoc); final FixedBitSet hits = searchIndex(s, query, 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) throws IOException {
hits.set(docBase+doc);
}
});
boolean fail = false; boolean fail = false;
NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id"); NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id");
@ -589,26 +537,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
System.out.println(" query=" + query + ", relation=" + queryRelation); System.out.println(" query=" + query + ", relation=" + queryRelation);
} }
final FixedBitSet hits = new FixedBitSet(maxDoc); final FixedBitSet hits = searchIndex(s, query, 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) throws IOException {
hits.set(docBase+doc);
}
});
boolean fail = false; boolean fail = false;
NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id"); NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id");
@ -681,26 +610,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
System.out.println(" query=" + query + ", relation=" + queryRelation); System.out.println(" query=" + query + ", relation=" + queryRelation);
} }
final FixedBitSet hits = new FixedBitSet(maxDoc); final FixedBitSet hits = searchIndex(s, query, 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) throws IOException {
hits.set(docBase+doc);
}
});
boolean fail = false; boolean fail = false;
NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id"); NumericDocValues docIDToID = MultiDocValues.getNumericValues(reader, "id");
@ -748,7 +658,30 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
} }
} }
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;
}
protected abstract Validator getValidator(); protected abstract Validator getValidator();
protected static abstract class Encoder { protected static abstract class Encoder {
@ -758,8 +691,6 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
abstract double quantizeXCeil(double raw); abstract double quantizeXCeil(double raw);
abstract double quantizeY(double raw); abstract double quantizeY(double raw);
abstract double quantizeYCeil(double raw); abstract double quantizeYCeil(double raw);
abstract double[] quantizeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca);
abstract ShapeField.DecodedTriangle encodeDecodeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca);
} }
private int scaledIterationCount(int shapes) { private int scaledIterationCount(int shapes) {
@ -783,9 +714,7 @@ public abstract class BaseShapeTestCase extends LuceneTestCase {
} }
protected QueryRelation queryRelation = QueryRelation.INTERSECTS; protected QueryRelation queryRelation = QueryRelation.INTERSECTS;
public abstract boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape);
public abstract boolean testComponentQuery(Component2D line2d, Object shape); public abstract boolean testComponentQuery(Component2D line2d, Object shape);
public Validator setRelation(QueryRelation relation) { public Validator setRelation(QueryRelation relation) {

View File

@ -23,6 +23,7 @@ import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.ShapeTestUtil; import org.apache.lucene.geo.ShapeTestUtil;
import org.apache.lucene.geo.Tessellator;
import org.apache.lucene.geo.XYCircle; import org.apache.lucene.geo.XYCircle;
import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.geo.XYLine; import org.apache.lucene.geo.XYLine;
@ -91,6 +92,11 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
return XYGeometry.create(Arrays.stream(polygons).toArray(XYPolygon[]::new)); return XYGeometry.create(Arrays.stream(polygons).toArray(XYPolygon[]::new));
} }
@Override
protected Component2D toRectangle2D(double minX, double maxX, double minY, double maxY) {
return XYGeometry.create(new XYRectangle((float)minX, (float)maxX, (float)minY, (float)maxY));
}
@Override @Override
protected Component2D toCircle2D(Object circle) { protected Component2D toCircle2D(Object circle) {
return XYGeometry.create((XYCircle) circle); return XYGeometry.create((XYCircle) circle);
@ -126,22 +132,10 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
return false; return false;
} }
/** use {@link ShapeTestUtil#nextPolygon()} to create a random line; TODO: move to GeoTestUtil */ /** use {@link ShapeTestUtil#nextPolygon()} to create a random line */
@Override @Override
public XYLine nextLine() { public XYLine nextLine() {
return getNextLine(); return ShapeTestUtil.nextLine();
}
public static XYLine getNextLine() {
XYPolygon poly = ShapeTestUtil.nextPolygon();
float[] x = new float[poly.numPoints() - 1];
float[] y = new float[x.length];
for (int i = 0; i < x.length; ++i) {
x[i] = poly.getPolyX(i);
y[i] = poly.getPolyY(i);
}
return new XYLine(x, y);
} }
@Override @Override
@ -197,46 +191,32 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
double quantizeYCeil(double raw) { double quantizeYCeil(double raw) {
return decode(encode((float) raw)); return decode(encode((float) raw));
} }
@Override
double[] quantizeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca) {
ShapeField.DecodedTriangle decoded = encodeDecodeTriangle(ax, ay, ab, bx, by, bc, cx, cy, ca);
return new double[]{decode(decoded.aY), decode(decoded.aX), decode(decoded.bY), decode(decoded.bX), decode(decoded.cY), decode(decoded.cX)};
}
@Override
ShapeField.DecodedTriangle encodeDecodeTriangle(double ax, double ay, boolean ab, double bx, double by, boolean bc, double cx, double cy, boolean ca) {
byte[] encoded = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(encoded, encode((float) ay), encode((float) ax), ab, encode((float) by), encode((float) bx), bc, encode((float) cy), encode((float) cx), ca);
ShapeField.DecodedTriangle triangle = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(encoded, triangle);
return triangle;
}
}; };
} }
/** internal shape type for testing different shape types */ /** internal shape type for testing different shape types */
protected enum ShapeType { protected enum ShapeType {
POINT() { POINT() {
public Point nextShape() { public XYPoint nextShape() {
return new Point((float)random().nextDouble(), (float)random().nextDouble()); return ShapeTestUtil.nextPoint();
} }
}, },
LINE() { LINE() {
public XYLine nextShape() { public XYLine nextShape() {
XYPolygon p = ShapeTestUtil.nextPolygon(); return ShapeTestUtil.nextLine();
float[] x = new float[p.numPoints() - 1];
float[] y = new float[x.length];
for (int i = 0; i < x.length; ++i) {
x[i] = p.getPolyX(i);
y[i] = p.getPolyY(i);
}
return new XYLine(x, y);
} }
}, },
POLYGON() { POLYGON() {
public XYPolygon nextShape() { public XYPolygon nextShape() {
return ShapeTestUtil.nextPolygon(); while (true) {
XYPolygon p = ShapeTestUtil.nextPolygon();
try {
Tessellator.tessellate(p);
return p;
} catch (IllegalArgumentException e) {
// if we can't tessellate; then random polygon generator created a malformed shape
}
}
} }
}, },
MIXED() { MIXED() {
@ -251,37 +231,5 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
} }
public abstract Object nextShape(); public abstract Object nextShape();
static ShapeType fromObject(Object shape) {
if (shape instanceof Point) {
return POINT;
} else if (shape instanceof XYLine) {
return LINE;
} else if (shape instanceof XYPolygon) {
return POLYGON;
}
throw new IllegalArgumentException("invalid shape type from " + shape.toString());
}
}
/** internal point class for testing point shapes */
protected static class Point {
float x;
float y;
public Point(float x, float y) {
this.x = x;
this.y = y;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("POINT(");
sb.append(x);
sb.append(',');
sb.append(y);
sb.append(')');
return sb.toString();
}
} }
} }

View File

@ -21,9 +21,7 @@ import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.GeoTestUtil; import org.apache.lucene.geo.GeoTestUtil;
import org.apache.lucene.geo.LatLonGeometry;
import org.apache.lucene.geo.Line; import org.apache.lucene.geo.Line;
import org.apache.lucene.geo.Rectangle;
/** random bounding box, line, and polygon query tests for random generated {@link Line} types */ /** random bounding box, line, and polygon query tests for random generated {@link Line} types */
@SuppressWarnings("SimpleText") @SuppressWarnings("SimpleText")
@ -74,13 +72,7 @@ public class TestLatLonLineShapeQueries extends BaseLatLonShapeTestCase {
protected LineValidator(Encoder encoder) { protected LineValidator(Encoder encoder) {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Component2D rectangle2D = LatLonGeometry.create(new Rectangle(minLat, maxLat, minLon, maxLon));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Line line = (Line) shape; Line line = (Line) shape;

View File

@ -73,24 +73,6 @@ public class TestLatLonMultiLineShapeQueries extends BaseLatLonShapeTestCase {
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Line[] lines = (Line[])shape;
for (Line l : lines) {
boolean b = LINEVALIDATOR.testBBoxQuery(minLat, maxLat, minLon, maxLon, l);
if (b == true && queryRelation == QueryRelation.INTERSECTS) {
return true;
} else if (b == true && queryRelation == QueryRelation.CONTAINS) {
return true;
} else if (b == false && queryRelation == QueryRelation.DISJOINT) {
return false;
} else if (b == false && queryRelation == QueryRelation.WITHIN) {
return false;
}
}
return queryRelation != QueryRelation.INTERSECTS && queryRelation != QueryRelation.CONTAINS;
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Line[] lines = (Line[])shape; Line[] lines = (Line[])shape;

View File

@ -21,6 +21,7 @@ import java.util.List;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.Point;
/** random bounding box, line, and polygon query tests for random indexed arrays of {@code latitude, longitude} points */ /** random bounding box, line, and polygon query tests for random indexed arrays of {@code latitude, longitude} points */
public class TestLatLonMultiPointShapeQueries extends BaseLatLonShapeTestCase { public class TestLatLonMultiPointShapeQueries extends BaseLatLonShapeTestCase {
@ -35,7 +36,7 @@ public class TestLatLonMultiPointShapeQueries extends BaseLatLonShapeTestCase {
int n = random().nextInt(4) + 1; int n = random().nextInt(4) + 1;
Point[] points = new Point[n]; Point[] points = new Point[n];
for (int i =0; i < n; i++) { for (int i =0; i < n; i++) {
points[i] = (Point)ShapeType.POINT.nextShape(); points[i] = (Point) ShapeType.POINT.nextShape();
} }
return points; return points;
} }
@ -45,7 +46,7 @@ public class TestLatLonMultiPointShapeQueries extends BaseLatLonShapeTestCase {
Point[] points = (Point[]) o; Point[] points = (Point[]) o;
List<Field> allFields = new ArrayList<>(); List<Field> allFields = new ArrayList<>();
for (Point point : points) { for (Point point : points) {
Field[] fields = LatLonShape.createIndexableFields(name, point.lat, point.lon); Field[] fields = LatLonShape.createIndexableFields(name, point.getLat(), point.getLon());
for (Field field : fields) { for (Field field : fields) {
allFields.add(field); allFields.add(field);
} }
@ -71,25 +72,7 @@ public class TestLatLonMultiPointShapeQueries extends BaseLatLonShapeTestCase {
POINTVALIDATOR.queryRelation = relation; POINTVALIDATOR.queryRelation = relation;
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Point[] points = (Point[]) shape;
for (Point p : points) {
boolean b = POINTVALIDATOR.testBBoxQuery(minLat, maxLat, minLon, maxLon, p);
if (b == true && queryRelation == QueryRelation.INTERSECTS) {
return true;
} else if (b == true && queryRelation == QueryRelation.CONTAINS) {
return true;
} else if (b == false && queryRelation == QueryRelation.DISJOINT) {
return false;
} else if (b == false && queryRelation == QueryRelation.WITHIN) {
return false;
}
}
return queryRelation != QueryRelation.INTERSECTS && queryRelation != QueryRelation.CONTAINS;
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Point[] points = (Point[]) shape; Point[] points = (Point[]) shape;

View File

@ -22,7 +22,6 @@ import java.util.List;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.Polygon; import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Tessellator;
/** random bounding box, line, and polygon query tests for random indexed arrays of {@link Polygon} types */ /** random bounding box, line, and polygon query tests for random indexed arrays of {@link Polygon} types */
public class TestLatLonMultiPolygonShapeQueries extends BaseLatLonShapeTestCase { public class TestLatLonMultiPolygonShapeQueries extends BaseLatLonShapeTestCase {
@ -37,47 +36,11 @@ public class TestLatLonMultiPolygonShapeQueries extends BaseLatLonShapeTestCase
int n = random().nextInt(4) + 1; int n = random().nextInt(4) + 1;
Polygon[] polygons = new Polygon[n]; Polygon[] polygons = new Polygon[n];
for (int i =0; i < n; i++) { for (int i =0; i < n; i++) {
int repetitions =0; polygons[i] = (Polygon) getShapeType().nextShape();
while (true) {
// if we can't tessellate; then random polygon generator created a malformed shape
Polygon p = (Polygon) getShapeType().nextShape();
try {
Tessellator.tessellate(p);
//polygons are disjoint so CONTAINS works. Note that if we intersect
//any shape then contains return false.
if (isDisjoint(polygons, p)) {
polygons[i] = p;
break;
}
repetitions++;
if (repetitions > 50) {
//try again
return nextShape();
}
} catch (IllegalArgumentException e) {
continue;
}
}
} }
return polygons; return polygons;
} }
private boolean isDisjoint(Polygon[] polygons, Polygon check) {
// we use bounding boxes so we do not get intersecting polygons.
for (Polygon polygon : polygons) {
if (polygon != null) {
if (getEncoder().quantizeY(polygon.minLat) > getEncoder().quantizeY(check.maxLat)
|| getEncoder().quantizeY(polygon.maxLat) < getEncoder().quantizeY(check.minLat)
|| getEncoder().quantizeX(polygon.minLon) > getEncoder().quantizeX(check.maxLon)
|| getEncoder().quantizeX(polygon.maxLon) < getEncoder().quantizeX(check.minLon)) {
continue;
}
return false;
}
}
return true;
}
@Override @Override
protected Field[] createIndexableFields(String name, Object o) { protected Field[] createIndexableFields(String name, Object o) {
Polygon[] polygons = (Polygon[]) o; Polygon[] polygons = (Polygon[]) o;
@ -111,24 +74,6 @@ public class TestLatLonMultiPolygonShapeQueries extends BaseLatLonShapeTestCase
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Polygon[] polygons = (Polygon[]) shape;
for (Polygon p : polygons) {
boolean b = POLYGONVALIDATOR.testBBoxQuery(minLat, maxLat, minLon, maxLon, p);
if (b == true && queryRelation == QueryRelation.INTERSECTS) {
return true;
} else if (b == true && queryRelation == QueryRelation.CONTAINS) {
return true;
} else if (b == false && queryRelation == QueryRelation.DISJOINT) {
return false;
} else if (b == false && queryRelation == QueryRelation.WITHIN) {
return false;
}
}
return queryRelation != QueryRelation.INTERSECTS && queryRelation != QueryRelation.CONTAINS;
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Polygon[] polygons = (Polygon[]) shape; Polygon[] polygons = (Polygon[]) shape;

View File

@ -20,9 +20,8 @@ import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.GeoTestUtil; import org.apache.lucene.geo.GeoTestUtil;
import org.apache.lucene.geo.LatLonGeometry;
import org.apache.lucene.geo.Line; import org.apache.lucene.geo.Line;
import org.apache.lucene.geo.Rectangle; import org.apache.lucene.geo.Point;
/** random bounding box, line, and polygon query tests for random generated {@code latitude, longitude} points */ /** random bounding box, line, and polygon query tests for random generated {@code latitude, longitude} points */
public class TestLatLonPointShapeQueries extends BaseLatLonShapeTestCase { public class TestLatLonPointShapeQueries extends BaseLatLonShapeTestCase {
@ -45,8 +44,8 @@ public class TestLatLonPointShapeQueries extends BaseLatLonShapeTestCase {
for (int i = 0, j = 0; j < lats.length && i < shapes.length; ++i, ++j) { for (int i = 0, j = 0; j < lats.length && i < shapes.length; ++i, ++j) {
Point p = (Point) (shapes[i]); Point p = (Point) (shapes[i]);
if (random().nextBoolean() && p != null) { if (random().nextBoolean() && p != null) {
lats[j] = p.lat; lats[j] = p.getLat();
lons[j] = p.lon; lons[j] = p.getLon();
} else { } else {
lats[j] = GeoTestUtil.nextLatitude(); lats[j] = GeoTestUtil.nextLatitude();
lons[j] = GeoTestUtil.nextLongitude(); lons[j] = GeoTestUtil.nextLongitude();
@ -60,7 +59,7 @@ public class TestLatLonPointShapeQueries extends BaseLatLonShapeTestCase {
@Override @Override
protected Field[] createIndexableFields(String field, Object point) { protected Field[] createIndexableFields(String field, Object point) {
Point p = (Point)point; Point p = (Point)point;
return LatLonShape.createIndexableFields(field, p.lat, p.lon); return LatLonShape.createIndexableFields(field, p.getLat(), p.getLon());
} }
@Override @Override
@ -72,20 +71,14 @@ public class TestLatLonPointShapeQueries extends BaseLatLonShapeTestCase {
protected PointValidator(Encoder encoder) { protected PointValidator(Encoder encoder) {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Component2D rectangle2D = LatLonGeometry.create(new Rectangle(minLat, maxLat, minLon, maxLon));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Point p = (Point) shape; Point p = (Point) shape;
if (queryRelation == QueryRelation.CONTAINS) { if (queryRelation == QueryRelation.CONTAINS) {
return testWithinQuery(query, LatLonShape.createIndexableFields("dummy", p.lat, p.lon)) == Component2D.WithinRelation.CANDIDATE; return testWithinQuery(query, LatLonShape.createIndexableFields("dummy", p.getLat(), p.getLon())) == Component2D.WithinRelation.CANDIDATE;
} }
return testComponentQuery(query, LatLonShape.createIndexableFields("dummy", p.lat, p.lon)); return testComponentQuery(query, LatLonShape.createIndexableFields("dummy", p.getLat(), p.getLon()));
} }
} }
} }

View File

@ -18,10 +18,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.LatLonGeometry;
import org.apache.lucene.geo.Polygon; import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.geo.Tessellator;
/** random bounding box, line, and polygon query tests for random indexed {@link Polygon} types */ /** random bounding box, line, and polygon query tests for random indexed {@link Polygon} types */
public class TestLatLonPolygonShapeQueries extends BaseLatLonShapeTestCase { public class TestLatLonPolygonShapeQueries extends BaseLatLonShapeTestCase {
@ -31,21 +28,6 @@ public class TestLatLonPolygonShapeQueries extends BaseLatLonShapeTestCase {
return ShapeType.POLYGON; return ShapeType.POLYGON;
} }
@Override
protected Polygon nextShape() {
Polygon p;
while (true) {
// if we can't tessellate; then random polygon generator created a malformed shape
p = (Polygon)getShapeType().nextShape();
try {
Tessellator.tessellate(p);
return p;
} catch (IllegalArgumentException e) {
continue;
}
}
}
@Override @Override
protected Field[] createIndexableFields(String field, Object polygon) { protected Field[] createIndexableFields(String field, Object polygon) {
return LatLonShape.createIndexableFields(field, (Polygon)polygon); return LatLonShape.createIndexableFields(field, (Polygon)polygon);
@ -61,12 +43,6 @@ public class TestLatLonPolygonShapeQueries extends BaseLatLonShapeTestCase {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minLat, double maxLat, double minLon, double maxLon, Object shape) {
Component2D rectangle2D = LatLonGeometry.create(new Rectangle(minLat, maxLat, minLon, maxLon));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object o) { public boolean testComponentQuery(Component2D query, Object o) {
Polygon polygon = (Polygon) o; Polygon polygon = (Polygon) o;

View File

@ -424,8 +424,8 @@ public class TestLatLonShape extends LuceneTestCase {
Directory dir = newDirectory(); Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir); RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
Document document = new Document(); Document document = new Document();
BaseLatLonShapeTestCase.Point p = (BaseLatLonShapeTestCase.Point) BaseLatLonShapeTestCase.ShapeType.POINT.nextShape(); Point p = GeoTestUtil.nextPoint();
Field[] fields = LatLonShape.createIndexableFields(FIELDNAME, p.lat, p.lon); Field[] fields = LatLonShape.createIndexableFields(FIELDNAME, p.getLat(), p.getLon());
for (Field f : fields) { for (Field f : fields) {
document.add(f); document.add(f);
} }
@ -437,7 +437,7 @@ public class TestLatLonShape extends LuceneTestCase {
IndexSearcher s = newSearcher(r); IndexSearcher s = newSearcher(r);
// search by same point // search by same point
Query q = LatLonShape.newPointQuery(FIELDNAME, QueryRelation.INTERSECTS, new double[] {p.lat, p.lon}); Query q = LatLonShape.newPointQuery(FIELDNAME, QueryRelation.INTERSECTS, new double[] {p.getLat(), p.getLon()});
assertEquals(1, s.count(q)); assertEquals(1, s.count(q));
IOUtils.close(r, dir); IOUtils.close(r, dir);
} }
@ -767,8 +767,8 @@ public class TestLatLonShape extends LuceneTestCase {
Directory dir = newDirectory(); Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir); RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
Document document = new Document(); Document document = new Document();
BaseLatLonShapeTestCase.Point p = (BaseLatLonShapeTestCase.Point) BaseLatLonShapeTestCase.ShapeType.POINT.nextShape(); Point p = GeoTestUtil.nextPoint();
Field[] fields = LatLonShape.createIndexableFields(FIELDNAME, p.lat,p.lon); Field[] fields = LatLonShape.createIndexableFields(FIELDNAME, p.getLat(), p.getLon());
for (Field f : fields) { for (Field f : fields) {
document.add(f); document.add(f);
} }
@ -786,7 +786,7 @@ public class TestLatLonShape extends LuceneTestCase {
Component2D circle2D = LatLonGeometry.create(circle); Component2D circle2D = LatLonGeometry.create(circle);
int expected; int expected;
int expectedDisjoint; int expectedDisjoint;
if (circle2D.contains(p.lon, p.lat)) { if (circle2D.contains(p.getLon(), p.getLat())) {
expected = 1; expected = 1;
expectedDisjoint = 0; expectedDisjoint = 0;
} else { } else {

View File

@ -23,9 +23,7 @@ import java.util.Random;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.ShapeTestUtil; import org.apache.lucene.geo.ShapeTestUtil;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.geo.XYLine; import org.apache.lucene.geo.XYLine;
import org.apache.lucene.geo.XYRectangle;
/** random cartesian bounding box, line, and polygon query tests for random generated cartesian {@link XYLine} types */ /** random cartesian bounding box, line, and polygon query tests for random generated cartesian {@link XYLine} types */
public class TestXYLineShapeQueries extends BaseXYShapeTestCase { public class TestXYLineShapeQueries extends BaseXYShapeTestCase {
@ -76,13 +74,7 @@ public class TestXYLineShapeQueries extends BaseXYShapeTestCase {
protected LineValidator(Encoder encoder) { protected LineValidator(Encoder encoder) {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
XYLine line = (XYLine) shape; XYLine line = (XYLine) shape;

View File

@ -21,9 +21,7 @@ import java.util.List;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.geo.XYLine; import org.apache.lucene.geo.XYLine;
import org.apache.lucene.geo.XYRectangle;
/** random cartesian bounding box, line, and polygon query tests for random indexed arrays of cartesian {@link XYLine} types */ /** random cartesian bounding box, line, and polygon query tests for random indexed arrays of cartesian {@link XYLine} types */
public class TestXYMultiLineShapeQueries extends BaseXYShapeTestCase { public class TestXYMultiLineShapeQueries extends BaseXYShapeTestCase {
@ -74,12 +72,6 @@ public class TestXYMultiLineShapeQueries extends BaseXYShapeTestCase {
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
XYLine[] lines = (XYLine[])shape; XYLine[] lines = (XYLine[])shape;

View File

@ -21,8 +21,8 @@ import java.util.List;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.XYGeometry; import org.apache.lucene.geo.ShapeTestUtil;
import org.apache.lucene.geo.XYRectangle; import org.apache.lucene.geo.XYPoint;
/** random cartesian bounding box, line, and polygon query tests for random indexed arrays of {@code x, y} points */ /** random cartesian bounding box, line, and polygon query tests for random indexed arrays of {@code x, y} points */
public class TestXYMultiPointShapeQueries extends BaseXYShapeTestCase { public class TestXYMultiPointShapeQueries extends BaseXYShapeTestCase {
@ -32,21 +32,21 @@ public class TestXYMultiPointShapeQueries extends BaseXYShapeTestCase {
} }
@Override @Override
protected Point[] nextShape() { protected XYPoint[] nextShape() {
int n = random().nextInt(4) + 1; int n = random().nextInt(4) + 1;
Point[] points = new Point[n]; XYPoint[] points = new XYPoint[n];
for (int i =0; i < n; i++) { for (int i =0; i < n; i++) {
points[i] = (Point)ShapeType.POINT.nextShape(); points[i] = ShapeTestUtil.nextPoint();
} }
return points; return points;
} }
@Override @Override
protected Field[] createIndexableFields(String name, Object o) { protected Field[] createIndexableFields(String name, Object o) {
Point[] points = (Point[]) o; XYPoint[] points = (XYPoint[]) o;
List<Field> allFields = new ArrayList<>(); List<Field> allFields = new ArrayList<>();
for (Point point : points) { for (XYPoint point : points) {
Field[] fields = XYShape.createIndexableFields(name, point.x, point.y); Field[] fields = XYShape.createIndexableFields(name, point.getX(), point.getY());
for (Field field : fields) { for (Field field : fields) {
allFields.add(field); allFields.add(field);
} }
@ -73,16 +73,10 @@ public class TestXYMultiPointShapeQueries extends BaseXYShapeTestCase {
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Point[] points = (Point[]) shape; XYPoint[] points = (XYPoint[]) shape;
for (Point p : points) { for (XYPoint p : points) {
boolean b = POINTVALIDATOR.testComponentQuery(query, p); boolean b = POINTVALIDATOR.testComponentQuery(query, p);
if (b == true && queryRelation == QueryRelation.INTERSECTS) { if (b == true && queryRelation == QueryRelation.INTERSECTS) {
return true; return true;

View File

@ -21,10 +21,7 @@ import java.util.List;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.Tessellator;
import org.apache.lucene.geo.XYPolygon; import org.apache.lucene.geo.XYPolygon;
import org.apache.lucene.geo.XYRectangle;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase;
/** random cartesian bounding box, line, and polygon query tests for random indexed arrays of cartesian {@link XYPolygon} types */ /** random cartesian bounding box, line, and polygon query tests for random indexed arrays of cartesian {@link XYPolygon} types */
@ -40,47 +37,11 @@ public class TestXYMultiPolygonShapeQueries extends BaseXYShapeTestCase {
int n = random().nextInt(4) + 1; int n = random().nextInt(4) + 1;
XYPolygon[] polygons = new XYPolygon[n]; XYPolygon[] polygons = new XYPolygon[n];
for (int i =0; i < n; i++) { for (int i =0; i < n; i++) {
int repetitions =0; polygons[i] = (XYPolygon) getShapeType().nextShape();
while (true) {
// if we can't tessellate; then random polygon generator created a malformed shape
XYPolygon p = (XYPolygon) getShapeType().nextShape();
try {
Tessellator.tessellate(p);
//polygons are disjoint so CONTAINS works. Note that if we intersect
//any shape then contains return false.
if (isDisjoint(polygons, p, i)) {
polygons[i] = p;
break;
}
repetitions++;
if (repetitions > 2) {
//try again
return nextShape();
}
} catch (IllegalArgumentException e) {
continue;
}
}
} }
return polygons; return polygons;
} }
private boolean isDisjoint(XYPolygon[] polygons, XYPolygon check, int totalPolygons) {
// we use bounding boxes so we do not get polygons with shared points.
for (XYPolygon polygon : polygons) {
if (polygon != null) {
if (getEncoder().quantizeY(polygon.minY) > getEncoder().quantizeY(check.maxY)
|| getEncoder().quantizeY(polygon.maxY) < getEncoder().quantizeY(check.minY)
|| getEncoder().quantizeX(polygon.minX) > getEncoder().quantizeX(check.maxX)
|| getEncoder().quantizeX(polygon.maxX) < getEncoder().quantizeX(check.minX)) {
continue;
}
return false;
}
}
return true;
}
@Override @Override
protected Field[] createIndexableFields(String name, Object o) { protected Field[] createIndexableFields(String name, Object o) {
XYPolygon[] polygons = (XYPolygon[]) o; XYPolygon[] polygons = (XYPolygon[]) o;
@ -114,12 +75,6 @@ public class TestXYMultiPolygonShapeQueries extends BaseXYShapeTestCase {
return this; return this;
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
XYPolygon[] polygons = (XYPolygon[]) shape; XYPolygon[] polygons = (XYPolygon[]) shape;

View File

@ -23,9 +23,8 @@ import java.util.Random;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.ShapeTestUtil; import org.apache.lucene.geo.ShapeTestUtil;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.geo.XYLine; import org.apache.lucene.geo.XYLine;
import org.apache.lucene.geo.XYRectangle; import org.apache.lucene.geo.XYPoint;
/** random cartesian bounding box, line, and polygon query tests for random generated {@code x, y} points */ /** random cartesian bounding box, line, and polygon query tests for random generated {@code x, y} points */
public class TestXYPointShapeQueries extends BaseXYShapeTestCase { public class TestXYPointShapeQueries extends BaseXYShapeTestCase {
@ -47,10 +46,10 @@ public class TestXYPointShapeQueries extends BaseXYShapeTestCase {
float[] x = new float[RandomNumbers.randomIntBetween(random, 2, maxBound)]; float[] x = new float[RandomNumbers.randomIntBetween(random, 2, maxBound)];
float[] y = new float[x.length]; float[] y = new float[x.length];
for (int i = 0, j = 0; j < x.length && i < shapes.length; ++i, ++j) { for (int i = 0, j = 0; j < x.length && i < shapes.length; ++i, ++j) {
Point p = (Point) (shapes[i]); XYPoint p = (XYPoint) (shapes[i]);
if (random.nextBoolean() && p != null) { if (random.nextBoolean() && p != null) {
x[j] = p.x; x[j] = p.getX();
y[j] = p.y; y[j] = p.getY();
} else { } else {
x[j] = ShapeTestUtil.nextFloat(random); x[j] = ShapeTestUtil.nextFloat(random);
y[j] = ShapeTestUtil.nextFloat(random); y[j] = ShapeTestUtil.nextFloat(random);
@ -63,8 +62,8 @@ public class TestXYPointShapeQueries extends BaseXYShapeTestCase {
@Override @Override
protected Field[] createIndexableFields(String field, Object point) { protected Field[] createIndexableFields(String field, Object point) {
Point p = (Point)point; XYPoint p = (XYPoint)point;
return XYShape.createIndexableFields(field, p.x, p.y); return XYShape.createIndexableFields(field, p.getX(), p.getY());
} }
@Override @Override
@ -76,20 +75,14 @@ public class TestXYPointShapeQueries extends BaseXYShapeTestCase {
protected PointValidator(Encoder encoder) { protected PointValidator(Encoder encoder) {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object shape) { public boolean testComponentQuery(Component2D query, Object shape) {
Point point = (Point) shape; XYPoint point = (XYPoint) shape;
if (queryRelation == QueryRelation.CONTAINS) { if (queryRelation == QueryRelation.CONTAINS) {
return testWithinQuery(query, XYShape.createIndexableFields("dummy", point.x, point.y)) == Component2D.WithinRelation.CANDIDATE; return testWithinQuery(query, XYShape.createIndexableFields("dummy", point.getX(), point.getY())) == Component2D.WithinRelation.CANDIDATE;
} }
return testComponentQuery(query, XYShape.createIndexableFields("dummy", point.x, point.y)); return testComponentQuery(query, XYShape.createIndexableFields("dummy", point.getX(), point.getY()));
} }
} }
} }

View File

@ -18,10 +18,7 @@ package org.apache.lucene.document;
import org.apache.lucene.document.ShapeField.QueryRelation; import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D; import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.Tessellator;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.geo.XYPolygon; import org.apache.lucene.geo.XYPolygon;
import org.apache.lucene.geo.XYRectangle;
/** random cartesian bounding box, line, and polygon query tests for random indexed {@link XYPolygon} types */ /** random cartesian bounding box, line, and polygon query tests for random indexed {@link XYPolygon} types */
public class TestXYPolygonShapeQueries extends BaseXYShapeTestCase { public class TestXYPolygonShapeQueries extends BaseXYShapeTestCase {
@ -31,21 +28,6 @@ public class TestXYPolygonShapeQueries extends BaseXYShapeTestCase {
return ShapeType.POLYGON; return ShapeType.POLYGON;
} }
@Override
protected XYPolygon nextShape() {
XYPolygon p;
while (true) {
// if we can't tessellate; then random polygon generator created a malformed shape
p = (XYPolygon)getShapeType().nextShape();
try {
Tessellator.tessellate(p);
return p;
} catch (IllegalArgumentException e) {
continue;
}
}
}
@Override @Override
protected Field[] createIndexableFields(String field, Object polygon) { protected Field[] createIndexableFields(String field, Object polygon) {
return XYShape.createIndexableFields(field, (XYPolygon)polygon); return XYShape.createIndexableFields(field, (XYPolygon)polygon);
@ -60,13 +42,7 @@ public class TestXYPolygonShapeQueries extends BaseXYShapeTestCase {
protected PolygonValidator(Encoder encoder) { protected PolygonValidator(Encoder encoder) {
super(encoder); super(encoder);
} }
@Override
public boolean testBBoxQuery(double minY, double maxY, double minX, double maxX, Object shape) {
Component2D rectangle2D = XYGeometry.create(new XYRectangle((float) minX, (float) maxX, (float) minY, (float) maxY));
return testComponentQuery(rectangle2D, shape);
}
@Override @Override
public boolean testComponentQuery(Component2D query, Object o) { public boolean testComponentQuery(Component2D query, Object o) {
XYPolygon polygon = (XYPolygon) o; XYPolygon polygon = (XYPolygon) o;

View File

@ -17,7 +17,6 @@
package org.apache.lucene.geo; package org.apache.lucene.geo;
import org.apache.lucene.document.TestLatLonLineShapeQueries;
import org.apache.lucene.index.PointValues.Relation; import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase;
@ -72,7 +71,7 @@ public class TestLine2D extends LuceneTestCase {
} }
public void testRandomTriangles() { public void testRandomTriangles() {
Line line = TestLatLonLineShapeQueries.getNextLine(); Line line = GeoTestUtil.nextLine();
Component2D line2D = Line2D.create(line); Component2D line2D = Line2D.create(line);
for (int i =0; i < 100; i++) { for (int i =0; i < 100; i++) {

View File

@ -391,6 +391,23 @@ public class GeoTestUtil {
return new Polygon(result[0], result[1]); return new Polygon(result[0], result[1]);
} }
public static Point nextPoint() {
double lat = nextLatitude();
double lon = nextLongitude();
return new Point(lat, lon);
}
public static Line nextLine() {
Polygon p = nextPolygon();
double[] lats = new double[p.numPoints() - 1];
double[] lons = new double[lats.length];
for (int i = 0; i < lats.length; ++i) {
lats[i] = p.getPolyLat(i);
lons[i] = p.getPolyLon(i);
}
return new Line(lats, lons);
}
public static Circle nextCircle() { public static Circle nextCircle() {
double lat = nextLatitude(); double lat = nextLatitude();
double lon = nextLongitude(); double lon = nextLongitude();

View File

@ -56,6 +56,13 @@ public class ShapeTestUtil {
} }
} }
public static XYPoint nextPoint() {
Random random = random();
float x = nextFloat(random);
float y = nextFloat(random);
return new XYPoint(x, y);
}
public static XYLine nextLine() { public static XYLine nextLine() {
XYPolygon poly = ShapeTestUtil.nextPolygon(); XYPolygon poly = ShapeTestUtil.nextPolygon();
float[] x = new float[poly.numPoints() - 1]; float[] x = new float[poly.numPoints() - 1];