[geos-commits] r3219 - in trunk: . capi tests/unit tests/unit/capi

svn_geos at osgeo.org svn_geos at osgeo.org
Tue Feb 15 10:15:09 EST 2011


Author: strk
Date: 2011-02-15 07:15:09 -0800 (Tue, 15 Feb 2011)
New Revision: 3219

Added:
   trunk/tests/unit/capi/GEOSisValidDetailTest.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:
Add a 'flags' parameter to GEOSisValidDetail.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2011-02-15 15:14:58 UTC (rev 3218)
+++ trunk/NEWS	2011-02-15 15:15:09 UTC (rev 3219)
@@ -3,7 +3,8 @@
 
 - New things:
   - CAPI: GEOSUnaryUnion
-  - CAPI: GEOSisValidDetail: tell state, reason & location apart
+  - CAPI: GEOSisValidDetail: tell state, reason & location apart. allows
+          passing flags.
   - CAPI: GEOSContext_setNoticeHandler_r, GEOSContext_setErrorHandler_r
   - CAPI: GEOSGeom_createEmptyPoint, GEOSGeom_createEmptyLineString
           GEOSGeom_createEmptyPolygon, GEOSGeom_createEmptyCollection

Modified: trunk/capi/geos_c.cpp
===================================================================
--- trunk/capi/geos_c.cpp	2011-02-15 15:14:58 UTC (rev 3218)
+++ trunk/capi/geos_c.cpp	2011-02-15 15:15:09 UTC (rev 3219)
@@ -209,10 +209,10 @@
 }
 
 char
