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() {