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:08:34 UTC
lucene-solr:master: LUCENE-7159: improve testing of polygon tree
methods
Repository: lucene-solr
Updated Branches:
refs/heads/master d30ebffc9 -> ef6a0d001
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/ef6a0d00
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ef6a0d00
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ef6a0d00
Branch: refs/heads/master
Commit: ef6a0d001361068a37dc2256cd33c11d771c653a
Parents: d30ebff
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:07: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/ef6a0d00/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/ef6a0d00/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() {