-GEOSisValidDetail(const Geometry *g,
+GEOSisValidDetail(const Geometry *g, int flags,
 	char** reason, Geometry ** location)
 {
-    return GEOSisValidDetail_r( handle, g, reason, location );
+    return GEOSisValidDetail_r( handle, g, flags, reason, location );
 }
 
 //-----------------------------------------------------------------

Modified: trunk/capi/geos_c.h.in
===================================================================
--- trunk/capi/geos_c.h.in	2011-02-15 15:14:58 UTC (rev 3218)
+++ trunk/capi/geos_c.h.in	2011-02-15 15:15:09 UTC (rev 3219)
@@ -778,12 +778,6 @@
  ***********************************************************************/
 
 extern char GEOS_DLL GEOSisEmpty(const GEOSGeometry* g1);
-extern char GEOS_DLL GEOSisValid(const GEOSGeometry* g1);
-extern char GEOS_DLL *GEOSisValidReason(const GEOSGeometry *g1);
-/* caller has the responsibility to destroy 'reason' (GEOSFree)
- * and 'location' (GEOSGeom_destroy) Sparams */
-extern char GEOS_DLL GEOSisValidDetail(const GEOSGeometry* g, char** reason,
-                                         GEOSGeometry** location);
 extern char GEOS_DLL GEOSisSimple(const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSisRing(const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSHasZ(const GEOSGeometry* g1);
@@ -791,15 +785,6 @@
 
 extern char GEOS_DLL GEOSisEmpty_r(GEOSContextHandle_t handle,
                                    const GEOSGeometry* g1);
-extern char GEOS_DLL GEOSisValid_r(GEOSContextHandle_t handle,
-                                   const GEOSGeometry* g1);
-extern char GEOS_DLL *GEOSisValidReason_r(GEOSContextHandle_t handle,
-                                         const GEOSGeometry* g1);
-/* caller has the responsibility to destroy 'reason' (GEOSFree_r)
- * and 'location' (GEOSGeom_destroy_r) Sparams */
-extern char GEOS_DLL GEOSisValidDetail_r(GEOSContextHandle_t handle,
-                                         const GEOSGeometry* g, char** reason,
-                                         GEOSGeometry** location);
 extern char GEOS_DLL GEOSisSimple_r(GEOSContextHandle_t handle,
                                     const GEOSGeometry* g1);
 extern char GEOS_DLL GEOSisRing_r(GEOSContextHandle_t handle,
@@ -811,6 +796,41 @@
 
 /************************************************************************
  *
+ *  Validity checking
+ *
+ ***********************************************************************/
+
+/* These are for use with GEOSisValidDetail (flags param) */
+enum GEOSValidFlags {
+	GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE=1
+};
+
+/* return 2 on exception, 1 on true, 0 on false */
+extern char GEOS_DLL GEOSisValid(const GEOSGeometry* g1);
+extern char GEOS_DLL GEOSisValid_r(GEOSContextHandle_t handle,
+                                   const GEOSGeometry* g1);
+
+/* return NULL on exception, a string to GEOSFree otherwise */
+extern char GEOS_DLL *GEOSisValidReason(const GEOSGeometry *g1);
+extern char GEOS_DLL *GEOSisValidReason_r(GEOSContextHandle_t handle,
+                                         const GEOSGeometry* g1);
+
+/*
+ * Caller has the responsibility to destroy 'reason' (GEOSFree)
+ * and 'location' (GEOSGeom_destroy) params
+ * return 2 on exception, 1 when valid, 0 when invalid
+ */
+extern char GEOS_DLL GEOSisValidDetail(const GEOSGeometry* g,
+                                       int flags,
+                                       char** reason, GEOSGeometry** location);
+extern char GEOS_DLL GEOSisValidDetail_r(GEOSContextHandle_t handle,
+                                         const GEOSGeometry* g,
+                                         int flags,
+                                         char** reason,
+                                         GEOSGeometry** location);
+
+/************************************************************************
+ *
  *  Geometry info
  *
  ***********************************************************************/

Modified: trunk/capi/geos_ts_c.cpp
===================================================================
--- trunk/capi/geos_ts_c.cpp	2011-02-15 15:14:58 UTC (rev 3218)
+++ trunk/capi/geos_ts_c.cpp	2011-02-15 15:15:09 UTC (rev 3219)
@@ -715,7 +715,7 @@
 
 char
 GEOSisValidDetail_r(GEOSContextHandle_t extHandle, const Geometry *g,
-	char** reason, Geometry ** location)
+	int flags, char** reason, Geometry ** location)
 {
     if ( 0 == extHandle )
     {
@@ -735,6 +735,9 @@
         using geos::operation::valid::TopologyValidationError;
 
         IsValidOp ivo(g);
+        if ( flags && GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE ) {
+        	ivo.setSelfTouchingRingFormingHoleValid(true);
+        }
         TopologyValidationError *err = ivo.getValidationError();
         if (0 != err)
         {

Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am	2011-02-15 15:14:58 UTC (rev 3218)
+++ trunk/tests/unit/Makefile.am	2011-02-15 15:15:09 UTC (rev 3219)
@@ -105,7 +105,8 @@
 	capi/GEOSSnapTest.cpp \
 	capi/GEOSSharedPathsTest.cpp \
 	capi/GEOSRelatePatternMatchTest.cpp \
-	capi/GEOSUnaryUnionTest.cpp
+	capi/GEOSUnaryUnionTest.cpp \
+	capi/GEOSisValidDetailTest.cpp
 
 noinst_HEADERS = \
 	utility.h

Added: trunk/tests/unit/capi/GEOSisValidDetailTest.cpp
===================================================================
--- trunk/tests/unit/capi/GEOSisValidDetailTest.cpp	                        (rev 0)
+++ trunk/tests/unit/capi/GEOSisValidDetailTest.cpp	2011-02-15 15:15:09 UTC (rev 3219)
@@ -0,0 +1,139 @@
+// $Id$
+// 
+// Test Suite for C-API GEOSisValidDetail
+
+#include <tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+namespace tut
+{
+    //
+    // Test Group
+    //
+
+    // Common data used in test cases.
+    struct test_capiisvaliddetail_data
+    {
+        GEOSWKTWriter* wktw_;
+        GEOSGeometry* geom_;
+        GEOSGeometry* loc_;
+        char* reason_;
+
+        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_capiisvaliddetail_data()
+            : geom_(0), loc_(0), reason_(0)
+        {
+            initGEOS(notice, notice);
+            wktw_ = GEOSWKTWriter_create();
+            GEOSWKTWriter_setTrim(wktw_, 1);
+            GEOSWKTWriter_setOutputDimension(wktw_, 3);
+        }       
+
+        std::string toWKT(GEOSGeometry* g)
+        {
+          char* wkt = GEOSWKTWriter_write(wktw_, g);
+          std::string ret (wkt);
+          GEOSFree(wkt);
+          return ret;
+        }
+
+        ~test_capiisvaliddetail_data()
+        {
+            GEOSGeom_destroy(geom_);
+            GEOSGeom_destroy(loc_);
+            GEOSFree(reason_);
+            GEOSWKTWriter_destroy(wktw_);
+            finishGEOS();
+        }
+
+    };
+
+    typedef test_group<test_capiisvaliddetail_data> group;
+    typedef group::object object;
+
+    group test_capiisvaliddetail_group("capi::GEOSisValidDetail");
+
+    //
+    // Test Cases
+    //
+
+
+    // Flag values
+    template<>
+    template<>
+    void object::test<1>()
+    {
+      ensure_equals(GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE, 1);
+    }
+
+    // Valid case
+    template<>
+    template<>
+    void object::test<2>()
+    {
+      // Looks invalid (self-intersecting) but isn't
+      // (is non-simple though)
+      geom_ = GEOSGeomFromWKT("LINESTRING(0 0, 10 0, 5 -5, 5 5)");
+      int r = GEOSisValidDetail(geom_, 0, &reason_, &loc_);
+      ensure_equals(r, 1); // valid
+      ensure_equals(reason_, (void*)0);
+      ensure_equals(loc_, (void*)0);
+    }
+
+    // Invalid coordinate
+    template<>
+    template<>
+    void object::test<3>()
+    {
+      geom_ = GEOSGeomFromWKT("LINESTRING(0 0, 10 0, NaN -5)");
+      int r = GEOSisValidDetail(geom_, 0, &reason_, &loc_);
+      ensure_equals(r, 0); // valid
+      ensure_equals(std::string(reason_), std::string("Invalid Coordinate"));
+      ensure_equals(toWKT(loc_), "POINT (nan -5)");
+    }
+
+    // Self intersecting ring forming hole
+    template<>
+    template<>
+    void object::test<4>()
+    {
+      geom_ = GEOSGeomFromWKT("POLYGON((0 1, -10 10, 10 10, 0 1, 4 6, -4 6, 0 1))");
+      int r = GEOSisValidDetail(geom_, 0, &reason_, &loc_);
+      ensure_equals(r, 0); // valid
+      ensure_equals(std::string(reason_), std::string("Ring Self-intersection"));
+      ensure_equals(toWKT(loc_), "POINT (0 1)");
+    }
+
+    // Self intersecting ring forming hole (with ESRI flag)
+    template<>
+    template<>
+    void object::test<5>()
+    {
+      geom_ = GEOSGeomFromWKT("POLYGON((0 1, -10 10, 10 10, 0 1, 4 6, -4 6, 0 1))");
+      int flags = GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE;
+
+      int r = GEOSisValidDetail(geom_, flags, &reason_, &loc_);
+      ensure_equals(r, 1); // valid
+      ensure_equals(reason_, (void*)0);
+      ensure_equals(loc_, (void*)0);
+    }
+
+} // namespace tut
+



More information about the geos-commits mailing list