[geos-commits] r3446 - in branches/3.2: source/algorithm tests/unit tests/unit/capi

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Jul 20 17:11:15 EDT 2011


Author: strk
Date: 2011-07-20 14:11:15 -0700 (Wed, 20 Jul 2011)
New Revision: 3446

Added:
   branches/3.2/tests/unit/capi/GEOSIntersectsTest.cpp
Modified:
   branches/3.2/source/algorithm/RobustDeterminant.cpp
   branches/3.2/tests/unit/Makefile.am
Log:
RobustDeterminant is not robust (#450)


Modified: branches/3.2/source/algorithm/RobustDeterminant.cpp
===================================================================
--- branches/3.2/source/algorithm/RobustDeterminant.cpp	2011-07-20 20:48:07 UTC (rev 3445)
+++ branches/3.2/source/algorithm/RobustDeterminant.cpp	2011-07-20 21:11:15 UTC (rev 3446)
@@ -20,9 +20,12 @@
  **********************************************************************/
 
 #include <geos/algorithm/RobustDeterminant.h>
+#include <geos/util/IllegalArgumentException.h> 
 
 #include <cmath>
 
+#include <geos/platform.h> // for ISNAN, FINITE
+
 #ifdef _MSC_VER
 #pragma warning(disable : 4127)
 #endif
@@ -32,6 +35,16 @@
 
 
 int RobustDeterminant::signOfDet2x2(double x1,double y1,double x2,double y2) {
+
+	using namespace std;
+
+  // Protect against non-finite numbers
+  if ( ISNAN(x1)   || ISNAN(y1)   || ISNAN(x2)   || ISNAN(y2) ||
+       !FINITE(x1) || !FINITE(y1) || !FINITE(x2) || !FINITE(y2) )
+  {
+    throw util::IllegalArgumentException("RobustDeterminant encountered non-finite numbers ");
+  }
+
 	// returns -1 if the determinant is negative,
 	// returns  1 if the determinant is positive,
 	// retunrs  0 if the determinant is null.

Modified: branches/3.2/tests/unit/Makefile.am
===================================================================
--- branches/3.2/tests/unit/Makefile.am	2011-07-20 20:48:07 UTC (rev 3445)
+++ branches/3.2/tests/unit/Makefile.am	2011-07-20 21:11:15 UTC (rev 3446)
@@ -86,6 +86,7 @@
 	capi/GEOSGeomFromWKBTest.cpp \
 	capi/GEOSGeomToWKTTest.cpp \
 	capi/GEOSContainsTest.cpp \
+	capi/GEOSIntersectsTest.cpp \
 	capi/GEOSWithinTest.cpp \
 	capi/GEOSSimplifyTest.cpp \
 	capi/GEOSPreparedGeometryTest.cpp \

Added: branches/3.2/tests/unit/capi/GEOSIntersectsTest.cpp
===================================================================
--- branches/3.2/tests/unit/capi/GEOSIntersectsTest.cpp	                        (rev 0)
+++ branches/3.2/tests/unit/capi/GEOSIntersectsTest.cpp	2011-07-20 21:11:15 UTC (rev 3446)
@@ -0,0 +1,163 @@
+// $Id$
+// 
+// Test Suite for C-API GEOSIntersects
+
+#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_capigeosintersects_data
+    {
+        GEOSGeometry* geom1_;
+        GEOSGeometry* geom2_;
+
+        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_capigeosintersects_data()
+            : geom1_(0), geom2_(0)
+        {
+            initGEOS(notice, notice);
+        }       
+
+        ~test_capigeosintersects_data()
+        {
+            GEOSGeom_destroy(geom1_);
+            GEOSGeom_destroy(geom2_);
+            geom1_ = 0;
+            geom2_ = 0;
+            finishGEOS();
+        }
+
+    };
+
+    typedef test_group<test_capigeosintersects_data> group;
+    typedef group::object object;
+
+    group test_capigeosintersects_group("capi::GEOSIntersects");
+
+    //
+    // Test Cases
+    //
+
+    template<>
+    template<>
+    void object::test<1>()
+    {
+        geom1_ = GEOSGeomFromWKT("POLYGON EMPTY");
+        geom2_ = GEOSGeomFromWKT("POLYGON EMPTY");
+
+        ensure( 0 != geom1_ );
+        ensure( 0 != geom2_ );
+
+        char const r1 = GEOSIntersects(geom1_, geom2_);
+
+        ensure_equals(r1, 0);
+
+        char const r2 = GEOSIntersects(geom2_, geom1_);
+
+        ensure_equals(r2, 0);
+    }
+
+    template<>
+    template<>
+    void object::test<2>()
+    {
+        geom1_ = GEOSGeomFromWKT("POLYGON((1 1,1 5,5 5,5 1,1 1))");
+        geom2_ = GEOSGeomFromWKT("POINT(2 2)");
+        
+        ensure( 0 != geom1_ );
+        ensure( 0 != geom2_ );
+
+        char const r1 = GEOSIntersects(geom1_, geom2_);
+
+        ensure_equals(int(r1), 1);
+
+        char const r2 = GEOSIntersects(geom2_, geom1_);
+
+        ensure_equals(int(r2), 1);
+    }
+    
+    template<>
+    template<>
+    void object::test<3>()
+    {
+        geom1_ = GEOSGeomFromWKT("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))");
+        geom2_ = GEOSGeomFromWKT("POLYGON((1 1,1 2,2 2,2 1,1 1))");
+        
+        ensure( 0 != geom1_ );
+        ensure( 0 != geom2_ );
+
+        char const r1 = GEOSIntersects(geom1_, geom2_);
+
+        ensure_equals(int(r1), 1);
+        
+        char const r2 = GEOSIntersects(geom2_, geom1_);
+
+        ensure_equals(int(r2), 1);
+    }
+
+    // This is a test for bug #357 (GEOSIntersects with nan coords)
+    template<>
+    template<>
+    void object::test<4>()
+    {
+        GEOSCoordSequence* cs = GEOSCoordSeq_create(5, 2);
+
+        double nan = std::numeric_limits<double>::quiet_NaN();        
+        GEOSCoordSeq_setX(cs, 0, 1); GEOSCoordSeq_setY(cs, 0, 1);
+        for (unsigned int i=1; i<4; ++i) {
+            GEOSCoordSeq_setX(cs, i, nan);
+            GEOSCoordSeq_setY(cs, i, nan);
+        }
+        GEOSCoordSeq_setX(cs, 4, 1); GEOSCoordSeq_setY(cs, 4, 1);
+
+        geom1_ = GEOSGeom_createPolygon(GEOSGeom_createLinearRing(cs),
+                                        NULL, 0);
+
+        char const r1 = GEOSIntersects(geom1_, geom1_);
+
+        ensure_equals(int(r1), 2);
+        
+    }
+
+    // This is a test for bug #357 (GEOSIntersects with inf coords)
+    template<>
+    template<>
+    void object::test<5>()
+    {
+        const char *hex = "0103000020E61000000100000005000000737979F3DDCC2CC0F92154F9E7534540000000000000F07F000000000000F07F8F806E993F7E55C0304B29FFEA8554400634E8D1DD424540B5FEE6A37FCD4540737979F3DDCC2CC0F92154F9E7534540";
+
+        geom1_ = GEOSGeomFromHEX_buf((unsigned char*)hex, std::strlen(hex));
+        
+        ensure( 0 != geom1_ );
+
+        char const r1 = GEOSIntersects(geom1_, geom1_);
+
+        ensure_equals(int(r1), 2);
+        
+    }
+ 
+} // namespace tut
+



More information about the geos-commits mailing list