[geos-commits] r3702 - in trunk: . capi tests/unit tests/unit/capi
svn_geos at osgeo.org
svn_geos at osgeo.org
Wed Jun 27 03:43:33 PDT 2012
Author: strk
Date: 2012-06-27 03:43:33 -0700 (Wed, 27 Jun 2012)
New Revision: 3702
Added:
trunk/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp
Modified:
trunk/NEWS
trunk/capi/geos_c.cpp
trunk/capi/geos_c.h.in
trunk/capi/geos_ts_c.cpp
trunk/tests/unit/Makefile.am
Log:
Expose Delaunay triangulation to C-API (#565)
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2012-06-27 10:43:19 UTC (rev 3701)
+++ trunk/NEWS 2012-06-27 10:43:33 UTC (rev 3702)
@@ -2,7 +2,7 @@
????-??-??
- New things:
- - Delaunay Triangulation API (#487)
+ - Delaunay Triangulation API (#487, #565)
- Interruptibility API (C and C++)
- CAPI: GEOSNode (#496) - PHP: Geometry->node
- GeometryPrecisionReducer class
Modified: trunk/capi/geos_c.cpp
===================================================================
--- trunk/capi/geos_c.cpp 2012-06-27 10:43:19 UTC (rev 3701)
+++ trunk/capi/geos_c.cpp 2012-06-27 10:43:33 UTC (rev 3702)
@@ -1258,4 +1258,10 @@
return GEOSBufferWithParams_r(handle, g, p, w);
}
+Geometry *
+GEOSDelaunayTriangulation(const Geometry *g, double tolerance, int onlyEdges)
+{
+ return GEOSDelaunayTriangulation_r(handle, g, tolerance, onlyEdges);
+}
+
} /* extern "C" */
Modified: trunk/capi/geos_c.h.in
===================================================================
--- trunk/capi/geos_c.h.in 2012-06-27 10:43:19 UTC (rev 3701)
+++ trunk/capi/geos_c.h.in 2012-06-27 10:43:33 UTC (rev 3702)
@@ -720,6 +720,27 @@
extern GEOSGeometry GEOS_DLL *GEOSSnap_r(GEOSContextHandle_t handle,
const GEOSGeometry* g1, const GEOSGeometry* g2, double tolerance);
+/*
+ * Return a Delaunay triangulation of the vertex of the given geometry
+ *
+ * @param g the input geometry whose vertex will be used as "sites"
+ * @param tolerance optional snapping tolerance to use for improved robustness
+ * @param onlyEdges if non-zero will return a MULTILINESTRING, otherwise it will
+ * return a GEOMETRYCOLLECTION containing triangular POLYGONs.
+ *
+ * @return a newly allocated geometry, or NULL on exception
+ */
+extern GEOSGeometry GEOS_DLL * GEOSDelaunayTriangulation(
+ const GEOSGeometry *g,
+ double tolerance,
+ int onlyEdges );
+
+extern GEOSGeometry GEOS_DLL * GEOSDelaunayTriangulation_r(
+ GEOSContextHandle_t handle,
+ const GEOSGeometry *g,
+ double tolerance,
+ int onlyEdges );
+
/************************************************************************
*
* Binary predicates - return 2 on exception, 1 on true, 0 on false
Modified: trunk/capi/geos_ts_c.cpp
===================================================================
--- trunk/capi/geos_ts_c.cpp 2012-06-27 10:43:19 UTC (rev 3701)
+++ trunk/capi/geos_ts_c.cpp 2012-06-27 10:43:33 UTC (rev 3702)
@@ -3,7 +3,7 @@
*
* C-Wrapper for GEOS library
*
- * Copyright (C) 2010 2011 Sandro Santilli <strk at keybit.net>
+ * Copyright (C) 2010-2012 Sandro Santilli <strk at keybit.net>
* Copyright (C) 2005-2006 Refractions Research Inc.
*
* This is free software; you can redistribute and/or modify it under
@@ -58,6 +58,7 @@
#include <geos/operation/relate/RelateOp.h>
#include <geos/operation/sharedpaths/SharedPathsOp.h>
#include <geos/linearref/LengthIndexedLine.h>
+#include <geos/triangulate/DelaunayTriangulationBuilder.h>
#include <geos/util/IllegalArgumentException.h>
#include <geos/util/Interrupt.h>
#include <geos/util/UniqueCoordinateArrayFilter.h>
@@ -6137,5 +6138,38 @@
return NULL;
}
+Geometry *
+GEOSDelaunayTriangulation_r(GEOSContextHandle_t extHandle, const Geometry *g1, double tolerance, int onlyEdges)
+{
+ if ( 0 == extHandle ) return NULL;
+
+ GEOSContextHandleInternal_t *handle = 0;
+ handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+ if ( 0 == handle->initialized ) return NULL;
+
+ using geos::triangulate::DelaunayTriangulationBuilder;
+
+ try
+ {
+ DelaunayTriangulationBuilder builder;
+ builder.setTolerance(tolerance);
+ builder.setSites(*g1);
+
+ if ( onlyEdges ) return builder.getEdges( *g1->getFactory() ).release();
+ else return builder.getTriangles( *g1->getFactory() ).release();
+
+ }
+ catch (const std::exception &e)
+ {
+ handle->ERROR_MESSAGE("%s", e.what());
+ }
+ catch (...)
+ {
+ handle->ERROR_MESSAGE("Unknown exception thrown");
+ }
+
+ return NULL;
+}
+
} /* extern "C" */
Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am 2012-06-27 10:43:19 UTC (rev 3701)
+++ trunk/tests/unit/Makefile.am 2012-06-27 10:43:33 UTC (rev 3702)
@@ -105,6 +105,7 @@
triangulate/DelaunayTest.cpp \
util/UniqueCoordinateArrayFilterTest.cpp \
capi/GEOSCoordSeqTest.cpp \
+ capi/GEOSDelaunayTriangulationTest.cpp \
capi/GEOSGeomFromWKBTest.cpp \
capi/GEOSGeomToWKTTest.cpp \
capi/GEOSGetCentroidTest.cpp \
Added: trunk/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp
===================================================================
--- trunk/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp (rev 0)
+++ trunk/tests/unit/capi/GEOSDelaunayTriangulationTest.cpp 2012-06-27 10:43:33 UTC (rev 3702)
@@ -0,0 +1,174 @@
+//
+// Test Suite for C-API GEOSDelaunayTriangulation
+
+#include <tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+
+namespace tut
+{
+ //
+ // Test Group
+ //
+
+ // Common data used in test cases.
+ struct test_capigeosdelaunaytriangulation_data
+ {
+ GEOSGeometry* geom1_;
+ GEOSGeometry* geom2_;
+ GEOSWKTWriter* w_;
+
+ 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_capigeosdelaunaytriangulation_data()
+ : geom1_(0), geom2_(0)
+ {
+ initGEOS(notice, notice);
+ w_ = GEOSWKTWriter_create();
+ GEOSWKTWriter_setTrim(w_, 1);
+ }
+
+ void ensure_equals_wkt(GEOSGeometry* g, const std::string& exp)
+ {
+ GEOSNormalize(g);
+ char* wkt_c = GEOSWKTWriter_write(w_, g);
+ std::string out(wkt_c);
+ free(wkt_c);
+ ensure_equals(out, exp);
+ }
+
+ ~test_capigeosdelaunaytriangulation_data()
+ {
+ GEOSGeom_destroy(geom1_);
+ GEOSGeom_destroy(geom2_);
+ GEOSWKTWriter_destroy(w_);
+ geom1_ = 0;
+ geom2_ = 0;
+ finishGEOS();
+ }
+
+ };
+
+ typedef test_group<test_capigeosdelaunaytriangulation_data> group;
+ typedef group::object object;
+
+ group test_capigeosdelaunaytriangulation_group("capi::GEOSDelaunayTriangulation");
+
+ //
+ // Test Cases
+ //
+
+ // Empty polygon
+ template<>
+ template<>
+ void object::test<1>()
+ {
+ geom1_ = GEOSGeomFromWKT("POLYGON EMPTY");
+
+ ensure_equals ( GEOSisEmpty(geom1_), 1 );
+
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+ ensure_equals ( GEOSisEmpty(geom2_), 1 );
+ ensure_equals ( GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION );
+
+ GEOSGeom_destroy(geom2_);
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
+ ensure_equals ( GEOSisEmpty(geom2_), 1 );
+ ensure_equals ( GEOSGeomTypeId(geom2_), GEOS_MULTILINESTRING );
+
+
+ }
+
+ // Single point
+ template<>
+ template<>
+ void object::test<2>()
+ {
+ geom1_ = GEOSGeomFromWKT("POINT(0 0)");
+
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+ ensure_equals ( GEOSisEmpty(geom2_), 1 );
+ ensure_equals ( GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION );
+
+ GEOSGeom_destroy(geom2_);
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
+ ensure_equals ( GEOSisEmpty(geom2_), 1 );
+ ensure_equals ( GEOSGeomTypeId(geom2_), GEOS_MULTILINESTRING );
+ }
+
+ // Three collinear points
+ template<>
+ template<>
+ void object::test<3>()
+ {
+ geom1_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 5 0, 10 0)");
+
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+ ensure_equals ( GEOSisEmpty(geom2_), 1 );
+ ensure_equals ( GEOSGeomTypeId(geom2_), GEOS_GEOMETRYCOLLECTION );
+
+ GEOSGeom_destroy(geom2_);
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
+ char* wkt_c = GEOSWKTWriter_write(w_, geom2_);
+ std::string out(wkt_c);
+ free(wkt_c);
+ ensure_equals(out, "MULTILINESTRING ((5 0, 10 0), (0 0, 5 0))");
+ }
+
+ // Three points
+ template<>
+ template<>
+ void object::test<4>()
+ {
+ geom1_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 5 0, 10 10)");
+
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+ ensure(geom2_ != 0);
+ ensure_equals_wkt(geom2_,
+ "GEOMETRYCOLLECTION (POLYGON ((0 0, 10 10, 5 0, 0 0)))"
+ );
+
+ GEOSGeom_destroy(geom2_);
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
+ ensure_equals_wkt(geom2_,
+ "MULTILINESTRING ((5 0, 10 10), (0 0, 10 10), (0 0, 5 0))"
+ );
+ }
+
+ // A polygon with an hole
+ template<>
+ template<>
+ void object::test<5>()
+ {
+ geom1_ = GEOSGeomFromWKT("POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2)))");
+
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 0);
+ ensure(geom2_ != 0);
+ ensure_equals_wkt(geom2_,
+"GEOMETRYCOLLECTION (POLYGON ((8 2, 10 10, 8.5 1, 8 2)), POLYGON ((7 8, 10 10, 8 2, 7 8)), POLYGON ((3 8, 10 10, 7 8, 3 8)), POLYGON ((2 2, 8 2, 8.5 1, 2 2)), POLYGON ((2 2, 7 8, 8 2, 2 2)), POLYGON ((2 2, 3 8, 7 8, 2 2)), POLYGON ((0.5 9, 10 10, 3 8, 0.5 9)), POLYGON ((0.5 9, 3 8, 2 2, 0.5 9)), POLYGON ((0 0, 2 2, 8.5 1, 0 0)), POLYGON ((0 0, 0.5 9, 2 2, 0 0)))"
+ );
+
+ GEOSGeom_destroy(geom2_);
+ geom2_ = GEOSDelaunayTriangulation(geom1_, 0, 1);
+ ensure_equals_wkt(geom2_,
+"MULTILINESTRING ((8.5 1, 10 10), (8 2, 10 10), (8 2, 8.5 1), (7 8, 10 10), (7 8, 8 2), (3 8, 10 10), (3 8, 7 8), (2 2, 8.5 1), (2 2, 8 2), (2 2, 7 8), (2 2, 3 8), (0.5 9, 10 10), (0.5 9, 3 8), (0.5 9, 2 2), (0 0, 8.5 1), (0 0, 2 2), (0 0, 0.5 9))"
+ );
+ }
+
+} // namespace tut
+
More information about the geos-commits
mailing list