[geos-commits] r3749 - in trunk: . include/geos/algorithm src/algorithm src/geom tests/xmltester tests/xmltester/tests/general
svn_geos at osgeo.org
svn_geos at osgeo.org
Mon Jan 14 08:15:37 PST 2013
Author: strk
Date: 2013-01-14 08:15:37 -0800 (Mon, 14 Jan 2013)
New Revision: 3749
Added:
trunk/include/geos/algorithm/Centroid.h
trunk/src/algorithm/Centroid.cpp
Modified:
trunk/NEWS
trunk/include/geos/algorithm/CentroidArea.h
trunk/include/geos/algorithm/CentroidLine.h
trunk/include/geos/algorithm/CentroidPoint.h
trunk/include/geos/algorithm/Makefile.am
trunk/src/algorithm/Makefile.am
trunk/src/geom/Geometry.cpp
trunk/tests/xmltester/XMLTester.cpp
trunk/tests/xmltester/tests/general/TestCentroid.xml
Log:
Fix EMPTY return from single-point lines and zero-length polygons
This commit ports new Centroid class from JTS (#612)
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/NEWS 2013-01-14 16:15:37 UTC (rev 3749)
@@ -7,6 +7,7 @@
- CAPI: GEOSNode (#496) - PHP: Geometry->node
- GeometryPrecisionReducer class
- BufferInputLineSimplifier header exposed (#548)
+ - New Centroid class supporting mixed geometry components (#612)
- C++ API changes:
- New noding::GeometryNoder class
- Added BufferOp::setSingleSided
@@ -15,7 +16,7 @@
- Signature of most functions taking an IntersectionMatrix changed
to take it by reference rather than pointer.
- GraphComponent::label is now a Label value (from a pointer)
- - NodedSegmentString takes ownership of CoordinateSequence now
+ -e NodedSegmentString takes ownership of CoordinateSenuence now
- Bug fixes / improvements
- Improve Buffer robustness by reducing input precision on topology
exception (#605)
@@ -23,6 +24,8 @@
by always using the lowest possible index value, and by trimming
zero-length components from results (#323)
- Fixed CMake configuration to set correct SOVERSION (current - age)
+ - Fix EMPTY return from single-point lines and zero-length polygons (#612)
+
Changes in 3.3.0
2011-05-30
Added: trunk/include/geos/algorithm/Centroid.h
===================================================================
--- trunk/include/geos/algorithm/Centroid.h (rev 0)
+++ trunk/include/geos/algorithm/Centroid.h 2013-01-14 16:15:37 UTC (rev 3749)
@@ -0,0 +1,157 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2013 Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: algorithm/Centroid.java r728 (JTS-0.13+)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_ALGORITHM_CENTROID_H
+#define GEOS_ALGORITHM_CENTROID_H
+
+#include <geos/export.h>
+#include <geos/geom/Coordinate.h> // for composition
+#include <memory> // for std::auto_ptr
+
+// Forward declarations
+namespace geos {
+ namespace geom {
+ class Geometry;
+ class Polygon;
+ class CoordinateSequence;
+ }
+}
+
+
+namespace geos {
+namespace algorithm { // geos::algorithm
+
+/**
+ * Computes the centroid of a {@link Geometry} of any dimension.
+ * If the geometry is nomimally of higher dimension, but contains only components
+ * having a lower effective dimension (i.e. zero length or area),
+ * the centroid will be computed appropriately.
+ *
+ * <h2>Algorithm</h2>
+ * <ul>
+ * <li><b>Dimension = 2</b> - Based on the usual algorithm for calculating
+ * the centroid as a weighted sum of the centroids
+ * of a decomposition of the area into (possibly overlapping) triangles.
+ * The algorithm has been extended to handle holes and multi-polygons.
+ * See <code>http://www.faqs.org/faqs/graphics/algorithms-faq/</code>
+ * for further details of the basic approach.
+ * <li><b>Dimension = 1</b> - Computes the average of the midpoints
+ * of all line segments weighted by the segment length.
+ * <li><b>Dimension = 0</b> - Compute the average coordinate over all points.
+ * </ul>
+ * If the input geometries are empty, a
+ * <code>null</code> Coordinate is returned.
+ *
+ */
+class GEOS_DLL Centroid {
+
+public:
+
+ /**
+ * Computes the centroid point of a geometry.
+ *
+ * @param geom the geometry to use
+ * @param cent will be set to the centroid point, if any
+ *
+ * @return true if a centroid could be computed,
+ * false otherwise (empty geom)
+ */
+ static bool getCentroid(const geom::Geometry& geom, geom::Coordinate& cent);
+
+ /**
+ * Creates a new instance for computing the centroid of a geometry
+ */
+ Centroid(const geom::Geometry& geom)
+ :
+ areasum2(0.0),
+ totalLength(0.0),
+ ptCount(0)
+ {
+ add(geom);
+ }
+
+ /**
+ * Gets the computed centroid.
+ *
+ * @param cent will be set to the centroid point, if any
+ *
+ * @return true if a centroid could be computed,
+ * false otherwise (empty geom)
+ */
+ bool getCentroid(geom::Coordinate& cent) const;
+
+private:
+
+ std::auto_ptr<geom::Coordinate> areaBasePt;
+ geom::Coordinate triangleCent3;
+ geom::Coordinate cg3;
+ geom::Coordinate lineCentSum;
+ geom::Coordinate ptCentSum;
+ double areasum2;
+ double totalLength;
+ int ptCount;
+
+ /**
+ * Adds a Geometry to the centroid total.
+ *
+ * @param geom the geometry to add
+ */
+ void add(const geom::Geometry& geom);
+
+ void setBasePoint(const geom::Coordinate& basePt);
+
+ void add(const geom::Polygon& poly);
+
+ void addShell(const geom::CoordinateSequence& pts);
+
+ void addHole(const geom::CoordinateSequence& pts);
+
+ void addTriangle(const geom::Coordinate& p0, const geom::Coordinate& p1, const geom::Coordinate& p2, bool isPositiveArea);
+
+ /**
+ * Computes three times the centroid of the triangle p1-p2-p3.
+ * The factor of 3 is
+ * left in to permit division to be avoided until later.
+ */
+ static void centroid3(const geom::Coordinate& p1, const geom::Coordinate& p2, const geom::Coordinate& p3, geom::Coordinate& c );
+
+ /**
+ * Returns twice the signed area of the triangle p1-p2-p3.
+ * The area is positive if the triangle is oriented CCW, and negative if CW.
+ */
+ static double area2(const geom::Coordinate& p1, const geom::Coordinate& p2, const geom::Coordinate& p3 );
+
+ /**
+ * Adds the line segments defined by an array of coordinates
+ * to the linear centroid accumulators.
+ *
+ * @param pts an array of {@link Coordinate}s
+ */
+ void addLineSegments(const geom::CoordinateSequence& pts);
+
+ /**
+ * Adds a point to the point centroid accumulator.
+ * @param pt a {@link Coordinate}
+ */
+ void addPoint(const geom::Coordinate& pt);
+};
+
+} // namespace geos::algorithm
+} // namespace geos
+
+#endif // GEOS_ALGORITHM_CENTROID_H
Modified: trunk/include/geos/algorithm/CentroidArea.h
===================================================================
--- trunk/include/geos/algorithm/CentroidArea.h 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/include/geos/algorithm/CentroidArea.h 2013-01-14 16:15:37 UTC (rev 3749)
@@ -53,6 +53,9 @@
* The code has also be extended to handle degenerate (zero-area) polygons.
* In this case, the centroid of the line segments in the polygon
* will be returned.
+ *
+ * @deprecated use Centroid instead
+ *
*/
class GEOS_DLL CentroidArea {
Modified: trunk/include/geos/algorithm/CentroidLine.h
===================================================================
--- trunk/include/geos/algorithm/CentroidLine.h 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/include/geos/algorithm/CentroidLine.h 2013-01-14 16:15:37 UTC (rev 3749)
@@ -31,6 +31,7 @@
namespace geos {
namespace algorithm { // geos::algorithm
+/// @deprecated use Centroid instead
class GEOS_DLL CentroidLine {
private:
Modified: trunk/include/geos/algorithm/CentroidPoint.h
===================================================================
--- trunk/include/geos/algorithm/CentroidPoint.h 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/include/geos/algorithm/CentroidPoint.h 2013-01-14 16:15:37 UTC (rev 3749)
@@ -30,6 +30,7 @@
namespace geos {
namespace algorithm { // geos::algorithm
+/// @deprecated use Centroid instead
class GEOS_DLL CentroidPoint {
private:
Modified: trunk/include/geos/algorithm/Makefile.am
===================================================================
--- trunk/include/geos/algorithm/Makefile.am 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/include/geos/algorithm/Makefile.am 2013-01-14 16:15:37 UTC (rev 3749)
@@ -13,6 +13,7 @@
Angle.h \
BoundaryNodeRule.h \
CentralEndpointIntersector.h \
+ Centroid.h \
CentroidArea.h \
CentroidLine.h \
CentroidPoint.h \
Added: trunk/src/algorithm/Centroid.cpp
===================================================================
--- trunk/src/algorithm/Centroid.cpp (rev 0)
+++ trunk/src/algorithm/Centroid.cpp 2013-01-14 16:15:37 UTC (rev 3749)
@@ -0,0 +1,194 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2013 Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: algorithm/Centroid.java r728 (JTS-0.13+)
+ *
+ **********************************************************************/
+
+#include <geos/algorithm/Centroid.h>
+#include <geos/algorithm/CGAlgorithms.h>
+#include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/Point.h>
+#include <geos/geom/Polygon.h>
+#include <geos/geom/GeometryCollection.h>
+#include <geos/geom/LineString.h>
+
+#include <cmath> // for std::abs
+
+using namespace geos::geom;
+
+namespace geos {
+namespace algorithm { // geos.algorithm
+
+/* static public */
+bool
+Centroid::getCentroid(const Geometry& geom, Coordinate& pt)
+{
+ Centroid cent(geom);
+ return cent.getCentroid(pt);
+}
+
+/* public */
+bool
+Centroid::getCentroid(Coordinate& cent) const
+{
+ if (std::abs(areasum2) > 0.0) {
+ cent.x = cg3.x / 3 / areasum2;
+ cent.y = cg3.y / 3 / areasum2;
+ }
+ else if (totalLength > 0.0) {
+ // if polygon was degenerate, compute linear centroid instead
+ cent.x = lineCentSum.x / totalLength;
+ cent.y = lineCentSum.y / totalLength;
+ }
+ else if (ptCount > 0){
+ cent.x = ptCentSum.x / ptCount;
+ cent.y = ptCentSum.y / ptCount;
+ }
+ else {
+ return false;
+ }
+ return true;
+}
+
+/* private */
+void
+Centroid::add(const Geometry& geom)
+{
+ if (geom.isEmpty()) return;
+
+ if (const Point* g = dynamic_cast<const Point*>(&geom)) {
+ addPoint(*g->getCoordinate());
+ }
+ else if (const LineString* g = dynamic_cast<const LineString*>(&geom)) {
+ addLineSegments(*g->getCoordinatesRO());
+ }
+ else if (const Polygon* g = dynamic_cast<const Polygon*>(&geom)) {
+ add(*g);
+ }
+ else if (const GeometryCollection* g = dynamic_cast<const GeometryCollection*>(&geom)) {
+ for (size_t i = 0; i < g->getNumGeometries(); i++) {
+ add(*g->getGeometryN(i));
+ }
+ }
+}
+
+/* private */
+void
+Centroid::setBasePoint(const Coordinate& basePt)
+{
+ if ( ! areaBasePt.get() )
+ areaBasePt.reset( new Coordinate(basePt) );
+}
+
+/* private */
+void
+Centroid::add(const Polygon& poly)
+{
+ addShell(*poly.getExteriorRing()->getCoordinatesRO());
+ for (size_t i = 0; i < poly.getNumInteriorRing(); i++) {
+ addHole(*poly.getInteriorRingN(i)->getCoordinatesRO());
+ }
+}
+
+/* private */
+void
+Centroid::addShell(const CoordinateSequence& pts)
+{
+ size_t len = pts.size();
+ if (len > 0)
+ setBasePoint(pts[0]);
+ bool isPositiveArea = ! CGAlgorithms::isCCW(&pts);
+ for (size_t i = 0; i < len - 1; ++i) {
+ addTriangle(*areaBasePt, pts[i], pts[i+1], isPositiveArea);
+ }
+ addLineSegments(pts);
+}
+
+/* private */
+void
+Centroid::addHole(const CoordinateSequence& pts)
+{
+ bool isPositiveArea = CGAlgorithms::isCCW(&pts);
+ for (size_t i = 0, e = pts.size() - 1; i < e; ++i) {
+ addTriangle(*areaBasePt, pts[i], pts[i+1], isPositiveArea);
+ }
+ addLineSegments(pts);
+}
+
+/* private */
+void
+Centroid::addTriangle(const Coordinate& p0, const Coordinate& p1, const Coordinate& p2, bool isPositiveArea)
+{
+ double sign = (isPositiveArea) ? 1.0 : -1.0;
+ centroid3( p0, p1, p2, triangleCent3 );
+ double a2 = area2( p0, p1, p2 );
+ cg3.x += sign * a2 * triangleCent3.x;
+ cg3.y += sign * a2 * triangleCent3.y;
+ areasum2 += sign * a2;
+}
+
+/* static private */
+void
+Centroid::centroid3(const Coordinate& p1, const Coordinate& p2, const Coordinate& p3, Coordinate& c )
+{
+ c.x = p1.x + p2.x + p3.x;
+ c.y = p1.y + p2.y + p3.y;
+ return;
+}
+
+/* static private */
+double
+Centroid::area2(const Coordinate& p1, const Coordinate& p2, const Coordinate& p3 )
+{
+ return
+ (p2.x - p1.x) * (p3.y - p1.y) -
+ (p3.x - p1.x) * (p2.y - p1.y);
+}
+
+/* private */
+void
+Centroid::addLineSegments(const CoordinateSequence& pts)
+{
+ size_t npts = pts.size();
+ double lineLen = 0.0;
+ for (size_t i = 0; i < npts - 1; i++) {
+ double segmentLen = pts[i].distance(pts[i + 1]);
+ if (segmentLen == 0.0)
+ continue;
+
+ lineLen += segmentLen;
+
+ double midx = (pts[i].x + pts[i + 1].x) / 2;
+ lineCentSum.x += segmentLen * midx;
+ double midy = (pts[i].y + pts[i + 1].y) / 2;
+ lineCentSum.y += segmentLen * midy;
+ }
+ totalLength += lineLen;
+ if (lineLen == 0.0 && npts > 0)
+ addPoint(pts[0]);
+}
+
+/* private */
+void
+Centroid::addPoint(const Coordinate& pt)
+{
+ ptCount += 1;
+ ptCentSum.x += pt.x;
+ ptCentSum.y += pt.y;
+}
+
+} // namespace geos.algorithm
+} // namespace geos
Modified: trunk/src/algorithm/Makefile.am
===================================================================
--- trunk/src/algorithm/Makefile.am 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/src/algorithm/Makefile.am 2013-01-14 16:15:37 UTC (rev 3749)
@@ -12,6 +12,7 @@
libalgorithm_la_SOURCES = \
Angle.cpp \
BoundaryNodeRule.cpp \
+ Centroid.cpp \
CentroidArea.cpp \
CentroidLine.cpp \
CentroidPoint.cpp \
Modified: trunk/src/geom/Geometry.cpp
===================================================================
--- trunk/src/geom/Geometry.cpp 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/src/geom/Geometry.cpp 2013-01-14 16:15:37 UTC (rev 3749)
@@ -34,9 +34,7 @@
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/IntersectionMatrix.h>
#include <geos/util/IllegalArgumentException.h>
-#include <geos/algorithm/CentroidPoint.h>
-#include <geos/algorithm/CentroidLine.h>
-#include <geos/algorithm/CentroidArea.h>
+#include <geos/algorithm/Centroid.h>
#include <geos/algorithm/InteriorPointPoint.h>
#include <geos/algorithm/InteriorPointLine.h>
#include <geos/algorithm/InteriorPointArea.h>
@@ -202,30 +200,8 @@
Geometry::getCentroid(Coordinate& ret) const
{
if ( isEmpty() ) { return false; }
-
- Coordinate c;
-
- int dim=getDimension();
- if(dim==0) {
- CentroidPoint cent;
- cent.add(this);
- if ( ! cent.getCentroid(c) )
- return false;
- } else if (dim==1) {
- CentroidLine cent;
- cent.add(this);
- if ( ! cent.getCentroid(c) )
- return false;
- } else {
- CentroidArea cent;
- cent.add(this);
- if ( ! cent.getCentroid(c) )
- return false;
- }
-
- getPrecisionModel()->makePrecise(c);
- ret=c;
-
+ if ( ! Centroid::getCentroid(*this, ret) ) return false;
+ getPrecisionModel()->makePrecise(ret); // not in JTS
return true;
}
Modified: trunk/tests/xmltester/XMLTester.cpp
===================================================================
--- trunk/tests/xmltester/XMLTester.cpp 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/tests/xmltester/XMLTester.cpp 2013-01-14 16:15:37 UTC (rev 3749)
@@ -957,7 +957,7 @@
GeomAutoPtr gRealRes(gT->getCentroid());
if ( gRealRes.get() ) gRealRes->normalize();
- else gRealRes.reset(factory->createGeometryCollection());
+ else gRealRes.reset(factory->createPoint());
gRealRes->normalize();
if (gRes->compareTo(gRealRes.get())==0) success=1;
Modified: trunk/tests/xmltester/tests/general/TestCentroid.xml
===================================================================
--- trunk/tests/xmltester/tests/general/TestCentroid.xml 2013-01-14 11:16:01 UTC (rev 3748)
+++ trunk/tests/xmltester/tests/general/TestCentroid.xml 2013-01-14 16:15:37 UTC (rev 3749)
@@ -1,7 +1,13 @@
<run>
- <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>
+ <!-- <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/> -->
<case>
+ <desc>P - empty</desc>
+ <a> POINT EMPTY </a>
+<test><op name="getCentroid" arg1="A" > POINT EMPTY </op></test>
+</case>
+
+<case>
<desc>P - single point</desc>
<a> POINT(10 10) </a>
<test><op name="getCentroid" arg1="A" > POINT(10 10) </op></test>
@@ -9,13 +15,13 @@
<case>
<desc>mP - two points</desc>
- <a> MULTIPOINT(10 10, 20 20 ) </a>
+ <a> MULTIPOINT((10 10), (20 20) ) </a>
<test><op name="getCentroid" arg1="A" > POINT(15 15) </op></test>
</case>
<case>
<desc>mP - 4 points</desc>
- <a> MULTIPOINT(10 10, 20 20, 10 20, 20 10) </a>
+ <a> MULTIPOINT((10 10), (20 20), (10 20), (20 10)) </a>
<test><op name="getCentroid" arg1="A" > POINT(15 15) </op></test>
</case>
@@ -26,6 +32,18 @@
</case>
<case>
+ <desc>L - zero length line</desc>
+ <a> LINESTRING (10 10, 10 10) </a>
+<test><op name="getCentroid" arg1="A" > POINT (10 10) </op></test>
+</case>
+
+<case>
+ <desc>mL - zero length lines</desc>
+ <a> MULTILINESTRING ((10 10, 10 10), (20 20, 20 20)) </a>
+<test><op name="getCentroid" arg1="A" > POINT (15 15) </op></test>
+</case>
+
+<case>
<desc>L - two segments</desc>
<a> LINESTRING (60 180, 120 100, 180 180) </a>
<test><op name="getCentroid" arg1="A" > POINT (120 140) </op></test>
@@ -35,7 +53,7 @@
<desc>L - elongated horseshoe</desc>
<a> LINESTRING (80 0, 80 120, 120 120, 120 0))
</a>
-<test><op name="getCentroid" arg1="A" > POINT (100 69) </op></test>
+<test><op name="getCentroid" arg1="A" > POINT (100 68.57142857142857) </op></test>
</case>
@@ -76,7 +94,7 @@
<case>
<desc>A - box with hole</desc>
<a> POLYGON ((0 200, 200 200, 200 0, 0 0, 0 200), (20 180, 80 180, 80 20, 20 20, 20 180)) </a>
-<test><op name="getCentroid" arg1="A" > POINT (116 100) </op></test>
+<test><op name="getCentroid" arg1="A" > POINT (115.78947368421052 100) </op></test>
</case>
<case>
@@ -84,7 +102,7 @@
<a> POLYGON ((0 0, 0 200, 200 200, 200 0, 0 0),
(60 180, 20 180, 20 140, 60 140, 60 180))
</a>
-<test><op name="getCentroid" arg1="A" > POINT (103 98) </op></test>
+<test><op name="getCentroid" arg1="A" > POINT (102.5 97.5) </op></test>
</case>
<case>
@@ -109,15 +127,15 @@
<a> GEOMETRYCOLLECTION (POLYGON ((0 200, 20 180, 20 140, 60 140, 200 0, 0 0, 0 200)),
POLYGON ((200 200, 0 200, 20 180, 60 180, 60 140, 200 0, 200 200)))
</a>
-<test><op name="getCentroid" arg1="A" > POINT (103 98) </op></test>
+<test><op name="getCentroid" arg1="A" > POINT (102.5 97.5) </op></test>
</case>
<case>
<desc>GC - heterogeneous collection of lines, points</desc>
<a> GEOMETRYCOLLECTION (LINESTRING (80 0, 80 120, 120 120, 120 0),
- MULTIPOINT (20 60, 40 80, 60 60))
+ MULTIPOINT ((20 60), (40 80), (60 60)))
</a>
-<test><op name="getCentroid" arg1="A" > POINT (100 69) </op></test>
+<test><op name="getCentroid" arg1="A" > POINT (100 68.57142857142857) </op></test>
</case>
<case>
@@ -129,15 +147,58 @@
</case>
<case>
- <desc>GC - heterogeneous collection of polygons, lines, points</desc>
+ <desc>GC - collection of polygons, lines, points</desc>
<a> GEOMETRYCOLLECTION (POLYGON ((0 40, 40 40, 40 0, 0 0, 0 40)),
LINESTRING (80 0, 80 80, 120 40),
- MULTIPOINT (20 60, 40 80, 60 60))
+ MULTIPOINT ((20 60), (40 80), (60 60)))
</a>
<test><op name="getCentroid" arg1="A" > POINT (20 20) </op></test>
</case>
<case>
+ <desc>GC - collection of zero-area polygons and lines</desc>
+ <a> GEOMETRYCOLLECTION (POLYGON ((10 10, 10 10, 10 10, 10 10)),
+ LINESTRING (20 20, 30 30))
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (25 25) </op></test>
+</case>
+
+<case>
+ <desc>GC - collection of zero-area polygons and zero-length lines</desc>
+ <a> GEOMETRYCOLLECTION (POLYGON ((10 10, 10 10, 10 10, 10 10)),
+ LINESTRING (20 20, 20 20))
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (15 15) </op></test>
+</case>
+
+<case>
+ <desc>GC - collection of zero-area polygons, zero-length lines, and points</desc>
+ <a> GEOMETRYCOLLECTION (POLYGON ((10 10, 10 10, 10 10, 10 10)),
+ LINESTRING (20 20, 20 20),
+ MULTIPOINT ((20 10), (10 20)) )
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (15 15) </op></test>
+</case>
+
+<case>
+ <desc>GC - collection of zero-area polygons, zero-length lines, and points</desc>
+ <a> GEOMETRYCOLLECTION (POLYGON ((10 10, 10 10, 10 10, 10 10)),
+ LINESTRING (20 20, 20 20),
+ POINT EMPTY )
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (15 15) </op></test>
+</case>
+
+<case>
+ <desc>GC - collection of zero-area polygons, zero-length lines, and points</desc>
+ <a> GEOMETRYCOLLECTION (POLYGON ((10 10, 10 10, 10 10, 10 10)),
+ LINESTRING EMPTY,
+ POINT EMPTY )
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (10 10) </op></test>
+</case>
+
+<case>
<desc>GC - overlapping polygons </desc>
<a> GEOMETRYCOLLECTION (POLYGON ((20 100, 20 -20, 60 -20, 60 100, 20 100)),
POLYGON ((-20 60, 100 60, 100 20, -20 20, -20 60)))
@@ -145,5 +206,36 @@
<test><op name="getCentroid" arg1="A" > POINT (40 40) </op></test>
</case>
+<case>
+ <desc>A - degenerate box</desc>
+ <a> POLYGON ((40 160, 160 160, 160 160, 40 160, 40 160)) </a>
+<test><op name="getCentroid" arg1="A" > POINT (100 160) </op></test>
+</case>
+<case>
+ <desc>A - degenerate triangle</desc>
+ <a> POLYGON ((10 10, 100 100, 100 100, 10 10)) </a>
+<test><op name="getCentroid" arg1="A" > POINT (55 55) </op></test>
+</case>
+
+<case>
+ <desc>A - empty</desc>
+ <a> POLYGON EMPTY
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT EMPTY </op></test>
+</case>
+
+<case>
+ <desc>A - almost degenerate triangle</desc>
+ <a> POLYGON((
+56.528666666700 25.2101666667,
+56.529000000000 25.2105000000,
+56.528833333300 25.2103333333,
+56.528666666700 25.2101666667))
+ </a>
+<test><op name="getCentroid" arg1="A" > POINT (56.52883333335 25.21033333335) </op></test>
+</case>
+
+
+
</run>
More information about the geos-commits
mailing list