From 1399208960d988331d7072490b33edf2ccdafde9 Mon Sep 17 00:00:00 2001 From: strk Date: Sun, 21 Feb 2010 15:03:15 +0000 Subject: [PATCH] GEOSGeom_extractUniquePoints [RT-SIGTA] git-svn-id: http://svn.osgeo.org/geos/trunk@2917 5242fede-7e19-0410-aef8-94bd7d2200fb --- NEWS | 1 + capi/geos_c.h.in | 5 ++ capi/geos_ts_c.cpp | 50 +++++++++++ tests/unit/Makefile.am | 3 +- .../unit/capi/GEOSGeom_extractUniquePointsTest.cpp | 100 +++++++++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/unit/capi/GEOSGeom_extractUniquePointsTest.cpp diff --git a/NEWS b/NEWS index b283fb0d..4c68c741 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Changes in 3.3.0 - CAPI: GEOSContext_setNoticeHandler_r, GEOSContext_setErrorHandler_r - CAPI: GEOSGeom_createEmptyPoint_r, GEOSGeom_createEmptyLineString_r GEOSGeom_createEmptyPolygon_r, GEOSGeom_createEmptyCollection_r + - CAPI: GEOSGeom_extractUniquePoints_r Changes in 3.2.0 diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in index fbb2d5be..5b8ec937 100644 --- a/capi/geos_c.h.in +++ b/capi/geos_c.h.in @@ -546,6 +546,11 @@ extern GEOSGeometry GEOS_DLL *GEOSTopologyPreserveSimplify_r( GEOSContextHandle_t handle, const GEOSGeometry* g1, double tolerance); +/* Return all distinct vertices of input geometry as a MULTIPOINT */ +extern GEOSGeometry GEOS_DLL *GEOSGeom_extractUniquePoints_r( + GEOSContextHandle_t handle, + const GEOSGeometry* g); + /************************************************************************ * * Binary predicates - return 2 on exception, 1 on true, 0 on false diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp index b0976f62..cadfbe91 100644 --- a/capi/geos_ts_c.cpp +++ b/capi/geos_ts_c.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -4672,6 +4673,55 @@ GEOSInterpolateNormalized_r(GEOSContextHandle_t extHandle, const Geometry *g, return GEOSInterpolate_r(extHandle, g, d * length); } +GEOSGeometry* +GEOSGeom_extractUniquePoints_r(GEOSContextHandle_t extHandle, + const GEOSGeometry* g) +{ + if ( 0 == extHandle ) return 0; + GEOSContextHandleInternal_t *handle = 0; + handle = reinterpret_cast(extHandle); + if ( handle->initialized == 0 ) return 0; + + using namespace geos::geom; + using namespace geos::util; + using namespace std; + + try + { + + /* 1: extract points */ + vector coords; + UniqueCoordinateArrayFilter filter(coords); + g->apply_ro(&filter); + + /* 2: for each point, create a geometry and put into a vector */ + vector* points = new vector(); + points->reserve(coords.size()); + const GeometryFactory* factory = g->getFactory(); + for (vector::iterator it=coords.begin(), + itE=coords.end(); + it != itE; ++it) + { + Geometry* point = factory->createPoint(*(*it)); + points->push_back(point); + } + + /* 3: create a multipoint */ + return factory->createMultiPoint(points); + + } + catch (const std::exception &e) + { + handle->ERROR_MESSAGE("%s", e.what()); + return 0; + } + catch (...) + { + handle->ERROR_MESSAGE("Unknown exception thrown"); + return 0; + } +} + } /* extern "C" */ diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 20cfd611..f1b28982 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -92,7 +92,8 @@ geos_unit_SOURCES = \ capi/GEOSPreparedGeometryTest.cpp \ capi/GEOSPolygonizer_getCutEdgesTest.cpp \ capi/GEOSBufferTest.cpp \ - capi/GEOSGeom_create.cpp + capi/GEOSGeom_create.cpp \ + capi/GEOSGeom_extractUniquePointsTest.cpp noinst_HEADERS = \ utility.h diff --git a/tests/unit/capi/GEOSGeom_extractUniquePointsTest.cpp b/tests/unit/capi/GEOSGeom_extractUniquePointsTest.cpp new file mode 100644 index 00000000..85d60492 --- /dev/null +++ b/tests/unit/capi/GEOSGeom_extractUniquePointsTest.cpp @@ -0,0 +1,100 @@ +// $Id: GEOSContainsTest.cpp 2424 2009-04-29 23:52:36Z mloskot $ +// +// Test Suite for C-API GEOSGeom_extractUniquePoints_r + +#include +// geos +#include +// std +#include +#include +#include + +namespace tut +{ + // + // Test Group + // + + // Common data used in test cases. + struct test_capigeosextractuniquepoints_data + { + GEOSGeometry* geom1_; + GEOSGeometry* geom2_; + GEOSContextHandle_t handle_; + + static void notice(const char *fmt, ...) + { + std::fprintf( stdout, "NOTICE: "); + + va_list ap; + va_start(ap, fmt); + std::vfprintf(stdout, fmt, ap); + va_end(ap); + + std::fprintf(stdout, "\n"); + } + + test_capigeosextractuniquepoints_data() + : geom1_(0), geom2_(0) + { + handle_ = initGEOS_r(notice, notice); + } + + ~test_capigeosextractuniquepoints_data() + { + GEOSGeom_destroy_r(handle_, geom1_); + GEOSGeom_destroy_r(handle_, geom2_); + geom1_ = 0; + geom2_ = 0; + finishGEOS_r(handle_); + } + + }; + + typedef test_group group; + typedef group::object object; + + group test_capigeosextractuniquepoints_group("capi::GEOSGeom_extractUniquePoints"); + + // + // Test Cases + // + + template<> + template<> + void object::test<1>() + { + geom1_ = GEOSGeomFromWKT_r(handle_, "POLYGON EMPTY"); + /* ensure_equals(GEOSGetNumGeometries_r(handle_, geom2_), 0); */ + ensure(GEOSisEmpty_r(handle_, + GEOSGeom_extractUniquePoints_r(handle_, geom1_))); + } + + template<> + template<> + void object::test<2>() + { + geom1_ = GEOSGeomFromWKT_r(handle_, "MULTIPOINT(0 0, 0 0, 1 1)"); + geom2_ = GEOSGeomFromWKT_r(handle_, "MULTIPOINT(0 0, 1 1)"); + /* ensure_equals(GEOSGetNumGeometries_r(handle_, geom2_), 0); */ + ensure(GEOSEquals_r(handle_, + GEOSGeom_extractUniquePoints_r(handle_, geom1_), + geom2_)); + } + + template<> + template<> + void object::test<3>() + { + geom1_ = GEOSGeomFromWKT_r(handle_, "GEOMETRYCOLLECTION(MULTIPOINT(0 0, 0 0, 1 1),LINESTRING(1 1, 2 2, 2 2, 0 0),POLYGON((5 5, 0 0, 0 2, 2 2, 5 5)))"); + geom2_ = GEOSGeomFromWKT_r(handle_, "MULTIPOINT(0 0, 1 1, 2 2, 5 5, 0 2)"); + /* ensure_equals(GEOSGetNumGeometries_r(handle_, geom2_), 0); */ + ensure(GEOSEquals_r(handle_, + GEOSGeom_extractUniquePoints_r(handle_, geom1_), + geom2_)); + } + + +} // namespace tut + -- 2.11.4.GIT