You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2016/04/03 20:09:07 UTC
lucene-solr:branch_6x: LUCENE-7159: improve testing of polygon tree
methods
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6x 741a1e4ee -> bb2e01c3d
LUCENE-7159: improve testing of polygon tree methods
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/bb2e01c3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/bb2e01c3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/bb2e01c3
Branch: refs/heads/branch_6x
Commit: bb2e01c3d913894062fff3f18bd5d0256f884185
Parents: 741a1e4
Author: Robert Muir <rm...@apache.org>
Authored: Sun Apr 3 14:07:56 2016 -0400
Committer: Robert Muir <rm...@apache.org>
Committed: Sun Apr 3 14:08:56 2016 -0400
----------------------------------------------------------------------
.../test/org/apache/lucene/geo/TestPolygon.java | 108 +++++++++++++++++++
.../java/org/apache/lucene/geo/GeoTestUtil.java | 13 +++
2 files changed, 121 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bb2e01c3/lucene/core/src/test/org/apache/lucene/geo/TestPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestPolygon.java b/lucene/core/src/test/org/apache/lucene/geo/TestPolygon.java
index efd6d58..0202562 100644
--- a/lucene/core/src/test/org/apache/lucene/geo/TestPolygon.java
+++ b/lucene/core/src/test/org/apache/lucene/geo/TestPolygon.java
@@ -145,4 +145,112 @@ public class TestPolygon extends LuceneTestCase {
}
}
}
+
+ /** If polygon.contains(box) returns true, then any point in that box should return true as well */
+ public void testContainsRandom() throws Exception {
+ for (int i = 0; i < 1000; i++) {
+ Polygon polygon = nextPolygon();
+
+ for (int j = 0; j < 100; j++) {
+ Rectangle rectangle = GeoTestUtil.nextSimpleBox();
+ // allowed to conservatively return false
+ if (polygon.contains(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon)) {
+ for (int k = 0; k < 1000; k++) {
+ // this tests in our range but sometimes outside! so we have to double-check its really in other box
+ double latitude = nextLatitudeAround(rectangle.minLat, rectangle.maxLat);
+ double longitude = nextLongitudeAround(rectangle.minLon, rectangle.maxLon);
+ // check for sure its in our box
+ if (latitude >= rectangle.minLat && latitude <= rectangle.maxLat && longitude >= rectangle.minLon && longitude <= rectangle.maxLon) {
+ assertTrue(polygon.contains(latitude, longitude));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /** If polygon.contains(box) returns true, then any point in that box should return true as well */
+ // different from testContainsRandom in that its not a purely random test. we iterate the vertices of the polygon
+ // and generate boxes near each one of those to try to be more efficient.
+ public void testContainsEdgeCases() throws Exception {
+ for (int i = 0; i < 1000; i++) {
+ Polygon polygon = nextPolygon();
+
+ double polyLats[] = polygon.getPolyLats();
+ double polyLons[] = polygon.getPolyLons();
+
+ for (int vertex = 0; vertex < polyLats.length; vertex++) {
+ for (int j = 0; j < 10; j++) {
+ Rectangle rectangle = GeoTestUtil.nextSimpleBoxNear(polyLats[vertex], polyLons[vertex]);
+ // allowed to conservatively return false
+ if (polygon.contains(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon)) {
+ for (int k = 0; k < 100; k++) {
+ // this tests in our range but sometimes outside! so we have to double-check its really in other box
+ double latitude = nextLatitudeAround(rectangle.minLat, rectangle.maxLat);
+ double longitude = nextLongitudeAround(rectangle.minLon, rectangle.maxLon);
+ // check for sure its in our box
+ if (latitude >= rectangle.minLat && latitude <= rectangle.maxLat && longitude >= rectangle.minLon && longitude <= rectangle.maxLon) {
+ assertTrue(polygon.contains(latitude, longitude));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /** If polygon.intersects(box) returns false, then any point in that box should return false as well */
+ public void testIntersectRandom() {
+ for (int i = 0; i < 100; i++) {
+ Polygon polygon = nextPolygon();
+
+ for (int j = 0; j < 100; j++) {
+ Rectangle rectangle = GeoTestUtil.nextSimpleBox();
+ // allowed to conservatively return true.
+ if (polygon.contains(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon) == false &&
+ polygon.crosses(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon) == false) {
+ for (int k = 0; k < 1000; k++) {
+ // this tests in our range but sometimes outside! so we have to double-check its really in other box
+ double latitude = nextLatitudeAround(rectangle.minLat, rectangle.maxLat);
+ double longitude = nextLongitudeAround(rectangle.minLon, rectangle.maxLon);
+ // check for sure its in our box
+ if (latitude >= rectangle.minLat && latitude <= rectangle.maxLat && longitude >= rectangle.minLon && longitude <= rectangle.maxLon) {
+ assertFalse(polygon.contains(latitude, longitude));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /** If polygon.intersects(box) returns false, then any point in that box should return false as well */
+ // different from testIntersectsRandom in that its not a purely random test. we iterate the vertices of the polygon
+ // and generate boxes near each one of those to try to be more efficient.
+ public void testIntersectEdgeCases() {
+ for (int i = 0; i < 100; i++) {
+ Polygon polygon = nextPolygon();
+
+ double polyLats[] = polygon.getPolyLats();
+ double polyLons[] = polygon.getPolyLons();
+
+ for (int vertex = 0; vertex < polyLats.length; vertex++) {
+ for (int j = 0; j < 10; j++) {
+ Rectangle rectangle = GeoTestUtil.nextSimpleBoxNear(polyLats[vertex], polyLons[vertex]);
+ // allowed to conservatively return true.
+ if (polygon.contains(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon) == false &&
+ polygon.crosses(rectangle.minLat, rectangle.maxLat, rectangle.minLon, rectangle.maxLon) == false) {
+ for (int k = 0; k < 100; k++) {
+ // this tests in our range but sometimes outside! so we have to double-check its really in other box
+ double latitude = nextLatitudeAround(rectangle.minLat, rectangle.maxLat);
+ double longitude = nextLongitudeAround(rectangle.minLon, rectangle.maxLon);
+ // check for sure its in our box
+ if (latitude >= rectangle.minLat && latitude <= rectangle.maxLat && longitude >= rectangle.minLon && longitude <= rectangle.maxLon) {
+ assertFalse(polygon.contains(latitude, longitude));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bb2e01c3/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java
index bcb473e..0d241f6 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java
@@ -75,6 +75,11 @@ public class GeoTestUtil {
public static Rectangle nextBox() {
return nextBoxInternal(nextLatitude(), nextLatitude(), nextLongitude(), nextLongitude(), true);
}
+
+ /** returns next pseudorandom box: will not cross the 180th meridian */
+ public static Rectangle nextSimpleBox() {
+ return nextBoxInternal(nextLatitude(), nextLatitude(), nextLongitude(), nextLongitude(), false);
+ }
/** returns next pseudorandom box, can cross the 180th meridian, kinda close to {@code otherLatitude} and {@code otherLongitude} */
public static Rectangle nextBoxNear(double otherLatitude, double otherLongitude) {
@@ -83,6 +88,14 @@ public class GeoTestUtil {
return nextBoxInternal(nextLatitudeNear(otherLatitude), nextLatitudeNear(otherLatitude),
nextLongitudeNear(otherLongitude), nextLongitudeNear(otherLongitude), true);
}
+
+ /** returns next pseudorandom box, will not cross the 180th meridian, kinda close to {@code otherLatitude} and {@code otherLongitude} */
+ public static Rectangle nextSimpleBoxNear(double otherLatitude, double otherLongitude) {
+ GeoUtils.checkLongitude(otherLongitude);
+ GeoUtils.checkLongitude(otherLongitude);
+ return nextBoxInternal(nextLatitudeNear(otherLatitude), nextLatitudeNear(otherLatitude),
+ nextLongitudeNear(otherLongitude), nextLongitudeNear(otherLongitude), false);
+ }
/** returns next pseudorandom polygon */
public static Polygon nextPolygon() {