You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2018/03/25 12:19:21 UTC

lucene-solr:branch_6x: LUCENE-8220: Switch over to using GeoComplexPolygon if we can't tile a polygon.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x 88b057025 -> 81ac4d28f


LUCENE-8220: Switch over to using GeoComplexPolygon if we can't tile a polygon.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/81ac4d28
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/81ac4d28
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/81ac4d28

Branch: refs/heads/branch_6x
Commit: 81ac4d28fb9eacfe80a9ce9e880b5592ea51e363
Parents: 88b0570
Author: Karl Wright <Da...@gmail.com>
Authored: Sun Mar 25 08:17:08 2018 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Sun Mar 25 08:19:15 2018 -0400

----------------------------------------------------------------------
 .../spatial3d/geom/GeoPolygonFactory.java       | 73 ++++++++++++--------
 .../lucene/spatial3d/geom/GeoPolygonTest.java   |  7 +-
 2 files changed, 48 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/81ac4d28/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
index 67f624f..9478388 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
@@ -164,32 +164,44 @@ public class GeoPolygonFactory {
       return null;
     }
 
-    //First approximation to find a point
-    final GeoPoint centerOfMass = getCenterOfMass(planetModel, filteredPointList);
-    final Boolean isCenterOfMassInside = isInsidePolygon(centerOfMass, filteredPointList);
-    if (isCenterOfMassInside != null) {
-      return generateGeoPolygon(planetModel, filteredPointList, holes, centerOfMass, isCenterOfMassInside);
-    }
-    
-    //System.err.println("points="+pointList);
-    // Create a random number generator.  Effectively this furnishes us with a repeatable sequence
-    // of points to use for poles.
-    final Random generator = new Random(1234);
-    for (int counter = 0; counter < 1000000; counter++) {
-      //counter++;
-      // Pick the next random pole
-      final GeoPoint pole = pickPole(generator, planetModel, filteredPointList);
-      // Is it inside or outside?
-      final Boolean isPoleInside = isInsidePolygon(pole, filteredPointList);
-      if (isPoleInside != null) {
-        // Legal pole
-        //System.out.println("Took "+counter+" iterations to find pole");
-        //System.out.println("Pole = "+pole+"; isInside="+isPoleInside+"; pointList = "+pointList);
-        return generateGeoPolygon(planetModel, filteredPointList, holes, pole, isPoleInside);
+    try {
+      //First approximation to find a point
+      final GeoPoint centerOfMass = getCenterOfMass(planetModel, filteredPointList);
+      final Boolean isCenterOfMassInside = isInsidePolygon(centerOfMass, filteredPointList);
+      if (isCenterOfMassInside != null) {
+        return generateGeoPolygon(planetModel, filteredPointList, holes, centerOfMass, isCenterOfMassInside);
       }
-      // If pole choice was illegal, try another one
+      
+      //System.err.println("points="+pointList);
+      // Create a random number generator.  Effectively this furnishes us with a repeatable sequence
+      // of points to use for poles.
+      final Random generator = new Random(1234);
+      for (int counter = 0; counter < 1000000; counter++) {
+        //counter++;
+        // Pick the next random pole
+        final GeoPoint pole = pickPole(generator, planetModel, filteredPointList);
+        // Is it inside or outside?
+        final Boolean isPoleInside = isInsidePolygon(pole, filteredPointList);
+        if (isPoleInside != null) {
+          // Legal pole
+          //System.out.println("Took "+counter+" iterations to find pole");
+          //System.out.println("Pole = "+pole+"; isInside="+isPoleInside+"; pointList = "+pointList);
+          return generateGeoPolygon(planetModel, filteredPointList, holes, pole, isPoleInside);
+        }
+        // If pole choice was illegal, try another one
+      }
+      throw new IllegalArgumentException("cannot find a point that is inside the polygon "+filteredPointList);
+    } catch (TileException e) {
+      // Couldn't tile the polygon; use GeoComplexPolygon instead, if we can.
+      if (holes != null && holes.size() > 0) {
+        // We currently cannot get the list of points that went into making a hole back out, so don't allow this case.
+        // In order to support it, we really need to change the API contract, which is a bigger deal.
+        throw new IllegalArgumentException(e.getMessage());
+      }
+      final List<PolygonDescription> description = new ArrayList<>(1);
+      description.add(new PolygonDescription(pointList));
+      return makeLargeGeoPolygon(planetModel, description);
     }
-    throw new IllegalArgumentException("cannot find a point that is inside the polygon "+filteredPointList);
   }
 
   /** Generate a point at the center of mass of a list of points.
@@ -372,7 +384,7 @@ public class GeoPolygonFactory {
     final List<GeoPoint> filteredPointList,
     final List<GeoPolygon> holes,
     final GeoPoint testPoint, 
-    final boolean testPointInside) {
+    final boolean testPointInside) throws TileException {
     // We will be trying twice to find the right GeoPolygon, using alternate siding choices for the first polygon
     // side.  While this looks like it might be 2x as expensive as it could be, there's really no other choice I can
     // find.
@@ -750,7 +762,7 @@ public class GeoPolygonFactory {
     final int endPointIndex,
     final SidedPlane startingEdge,
     final List<GeoPolygon> holes,
-    final GeoPoint testPoint) {
+    final GeoPoint testPoint) throws TileException {
 
     // It could be the case that we need a concave polygon.  So we need to try and look for that case
     // as part of the general code for constructing complex polygons.
@@ -1003,7 +1015,7 @@ public class GeoPolygonFactory {
 
     if (foundBadEdge) {
       // Unaddressed bad edge
-      throw new IllegalArgumentException("Could not tile polygon; found a pathological coplanarity that couldn't be addressed");
+      throw new TileException("Could not tile polygon; found a pathological coplanarity that couldn't be addressed");
     }
     
     // No violations found: we know it's a legal concave polygon.
@@ -1686,4 +1698,11 @@ public class GeoPolygonFactory {
     public boolean value = false;
   }
   
+  /** Exception we throw when we can't tile a polygon due to numerical precision issues.
+   */
+  private static class TileException extends Exception {
+    public TileException(final String msg) {
+      super(msg);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/81ac4d28/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
index a780bad..fdc9c6d 100755
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
@@ -22,7 +22,6 @@ import java.util.BitSet;
 import java.util.Collections;
 
 import org.junit.Test;
-import org.junit.Ignore;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -623,7 +622,7 @@ shape:
   }
   
   @Test
-  public void testPolygonFactoryCase3() {
+  public void testPolygonFactoryCase3() throws Exception {
     /*
     This one failed to be detected as convex:
 
@@ -1102,7 +1101,6 @@ shape:
   }
 
   @Test
-  @Ignore
   public void testCoplanarityTileConvex() throws Exception {
     // This test has been disabled because it is possible that the polygon specified actually intersects itself.
     //POLYGON((24.39398 65.77519,24.3941 65.77498,24.394024 65.77497,24.393976 65.77495,24.393963 65.77493,24.394068 65.774925,24.394156 65.77495,24.394201 65.77495,24.394234 65.77496,24.394266 65.77498,24.394318 65.77498,24.39434 65.774956,24.394377 65.77495,24.394451 65.77494,24.394476 65.77495,24.394457 65.77498,24.39398 65.77519))"
@@ -1123,12 +1121,11 @@ shape:
     points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(65.77494), Geo3DUtil.fromDegrees(24.394451)));
     points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(65.77495), Geo3DUtil.fromDegrees(24.394476)));
     points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(65.77498), Geo3DUtil.fromDegrees(24.394457)));
-    GeoCompositePolygon polygon = (GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
+    GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
     assertTrue(polygon != null);
   }
 
   @Test
-  @Ignore
   public void testCoplanarityConcave() throws Exception {
     //POLYGON((-52.18851 64.53777,-52.18853 64.53828,-52.18675 64.53829,-52.18676 64.53855,-52.18736 64.53855,-52.18737 64.53881,-52.18677 64.53881,-52.18683 64.54009,-52.18919 64.53981,-52.18916 64.53905,-52.19093 64.53878,-52.19148 64.53775,-52.18851 64.53777))
     List<GeoPoint> points = new ArrayList<>();