mirror of https://github.com/apache/lucene.git
LUCENE-8220: Switch over to using GeoComplexPolygon if we can't tile a polygon.
This commit is contained in:
parent
5e1d6f36f7
commit
273a829c46
|
@ -164,32 +164,44 @@ public class GeoPolygonFactory {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//First approximation to find a point
|
try {
|
||||||
final GeoPoint centerOfMass = getCenterOfMass(planetModel, filteredPointList);
|
//First approximation to find a point
|
||||||
final Boolean isCenterOfMassInside = isInsidePolygon(centerOfMass, filteredPointList);
|
final GeoPoint centerOfMass = getCenterOfMass(planetModel, filteredPointList);
|
||||||
if (isCenterOfMassInside != null) {
|
final Boolean isCenterOfMassInside = isInsidePolygon(centerOfMass, filteredPointList);
|
||||||
return generateGeoPolygon(planetModel, filteredPointList, holes, centerOfMass, isCenterOfMassInside);
|
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);
|
|
||||||
}
|
}
|
||||||
// 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.
|
/** 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<GeoPoint> filteredPointList,
|
||||||
final List<GeoPolygon> holes,
|
final List<GeoPolygon> holes,
|
||||||
final GeoPoint testPoint,
|
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
|
// 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
|
// side. While this looks like it might be 2x as expensive as it could be, there's really no other choice I can
|
||||||
// find.
|
// find.
|
||||||
|
@ -750,7 +762,7 @@ public class GeoPolygonFactory {
|
||||||
final int endPointIndex,
|
final int endPointIndex,
|
||||||
final SidedPlane startingEdge,
|
final SidedPlane startingEdge,
|
||||||
final List<GeoPolygon> holes,
|
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
|
// 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.
|
// as part of the general code for constructing complex polygons.
|
||||||
|
@ -1003,7 +1015,7 @@ public class GeoPolygonFactory {
|
||||||
|
|
||||||
if (foundBadEdge) {
|
if (foundBadEdge) {
|
||||||
// Unaddressed bad edge
|
// 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.
|
// No violations found: we know it's a legal concave polygon.
|
||||||
|
@ -1686,4 +1698,11 @@ public class GeoPolygonFactory {
|
||||||
public boolean value = false;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.util.BitSet;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.Ignore;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -623,7 +622,7 @@ shape:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPolygonFactoryCase3() {
|
public void testPolygonFactoryCase3() throws Exception {
|
||||||
/*
|
/*
|
||||||
This one failed to be detected as convex:
|
This one failed to be detected as convex:
|
||||||
|
|
||||||
|
@ -1102,7 +1101,6 @@ shape:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testCoplanarityTileConvex() throws Exception {
|
public void testCoplanarityTileConvex() throws Exception {
|
||||||
// This test has been disabled because it is possible that the polygon specified actually intersects itself.
|
// 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))"
|
//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.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.77495), Geo3DUtil.fromDegrees(24.394476)));
|
||||||
points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(65.77498), Geo3DUtil.fromDegrees(24.394457)));
|
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);
|
assertTrue(polygon != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testCoplanarityConcave() throws Exception {
|
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))
|
//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<>();
|
List<GeoPoint> points = new ArrayList<>();
|
||||||
|
|
Loading…
Reference in New Issue