[geos-commits] r4039 - in branches/3.4: . include/geos/algorithm src/algorithm swig/python tests/xmltester tests/xmltester/tests/ticket

svn_geos at osgeo.org svn_geos at osgeo.org
Mon Jan 19 02:59:18 PST 2015


Author: strk
Date: 2015-01-19 02:59:17 -0800 (Mon, 19 Jan 2015)
New Revision: 4039

Added:
   branches/3.4/tests/xmltester/tests/ticket/bug716.xml
Modified:
   branches/3.4/NEWS
   branches/3.4/include/geos/algorithm/RayCrossingCounter.h
   branches/3.4/src/algorithm/CGAlgorithms.cpp
   branches/3.4/src/algorithm/RayCrossingCounter.cpp
   branches/3.4/swig/python/geos.py
   branches/3.4/swig/python/geos_wrap.cxx
   branches/3.4/tests/xmltester/Makefile.am
Log:
Improve robustness of intersection testing (#716)

RayCrossingCounter uses orientationIndex to handle floating point
precision errors the same way as LineIntersector.

Includes testcase for ticket #716 with CW and CCW polygons

Patch by Asmund Tokheim <tokheim at outlook.com>

Modified: branches/3.4/NEWS
===================================================================
--- branches/3.4/NEWS	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/NEWS	2015-01-19 10:59:17 UTC (rev 4039)
@@ -2,6 +2,7 @@
 YYYY-MM-DD
 
 - Bug fixes / improvements
+ - Improve robustness of intersection testing (#716)
  - Fixed compilation against thread-safe PHP (#541)
  - Fix Empty to Empty equals (#703)
  - Fix build on OpenBSD (#700)

Modified: branches/3.4/include/geos/algorithm/RayCrossingCounter.h
===================================================================
--- branches/3.4/include/geos/algorithm/RayCrossingCounter.h	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/include/geos/algorithm/RayCrossingCounter.h	2015-01-19 10:59:17 UTC (rev 4039)
@@ -93,6 +93,22 @@
 	static int locatePointInRing(const geom::Coordinate& p,
 	         const std::vector<const geom::Coordinate*>& ring);
 
+	/** \brief
+	 * Returns the index of the direction of the point <code>q</code>
+	 * relative to a vector specified by <code>p1-p2</code>.
+	 *
+	 * @param p1 the origin point of the vector
+	 * @param p2 the final point of the vector
+	 * @param q the point to compute the direction to
+	 *
+	 * @return 1 if q is counter-clockwise (left) from p1-p2
+	 * @return -1 if q is clockwise (right) from p1-p2
+	 * @return 0 if q is collinear with p1-p2
+	 */
+	static int orientationIndex(const geom::Coordinate& p1,
+	         const geom::Coordinate& p2,
+	         const geom::Coordinate& q);
+
 	RayCrossingCounter(const geom::Coordinate& point)
 	:	point( point),
 		crossingCount( 0),

Modified: branches/3.4/src/algorithm/CGAlgorithms.cpp
===================================================================
--- branches/3.4/src/algorithm/CGAlgorithms.cpp	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/src/algorithm/CGAlgorithms.cpp	2015-01-19 10:59:17 UTC (rev 4039)
@@ -42,14 +42,7 @@
 int
 CGAlgorithms::orientationIndex(const Coordinate& p1,const Coordinate& p2,const Coordinate& q)
 {
-	// travelling along p1->p2, turn counter clockwise to get to q return 1,
-	// travelling along p1->p2, turn clockwise to get to q return -1,
-	// p1, p2 and q are colinear return 0.
-	double dx1=p2.x-p1.x;
-	double dy1=p2.y-p1.y;
-	double dx2=q.x-p2.x;
-	double dy2=q.y-p2.y;
-	return RobustDeterminant::signOfDet2x2(dx1,dy1,dx2,dy2);
+	return RayCrossingCounter::orientationIndex(p1, p2, q);
 }
 
 /*public static*/

Modified: branches/3.4/src/algorithm/RayCrossingCounter.cpp
===================================================================
--- branches/3.4/src/algorithm/RayCrossingCounter.cpp	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/src/algorithm/RayCrossingCounter.cpp	2015-01-19 10:59:17 UTC (rev 4039)
@@ -45,8 +45,8 @@
 
 	for (std::size_t i = 1, ni = ring.size(); i < ni; i++) 
 	{
-		const geom::Coordinate & p1 = ring[ i ];
-		const geom::Coordinate & p2 = ring[ i - 1 ];
+		const geom::Coordinate & p1 = ring[ i - 1 ];
+		const geom::Coordinate & p2 = ring[ i ];
 
 		rcc.countSegment(p1, p2);
 
@@ -64,8 +64,8 @@
 
 	for (std::size_t i = 1, ni = ring.size(); i < ni; i++) 
 	{
-		const geom::Coordinate & p1 = *ring[ i ];
-		const geom::Coordinate & p2 = *ring[ i - 1 ];
+		const geom::Coordinate & p1 = *ring[ i - 1 ];
+		const geom::Coordinate & p2 = *ring[ i ];
 
 		rcc.countSegment(p1, p2);
 
@@ -75,6 +75,20 @@
 	return rcc.getLocation();
 }
 
+/*public static*/
+int
+RayCrossingCounter::orientationIndex(const geom::Coordinate& p1,
+         const geom::Coordinate& p2, const geom::Coordinate& q)
+{
+	// travelling along p1->p2, turn counter clockwise to get to q return 1,
+	// travelling along p1->p2, turn clockwise to get to q return -1,
+	// p1, p2 and q are colinear return 0.
+	double dx1=p2.x-p1.x;
+	double dy1=p2.y-p1.y;
+	double dx2=q.x-p2.x;
+	double dy2=q.y-p2.y;
+	return RobustDeterminant::signOfDet2x2(dx1,dy1,dx2,dy2);
+}
 
 void 
 RayCrossingCounter::countSegment(const geom::Coordinate& p1,
@@ -124,30 +138,20 @@
 	if (((p1.y > point.y) && (p2.y <= point.y)) ||
 		((p2.y > point.y) && (p1.y <= point.y)) ) 
 	{
-		// translate the segment so that the test point lies
-		// on the origin
-		double x1 = p1.x - point.x;
-		double y1 = p1.y - point.y;
-		double x2 = p2.x - point.x;
-		double y2 = p2.y - point.y;
-
-		// The translated segment straddles the x-axis.
-		// Compute the sign of the ordinate of intersection
-		// with the x-axis. (y2 != y1, so denominator
-		// will never be 0.0)
-                        // MD - faster & more robust computation?
-                double xIntSign = RobustDeterminant::signOfDet2x2(x1, y1, x2, y2);
-		if (xIntSign == 0.0) 
+		// For an upward edge, orientationIndex will be positive when p1->p2
+		// crosses ray. Conversely, downward edges should have negative sign.
+		int sign = orientationIndex(p1, p2, point);
+		if (sign == 0)
 		{
 			isPointOnSegment = true;
 			return;
 		}
 
-		if (y2 < y1)
-			xIntSign = -xIntSign;
+		if (p2.y < p1.y)
+			sign = -sign;
 
 		// The segment crosses the ray if the sign is strictly positive.
-		if (xIntSign > 0.0) 
+		if (sign > 0)
 			crossingCount++;
 	}
 }

Modified: branches/3.4/swig/python/geos.py
===================================================================
--- branches/3.4/swig/python/geos.py	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/swig/python/geos.py	2015-01-19 10:59:17 UTC (rev 4039)
@@ -1,11 +1,13 @@
 # This file was automatically generated by SWIG (http://www.swig.org).
-# Version 2.0.4
+# Version 2.0.11
 #
 # Do not make changes to this file unless you know what you are doing--modify
 # the SWIG interface file instead.
 
 
 
+
+
 from sys import version_info
 if version_info >= (2,6,0):
     def swig_import_helper():
@@ -84,8 +86,8 @@
     __swig_destroy__ = _geos.delete_SwigPyIterator
     __del__ = lambda self : None;
     def value(self): return _geos.SwigPyIterator_value(self)
-    def incr(self, n = 1): return _geos.SwigPyIterator_incr(self, n)
-    def decr(self, n = 1): return _geos.SwigPyIterator_decr(self, n)
+    def incr(self, n=1): return _geos.SwigPyIterator_incr(self, n)
+    def decr(self, n=1): return _geos.SwigPyIterator_decr(self, n)
     def distance(self, *args): return _geos.SwigPyIterator_distance(self, *args)
     def equal(self, *args): return _geos.SwigPyIterator_equal(self, *args)
     def copy(self): return _geos.SwigPyIterator_copy(self)

Modified: branches/3.4/swig/python/geos_wrap.cxx
===================================================================
--- branches/3.4/swig/python/geos_wrap.cxx	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/swig/python/geos_wrap.cxx	2015-01-19 10:59:17 UTC (rev 4039)
@@ -1,11 +1,11 @@
 /* ----------------------------------------------------------------------------
  * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 2.0.4
- * 
- * This file is not intended to be easily readable and contains a number of 
+ * Version 2.0.11
+ *
+ * This file is not intended to be easily readable and contains a number of
  * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG 
- * interface file instead. 
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
  * ----------------------------------------------------------------------------- */
 
 #define SWIGPYTHON
@@ -66,28 +66,28 @@
 #ifndef SWIGUNUSED
 # if defined(__GNUC__)
 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#     define SWIGUNUSED __attribute__ ((__unused__)) 
+#     define SWIGUNUSED __attribute__ ((__unused__))
 #   else
 #     define SWIGUNUSED
 #   endif
 # elif defined(__ICC)
-#   define SWIGUNUSED __attribute__ ((__unused__)) 
+#   define SWIGUNUSED __attribute__ ((__unused__))
 # else
-#   define SWIGUNUSED 
+#   define SWIGUNUSED
 # endif
 #endif
 
 #ifndef SWIG_MSC_UNSUPPRESS_4505
 # if defined(_MSC_VER)
 #   pragma warning(disable : 4505) /* unreferenced local function has been removed */
-# endif 
+# endif
 #endif
 
 #ifndef SWIGUNUSEDPARM
 # ifdef __cplusplus
 #   define SWIGUNUSEDPARM(p)
 # else
-#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
+#   define SWIGUNUSEDPARM(p) p SWIGUNUSED
 # endif
 #endif
 
@@ -130,7 +130,7 @@
 #   define SWIGSTDCALL __stdcall
 # else
 #   define SWIGSTDCALL
-# endif 
+# endif
 #endif
 
 /* Deal with Microsoft's attempt at deprecating C standard runtime functions */
@@ -145,8 +145,14 @@
 
 
 
-/* Python.h has to appear first */
-#include <Python.h>
+#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
+/* Use debug wrappers with the Python release dll */
+# undef _DEBUG
+# include <Python.h>
+# define _DEBUG
+#else
+# include <Python.h>
+#endif
 
 /* -----------------------------------------------------------------------------
  * swigrun.swg
@@ -172,7 +178,7 @@
   You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
   creating a static or dynamic library from the SWIG runtime code.
   In 99.9% of the cases, SWIG just needs to declare them as 'static'.
-  
+
   But only do this if strictly necessary, ie, if you have problems
   with your compiler or suchlike.
 */
@@ -198,16 +204,16 @@
 #define SWIG_POINTER_OWN           0x1
 
 
-/* 
+/*
    Flags/methods for returning states.
-   
-   The SWIG conversion methods, as ConvertPtr, return an integer 
+
+   The SWIG conversion methods, as ConvertPtr, return an integer
    that tells if the conversion was successful or not. And if not,
    an error code can be returned (see swigerrors.swg for the codes).
-   
+
    Use the following macros/flags to set or process the returning
    states.
-   
+
    In old versions of SWIG, code such as the following was usually written:
 
      if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
@@ -240,23 +246,23 @@
     } else {
       // fail code
     }
-    
+
    I.e., now SWIG_ConvertPtr can return new objects and you can
    identify the case and take care of the deallocation. Of course that
    also requires SWIG_ConvertPtr to return new result values, such as
 
-      int SWIG_ConvertPtr(obj, ptr,...) {         
-        if (<obj is ok>) {			       
-          if (<need new object>) {		       
-            *ptr = <ptr to new allocated object>; 
-            return SWIG_NEWOBJ;		       
-          } else {				       
-            *ptr = <ptr to old object>;	       
-            return SWIG_OLDOBJ;		       
-          } 				       
-        } else {				       
-          return SWIG_BADOBJ;		       
-        }					       
+      int SWIG_ConvertPtr(obj, ptr,...) {
+        if (<obj is ok>) {
+          if (<need new object>) {
+            *ptr = <ptr to new allocated object>;
+            return SWIG_NEWOBJ;
+          } else {
+            *ptr = <ptr to old object>;
+            return SWIG_OLDOBJ;
+          }
+        } else {
+          return SWIG_BADOBJ;
+        }
       }
 
    Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
@@ -270,17 +276,17 @@
        int fooi(int);
 
    and you call
- 
+
       food(1)   // cast rank '1'  (1 -> 1.0)
       fooi(1)   // cast rank '0'
 
    just use the SWIG_AddCast()/SWIG_CheckState()
 */
 
-#define SWIG_OK                    (0) 
+#define SWIG_OK                    (0)
 #define SWIG_ERROR                 (-1)
 #define SWIG_IsOK(r)               (r >= 0)
-#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
+#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)
 
 /* The CastRankLimit says how many bits are used for the cast rank */
 #define SWIG_CASTRANKLIMIT         (1 << 8)
@@ -311,14 +317,14 @@
 #  endif
 #  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
 #  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
-SWIGINTERNINLINE int SWIG_AddCast(int r) { 
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
   return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
 }
-SWIGINTERNINLINE int SWIG_CheckState(int r) { 
-  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
 }
 #else /* no cast-rank mode */
-#  define SWIG_AddCast
+#  define SWIG_AddCast(r) (r)
 #  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
 #endif
 
@@ -362,7 +368,7 @@
   void                    *clientdata;		/* Language specific module data */
 } swig_module_info;
 
-/* 
+/*
   Compare two type names skipping the space characters, therefore
   "char*" == "char *" and "Class<int>" == "Class<int >", etc.
 
@@ -382,18 +388,18 @@
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if not equal, 1 if equal
+  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
 */
 SWIGRUNTIME int
-SWIG_TypeEquiv(const char *nb, const char *tb) {
-  int equiv = 0;
+SWIG_TypeCmp(const char *nb, const char *tb) {
+  int equiv = 1;
   const char* te = tb + strlen(tb);
   const char* ne = nb;
-  while (!equiv && *ne) {
+  while (equiv != 0 && *ne) {
     for (nb = ne; *ne; ++ne) {
       if (*ne == '|') break;
     }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
     if (*ne) ++ne;
   }
   return equiv;
@@ -401,24 +407,13 @@
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+  Return 0 if not equal, 1 if equal
 */
 SWIGRUNTIME int
-SWIG_TypeCompare(const char *nb, const char *tb) {
-  int equiv = 0;
-  const char* te = tb + strlen(tb);
-  const char* ne = nb;
-  while (!equiv && *ne) {
-    for (nb = ne; *ne; ++ne) {
-      if (*ne == '|') break;
-    }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
-    if (*ne) ++ne;
-  }
-  return equiv;
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
 }
 
-
 /*
   Check the typename
 */
@@ -446,7 +441,7 @@
   return 0;
 }
 
-/* 
+/*
   Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
 */
 SWIGRUNTIME swig_cast_info *
@@ -481,7 +476,7 @@
   return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
 }
 
-/* 
+/*
    Dynamic pointer casting. Down an inheritance hierarchy
 */
 SWIGRUNTIME swig_type_info *
@@ -525,7 +520,7 @@
     return type->name;
 }
 
-/* 
+/*
    Set the clientdata field for a type
 */
 SWIGRUNTIME void
@@ -533,14 +528,14 @@
   swig_cast_info *cast = ti->cast;
   /* if (ti->clientdata == clientdata) return; */
   ti->clientdata = clientdata;
-  
+
   while (cast) {
     if (!cast->converter) {
       swig_type_info *tc = cast->type;
       if (!tc->clientdata) {
 	SWIG_TypeClientData(tc, clientdata);
       }
-    }    
+    }
     cast = cast->next;
   }
 }
@@ -549,18 +544,18 @@
   SWIG_TypeClientData(ti, clientdata);
   ti->owndata = 1;
 }
-  
+
 /*
   Search for a swig_type_info structure only by mangled name
   Search is a O(log #types)
-  
-  We start searching at module start, and finish searching when start == end.  
+
+  We start searching at module start, and finish searching when start == end.
   Note: if start == end at the beginning of the function, we go all the way around
   the circular list.
 */
 SWIGRUNTIME swig_type_info *
-SWIG_MangledTypeQueryModule(swig_module_info *start, 
-                            swig_module_info *end, 
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+                            swig_module_info *end,
 		            const char *name) {
   swig_module_info *iter = start;
   do {
@@ -569,11 +564,11 @@
       register size_t r = iter->size - 1;
       do {
 	/* since l+r >= 0, we can (>> 1) instead (/ 2) */
-	register size_t i = (l + r) >> 1; 
+	register size_t i = (l + r) >> 1;
 	const char *iname = iter->types[i]->name;
 	if (iname) {
 	  register int compare = strcmp(name, iname);
-	  if (compare == 0) {	    
+	  if (compare == 0) {
 	    return iter->types[i];
 	  } else if (compare < 0) {
 	    if (i) {
@@ -598,14 +593,14 @@
   Search for a swig_type_info structure for either a mangled name or a human readable name.
   It first searches the mangled names of the types, which is a O(log #types)
   If a type is not found it then searches the human readable names, which is O(#types).
-  
-  We start searching at module start, and finish searching when start == end.  
+
+  We start searching at module start, and finish searching when start == end.
   Note: if start == end at the beginning of the function, we go all the way around
   the circular list.
 */
 SWIGRUNTIME swig_type_info *
-SWIG_TypeQueryModule(swig_module_info *start, 
-                     swig_module_info *end, 
+SWIG_TypeQueryModule(swig_module_info *start,
+                     swig_module_info *end,
 		     const char *name) {
   /* STEP 1: Search the name field using binary search */
   swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
@@ -624,12 +619,12 @@
       iter = iter->next;
     } while (iter != end);
   }
-  
+
   /* neither found a match */
   return 0;
 }
 
-/* 
+/*
    Pack binary data into a string
 */
 SWIGRUNTIME char *
@@ -645,7 +640,7 @@
   return c;
 }
 
-/* 
+/*
    Unpack binary data from a string
 */
 SWIGRUNTIME const char *
@@ -659,21 +654,21 @@
       uu = ((d - '0') << 4);
     else if ((d >= 'a') && (d <= 'f'))
       uu = ((d - ('a'-10)) << 4);
-    else 
+    else
       return (char *) 0;
     d = *(c++);
     if ((d >= '0') && (d <= '9'))
       uu |= (d - '0');
     else if ((d >= 'a') && (d <= 'f'))
       uu |= (d - ('a'-10));
-    else 
+    else
       return (char *) 0;
     *u = uu;
   }
   return c;
 }
 
-/* 
+/*
    Pack 'void *' into a string buffer.
 */
 SWIGRUNTIME char *
@@ -733,18 +728,18 @@
 #endif
 
 /*  Errors in SWIG */
-#define  SWIG_UnknownError    	   -1 
-#define  SWIG_IOError        	   -2 
-#define  SWIG_RuntimeError   	   -3 
-#define  SWIG_IndexError     	   -4 
-#define  SWIG_TypeError      	   -5 
-#define  SWIG_DivisionByZero 	   -6 
-#define  SWIG_OverflowError  	   -7 
-#define  SWIG_SyntaxError    	   -8 
-#define  SWIG_ValueError     	   -9 
+#define  SWIG_UnknownError    	   -1
+#define  SWIG_IOError        	   -2
+#define  SWIG_RuntimeError   	   -3
+#define  SWIG_IndexError     	   -4
+#define  SWIG_TypeError      	   -5
+#define  SWIG_DivisionByZero 	   -6
+#define  SWIG_OverflowError  	   -7
+#define  SWIG_SyntaxError    	   -8
+#define  SWIG_ValueError     	   -9
 #define  SWIG_SystemError    	   -10
 #define  SWIG_AttributeError 	   -11
-#define  SWIG_MemoryError    	   -12 
+#define  SWIG_MemoryError    	   -12
 #define  SWIG_NullReferenceError   -13
 
 
@@ -756,6 +751,7 @@
 #define PyInt_Check(x) PyLong_Check(x)
 #define PyInt_AsLong(x) PyLong_AsLong(x)
 #define PyInt_FromLong(x) PyLong_FromLong(x)
+#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
 #define PyString_Check(name) PyBytes_Check(name)
 #define PyString_FromString(x) PyUnicode_FromString(x)
 #define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
@@ -925,6 +921,10 @@
 }
 #endif
 
+#if PY_VERSION_HEX < 0x02050000
+#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
+#endif
+
 #if PY_VERSION_HEX < 0x02040000
 #define Py_VISIT(op)				\
   do { 						\
@@ -1196,7 +1196,7 @@
 
 /* Runtime API */
 
-#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule()
+#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
 #define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
 #define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
 
@@ -1222,7 +1222,7 @@
 SWIGINTERN void 
 SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
   SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-  PyErr_SetString(errtype, (char *) msg);
+  PyErr_SetString(errtype, msg);
   SWIG_PYTHON_THREAD_END_BLOCK;
 }
 
@@ -1241,7 +1241,11 @@
 
 SWIGINTERN void
 SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
+#if PY_VERSION_HEX < 0x02030000
   PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
   Py_DECREF(obj);
   if (public_interface)
     SwigPyBuiltin_AddPublicSymbol(public_interface, name);
@@ -1251,7 +1255,11 @@
 
 SWIGINTERN void
 SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
+#if PY_VERSION_HEX < 0x02030000
   PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
   Py_DECREF(obj);                            
 }
 
@@ -1572,7 +1580,7 @@
 #endif
 {
   const char *name = SWIG_TypePrettyName(v->ty);
-  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", name, (void *)v);
+  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
   if (v->next) {
 # ifdef METH_NOARGS
     PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
@@ -1592,34 +1600,6 @@
 }
 
 SWIGRUNTIME int
-SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
-{
-  char *str;
-#ifdef METH_NOARGS
-  PyObject *repr = SwigPyObject_repr(v);
-#else
-  PyObject *repr = SwigPyObject_repr(v, NULL);
-#endif
-  if (repr) {
-    str = SWIG_Python_str_AsChar(repr); 
-    fputs(str, fp);
-    SWIG_Python_str_DelForPy3(str);
-    Py_DECREF(repr);
-    return 0; 
-  } else {
-    return 1; 
-  }
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_str(SwigPyObject *v)
-{
-  char result[SWIG_BUFFER_SIZE];
-  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
-    SWIG_Python_str_FromChar(result) : 0;
-}
-
-SWIGRUNTIME int
 SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
 {
   void *i = v->ptr;
@@ -1776,8 +1756,10 @@
   PyObject *val = 0;
 #if (PY_VERSION_HEX < 0x02020000)
   if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
+#elif (PY_VERSION_HEX < 0x02050000)
+  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
 #else
-  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
+  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
 #endif
     {
       return NULL;
@@ -1809,7 +1791,7 @@
 static PyMethodDef
 swigobject_methods[] = {
   {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
-  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"aquires ownership of the pointer"},
+  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
   {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
   {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
   {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
@@ -1902,7 +1884,7 @@
       sizeof(SwigPyObject),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
-      (printfunc)SwigPyObject_print,        /* tp_print */
+      0,				    /* tp_print */
 #if PY_VERSION_HEX < 0x02020000
       (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
 #else
@@ -1920,7 +1902,7 @@
       0,                                    /* tp_as_mapping */
       (hashfunc)0,                          /* tp_hash */
       (ternaryfunc)0,                       /* tp_call */
-      (reprfunc)SwigPyObject_str,           /* tp_str */
+      0,				    /* tp_str */
       PyObject_GenericGetAttr,              /* tp_getattro */
       0,                                    /* tp_setattro */
       0,                                    /* tp_as_buffer */
@@ -2297,10 +2279,11 @@
 SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
   int res;
   SwigPyObject *sobj;
+  int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0;
 
   if (!obj)
     return SWIG_ERROR;
-  if (obj == Py_None) {
+  if (obj == Py_None && !implicit_conv) {
     if (ptr)
       *ptr = 0;
     return SWIG_OK;
@@ -2349,7 +2332,7 @@
     }
     res = SWIG_OK;
   } else {
-    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+    if (implicit_conv) {
       SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
       if (data && !data->implicitconv) {
         PyObject *klass = data->klass;
@@ -2384,6 +2367,13 @@
         }
       }
     }
+    if (!SWIG_IsOK(res) && obj == Py_None) {
+      if (ptr)
+        *ptr = 0;
+      if (PyErr_Occurred())
+        PyErr_Clear();
+      res = SWIG_OK;
+    }
   }
   return res;
 }
@@ -2472,23 +2462,29 @@
   } else {
 #if PY_VERSION_HEX >= 0x03000000
     inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
-    PyObject_SetAttr(inst, SWIG_This(), swig_this);
-    Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+    if (inst) {
+      PyObject_SetAttr(inst, SWIG_This(), swig_this);
+      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+    }
 #else
     PyObject *dict = PyDict_New();
-    PyDict_SetItem(dict, SWIG_This(), swig_this);
-    inst = PyInstance_NewRaw(data->newargs, dict);
-    Py_DECREF(dict);
+    if (dict) {
+      PyDict_SetItem(dict, SWIG_This(), swig_this);
+      inst = PyInstance_NewRaw(data->newargs, dict);
+      Py_DECREF(dict);
+    }
 #endif
   }
   return inst;
 #else
 #if (PY_VERSION_HEX >= 0x02010000)
-  PyObject *inst;
+  PyObject *inst = 0;
   PyObject *dict = PyDict_New();
-  PyDict_SetItem(dict, SWIG_This(), swig_this);
-  inst = PyInstance_NewRaw(data->newargs, dict);
-  Py_DECREF(dict);
+  if (dict) {
+    PyDict_SetItem(dict, SWIG_This(), swig_this);
+    inst = PyInstance_NewRaw(data->newargs, dict);
+    Py_DECREF(dict);
+  }
   return (PyObject *) inst;
 #else
   PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
@@ -2539,7 +2535,7 @@
 SWIGINTERN PyObject *
 SWIG_Python_InitShadowInstance(PyObject *args) {
   PyObject *obj[2];
-  if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
     return NULL;
   } else {
     SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
@@ -2595,12 +2591,10 @@
   assert(!(flags & SWIG_BUILTIN_TP_INIT));
 
   robj = SwigPyObject_New(ptr, type, own);
-  if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
     PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
-    if (inst) {
-      Py_DECREF(robj);
-      robj = inst;
-    }
+    Py_DECREF(robj);
+    robj = inst;
   }
   return robj;
 }
@@ -2621,7 +2615,7 @@
 #endif
 
 SWIGRUNTIME swig_module_info *
-SWIG_Python_GetModule(void) {
+SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
   static void *type_pointer = (void *)0;
   /* first check if module already created */
   if (!type_pointer) {
@@ -2747,7 +2741,7 @@
     descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
 #endif
   } else {
-    swig_module_info *swig_module = SWIG_Python_GetModule();
+    swig_module_info *swig_module = SWIG_GetModule(0);
     descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
     if (descriptor) {
 #ifdef SWIGPY_USE_CAPSULE
@@ -2815,7 +2809,7 @@
 {
   SwigPyObject *v = (SwigPyObject *)self;
   swig_type_info *ty = v ? v->ty : 0;
-  return ty ? ty->str : (char*)"";
+  return ty ? ty->str : "";
 }
 
 SWIGRUNTIME void
@@ -2872,23 +2866,24 @@
   return result;
 }
 
+#ifdef SWIGPYTHON_BUILTIN
 SWIGRUNTIME int
 SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
   PyTypeObject *tp = obj->ob_type;
   PyObject *descr;
   PyObject *encoded_name;
   descrsetfunc f;
-  int res;
+  int res = -1;
 
-#ifdef Py_USING_UNICODE
+# ifdef Py_USING_UNICODE
   if (PyString_Check(name)) {
     name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
     if (!name)
       return -1;
   } else if (!PyUnicode_Check(name))
-#else
+# else
   if (!PyString_Check(name))
-#endif
+# endif
   {
     PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
     return -1;
@@ -2901,7 +2896,6 @@
       goto done;
   }
 
-  res = -1;
   descr = _PyType_Lookup(tp, name);
   f = NULL;
   if (descr != NULL)
@@ -2923,6 +2917,7 @@
   Py_DECREF(name);
   return res;
 }
+#endif
 
 
 #ifdef __cplusplus
@@ -2998,7 +2993,7 @@
 #endif
 #define SWIG_name    "_geos"
 
-#define SWIGVERSION 0x020004 
+#define SWIGVERSION 0x020011 
 #define SWIG_VERSION SWIGVERSION
 
 
@@ -3097,7 +3092,10 @@
 #include <stdexcept>
 #include <stddef.h>
 
-  
+
+  #include <stddef.h>
+
+
 namespace swig {
   struct stop_iteration {
   };
@@ -3308,6 +3306,7 @@
 SWIGINTERN int
 SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) 
 {
+#if PY_VERSION_HEX < 0x03000000
   if (PyInt_Check(obj)) {
     long v = PyInt_AsLong(obj);
     if (v >= 0) {
@@ -3316,13 +3315,27 @@
     } else {
       return SWIG_OverflowError;
     }
-  } else if (PyLong_Check(obj)) {
+  } else
+#endif
+  if (PyLong_Check(obj)) {
     unsigned long v = PyLong_AsUnsignedLong(obj);
     if (!PyErr_Occurred()) {
       if (val) *val = v;
       return SWIG_OK;
     } else {
       PyErr_Clear();
+#if PY_VERSION_HEX >= 0x03000000
+      {
+        long v = PyLong_AsLong(obj);
+        if (!PyErr_Occurred()) {
+          if (v < 0) {
+            return SWIG_OverflowError;
+          }
+        } else {
+          PyErr_Clear();
+        }
+      }
+#endif
     }
   }
 #ifdef SWIG_PYTHON_CAST_MODE
@@ -3359,7 +3372,7 @@
 }
 
 
-  #define SWIG_From_long   PyInt_FromLong 
+  #define SWIG_From_long   PyLong_FromLong 
 
 
 SWIGINTERNINLINE PyObject *
@@ -3439,10 +3452,10 @@
 #include <stdarg.h>
 
 
-SWIGINTERNINLINE PyObject *
-SWIG_From_int  (int value)
-{    
-  return SWIG_From_long  (value);
+SWIGINTERNINLINE PyObject*
+  SWIG_From_int  (int value)
+{
+  return PyInt_FromLong((long) value);
 }
 
 
@@ -3592,20 +3605,12 @@
         return result;
     }
 
-SWIGINTERNINLINE PyObject* 
-SWIG_From_unsigned_SS_long  (unsigned long value)
+SWIGINTERNINLINE PyObject*
+  SWIG_From_unsigned_SS_int  (unsigned int value)
 {
-  return (value > LONG_MAX) ?
-    PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); 
+  return PyInt_FromSize_t((size_t) value);
 }
 
-
-SWIGINTERNINLINE PyObject *
-SWIG_From_unsigned_SS_int  (unsigned int value)
-{    
-  return SWIG_From_unsigned_SS_long  (value);
-}
-
 SWIGINTERN unsigned int GeosCoordinateSequence_getDimensions(GeosCoordinateSequence *self){
         unsigned int result;
         GEOSCoordSeq coords = (GEOSCoordSeq) self;
@@ -3704,6 +3709,14 @@
         return GEOSGeom_getDimensions(geom);
     }
 
+SWIGINTERNINLINE PyObject* 
+SWIG_From_unsigned_SS_long  (unsigned long value)
+{
+  return (value > LONG_MAX) ?
+    PyLong_FromUnsignedLong(value) : PyLong_FromLong(static_cast< long >(value)); 
+}
+
+
 SWIGINTERNINLINE PyObject *
 SWIG_From_size_t  (size_t value)
 {    
@@ -10381,18 +10394,18 @@
 #endif
 /* -----------------------------------------------------------------------------
  * Type initialization:
- * This problem is tough by the requirement that no dynamic 
- * memory is used. Also, since swig_type_info structures store pointers to 
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
  * swig_cast_info structures and swig_cast_info structures store pointers back
- * to swig_type_info structures, we need some lookup code at initialization. 
- * The idea is that swig generates all the structures that are needed. 
- * The runtime then collects these partially filled structures. 
- * The SWIG_InitializeModule function takes these initial arrays out of 
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
  * swig_module, and does all the lookup, filling in the swig_module.types
  * array with the correct data and linking the correct swig_cast_info
  * structures together.
  *
- * The generated swig_type_info structures are assigned staticly to an initial 
+ * The generated swig_type_info structures are assigned staticly to an initial
  * array. We just loop through that array, and handle each type individually.
  * First we lookup if this type has been already loaded, and if so, use the
  * loaded structure instead of the generated one. Then we have to fill in the
@@ -10402,17 +10415,17 @@
  * a column is one of the swig_cast_info structures for that type.
  * The cast_initial array is actually an array of arrays, because each row has
  * a variable number of columns. So to actually build the cast linked list,
- * we find the array of casts associated with the type, and loop through it 
+ * we find the array of casts associated with the type, and loop through it
  * adding the casts to the list. The one last trick we need to do is making
  * sure the type pointer in the swig_cast_info struct is correct.
  *
- * First off, we lookup the cast->type name to see if it is already loaded. 
+ * First off, we lookup the cast->type name to see if it is already loaded.
  * There are three cases to handle:
  *  1) If the cast->type has already been loaded AND the type we are adding
  *     casting info to has not been loaded (it is in this module), THEN we
  *     replace the cast->type pointer with the type pointer that has already
  *     been loaded.
- *  2) If BOTH types (the one we are adding casting info to, and the 
+ *  2) If BOTH types (the one we are adding casting info to, and the
  *     cast->type) are loaded, THEN the cast info has already been loaded by
  *     the previous module so we just ignore it.
  *  3) Finally, if cast->type has not already been loaded, then we add that
@@ -10438,8 +10451,6 @@
   swig_module_info *module_head, *iter;
   int found, init;
   
-  clientdata = clientdata;
-  
   /* check to see if the circular list has been setup, if not, set it up */
   if (swig_module.next==0) {
     /* Initialize the swig_module */
@@ -10477,7 +10488,7 @@
     module_head->next = &swig_module;
   }
   
-  /* When multiple interpeters are used, a module could have already been initialized in
+  /* When multiple interpreters are used, a module could have already been initialized in
        a different interpreter, but not yet have a pointer in this interpreter.
        In this case, we do not want to continue adding types... everything should be
        set up already */
@@ -11012,6 +11023,7 @@
   m = Py_InitModule((char *) SWIG_name, SwigMethods);
 #endif
   md = d = PyModule_GetDict(m);
+  (void)md;
   
   SWIG_InitializeModule(0);
   
@@ -11055,14 +11067,14 @@
   
   SWIG_Python_SetConstant(d, "GEOS_VERSION_MAJOR",SWIG_From_int(static_cast< int >(3)));
   SWIG_Python_SetConstant(d, "GEOS_VERSION_MINOR",SWIG_From_int(static_cast< int >(4)));
-  SWIG_Python_SetConstant(d, "GEOS_VERSION",SWIG_FromCharPtr("3.4.0dev"));
+  SWIG_Python_SetConstant(d, "GEOS_VERSION",SWIG_FromCharPtr("3.4.3dev"));
   SWIG_Python_SetConstant(d, "GEOS_JTS_PORT",SWIG_FromCharPtr("1.12.0"));
   SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION_MAJOR",SWIG_From_int(static_cast< int >(1)));
   SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION_MINOR",SWIG_From_int(static_cast< int >(8)));
-  SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION_PATCH",SWIG_From_int(static_cast< int >(0)));
+  SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION_PATCH",SWIG_From_int(static_cast< int >(3)));
   SWIG_Python_SetConstant(d, "GEOS_CAPI_FIRST_INTERFACE",SWIG_From_int(static_cast< int >(1)));
   SWIG_Python_SetConstant(d, "GEOS_CAPI_LAST_INTERFACE",SWIG_From_int(static_cast< int >((1+8))));
-  SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION",SWIG_FromCharPtr("3.4.0dev-CAPI-1.8.0"));
+  SWIG_Python_SetConstant(d, "GEOS_CAPI_VERSION",SWIG_FromCharPtr("3.4.3dev-CAPI-1.8.3"));
   SWIG_Python_SetConstant(d, "GEOS_POINT",SWIG_From_int(static_cast< int >(GEOS_POINT)));
   SWIG_Python_SetConstant(d, "GEOS_LINESTRING",SWIG_From_int(static_cast< int >(GEOS_LINESTRING)));
   SWIG_Python_SetConstant(d, "GEOS_LINEARRING",SWIG_From_int(static_cast< int >(GEOS_LINEARRING)));

Modified: branches/3.4/tests/xmltester/Makefile.am
===================================================================
--- branches/3.4/tests/xmltester/Makefile.am	2014-12-05 09:37:26 UTC (rev 4038)
+++ branches/3.4/tests/xmltester/Makefile.am	2015-01-19 10:59:17 UTC (rev 4039)
@@ -39,6 +39,7 @@
 	$(srcdir)/tests/ticket/bug599.xml \
 	$(srcdir)/tests/ticket/bug605.xml \
 	$(srcdir)/tests/ticket/bug615.xml \
+	$(srcdir)/tests/ticket/bug716.xml \
 	$(srcdir)/tests/general/TestBoundary.xml \
 	$(srcdir)/tests/general/TestBuffer.xml \
 	$(srcdir)/tests/general/TestBufferMitredJoin.xml \

Added: branches/3.4/tests/xmltester/tests/ticket/bug716.xml
===================================================================
--- branches/3.4/tests/xmltester/tests/ticket/bug716.xml	                        (rev 0)
+++ branches/3.4/tests/xmltester/tests/ticket/bug716.xml	2015-01-19 10:59:17 UTC (rev 4039)
@@ -0,0 +1,75 @@
+<run>
+  <precisionModel type="FLOATING"/>
+  <desc>
+    Intersects operation of polygons with collinear lines. 
+    http://trac.osgeo.org/geos/ticket/716
+  </desc>
+<case>
+    <desc>
+      http://trac.osgeo.org/geos/ticket/716
+      a CW, b CW
+    </desc>
+  <a>
+    POLYGON((0.04745459120333707 7.998990511152711, 10.222919749090828 34.08521670606894, 10 10, 0.04745459120333707 7.998990511152711))
+  </a>
+  <b>
+    POLYGON((15 5, 0.010044793132693013 7.903085268568247, 10.260329547338191 34.181121949106455, 15 5))
+  </b>
+<test>
+  <op name="intersects" arg1="A" arg2="B">
+    true
+  </op>
+</test>
+</case>
+<case>
+    <desc>
+      http://trac.osgeo.org/geos/ticket/716
+      a CCW, b CW
+    </desc>
+  <a>
+    POLYGON((0.04745459120333707 7.998990511152711, 10 10, 10.222919749090828 34.08521670606894, 0.04745459120333707 7.998990511152711))
+  </a>
+  <b>
+    POLYGON((15 5, 0.010044793132693013 7.903085268568247, 10.260329547338191 34.181121949106455, 15 5))
+  </b>
+<test>
+  <op name="intersects" arg1="A" arg2="B">
+    true
+  </op>
+</test>
+</case>
+<case>
+    <desc>
+      http://trac.osgeo.org/geos/ticket/716
+      a CW, b CCW
+    </desc>
+  <a>
+    POLYGON((0.04745459120333707 7.998990511152711, 10.222919749090828 34.08521670606894, 10 10, 0.04745459120333707 7.998990511152711))
+  </a>
+  <b>
+    POLYGON((15 5, 10.260329547338191 34.181121949106455, 0.010044793132693013 7.903085268568247, 15 5))
+  </b>
+<test>
+  <op name="intersects" arg1="A" arg2="B">
+    true
+  </op>
+</test>
+</case>
+<case>
+    <desc>
+      http://trac.osgeo.org/geos/ticket/716
+      a CCW, b CCW
+    </desc>
+  <a>
+    POLYGON((0.04745459120333707 7.998990511152711, 10 10, 10.222919749090828 34.08521670606894, 0.04745459120333707 7.998990511152711))
+  </a>
+  <b>
+    POLYGON((15 5, 10.260329547338191 34.181121949106455, 0.010044793132693013 7.903085268568247, 15 5))
+  </b>
+<test>
+  <op name="intersects" arg1="A" arg2="B">
+    true
+  </op>
+</test>
+</case>
+</run>



More information about the geos-commits mailing list