Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog/135176.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 135176
summary: '`CentroidCalculator` does not return negative summation weights'
area: Geo
type: bug
issues:
- 131861
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ public double getY() {
* @return the sum of all the weighted coordinates summed in the calculator
*/
public double sumWeight() {
return visitor.compSumWeight.value();
double sumWeight = visitor.compSumWeight.value();
if (sumWeight < 0) {
// we can get negative values due to rounding errors in degenerated polygons. The proper fix would be to compute
// the centroid using the tessellation algorithm. For the time being we just return 0.
return 0d;
}

return sumWeight;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;

public abstract class CentroidCalculatorTests extends ESTestCase {
private static final double DELTA = 0.000000001;
Expand Down Expand Up @@ -398,6 +399,36 @@ public void testAddDifferentDimensionalType() {
}
}

public void testDegeneratedPolygon() {
LinearRing outer = new LinearRing(
new double[] {
144.9738739160867,
144.97387390626216,
144.97387394861903,
144.97387410671985,
144.97387431344814,
144.97387422754971,
144.97387403679602,
144.9738739160867 },
new double[] {
-37.812764320048906,
-37.81276430546101,
-37.81276433502755,
-37.81276449365169,
-37.81276470177617,
-37.8127646444251,
-37.812764516780305,
-37.812764320048906 }
);
LinearRing inner = new LinearRing(
new double[] { 144.9738739160867, 144.97387396264085, 144.97387400134224, 144.97387405619358, 144.9738739160867 },
new double[] { -37.812764320048906, -37.81276437348886, -37.81276441404389, -37.81276447205519, -37.812764320048906 }
);
CentroidCalculator polygonCalculator = new CentroidCalculator();
polygonCalculator.add(new Polygon(outer, List.of(inner)));
assertThat(polygonCalculator.sumWeight(), greaterThanOrEqualTo(0d));
}

private Matcher<CentroidCalculator> matchesCentroid(Point point, double weight) {
return new CentroidMatcher(point.getX(), point.getY(), weight, 1.0);
}
Expand Down