[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