mirror of https://github.com/apache/lucene.git
Fix algorithm that chooses the bridge between a polygon and a hole (#11988)
This commit is contained in:
parent
486003833f
commit
ef5766aa81
|
@ -183,6 +183,9 @@ Bug Fixes
|
|||
so that subsequent passage merges don't mean that we return too few passages in
|
||||
total. (Alan Woodward, Dawid Weiss)
|
||||
|
||||
* GITHUB#11986: Fix algorithm that chooses the bridge between a polygon and a hole when there is
|
||||
common vertex. (Ignacio Vera)
|
||||
|
||||
Optimizations
|
||||
---------------------
|
||||
* GITHUB#11738: Optimize MultiTermQueryConstantScoreWrapper when a term is present that matches all
|
||||
|
|
|
@ -435,42 +435,21 @@ public final class Tessellator {
|
|||
final double my = connection.getY();
|
||||
double tanMin = Double.POSITIVE_INFINITY;
|
||||
double tan;
|
||||
p = connection.next;
|
||||
{
|
||||
while (p != stop) {
|
||||
if (hx >= p.getX()
|
||||
&& p.getX() >= mx
|
||||
&& hx != p.getX()
|
||||
&& pointInEar(
|
||||
p.getX(), p.getY(), hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy)) {
|
||||
tan = Math.abs(hy - p.getY()) / (hx - p.getX()); // tangential
|
||||
if (isVertexEquals(p, connection) && isLocallyInside(p, holeNode)) {
|
||||
// make sure we are not crossing the polygon. This might happen when several holes have
|
||||
// a bridge to the same polygon vertex
|
||||
// and this vertex has different vertex.
|
||||
boolean crosses =
|
||||
GeoUtils.lineCrossesLine(
|
||||
p.getX(),
|
||||
p.getY(),
|
||||
holeNode.getX(),
|
||||
holeNode.getY(),
|
||||
connection.next.getX(),
|
||||
connection.next.getY(),
|
||||
connection.previous.getX(),
|
||||
connection.previous.getY());
|
||||
if (crosses == false) {
|
||||
connection = p;
|
||||
tanMin = tan;
|
||||
}
|
||||
} else if ((tan < tanMin || (tan == tanMin && p.getX() > connection.getX()))
|
||||
&& isLocallyInside(p, holeNode)) {
|
||||
connection = p;
|
||||
tanMin = tan;
|
||||
}
|
||||
p = connection;
|
||||
do {
|
||||
if (hx >= p.getX()
|
||||
&& p.getX() >= mx
|
||||
&& hx != p.getX()
|
||||
&& pointInEar(p.getX(), p.getY(), hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy)) {
|
||||
tan = Math.abs(hy - p.getY()) / (hx - p.getX()); // tangential
|
||||
if ((tan < tanMin || (tan == tanMin && p.getX() > connection.getX()))
|
||||
&& isLocallyInside(p, holeNode)) {
|
||||
connection = p;
|
||||
tanMin = tan;
|
||||
}
|
||||
p = p.next;
|
||||
}
|
||||
}
|
||||
p = p.next;
|
||||
} while (p != stop);
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
|
@ -845,7 +845,7 @@ public class TestTessellator extends LuceneTestCase {
|
|||
Polygon polygon = polygons[0];
|
||||
TestCountingMonitor monitor = new TestCountingMonitor();
|
||||
Tessellator.tessellate(polygon, true, monitor);
|
||||
assertThat("Expected many monitor calls", monitor.count, greaterThan(400));
|
||||
assertThat("Expected many monitor calls", monitor.count, greaterThan(390));
|
||||
assertThat("Expected specific number of splits", monitor.splitsStarted, equalTo(3));
|
||||
assertThat(
|
||||
"Expected splits to start and end", monitor.splitsStarted, equalTo(monitor.splitsEnded));
|
||||
|
@ -891,6 +891,30 @@ public class TestTessellator extends LuceneTestCase {
|
|||
ex.getMessage());
|
||||
}
|
||||
|
||||
public void testComplexPolygon53() throws Exception {
|
||||
String geoJson = GeoTestUtil.readShape("github-11986-1.geojson.gz");
|
||||
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
|
||||
for (Polygon polygon : polygons) {
|
||||
List<Tessellator.Triangle> tessellation = Tessellator.tessellate(polygon, true);
|
||||
assertEquals(area(polygon), area(tessellation), 0.0);
|
||||
for (Tessellator.Triangle t : tessellation) {
|
||||
checkTriangleEdgesFromPolygon(polygon, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testComplexPolygon54() throws Exception {
|
||||
String geoJson = GeoTestUtil.readShape("github-11986-2.geojson.gz");
|
||||
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
|
||||
for (Polygon polygon : polygons) {
|
||||
List<Tessellator.Triangle> tessellation = Tessellator.tessellate(polygon, true);
|
||||
assertEquals(area(polygon), area(tessellation), 0.0);
|
||||
for (Tessellator.Triangle t : tessellation) {
|
||||
checkTriangleEdgesFromPolygon(polygon, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestCountingMonitor implements Tessellator.Monitor {
|
||||
private int count = 0;
|
||||
private int splitsStarted = 0;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue