Skip to content

Commit

Permalink
Improve MultiPolygon centroid robustness
Browse files Browse the repository at this point in the history
Do this by allowing each polygon shell to set its own origin point,
instead of re-using the origin point from the first polygon in
the geometry.

Signed-off-by: Daniel Baston <[email protected]>
  • Loading branch information
dbaston committed Aug 19, 2017
1 parent 3fcae9e commit 44dbbfb
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ else if (ptCount > 0){

private void setBasePoint(Coordinate basePt)
{
if (this.areaBasePt == null)
this.areaBasePt = basePt;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.locationtech.jts.algorithm;

import junit.framework.TestCase;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.WKTReader;

public class CentroidTest extends TestCase {


public CentroidTest(String name) {
super(name);
}

public void testCentroidMultiPolygon() throws Exception {
// Verify that the computed centroid of a MultiPolygon is equivalent to the
// area-weighted average of its components.
Geometry g = new WKTReader().read(
"MULTIPOLYGON ((( -92.661322 36.58994900000003, -92.66132199999993 36.58994900000005, -92.66132199999993 36.589949000000004, -92.661322 36.589949, -92.661322 36.58994900000003)), (( -92.65560500000008 36.58708800000005, -92.65560499999992 36.58708800000005, -92.65560499998745 36.587087999992576, -92.655605 36.587088, -92.65560500000008 36.58708800000005 )), (( -92.65512450000065 36.586800000000466, -92.65512449999994 36.58680000000004, -92.65512449998666 36.5867999999905, -92.65512450000065 36.586800000000466 )))"
);

double totalArea = g.getArea();
double cx = 0;
double cy = 0;

for(int i = 0; i < g.getNumGeometries(); i++) {
Geometry component = g.getGeometryN(i);
double areaFraction = component.getArea() / totalArea;

Coordinate componentCentroid = component.getCentroid().getCoordinate();

cx += areaFraction * componentCentroid.x;
cy += areaFraction * componentCentroid.y;
}

assertEquals(new Coordinate(cx, cy), g.getCentroid().getCoordinate());
System.out.println(new GeometryFactory().createPoint(new Coordinate(cx, cy)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,30 @@
<test><op name="getCentroid" arg1="A" > POINT (56.52883333335 25.21033333335) </op></test>
</case>


<case>
<desc>A - almost degenerate MultiPolygon</desc>
<a>
MULTIPOLYGON (((
-92.661322 36.58994900000003,
-92.66132199999993 36.58994900000005,
-92.66132199999993 36.589949000000004,
-92.661322 36.589949,
-92.661322 36.58994900000003)),
((
-92.65560500000008 36.58708800000005,
-92.65560499999992 36.58708800000005,
-92.65560499998745 36.587087999992576,
-92.655605 36.587088,
-92.65560500000008 36.58708800000005
)),
((
-92.65512450000065 36.586800000000466,
-92.65512449999994 36.58680000000004,
-92.65512449998666 36.5867999999905,
-92.65512450000065 36.586800000000466
)))
</a>
<test><op name="getCentroid" arg1="A" >POINT (-92.6553838608954 36.58695407733924)</op></test>
</case>

</run>

0 comments on commit 44dbbfb

Please sign in to comment.