[Community] Shapely is_empty fails on Linux

Sean Gillies sean.gillies at gmail.com
Sun Jan 24 16:00:22 EET 2010


On Jan 21, 2010, at 10:42 PM, Patrick Hartling wrote:

> Patrick Hartling wrote:
>> Sean Gillies wrote:
>>> On Jan 21, 2010, at 5:35 PM, Patrick Hartling wrote:
>>>
>>>> Howard Butler wrote:
>>>>> On Jan 21, 2010, at 9:30 AM, Patrick Hartling wrote:
>>>>>
>>>>>> We have run into a strange problem with the is_empty property on
>>>>>> Shapely
>>>>>> goemetry objects failing on Linux. We are using r1485 from the
>>>>>> Shapely 1.2
>>>>>> branch with GEOS 3.1.1 and Python 2.6.2 on 64-bit Ubuntu Linux
>>>>>> 9.04. The
>>>>>> code below demonstrates the problem:
>>>>>>
>>>>>> import shapely.geometry
>>>>>> assert shapely.geometry.Point(1,1).is_empty == False
>>>>> What about this?  Maybe the chaining is causing the reference to  
>>>>> go
>>>>> bad.
>>>>>
>>>>> p = shapely.geometry.Point(1,1)
>>>>> p.is_empty
>>>> The result is the same in that case: is_empty still returns False.
>>>>
>>>> -Patrick
>>> An "empty" geometry is an odd beast. Not quite the same as None,  
>>> it's
>>> a reflection of whether the geometry has coordinates or a sequence  
>>> of
>>> coordinates. A Point with x and y values set is definitely not  
>>> empty.
>>> The following is correct:
>>>
>>>>>> from shapely.geometry import Point
>>>>>> p = Point(0, 0)
>>>>>> p.is_empty
>>>   False
>>>
>>> Thanks for trying the code, Patrick. I'm going to try to make a  
>>> second
>>> alpha release of 1.2 tonight or tomorrow and will notify this list.
>>
>> Using r1521 of the Shapely 1.2 branch, I get the same failure with  
>> is_empty:
>>
>>>>> from shapely.geometry import Point
>>>>> p = Point(0, 0)
>>>>> p.is_empty
>>   True
>>
>> I think that the next logical thing for me to try is to run this in  
>> GDB and
>> see what is happening in GEOS.
>
> I figured out what was going wrong. The return type on some of the  
> ctypes
> declarations did not match the actual GEOS C function, and this  
> caused bogus
> results to be extracted from the stack frame. On x86_64 Linux, int  
> is 64
> bits wide. GEOS C functions that return a boolean value have char as  
> the
> return type. By using the attached patch (made against r1521 of the  
> 1.2
> branch), my test code works, and 5 Shapely test suite failures are  
> fixed. I
> have not tried this patch on Windows or Mac OS X yet, however, but I  
> can
> check on them soon.
>
> -Patrick
>
>
> -- 
> Patrick L. Hartling
> Senior Software Engineer, Priority 5
> http://www.priority5.com/
>
> The information transmitted in this communication is intended only for
> the person or entity to which it is addressed and contains proprietary
> material. Any review, retransmission, dissemination or other use of,  
> or
> taking of any action in reliance upon, this information by persons or
> entities other than the intended recipient is prohibited. If you
> received this in error, please destroy any copies, contact the sender
> and delete the material from any computer.
> Index: shapely/ctypes_declarations.py
> ===================================================================
> --- shapely/ctypes_declarations.py	(revision 1521)
> +++ shapely/ctypes_declarations.py	(working copy)
> @@ -134,46 +134,46 @@
>     lgeos.GEOSRelatePattern.restype = ctypes.c_char
>     lgeos.GEOSRelatePattern.argtypes = [ctypes.c_void_p,  
> ctypes.c_void_p, ctypes.c_char_p]
>
> -    lgeos.GEOSDisjoint.restype = ctypes.c_int
> +    lgeos.GEOSDisjoint.restype = ctypes.c_int8
>     lgeos.GEOSDisjoint.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSTouches.restype = ctypes.c_int
> +    lgeos.GEOSTouches.restype = ctypes.c_int8
>     lgeos.GEOSTouches.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSIntersects.restype = ctypes.c_int
> +    lgeos.GEOSIntersects.restype = ctypes.c_int8
>     lgeos.GEOSIntersects.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSCrosses.restype = ctypes.c_int
> +    lgeos.GEOSCrosses.restype = ctypes.c_int8
>     lgeos.GEOSCrosses.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSWithin.restype = ctypes.c_int
> +    lgeos.GEOSWithin.restype = ctypes.c_int8
>     lgeos.GEOSWithin.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSContains.restype = ctypes.c_int
> +    lgeos.GEOSContains.restype = ctypes.c_int8
>     lgeos.GEOSContains.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSOverlaps.restype = ctypes.c_int
> +    lgeos.GEOSOverlaps.restype = ctypes.c_int8
>     lgeos.GEOSOverlaps.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSEquals.restype = ctypes.c_int
> +    lgeos.GEOSEquals.restype = ctypes.c_int8
>     lgeos.GEOSEquals.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
>
> -    lgeos.GEOSEqualsExact.restype = ctypes.c_int
> +    lgeos.GEOSEqualsExact.restype = ctypes.c_int8
>     lgeos.GEOSEqualsExact.argtypes = [ctypes.c_void_p,  
> ctypes.c_void_p, ctypes.c_double]
>
> -    lgeos.GEOSisEmpty.restype = ctypes.c_int
> +    lgeos.GEOSisEmpty.restype = ctypes.c_int8
>     lgeos.GEOSisEmpty.argtypes = [ctypes.c_void_p]
>
> -    lgeos.GEOSisValid.restype = ctypes.c_int
> +    lgeos.GEOSisValid.restype = ctypes.c_int8
>     lgeos.GEOSisValid.argtypes = [ctypes.c_void_p]
>
> -    lgeos.GEOSisSimple.restype = ctypes.c_int
> +    lgeos.GEOSisSimple.restype = ctypes.c_int8
>     lgeos.GEOSisSimple.argtypes = [ctypes.c_void_p]
>
> -    lgeos.GEOSisRing.restype = ctypes.c_int
> +    lgeos.GEOSisRing.restype = ctypes.c_int8
>     lgeos.GEOSisRing.argtypes = [ctypes.c_void_p]
>
> -    lgeos.GEOSHasZ.restype = ctypes.c_int
> +    lgeos.GEOSHasZ.restype = ctypes.c_int8
>     lgeos.GEOSHasZ.argtypes = [ctypes.c_void_p]
>
>     lgeos.GEOSGeomType.restype = ctypes.c_char_p

Thanks! It's fixed in r1529

http://trac.gispython.org/lab/changeset/1529

--
Sean




More information about the Community mailing list