[python-shapely] 62/148: Imported Upstream version 1.2.10

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Thu Aug 20 17:42:04 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository python-shapely.

commit 6cca9d1cdee76d0481d53bc774c0c9404ed083b9
Author: Pietro Battiston <me at pietrobattiston.it>
Date:   Thu Jun 30 08:23:14 2011 +0200

    Imported Upstream version 1.2.10
---
 CHANGES.txt                                 |   18 +
 PKG-INFO                                    |  208 +-
 README.txt                                  |    6 +-
 Shapely.egg-info/PKG-INFO                   |  208 +-
 Shapely.egg-info/SOURCES.txt                |   15 +-
 docs/manual.txt                             |   89 +-
 setup.py                                    |   70 +-
 shapely/algorithms/__init__.py              |    0
 shapely/algorithms/cga.py                   |   17 +
 shapely/coords.py                           |    3 +-
 shapely/examples/__init__.py                |    1 +
 {examples => shapely/examples}/dissolve.py  |    0
 shapely/examples/geoms.py                   |   51 +
 {examples => shapely/examples}/intersect.py |    0
 shapely/examples/world.py                   |   21 +
 shapely/geometry/__init__.py                |    4 +-
 shapely/geometry/geo.py                     |    9 +-
 shapely/geometry/polygon.py                 |   21 +
 shapely/geometry/proxy.py                   |    1 -
 shapely/geos.py                             |    3 +-
 shapely/impl.py                             |    4 +
 shapely/iterops.py                          |    2 +-
 shapely/predicates.py                       |    1 -
 shapely/speedups/__init__.py                |   39 +
 shapely/speedups/_speedups.c                | 4551 +++++++++++++++++++++++++++
 shapely/speedups/_speedups.pyx              |  295 ++
 shapely/tests/__init__.py                   |    5 +-
 shapely/tests/test_box.py                   |   19 +
 shapely/tests/test_cga.py                   |   33 +
 shapely/tests/test_dlls.py                  |    7 +-
 shapely/tests/test_speedups.py              |   38 +
 shapely/wkb.py                              |    3 +-
 32 files changed, 5704 insertions(+), 38 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index eefb494..3897490 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,21 @@
+=======
+CHANGES
+=======
+
+1.2.10 (2011-05-09)
+-------------------
+- Add optional Cython speedups.
+- Add is_cww predicate to LinearRing.
+- Add function that forces orientation of Polygons.
+- Disable build of speedups on Windows pending packaging work.
+
+1.2.9 (2011-03-31)
+------------------
+- Remove extra glob import.
+- Move examples to shapely.examples.
+- Add box() constructor for rectangular polygons.
+- Fix extraneous imports.
+
 1.2.8 (2011-12-03)
 ------------------
 - New parallel_offset method (#6).
diff --git a/PKG-INFO b/PKG-INFO
index db7cc87..78a49df 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,14 +1,14 @@
 Metadata-Version: 1.0
 Name: Shapely
-Version: 1.2.8
+Version: 1.2.10
 Summary: Geometric objects, predicates, and operations
 Home-page: http://trac.gispython.org/lab/wiki/Shapely
 Author: Sean Gillies
 Author-email: sean.gillies at gmail.com
 License: BSD
-Description: =======
-        Shapely
-        =======
+Description: ======
+        README
+        ======
         
         .. image:: http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
         :width: 800
@@ -162,6 +162,206 @@ Description: =======
         :trim:
         .. _Pleiades: http://pleiades.stoa.org
         
+        =======
+        CHANGES
+        =======
+        
+        1.2.10 (2011-05-09)
+        -------------------
+        - Add optional Cython speedups.
+        - Add is_cww predicate to LinearRing.
+        - Add function that forces orientation of Polygons.
+        - Disable build of speedups on Windows pending packaging work.
+        
+        1.2.9 (2011-03-31)
+        ------------------
+        - Remove extra glob import.
+        - Move examples to shapely.examples.
+        - Add box() constructor for rectangular polygons.
+        - Fix extraneous imports.
+        
+        1.2.8 (2011-12-03)
+        ------------------
+        - New parallel_offset method (#6).
+        - Support for Python 2.4.
+        
+        1.2.7 (2010-11-05)
+        ------------------
+        - Support for Windows eggs.
+        
+        1.2.6 (2010-10-21)
+        ------------------
+        - The geoms property of an empty collection yields [] instead of a ValueError
+        (#3).
+        - The coords and geometry type sproperties have the same behavior as above.
+        - Ensure that z values carry through into products of operations (#4).
+        
+        1.2.5 (2010-09-19)
+        ------------------
+        - Stop distributing docs/_build.
+        - Include library fallbacks in test_dlls.py for linux platform.
+        
+        1.2.4 (2010-09-09)
+        ------------------
+        - Raise AttributeError when there's no backend support for a method.
+        - Raise OSError if libgeos_c.so (or variants) can't be found and loaded.
+        - Add geos_c DLL loading support for linux platforms where find_library doesn't
+        work.
+        
+        1.2.3 (2010-08-17)
+        ------------------
+        - Add mapping function.
+        - Fix problem with GEOSisValidReason symbol for GEOS < 3.1.
+        
+        1.2.2 (2010-07-23)
+        ------------------
+        - Add representative_point method.
+        
+        1.2.1 (2010-06-23)
+        ------------------
+        - Fixed bounds of singular polygons.
+        - Added shapely.validation.explain_validity function (#226).
+        
+        1.2 (2010-05-27)
+        ----------------
+        - Final release.
+        
+        1.2rc2 (2010-05-26)
+        -------------------
+        - Add examples and tests to MANIFEST.in.
+        - Release candidate 2.
+        
+        1.2rc1 (2010-05-25)
+        -------------------
+        - Release candidate.
+        
+        1.2b7 (2010-04-22)
+        ------------------
+        - Memory leak associated with new empty geometry state fixed.
+        
+        1.2b6 (2010-04-13)
+        ------------------
+        - Broken GeometryCollection fixed.
+        
+        1.2b5 (2010-04-09)
+        ------------------
+        - Objects can be constructed from others of the same type, thereby making
+        copies. Collections can be constructed from sequences of objects, also making
+        copies.
+        - Collections are now iterators over their component objects.
+        - New code for manual figures, using the descartes package.
+        
+        1.2b4 (2010-03-19)
+        ------------------
+        - Adds support for the "sunos5" platform.
+        
+        1.2b3 (2010-02-28)
+        ------------------
+        - Only provide simplification implementations for GEOS C API >= 1.5.
+        
+        1.2b2 (2010-02-19)
+        ------------------
+        - Fix cascaded_union bug introduced in 1.2b1 (#212).
+        
+        1.2b1 (2010-02-18)
+        ------------------
+        - Update the README. Remove cruft from setup.py. Add some version 1.2 metadata
+        regarding required Python version (>=2.5,<3) and external dependency
+        (libgeos_c >= 3.1).
+        
+        1.2a6 (2010-02-09)
+        ------------------
+        - Add accessor for separate arrays of X and Y values (#210).
+        
+        TODO: fill gap here
+        
+        1.2a1 (2010-01-20)
+        ------------------
+        - Proper prototyping of WKB writer, and avoidance of errors on 64-bit systems
+        (#191).
+        - Prototype libgeos_c functions in a way that lets py2exe apps import shapely
+        (#189).
+        
+        =========================
+        1.2 Branched (2009-09-19)
+        =========================
+        
+        1.0.12 (2009-04-09)
+        -------------------
+        - Fix for references held by topology and predicate descriptors.
+        
+        1.0.11 (2008-11-20)
+        -------------------
+        - Work around bug in GEOS 2.2.3, GEOSCoordSeq_getOrdinate not exported properly
+        (#178).
+        
+        1.0.10 (2008-11-17)
+        -------------------
+        - Fixed compatibility with GEOS 2.2.3 that was broken in 1.0.8 release (#176).
+        
+        1.0.9 (2008-11-16)
+        ------------------
+        - Find and load MacPorts libgeos.
+        
+        1.0.8 (2008-11-01)
+        ------------------
+        - Fill out GEOS function result and argument types to prevent faults on a
+        64-bit arch.
+        
+        1.0.7 (2008-08-22)
+        ------------------
+        - Polygon rings now have the same dimensions as parent (#168).
+        - Eliminated reference cycles in polygons (#169).
+        
+        1.0.6 (2008-07-10)
+        ------------------
+        - Fixed adaptation of multi polygon data.
+        - Raise exceptions earlier from binary predicates.
+        - Beginning distributing new windows DLLs (#166).
+        
+        1.0.5 (2008-05-20)
+        ------------------
+        - Added access to GEOS polygonizer function.
+        - Raise exception when insufficient coordinate tuples are passed to LinearRing
+        constructor (#164).
+        
+        1.0.4 (2008-05-01)
+        ------------------
+        - Disentangle Python and topological equality (#163).
+        - Add shape(), a factory that copies coordinates from a geo interface provider.
+        To be used instead of asShape() unless you really need to store coordinates
+        outside shapely for efficient use in other code.
+        - Cache GEOS geometries in adapters (#163).
+        
+        1.0.3 (2008-04-09)
+        ------------------
+        - Do not release GIL when calling GEOS functions (#158).
+        - Prevent faults when chaining multiple GEOS operators (#159).
+        
+        1.0.2 (2008-02-26)
+        ------------------
+        - Fix loss of dimensionality in polygon rings (#155).
+        
+        1.0.1 (2008-02-08)
+        ------------------
+        - Allow chaining expressions involving coordinate sequences and geometry parts
+        (#151).
+        - Protect against abnormal use of coordinate accessors (#152).
+        - Coordinate sequences now implement the numpy array protocol (#153).
+        
+        1.0 (2008-01-18)
+        ----------------
+        - Final release.
+        
+        1.0 RC2 (2008-01-16)
+        --------------------
+        - Added temporary solution for #149.
+        
+        1.0 RC1 (2008-01-14)
+        --------------------
+        - First release candidate
+        
+        
 Keywords: geometry topology gis
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff --git a/README.txt b/README.txt
index e89f2f4..382b16f 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
-=======
-Shapely
-=======
+======
+README
+======
 
 .. image:: http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
    :width: 800
diff --git a/Shapely.egg-info/PKG-INFO b/Shapely.egg-info/PKG-INFO
index db7cc87..78a49df 100644
--- a/Shapely.egg-info/PKG-INFO
+++ b/Shapely.egg-info/PKG-INFO
@@ -1,14 +1,14 @@
 Metadata-Version: 1.0
 Name: Shapely
-Version: 1.2.8
+Version: 1.2.10
 Summary: Geometric objects, predicates, and operations
 Home-page: http://trac.gispython.org/lab/wiki/Shapely
 Author: Sean Gillies
 Author-email: sean.gillies at gmail.com
 License: BSD
-Description: =======
-        Shapely
-        =======
+Description: ======
+        README
+        ======
         
         .. image:: http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
         :width: 800
@@ -162,6 +162,206 @@ Description: =======
         :trim:
         .. _Pleiades: http://pleiades.stoa.org
         
+        =======
+        CHANGES
+        =======
+        
+        1.2.10 (2011-05-09)
+        -------------------
+        - Add optional Cython speedups.
+        - Add is_cww predicate to LinearRing.
+        - Add function that forces orientation of Polygons.
+        - Disable build of speedups on Windows pending packaging work.
+        
+        1.2.9 (2011-03-31)
+        ------------------
+        - Remove extra glob import.
+        - Move examples to shapely.examples.
+        - Add box() constructor for rectangular polygons.
+        - Fix extraneous imports.
+        
+        1.2.8 (2011-12-03)
+        ------------------
+        - New parallel_offset method (#6).
+        - Support for Python 2.4.
+        
+        1.2.7 (2010-11-05)
+        ------------------
+        - Support for Windows eggs.
+        
+        1.2.6 (2010-10-21)
+        ------------------
+        - The geoms property of an empty collection yields [] instead of a ValueError
+        (#3).
+        - The coords and geometry type sproperties have the same behavior as above.
+        - Ensure that z values carry through into products of operations (#4).
+        
+        1.2.5 (2010-09-19)
+        ------------------
+        - Stop distributing docs/_build.
+        - Include library fallbacks in test_dlls.py for linux platform.
+        
+        1.2.4 (2010-09-09)
+        ------------------
+        - Raise AttributeError when there's no backend support for a method.
+        - Raise OSError if libgeos_c.so (or variants) can't be found and loaded.
+        - Add geos_c DLL loading support for linux platforms where find_library doesn't
+        work.
+        
+        1.2.3 (2010-08-17)
+        ------------------
+        - Add mapping function.
+        - Fix problem with GEOSisValidReason symbol for GEOS < 3.1.
+        
+        1.2.2 (2010-07-23)
+        ------------------
+        - Add representative_point method.
+        
+        1.2.1 (2010-06-23)
+        ------------------
+        - Fixed bounds of singular polygons.
+        - Added shapely.validation.explain_validity function (#226).
+        
+        1.2 (2010-05-27)
+        ----------------
+        - Final release.
+        
+        1.2rc2 (2010-05-26)
+        -------------------
+        - Add examples and tests to MANIFEST.in.
+        - Release candidate 2.
+        
+        1.2rc1 (2010-05-25)
+        -------------------
+        - Release candidate.
+        
+        1.2b7 (2010-04-22)
+        ------------------
+        - Memory leak associated with new empty geometry state fixed.
+        
+        1.2b6 (2010-04-13)
+        ------------------
+        - Broken GeometryCollection fixed.
+        
+        1.2b5 (2010-04-09)
+        ------------------
+        - Objects can be constructed from others of the same type, thereby making
+        copies. Collections can be constructed from sequences of objects, also making
+        copies.
+        - Collections are now iterators over their component objects.
+        - New code for manual figures, using the descartes package.
+        
+        1.2b4 (2010-03-19)
+        ------------------
+        - Adds support for the "sunos5" platform.
+        
+        1.2b3 (2010-02-28)
+        ------------------
+        - Only provide simplification implementations for GEOS C API >= 1.5.
+        
+        1.2b2 (2010-02-19)
+        ------------------
+        - Fix cascaded_union bug introduced in 1.2b1 (#212).
+        
+        1.2b1 (2010-02-18)
+        ------------------
+        - Update the README. Remove cruft from setup.py. Add some version 1.2 metadata
+        regarding required Python version (>=2.5,<3) and external dependency
+        (libgeos_c >= 3.1).
+        
+        1.2a6 (2010-02-09)
+        ------------------
+        - Add accessor for separate arrays of X and Y values (#210).
+        
+        TODO: fill gap here
+        
+        1.2a1 (2010-01-20)
+        ------------------
+        - Proper prototyping of WKB writer, and avoidance of errors on 64-bit systems
+        (#191).
+        - Prototype libgeos_c functions in a way that lets py2exe apps import shapely
+        (#189).
+        
+        =========================
+        1.2 Branched (2009-09-19)
+        =========================
+        
+        1.0.12 (2009-04-09)
+        -------------------
+        - Fix for references held by topology and predicate descriptors.
+        
+        1.0.11 (2008-11-20)
+        -------------------
+        - Work around bug in GEOS 2.2.3, GEOSCoordSeq_getOrdinate not exported properly
+        (#178).
+        
+        1.0.10 (2008-11-17)
+        -------------------
+        - Fixed compatibility with GEOS 2.2.3 that was broken in 1.0.8 release (#176).
+        
+        1.0.9 (2008-11-16)
+        ------------------
+        - Find and load MacPorts libgeos.
+        
+        1.0.8 (2008-11-01)
+        ------------------
+        - Fill out GEOS function result and argument types to prevent faults on a
+        64-bit arch.
+        
+        1.0.7 (2008-08-22)
+        ------------------
+        - Polygon rings now have the same dimensions as parent (#168).
+        - Eliminated reference cycles in polygons (#169).
+        
+        1.0.6 (2008-07-10)
+        ------------------
+        - Fixed adaptation of multi polygon data.
+        - Raise exceptions earlier from binary predicates.
+        - Beginning distributing new windows DLLs (#166).
+        
+        1.0.5 (2008-05-20)
+        ------------------
+        - Added access to GEOS polygonizer function.
+        - Raise exception when insufficient coordinate tuples are passed to LinearRing
+        constructor (#164).
+        
+        1.0.4 (2008-05-01)
+        ------------------
+        - Disentangle Python and topological equality (#163).
+        - Add shape(), a factory that copies coordinates from a geo interface provider.
+        To be used instead of asShape() unless you really need to store coordinates
+        outside shapely for efficient use in other code.
+        - Cache GEOS geometries in adapters (#163).
+        
+        1.0.3 (2008-04-09)
+        ------------------
+        - Do not release GIL when calling GEOS functions (#158).
+        - Prevent faults when chaining multiple GEOS operators (#159).
+        
+        1.0.2 (2008-02-26)
+        ------------------
+        - Fix loss of dimensionality in polygon rings (#155).
+        
+        1.0.1 (2008-02-08)
+        ------------------
+        - Allow chaining expressions involving coordinate sequences and geometry parts
+        (#151).
+        - Protect against abnormal use of coordinate accessors (#152).
+        - Coordinate sequences now implement the numpy array protocol (#153).
+        
+        1.0 (2008-01-18)
+        ----------------
+        - Final release.
+        
+        1.0 RC2 (2008-01-16)
+        --------------------
+        - Added temporary solution for #149.
+        
+        1.0 RC1 (2008-01-14)
+        --------------------
+        - First release candidate
+        
+        
 Keywords: geometry topology gis
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff --git a/Shapely.egg-info/SOURCES.txt b/Shapely.egg-info/SOURCES.txt
index b4200b7..74426a7 100644
--- a/Shapely.egg-info/SOURCES.txt
+++ b/Shapely.egg-info/SOURCES.txt
@@ -9,8 +9,6 @@ Shapely.egg-info/SOURCES.txt
 Shapely.egg-info/dependency_links.txt
 Shapely.egg-info/top_level.txt
 docs/manual.txt
-examples/dissolve.py
-examples/intersect.py
 shapely/__init__.py
 shapely/coords.py
 shapely/ctypes_declarations.py
@@ -26,6 +24,13 @@ shapely/topology.py
 shapely/validation.py
 shapely/wkb.py
 shapely/wkt.py
+shapely/algorithms/__init__.py
+shapely/algorithms/cga.py
+shapely/examples/__init__.py
+shapely/examples/dissolve.py
+shapely/examples/geoms.py
+shapely/examples/intersect.py
+shapely/examples/world.py
 shapely/geometry/__init__.py
 shapely/geometry/base.py
 shapely/geometry/collection.py
@@ -37,6 +42,9 @@ shapely/geometry/multipolygon.py
 shapely/geometry/point.py
 shapely/geometry/polygon.py
 shapely/geometry/proxy.py
+shapely/speedups/__init__.py
+shapely/speedups/_speedups.c
+shapely/speedups/_speedups.pyx
 shapely/tests/Array.txt
 shapely/tests/GeoInterface.txt
 shapely/tests/IterOps.txt
@@ -57,6 +65,8 @@ shapely/tests/dimensions.txt
 shapely/tests/invalid_intersection.txt
 shapely/tests/linemerge.txt
 shapely/tests/polygonize.txt
+shapely/tests/test_box.py
+shapely/tests/test_cga.py
 shapely/tests/test_collection.py
 shapely/tests/test_delegated.py
 shapely/tests/test_dlls.py
@@ -69,6 +79,7 @@ shapely/tests/test_mapping.py
 shapely/tests/test_prepared.py
 shapely/tests/test_products_z.py
 shapely/tests/test_singularity.py
+shapely/tests/test_speedups.py
 shapely/tests/test_validation.py
 shapely/tests/test_xy.py
 shapely/tests/threading_test.py
diff --git a/docs/manual.txt b/docs/manual.txt
index 0c74664..1d0bfde 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -3,8 +3,8 @@ The Shapely User Manual
 =======================
 
 :Author: Sean Gillies, <sean.gillies at gmail.com>
-:Revision: 1.2.6
-:Date: 17 October 2010
+:Revision: 1.2.10
+:Date: 2 May 2011
 :Copyright: 
   This work is licensed under a `Creative Commons Attribution 3.0
   United States License`__.
@@ -470,6 +470,40 @@ The `Polygon` constructor also accepts instances of `LineString` and
   >>> t.area
   6.5507620529190334
 
+Rectangular polygons occur commonly, and can be conveniently constructed using
+the :func:`shapely.geometry.box()` function.
+
+.. function:: shapely.geometry.box(minx, miny, maxx, maxy, ccw=True)
+
+  Makes a rectangular polygon from the provided bounding box values, with
+  counter-clockwise order by default.
+
+  `New in version 1.2.9`.
+
+For example:
+
+.. sourcecode:: pycon
+
+  >>> from shapely.geometry import box
+  >>> b = box(0.0, 0.0, 1.0, 1.0)
+  >>> b
+  <shapely.geometry.polygon.Polygon object at 0x...>
+  >>> list(b.exterior.coords)
+  [(1.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.0, 0.0), (1.0, 0.0)]
+
+This is the first appearance of an explicit polygon handedness in Shapely.
+
+To obtain a polygon with a known orientation, use 
+:func:`shapely.geometry.polygon.orient()`:
+
+.. function:: shapely.geometry.polygon.orient(polygon, sign=1.0)
+
+  Returns a properly oriented copy of the given polygon. The signed area of the
+  result will have the given sign. A sign of 1.0 means that the coordinates of the
+  product's exterior ring will be oriented counter-clockwise.
+
+  `New in version 1.2.10`.
+
 .. _collections:
 
 Collections
@@ -812,6 +846,29 @@ example will be shown for each.
   >>> Point(0, 0, 0).has_z
   True
 
+.. attribute:: object.is_ccw
+
+  Returns ``True`` if coordinates are in counter-clockwise order (bounding a region
+  with positive signed area). This method applies to `LinearRing` objects only.
+
+  `New in version 1.2.10`.
+
+.. sourcecode:: pycon
+
+  >>> LinearRing([(1,0), (1,1), (0,0)]).is_ccw
+  True
+
+A ring with an undesired orientation can be reversed like this:
+
+.. sourcecode:: pycon
+
+  >>> ring = LinearRing([(0,0), (1,1), (1,0)])
+  >>> ring.is_ccw
+  False
+  >>> ring.coords = list(ring.coords)[::-1]
+  >>> ring.is_ccw
+  True
+
 .. attribute:: object.is_empty
 
   Returns ``True`` if the feature's `interior` and `boundary` (in point set
@@ -1733,6 +1790,34 @@ For example, using the same `GeoThing` class:
   >>> m['coordinates']
   (0.0, 0.0)}
 
+
+Performance
+===========
+
+Shapely uses the GEOS_ library for all operations. GEOS is written in C++ and
+used in many applications and you can expect that all operations are highly
+optimized. Only the creation of new geometries involves some overhead that
+might slow down your code, if you create lots of geometries with a large number
+of coordinates.
+
+.. versionadded:: 1.2.10
+
+The :mod:`shapely.speedups` module contains performance enhancements written
+in C. They are automaticaly installed when Python has access to a compiler
+during installation.
+
+You can check if the speedups are installed with the :attr:`available`
+attribute. To enable the speedups call :func:`enable`. You can revert to the
+default implementation with :func:`disable`.
+
+.. sourcecode:: pycon
+
+  >>> from shapely import speedups
+  >>> speedups.available
+  True
+  >>> speedups.enable()
+
+
 Conclusion
 ==========
 
diff --git a/setup.py b/setup.py
index f5e332e..9d30ac1 100644
--- a/setup.py
+++ b/setup.py
@@ -9,15 +9,20 @@ except:
     "Failed to import distribute_setup, continuing without distribute.", 
     Warning)
 
+from distutils.errors import CCompilerError, DistutilsExecError, \
+    DistutilsPlatformError
+from setuptools.extension import Extension
+from setuptools.command.build_ext import build_ext
 from setuptools import setup, find_packages
 import sys
 
 readme_text = file('README.txt', 'rb').read()
+changes_text = file('CHANGES.txt', 'rb').read()
 
 setup_args = dict(
     metadata_version    = '1.2',
     name                = 'Shapely',
-    version             = '1.2.8',
+    version             = '1.2.10',
     requires_python     = '>=2.5,<3',
     requires_external   = 'libgeos_c (>=3.1)', 
     description         = 'Geometric objects, predicates, and operations',
@@ -28,9 +33,8 @@ setup_args = dict(
     maintainer          = 'Sean Gillies',
     maintainer_email    = 'sean.gillies at gmail.com',
     url                 = 'http://trac.gispython.org/lab/wiki/Shapely',
-    long_description    = readme_text,
-    packages            = ['shapely', 'shapely.geometry'],
-    scripts             = ['examples/dissolve.py', 'examples/intersect.py'],
+    long_description    = readme_text + "\n" + changes_text,
+    packages            = find_packages(),
     test_suite          = 'shapely.tests.test_suite',
     classifiers         = [
         'Development Status :: 5 - Production/Stable',
@@ -45,7 +49,6 @@ setup_args = dict(
 
 # Add DLLs for Windows
 if sys.platform == 'win32':
-    import glob
     if '(AMD64)' in sys.version:
         setup_args.update(
             data_files=[('DLLs', glob.glob('DLLs_AMD64/*.dll'))]
@@ -55,4 +58,59 @@ if sys.platform == 'win32':
             data_files=[('DLLs', glob.glob('DLLs_x86/*.dll'))]
             )
 
-setup(**setup_args)
+
+# Optional compilation of speedups
+# setuptools stuff from Bob Ippolito's simplejson project
+if sys.platform == 'win32' and sys.version_info > (2, 6):
+   # 2.6's distutils.msvc9compiler can raise an IOError when failing to
+   # find the compiler
+   ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError,
+                 IOError)
+else:
+   ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
+
+class BuildFailed(Exception):
+    pass
+
+class ve_build_ext(build_ext):
+    # This class allows C extension building to fail.
+
+    def run(self):
+        try:
+            build_ext.run(self)
+        except DistutilsPlatformError, x:
+            raise BuildFailed(x)
+
+    def build_extension(self, ext):
+        try:
+            build_ext.build_extension(self, ext)
+        except ext_errors, x:
+            raise BuildFailed(x)
+
+if sys.platform == 'win32':
+    ext_modules = []
+else:
+    ext_modules = [
+        Extension("shapely.speedups._speedups", 
+              ["shapely/speedups/_speedups.c"], libraries=['geos_c']),
+    ]
+
+try:
+    # try building with speedups
+    setup(
+        cmdclass={'build_ext': ve_build_ext},
+        ext_modules=ext_modules,
+        **setup_args
+    )
+except BuildFailed, ex:
+    BUILD_EXT_WARNING = "Warning: The C extension could not be compiled, speedups are not enabled."
+    print ex
+    print BUILD_EXT_WARNING
+    print "Failure information, if any, is above."
+    print "I'm retrying the build without the C extension now."
+
+    setup(**setup_args)
+
+    print BUILD_EXT_WARNING
+    print "Plain-Python installation succeeded."
+
diff --git a/shapely/algorithms/__init__.py b/shapely/algorithms/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/shapely/algorithms/cga.py b/shapely/algorithms/cga.py
new file mode 100644
index 0000000..040e376
--- /dev/null
+++ b/shapely/algorithms/cga.py
@@ -0,0 +1,17 @@
+from itertools import islice, izip
+
+def signed_area(ring):
+    """Return the signed area enclosed by a ring in linear time using the 
+    algorithm at: http://www.cgafaq.info/wiki/Polygon_Area.
+    """
+    xs, ys = ring.coords.xy
+    xs.append(xs[1])
+    ys.append(ys[1])
+    return sum(xs[i]*(ys[i+1]-ys[i-1]) for i in range(1, len(ring.coords)))/2.0
+
+def is_ccw_impl(name):
+    """Predicate implementation"""
+    def is_ccw_op(ring):
+        return signed_area(ring) >= 0.0
+    return is_ccw_op
+
diff --git a/shapely/coords.py b/shapely/coords.py
index 005115e..131876a 100644
--- a/shapely/coords.py
+++ b/shapely/coords.py
@@ -2,8 +2,7 @@
 """
 
 from array import array
-from ctypes import string_at, byref, c_char_p, c_double, c_void_p
-from ctypes import c_int, c_size_t, c_uint
+from ctypes import byref, c_double, c_uint
 import sys
 
 from shapely.geos import lgeos
diff --git a/shapely/examples/__init__.py b/shapely/examples/__init__.py
new file mode 100644
index 0000000..2560578
--- /dev/null
+++ b/shapely/examples/__init__.py
@@ -0,0 +1 @@
+# Examples module
diff --git a/examples/dissolve.py b/shapely/examples/dissolve.py
similarity index 100%
rename from examples/dissolve.py
rename to shapely/examples/dissolve.py
diff --git a/shapely/examples/geoms.py b/shapely/examples/geoms.py
new file mode 100644
index 0000000..164ab72
--- /dev/null
+++ b/shapely/examples/geoms.py
@@ -0,0 +1,51 @@
+from numpy import asarray
+import pylab
+from shapely.geometry import Point, LineString, Polygon
+
+polygon = Polygon(((-1.0, -1.0), (-1.0, 1.0), (1.0, 1.0), (1.0, -1.0)))
+
+point_r = Point(-1.5, 1.2)
+point_g = Point(-1.0, 1.0)
+point_b = Point(-0.5, 0.5)
+
+line_r = LineString(((-0.5, 0.5), (0.5, 0.5)))
+line_g = LineString(((1.0, -1.0), (1.8, 0.5)))
+line_b = LineString(((-1.8, -1.2), (1.8, 0.5)))
+
+def plot_point(g, o, l):
+    pylab.plot([g.x], [g.y], o, label=l)
+
+def plot_line(g, o):
+    a = asarray(g)
+    pylab.plot(a[:,0], a[:,1], o)
+
+def fill_polygon(g, o):
+    a = asarray(g.exterior)
+    pylab.fill(a[:,0], a[:,1], o, alpha=0.5)
+
+def fill_multipolygon(g, o):
+    for g in g.geoms:
+        fill_polygon(g, o)
+
+if __name__ == "__main__":
+    from numpy import asarray
+    import pylab
+    
+    fig = pylab.figure(1, figsize=(4, 3), dpi=150)
+    #pylab.axis([-2.0, 2.0, -1.5, 1.5])
+    pylab.axis('tight')
+
+    a = asarray(polygon.exterior)
+    pylab.fill(a[:,0], a[:,1], 'c')
+
+    plot_point(point_r, 'ro', 'b')
+    plot_point(point_g, 'go', 'c')
+    plot_point(point_b, 'bo', 'd')
+
+    plot_line(line_r, 'r')
+    plot_line(line_g, 'g')
+    plot_line(line_b, 'b')
+
+    pylab.show()
+
+
diff --git a/examples/intersect.py b/shapely/examples/intersect.py
similarity index 100%
rename from examples/intersect.py
rename to shapely/examples/intersect.py
diff --git a/shapely/examples/world.py b/shapely/examples/world.py
new file mode 100644
index 0000000..81b9af8
--- /dev/null
+++ b/shapely/examples/world.py
@@ -0,0 +1,21 @@
+import ogr
+import pylab
+from numpy import asarray
+
+from shapely.wkb import loads
+
+source = ogr.Open("/var/gis/data/world/world_borders.shp")
+borders = source.GetLayerByName("world_borders")
+
+fig = pylab.figure(1, figsize=(4,2), dpi=300)
+
+while 1:
+    feature = borders.GetNextFeature()
+    if not feature:
+        break
+    
+    geom = loads(feature.GetGeometryRef().ExportToWkb())
+    a = asarray(geom)
+    pylab.plot(a[:,0], a[:,1])
+
+pylab.show()
diff --git a/shapely/geometry/__init__.py b/shapely/geometry/__init__.py
index 4e1a1a9..3f29cbc 100644
--- a/shapely/geometry/__init__.py
+++ b/shapely/geometry/__init__.py
@@ -1,7 +1,7 @@
 """Geometry classes and factories
 """
 
-from geo import shape, asShape, mapping
+from geo import box, shape, asShape, mapping
 from point import Point, asPoint
 from linestring import LineString, asLineString
 from polygon import Polygon, asPolygon
@@ -11,7 +11,7 @@ from multipolygon import MultiPolygon, asMultiPolygon
 from collection import GeometryCollection
 
 __all__ = [
-    'shape', 'asShape', 'Point', 'asPoint', 'LineString', 'asLineString',
+    'box', 'shape', 'asShape', 'Point', 'asPoint', 'LineString', 'asLineString',
     'Polygon', 'asPolygon', 'MultiPoint', 'asMultiPoint',
     'MultiLineString', 'asMultiLineString', 'MultiPolygon', 'asMultiPolygon',
     'GeometryCollection', 'mapping'
diff --git a/shapely/geometry/geo.py b/shapely/geometry/geo.py
index ebdc9ac..1f7447e 100644
--- a/shapely/geometry/geo.py
+++ b/shapely/geometry/geo.py
@@ -7,9 +7,16 @@ from linestring import LineString, asLineString
 from polygon import Polygon, asPolygon
 from multipoint import MultiPoint, asMultiPoint
 from multilinestring import MultiLineString, asMultiLineString
-from multipolygon import MultiPolygon, MultiPolygonAdapter, asMultiPolygon
+from multipolygon import MultiPolygon, MultiPolygonAdapter
 
 
+def box(minx, miny, maxx, maxy, ccw=True):
+    """Return a rectangular polygon with configurable normal vector"""
+    coords = [(maxx, miny), (maxx, maxy), (minx, maxy), (minx, miny)]
+    if not ccw:
+        coords = coords[::-1]
+    return Polygon(coords)
+
 def shape(context):
     """Return a new, independent geometry with coordinates *copied* from the
     context.
diff --git a/shapely/geometry/polygon.py b/shapely/geometry/polygon.py
index e970383..5fb5ccb 100644
--- a/shapely/geometry/polygon.py
+++ b/shapely/geometry/polygon.py
@@ -4,6 +4,8 @@
 from ctypes import c_double, c_void_p, cast, POINTER
 from ctypes import ArgumentError
 import weakref
+
+from shapely.algorithms.cga import signed_area
 from shapely.geos import lgeos
 from shapely.geometry.base import BaseGeometry
 from shapely.geometry.linestring import LineString, LineStringAdapter
@@ -61,6 +63,11 @@ class LinearRing(LineString):
 
     coords = property(_get_coords, _set_coords)
 
+    @property
+    def is_ccw(self):
+        """Brand new"""
+        return bool(self.impl['is_ccw'](self))
+
 
 class LinearRingAdapter(LineStringAdapter):
 
@@ -277,6 +284,20 @@ def asPolygon(shell, holes=None):
     """Adapt objects to the Polygon interface"""
     return PolygonAdapter(shell, holes)
 
+def orient(polygon, sign=1.0):
+    s = float(sign)
+    rings = []
+    ring = polygon.exterior
+    if signed_area(ring)/s >= 0.0:
+        rings.append(ring)
+    else:
+        rings.append(list(ring.coords)[::-1])
+    for ring in polygon.interiors:
+        if signed_area(ring)/s <= 0.0:
+            rings.append(ring)
+        else:
+            rings.append(list(ring.coords)[::-1])
+    return Polygon(rings[0], rings[1:])
 
 def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
     try:
diff --git a/shapely/geometry/proxy.py b/shapely/geometry/proxy.py
index 85ceb25..fe7ed12 100644
--- a/shapely/geometry/proxy.py
+++ b/shapely/geometry/proxy.py
@@ -23,7 +23,6 @@ class CachingGeometryProxy(object):
 
     def empty(self):
         if not self._is_empty:
-            from shapely.geos import lgeos
             lgeos.GEOSGeom_destroy(self.__geom__)
         self.__geom__ = EMPTY
 
diff --git a/shapely/geos.py b/shapely/geos.py
index 47dc3dd..dbaa983 100644
--- a/shapely/geos.py
+++ b/shapely/geos.py
@@ -6,10 +6,9 @@ import atexit
 import logging
 import os
 import sys
-import time
 import threading
 import ctypes
-from ctypes import cdll, CDLL, PyDLL, CFUNCTYPE, c_char_p, c_void_p, string_at
+from ctypes import cdll, CDLL, CFUNCTYPE, c_char_p, c_void_p, string_at
 from ctypes.util import find_library
 
 import ftools
diff --git a/shapely/impl.py b/shapely/impl.py
index 861b5b7..214a333 100644
--- a/shapely/impl.py
+++ b/shapely/impl.py
@@ -13,6 +13,7 @@ Shapely 1.2 includes a GEOS backend and it is the default.
 
 from ftools import wraps
 
+from shapely.algorithms import cga
 from shapely.coords import BoundsOp
 from shapely.geos import lgeos
 from shapely.linref import ProjectOp, InterpolateOp
@@ -81,6 +82,9 @@ IMPL14 = {
     'touches': (BinaryPredicate, 'touches'),
     'within': (BinaryPredicate, 'within'),
     'equals_exact': (BinaryPredicate, 'equals_exact'),
+    
+    # First pure Python implementation
+    'is_ccw': (cga.is_ccw_impl, 'is_ccw'),
     }
 
 IMPL15 = {
diff --git a/shapely/iterops.py b/shapely/iterops.py
index 70b6f5d..894aa9a 100644
--- a/shapely/iterops.py
+++ b/shapely/iterops.py
@@ -3,7 +3,7 @@ Iterative forms of operations
 """
 
 from ctypes import c_char_p, c_size_t
-from shapely.geos import lgeos, free
+from shapely.geos import lgeos, PredicateError
 
 
 def geos_from_geometry(geom):
diff --git a/shapely/predicates.py b/shapely/predicates.py
index bc28ba7..73c5b8b 100644
--- a/shapely/predicates.py
+++ b/shapely/predicates.py
@@ -2,7 +2,6 @@
 Support for GEOS spatial predicates
 """
 
-from shapely.geos import PredicateError, lgeos
 from shapely.topology import Delegating
 
 class BinaryPredicate(Delegating):
diff --git a/shapely/speedups/__init__.py b/shapely/speedups/__init__.py
new file mode 100644
index 0000000..eec8e46
--- /dev/null
+++ b/shapely/speedups/__init__.py
@@ -0,0 +1,39 @@
+import warnings
+
+from shapely.geometry import linestring, polygon
+from shapely import coords
+
+try:
+    from shapely.speedups import _speedups
+    available = True
+except ImportError:
+    available = False
+
+__all__ = ['available', 'enable', 'disable']
+_orig = {}
+
+def enable():
+    if not available:
+        warnings.warn("shapely.speedups not available", RuntimeWarning)
+        return
+    
+    if _orig:
+        return
+    
+    _orig['CoordinateSequence.ctypes'] = coords.CoordinateSequence.ctypes
+    coords.CoordinateSequence.ctypes = property(_speedups.coordseq_ctypes)
+    
+    _orig['geos_linestring_from_py'] = linestring.geos_linestring_from_py
+    linestring.geos_linestring_from_py = _speedups.geos_linestring_from_py
+
+    _orig['geos_linearring_from_py']  = polygon.geos_linearring_from_py
+    polygon.geos_linearring_from_py = _speedups.geos_linearring_from_py
+
+def disable():
+    if not _orig:
+        return
+
+    coords.CoordinateSequence.ctypes = _orig['CoordinateSequence.ctypes']
+    linestring.geos_linestring_from_py = _orig['geos_linestring_from_py']
+    polygon.geos_linearring_from_py = _orig['geos_linearring_from_py']
+    _orig.clear()
\ No newline at end of file
diff --git a/shapely/speedups/_speedups.c b/shapely/speedups/_speedups.c
new file mode 100644
index 0000000..94cb1f3
--- /dev/null
+++ b/shapely/speedups/_speedups.c
@@ -0,0 +1,4551 @@
+/* Generated by Cython 0.14 on Mon Apr 25 17:07:41 2011 */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#ifndef Py_PYTHON_H
+    #error Python headers needed to compile C extensions, please install development version of Python.
+#else
+
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
+
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
+
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+
+#if PY_VERSION_HEX < 0x02040000
+  #define METH_COEXIST 0
+  #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
+  #define PyDict_Contains(d,o)   PySequence_Contains(d,o)
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T ""
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)
+  #define PyNumber_Index(o)    PyNumber_Int(o)
+  #define PyIndex_Check(o)     PyNumber_Check(o)
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+#endif
+
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+
+#endif
+
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
+  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#endif
+
+#ifndef PySet_CheckExact
+#  define PySet_CheckExact(obj)          (Py_TYPE(obj) == &PySet_Type)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyIntObject                  PyLongObject
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyBoolObject PyLongObject
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)
+#endif
+
+#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
+  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
+  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
+#else
+  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
+  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
+  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
+        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
+        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
+            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+
+#ifdef __cplusplus
+#define __PYX_EXTERN_C extern "C"
+#else
+#define __PYX_EXTERN_C extern
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE_API__shapely__speedups___speedups
+#include "geos_c.h"
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+
+/* inline attribute */
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+
+/* unused attribute */
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#     define CYTHON_UNUSED __attribute__ ((__unused__))
+#   else
+#     define CYTHON_UNUSED
+#   endif
+# elif defined(__ICC) || defined(__INTEL_COMPILER)
+#   define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+#   define CYTHON_UNUSED
+# endif
+#endif
+
+typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+
+/* Type Conversion Predeclarations */
+
+#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
+#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
+
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
+
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+
+
+#ifdef __GNUC__
+/* Test for GCC > 2.95 */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
+#define likely(x)   __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* __GNUC__ > 2 ... */
+#define likely(x)   (x)
+#define unlikely(x) (x)
+#endif /* __GNUC__ > 2 ... */
+#else /* __GNUC__ */
+#define likely(x)   (x)
+#define unlikely(x) (x)
+#endif /* __GNUC__ */
+    
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+  "_speedups.pyx",
+};
+
+/* Type declarations */
+
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+  end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+  }
+  #define __Pyx_RefNannySetupContext(name)           void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+  #define __Pyx_RefNannyFinishContext()           __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
+#else
+  #define __Pyx_RefNannySetupContext(name)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
+#endif /* CYTHON_REFNANNY */
+#define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
+#define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name, PyObject* kw_name); /*proto*/
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,     const char* function_name); /*proto*/
+
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+
+
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
+    if (likely(o != Py_None)) {
+        if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+            PyObject *r = PyList_GET_ITEM(o, i);
+            Py_INCREF(r);
+            return r;
+        }
+        else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
+            PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
+    if (likely(o != Py_None)) {
+        if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, i);
+            Py_INCREF(r);
+            return r;
+        }
+        else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
+            PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+
+#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
+                                                    __Pyx_GetItemInt_Fast(o, i) : \
+                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+    PyObject *r;
+    if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+    }
+    else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+    }
+    else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
+        r = PySequence_GetItem(o, i);
+    }
+    else {
+        r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+    }
+    return r;
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+
+static void __Pyx_AddTraceback(const char *funcname); /*proto*/
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+/* Module declarations from shapely.speedups._speedups */
+
+static CYTHON_INLINE GEOSGeometry *__pyx_f_7shapely_8speedups_9_speedups_cast_geom(long); /*proto*/
+static CYTHON_INLINE struct GEOSContextHandle_HS *__pyx_f_7shapely_8speedups_9_speedups_cast_handle(long); /*proto*/
+static CYTHON_INLINE GEOSCoordSequence *__pyx_f_7shapely_8speedups_9_speedups_cast_seq(long); /*proto*/
+#define __Pyx_MODULE_NAME "shapely.speedups._speedups"
+int __pyx_module_is_main_shapely__speedups___speedups = 0;
+
+/* Implementation of shapely.speedups._speedups */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_AttributeError;
+static PyObject *__pyx_builtin_TypeError;
+static char __pyx_k_1[] = "LineStrings must have at least 2 coordinate tuples";
+static char __pyx_k_3[] = "Input %s is the wrong shape for a LineString";
+static char __pyx_k_4[] = "Wrong coordinate dimensions; this geometry has dimensions: %d";
+static char __pyx_k_6[] = "Inconsistent coordinate dimensionality";
+static char __pyx_k_8[] = "A LinearRing must have at least 3 coordinate tuples";
+static char __pyx_k_11[] = "shapely.geos";
+static char __pyx_k_12[] = "shapely.speedups._speedups";
+static char __pyx_k_13[] = "geos_linestring_from_py";
+static char __pyx_k_14[] = "geos_linearring_from_py";
+static char __pyx_k__ob[] = "ob";
+static char __pyx_k__data[] = "data";
+static char __pyx_k__Array[] = "Array";
+static char __pyx_k___cseq[] = "_cseq";
+static char __pyx_k___ndim[] = "_ndim";
+static char __pyx_k__lgeos[] = "lgeos";
+static char __pyx_k__range[] = "range";
+static char __pyx_k__shape[] = "shape";
+static char __pyx_k__ctypes[] = "ctypes";
+static char __pyx_k__xrange[] = "xrange";
+static char __pyx_k____len__[] = "__len__";
+static char __pyx_k___update[] = "_update";
+static char __pyx_k__destroy[] = "destroy";
+static char __pyx_k____main__[] = "__main__";
+static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__c_double[] = "c_double";
+static char __pyx_k__TypeError[] = "TypeError";
+static char __pyx_k__addressof[] = "addressof";
+static char __pyx_k__IndexError[] = "IndexError";
+static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k__geos_handle[] = "geos_handle";
+static char __pyx_k__update_geom[] = "update_geom";
+static char __pyx_k__update_ndim[] = "update_ndim";
+static char __pyx_k__AttributeError[] = "AttributeError";
+static char __pyx_k__coordseq_ctypes[] = "coordseq_ctypes";
+static char __pyx_k____array_interface__[] = "__array_interface__";
+static PyObject *__pyx_kp_s_1;
+static PyObject *__pyx_n_s_11;
+static PyObject *__pyx_n_s_12;
+static PyObject *__pyx_n_s_13;
+static PyObject *__pyx_n_s_14;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_kp_s_4;
+static PyObject *__pyx_kp_s_6;
+static PyObject *__pyx_kp_s_8;
+static PyObject *__pyx_n_s__Array;
+static PyObject *__pyx_n_s__AttributeError;
+static PyObject *__pyx_n_s__IndexError;
+static PyObject *__pyx_n_s__TypeError;
+static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____array_interface__;
+static PyObject *__pyx_n_s____len__;
+static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____test__;
+static PyObject *__pyx_n_s___cseq;
+static PyObject *__pyx_n_s___ndim;
+static PyObject *__pyx_n_s___update;
+static PyObject *__pyx_n_s__addressof;
+static PyObject *__pyx_n_s__c_double;
+static PyObject *__pyx_n_s__coordseq_ctypes;
+static PyObject *__pyx_n_s__ctypes;
+static PyObject *__pyx_n_s__data;
+static PyObject *__pyx_n_s__destroy;
+static PyObject *__pyx_n_s__geos_handle;
+static PyObject *__pyx_n_s__lgeos;
+static PyObject *__pyx_n_s__ob;
+static PyObject *__pyx_n_s__range;
+static PyObject *__pyx_n_s__shape;
+static PyObject *__pyx_n_s__update_geom;
+static PyObject *__pyx_n_s__update_ndim;
+static PyObject *__pyx_n_s__xrange;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_k_tuple_2;
+static PyObject *__pyx_k_tuple_5;
+static PyObject *__pyx_k_tuple_7;
+static PyObject *__pyx_k_tuple_9;
+static PyObject *__pyx_k_tuple_10;
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":28
+ *     void GEOSGeom_destroy_r(GEOSContextHandle_HS *, GEOSGeometry *)
+ * 
+ * cdef inline GEOSGeometry *cast_geom(long geom_addr):             # <<<<<<<<<<<<<<
+ *     return <GEOSGeometry *>geom_addr
+ * 
+ */
+
+static CYTHON_INLINE GEOSGeometry *__pyx_f_7shapely_8speedups_9_speedups_cast_geom(long __pyx_v_geom_addr) {
+  GEOSGeometry *__pyx_r;
+  __Pyx_RefNannySetupContext("cast_geom");
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":29
+ * 
+ * cdef inline GEOSGeometry *cast_geom(long geom_addr):
+ *     return <GEOSGeometry *>geom_addr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline GEOSContextHandle_HS *cast_handle(long handle_addr):
+ */
+  __pyx_r = ((GEOSGeometry *)__pyx_v_geom_addr);
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":31
+ *     return <GEOSGeometry *>geom_addr
+ * 
+ * cdef inline GEOSContextHandle_HS *cast_handle(long handle_addr):             # <<<<<<<<<<<<<<
+ *     return <GEOSContextHandle_HS *>handle_addr
+ * 
+ */
+
+static CYTHON_INLINE struct GEOSContextHandle_HS *__pyx_f_7shapely_8speedups_9_speedups_cast_handle(long __pyx_v_handle_addr) {
+  struct GEOSContextHandle_HS *__pyx_r;
+  __Pyx_RefNannySetupContext("cast_handle");
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":32
+ * 
+ * cdef inline GEOSContextHandle_HS *cast_handle(long handle_addr):
+ *     return <GEOSContextHandle_HS *>handle_addr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline GEOSCoordSequence *cast_seq(long handle_addr):
+ */
+  __pyx_r = ((struct GEOSContextHandle_HS *)__pyx_v_handle_addr);
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":34
+ *     return <GEOSContextHandle_HS *>handle_addr
+ * 
+ * cdef inline GEOSCoordSequence *cast_seq(long handle_addr):             # <<<<<<<<<<<<<<
+ *     return <GEOSCoordSequence *>handle_addr
+ * 
+ */
+
+static CYTHON_INLINE GEOSCoordSequence *__pyx_f_7shapely_8speedups_9_speedups_cast_seq(long __pyx_v_handle_addr) {
+  GEOSCoordSequence *__pyx_r;
+  __Pyx_RefNannySetupContext("cast_seq");
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":35
+ * 
+ * cdef inline GEOSCoordSequence *cast_seq(long handle_addr):
+ *     return <GEOSCoordSequence *>handle_addr             # <<<<<<<<<<<<<<
+ * 
+ * def destroy(geom):
+ */
+  __pyx_r = ((GEOSCoordSequence *)__pyx_v_handle_addr);
+  goto __pyx_L0;
+
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":37
+ *     return <GEOSCoordSequence *>handle_addr
+ * 
+ * def destroy(geom):             # <<<<<<<<<<<<<<
+ *     GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))
+ * 
+ */
+
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_0destroy(PyObject *__pyx_self, PyObject *__pyx_v_geom); /*proto*/
+static PyMethodDef __pyx_mdef_7shapely_8speedups_9_speedups_0destroy = {__Pyx_NAMESTR("destroy"), (PyCFunction)__pyx_pf_7shapely_8speedups_9_speedups_0destroy, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_0destroy(PyObject *__pyx_self, PyObject *__pyx_v_geom) {
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  long __pyx_t_3;
+  long __pyx_t_4;
+  __Pyx_RefNannySetupContext("destroy");
+  __pyx_self = __pyx_self;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":38
+ * 
+ * def destroy(geom):
+ *     GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))             # <<<<<<<<<<<<<<
+ * 
+ * def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__lgeos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__geos_handle); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsLong(__pyx_v_geom); if (unlikely((__pyx_t_4 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  GEOSGeom_destroy_r(__pyx_f_7shapely_8speedups_9_speedups_cast_handle(__pyx_t_3), __pyx_f_7shapely_8speedups_9_speedups_cast_geom(__pyx_t_4));
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("shapely.speedups._speedups.destroy");
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":40
+ *     GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))
+ * 
+ * def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):             # <<<<<<<<<<<<<<
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+ */
+
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_1geos_linestring_from_py(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7shapely_8speedups_9_speedups_1geos_linestring_from_py = {__Pyx_NAMESTR("geos_linestring_from_py"), (PyCFunction)__pyx_pf_7shapely_8speedups_9_speedups_1geos_linestring_from_py, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_1geos_linestring_from_py(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_ob = 0;
+  PyObject *__pyx_v_update_geom = 0;
+  PyObject *__pyx_v_update_ndim = 0;
+  double *__pyx_v_cp;
+  struct GEOSContextHandle_HS *__pyx_v_handle;
+  GEOSCoordSequence *__pyx_v_cs;
+  double __pyx_v_dx;
+  double __pyx_v_dy;
+  double __pyx_v_dz;
+  int __pyx_v_i;
+  int __pyx_v_n;
+  int __pyx_v_m;
+  PyObject *__pyx_v_array;
+  PyObject *__pyx_v_coords;
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  long __pyx_t_3;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_t_10;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  double __pyx_t_14;
+  static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ob,&__pyx_n_s__update_geom,&__pyx_n_s__update_ndim,0};
+  __Pyx_RefNannySetupContext("geos_linestring_from_py");
+  __pyx_self = __pyx_self;
+  if (unlikely(__pyx_kwds)) {
+    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)Py_None);
+    values[2] = ((PyObject *)__pyx_int_0);
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      case  0: break;
+      default: goto __pyx_L5_argtuple_error;
+    }
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  0:
+      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob);
+      if (likely(values[0])) kw_args--;
+      else goto __pyx_L5_argtuple_error;
+      case  1:
+      if (kw_args > 0) {
+        PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__update_geom);
+        if (value) { values[1] = value; kw_args--; }
+      }
+      case  2:
+      if (kw_args > 0) {
+        PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__update_ndim);
+        if (value) { values[2] = value; kw_args--; }
+      }
+    }
+    if (unlikely(kw_args > 0)) {
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "geos_linestring_from_py") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    }
+    __pyx_v_ob = values[0];
+    __pyx_v_update_geom = values[1];
+    __pyx_v_update_ndim = values[2];
+  } else {
+    __pyx_v_update_geom = ((PyObject *)Py_None);
+    __pyx_v_update_ndim = ((PyObject *)__pyx_int_0);
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  3: __pyx_v_update_ndim = PyTuple_GET_ITEM(__pyx_args, 2);
+      case  2: __pyx_v_update_geom = PyTuple_GET_ITEM(__pyx_args, 1);
+      case  1: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 0);
+      break;
+      default: goto __pyx_L5_argtuple_error;
+    }
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("geos_linestring_from_py", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("shapely.speedups._speedups.geos_linestring_from_py");
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_v_array = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_v_coords = Py_None; __Pyx_INCREF(Py_None);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":42
+ * def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)             # <<<<<<<<<<<<<<
+ *     cdef GEOSCoordSequence *cs
+ *     cdef double dx, dy, dz
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__lgeos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__geos_handle); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_handle = __pyx_f_7shapely_8speedups_9_speedups_cast_handle(__pyx_t_3);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":46
+ *     cdef double dx, dy, dz
+ *     cdef int i, n, m
+ *     try:             # <<<<<<<<<<<<<<
+ *         # From array protocol
+ *         array = ob.__array_interface__
+ */
+  {
+    PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb;
+    __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb);
+    __Pyx_XGOTREF(__pyx_save_exc_type);
+    __Pyx_XGOTREF(__pyx_save_exc_value);
+    __Pyx_XGOTREF(__pyx_save_exc_tb);
+    /*try:*/ {
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":48
+ *     try:
+ *         # From array protocol
+ *         array = ob.__array_interface__             # <<<<<<<<<<<<<<
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_ob, __pyx_n_s____array_interface__); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_v_array);
+      __pyx_v_array = __pyx_t_2;
+      __pyx_t_2 = 0;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":49
+ *         # From array protocol
+ *         array = ob.__array_interface__
+ *         assert len(array['shape']) == 2             # <<<<<<<<<<<<<<
+ *         m = array['shape'][0]
+ *         if m < 2:
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      if (unlikely(!(__pyx_t_4 == 2))) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":50
+ *         array = ob.__array_interface__
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]             # <<<<<<<<<<<<<<
+ *         if m < 2:
+ *             raise ValueError(
+ */
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_v_m = __pyx_t_5;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":51
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]
+ *         if m < 2:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ */
+      __pyx_t_6 = (__pyx_v_m < 2);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":52
+ *         m = array['shape'][0]
+ *         if m < 2:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ */
+        __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_Raise(__pyx_t_1, 0, 0);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":54
+ *             raise ValueError(
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:             # <<<<<<<<<<<<<<
+ *             n = array['shape'][1]
+ *         except IndexError:
+ */
+      {
+        PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb;
+        __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb);
+        __Pyx_XGOTREF(__pyx_save_exc_type);
+        __Pyx_XGOTREF(__pyx_save_exc_value);
+        __Pyx_XGOTREF(__pyx_save_exc_tb);
+        /*try:*/ {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":55
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ *             n = array['shape'][1]             # <<<<<<<<<<<<<<
+ *         except IndexError:
+ *             raise ValueError(
+ */
+          __pyx_t_1 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L15_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __pyx_v_n = __pyx_t_5;
+        }
+        __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0;
+        __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0;
+        __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0;
+        goto __pyx_L22_try_end;
+        __pyx_L15_error:;
+        __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":56
+ *         try:
+ *             n = array['shape'][1]
+ *         except IndexError:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))
+ */
+        __pyx_t_5 = PyErr_ExceptionMatches(__pyx_builtin_IndexError);
+        if (__pyx_t_5) {
+          __Pyx_AddTraceback("shapely.speedups._speedups.geos_linestring_from_py");
+          if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_1, &__pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_GOTREF(__pyx_t_1);
+          __Pyx_GOTREF(__pyx_t_7);
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":58
+ *         except IndexError:
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))             # <<<<<<<<<<<<<<
+ *         assert n == 2 or n == 3
+ * 
+ */
+          __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_8));
+          __Pyx_INCREF(__pyx_v_ob);
+          PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_ob);
+          __Pyx_GIVEREF(__pyx_v_ob);
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
+          __pyx_t_8 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_3), __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_8));
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_9));
+          PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_8));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_8));
+          __pyx_t_8 = 0;
+          __pyx_t_8 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+          __Pyx_Raise(__pyx_t_8, 0, 0);
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L17_except_error;}
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+          goto __pyx_L16_exception_handled;
+        }
+        __pyx_L17_except_error:;
+        __Pyx_XGIVEREF(__pyx_save_exc_type);
+        __Pyx_XGIVEREF(__pyx_save_exc_value);
+        __Pyx_XGIVEREF(__pyx_save_exc_tb);
+        __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+        goto __pyx_L6_error;
+        __pyx_L16_exception_handled:;
+        __Pyx_XGIVEREF(__pyx_save_exc_type);
+        __Pyx_XGIVEREF(__pyx_save_exc_value);
+        __Pyx_XGIVEREF(__pyx_save_exc_tb);
+        __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+        __pyx_L22_try_end:;
+      }
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":59
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))
+ *         assert n == 2 or n == 3             # <<<<<<<<<<<<<<
+ * 
+ *         # Make pointer to the coordinate array
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      switch (__pyx_v_n) {
+        case 2:
+        case 3:
+        __pyx_t_6 = 1;
+        break;
+        default:
+        __pyx_t_6 = 0;
+        break;
+      }
+      if (unlikely(!__pyx_t_6)) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":62
+ * 
+ *         # Make pointer to the coordinate array
+ *         if isinstance(array['data'], ctypes.Array):             # <<<<<<<<<<<<<<
+ *             cp = <double *><long>ctypes.addressof(array['data'])
+ *         else:
+ */
+      __pyx_t_7 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__Array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_6 = PyObject_IsInstance(__pyx_t_7, __pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":63
+ *         # Make pointer to the coordinate array
+ *         if isinstance(array['data'], ctypes.Array):
+ *             cp = <double *><long>ctypes.addressof(array['data'])             # <<<<<<<<<<<<<<
+ *         else:
+ *             cp = <double *><long>array['data'][0]
+ */
+        __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_7 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__addressof); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+        __Pyx_GIVEREF(__pyx_t_2);
+        __pyx_t_2 = 0;
+        __pyx_t_2 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_v_cp = ((double *)__pyx_t_3);
+        goto __pyx_L25;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":65
+ *             cp = <double *><long>ctypes.addressof(array['data'])
+ *         else:
+ *             cp = <double *><long>array['data'][0]             # <<<<<<<<<<<<<<
+ * 
+ *         # Create a coordinate sequence
+ */
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_v_cp = ((double *)__pyx_t_3);
+      }
+      __pyx_L25:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":68
+ * 
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:             # <<<<<<<<<<<<<<
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:
+ */
+      __pyx_t_6 = (__pyx_v_update_geom != Py_None);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":69
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))             # <<<<<<<<<<<<<<
+ *             if n != update_ndim:
+ *                 raise ValueError(
+ */
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_v_update_geom); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __pyx_v_cs = GEOSGeom_getCoordSeq_r(__pyx_v_handle, __pyx_f_7shapely_8speedups_9_speedups_cast_geom(__pyx_t_3));
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":70
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:             # <<<<<<<<<<<<<<
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ */
+        __pyx_t_1 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_v_update_ndim, Py_NE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":73
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ *                 % update_ndim)             # <<<<<<<<<<<<<<
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)
+ */
+          __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), __pyx_v_update_ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+          __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+          PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
+          __pyx_t_2 = 0;
+          __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+          __Pyx_Raise(__pyx_t_2, 0, 0);
+          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          goto __pyx_L27;
+        }
+        __pyx_L27:;
+        goto __pyx_L26;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":75
+ *                 % update_ndim)
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)             # <<<<<<<<<<<<<<
+ * 
+ *         # add to coordinate sequence
+ */
+        __pyx_v_cs = GEOSCoordSeq_create_r(__pyx_v_handle, __pyx_v_m, __pyx_v_n);
+      }
+      __pyx_L26:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":78
+ * 
+ *         # add to coordinate sequence
+ *         for i in xrange(m):             # <<<<<<<<<<<<<<
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]
+ */
+      __pyx_t_5 = __pyx_v_m;
+      for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_5; __pyx_t_10+=1) {
+        __pyx_v_i = __pyx_t_10;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":79
+ *         # add to coordinate sequence
+ *         for i in xrange(m):
+ *             dx = cp[n*i]             # <<<<<<<<<<<<<<
+ *             dy = cp[n*i+1]
+ *             dz = 0
+ */
+        __pyx_v_dx = (__pyx_v_cp[(__pyx_v_n * __pyx_v_i)]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":80
+ *         for i in xrange(m):
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_v_dy = (__pyx_v_cp[((__pyx_v_n * __pyx_v_i) + 1)]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":81
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 dz = cp[n*i+2]
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":82
+ *             dy = cp[n*i+1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 dz = cp[n*i+2]
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":83
+ *             dz = 0
+ *             if n == 3:
+ *                 dz = cp[n*i+2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_v_dz = (__pyx_v_cp[((__pyx_v_n * __pyx_v_i) + 2)]);
+          goto __pyx_L30;
+        }
+        __pyx_L30:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":87
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":88
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":89
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":90
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)             # <<<<<<<<<<<<<<
+ * 
+ *     except AttributeError:
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dz);
+          goto __pyx_L31;
+        }
+        __pyx_L31:;
+      }
+    }
+    __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0;
+    __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0;
+    __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0;
+    goto __pyx_L13_try_end;
+    __pyx_L6_error:;
+    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":92
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ *     except AttributeError:             # <<<<<<<<<<<<<<
+ *         # Fall back on list
+ *         m = len(ob)
+ */
+    __pyx_t_5 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError);
+    if (__pyx_t_5) {
+      __Pyx_AddTraceback("shapely.speedups._speedups.geos_linestring_from_py");
+      if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_1, &__pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_t_7);
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":94
+ *     except AttributeError:
+ *         # Fall back on list
+ *         m = len(ob)             # <<<<<<<<<<<<<<
+ *         if m < 2:
+ *             raise ValueError(
+ */
+      __pyx_t_4 = PyObject_Length(__pyx_v_ob); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __pyx_v_m = __pyx_t_4;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":95
+ *         # Fall back on list
+ *         m = len(ob)
+ *         if m < 2:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ */
+      __pyx_t_6 = (__pyx_v_m < 2);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":96
+ *         m = len(ob)
+ *         if m < 2:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ */
+        __pyx_t_8 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_5), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_Raise(__pyx_t_8, 0, 0);
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        goto __pyx_L34;
+      }
+      __pyx_L34:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":98
+ *             raise ValueError(
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:             # <<<<<<<<<<<<<<
+ *             n = len(ob[0])
+ *         except TypeError:
+ */
+      {
+        PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb;
+        __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb);
+        __Pyx_XGOTREF(__pyx_save_exc_type);
+        __Pyx_XGOTREF(__pyx_save_exc_value);
+        __Pyx_XGOTREF(__pyx_save_exc_tb);
+        /*try:*/ {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":99
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ *             n = len(ob[0])             # <<<<<<<<<<<<<<
+ *         except TypeError:
+ *             raise ValueError(
+ */
+          __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_ob, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L35_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __pyx_t_4 = PyObject_Length(__pyx_t_8); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L35_error;}
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __pyx_v_n = __pyx_t_4;
+        }
+        __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0;
+        __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0;
+        __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0;
+        goto __pyx_L42_try_end;
+        __pyx_L35_error:;
+        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":100
+ *         try:
+ *             n = len(ob[0])
+ *         except TypeError:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))
+ */
+        __pyx_t_5 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+        if (__pyx_t_5) {
+          __Pyx_AddTraceback("shapely.speedups._speedups.geos_linestring_from_py");
+          if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_9, &__pyx_t_11) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(__pyx_t_8);
+          __Pyx_GOTREF(__pyx_t_9);
+          __Pyx_GOTREF(__pyx_t_11);
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":102
+ *         except TypeError:
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))             # <<<<<<<<<<<<<<
+ *         assert n == 2 or n == 3
+ * 
+ */
+          __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_12));
+          __Pyx_INCREF(__pyx_v_ob);
+          PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_v_ob);
+          __Pyx_GIVEREF(__pyx_v_ob);
+          __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_12), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_DECREF(((PyObject *)__pyx_t_12)); __pyx_t_12 = 0;
+          __pyx_t_12 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_3), __pyx_t_13); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_12));
+          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+          __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+          PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_12));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_12));
+          __pyx_t_12 = 0;
+          __pyx_t_12 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+          __Pyx_Raise(__pyx_t_12, 0, 0);
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L37_except_error;}
+          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          goto __pyx_L36_exception_handled;
+        }
+        __pyx_L37_except_error:;
+        __Pyx_XGIVEREF(__pyx_save_exc_type);
+        __Pyx_XGIVEREF(__pyx_save_exc_value);
+        __Pyx_XGIVEREF(__pyx_save_exc_tb);
+        __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+        goto __pyx_L8_except_error;
+        __pyx_L36_exception_handled:;
+        __Pyx_XGIVEREF(__pyx_save_exc_type);
+        __Pyx_XGIVEREF(__pyx_save_exc_value);
+        __Pyx_XGIVEREF(__pyx_save_exc_tb);
+        __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+        __pyx_L42_try_end:;
+      }
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":103
+ *             raise ValueError(
+ *                 "Input %s is the wrong shape for a LineString" % str(ob))
+ *         assert n == 2 or n == 3             # <<<<<<<<<<<<<<
+ * 
+ *         # Create a coordinate sequence
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      switch (__pyx_v_n) {
+        case 2:
+        case 3:
+        __pyx_t_6 = 1;
+        break;
+        default:
+        __pyx_t_6 = 0;
+        break;
+      }
+      if (unlikely(!__pyx_t_6)) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":106
+ * 
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:             # <<<<<<<<<<<<<<
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:
+ */
+      __pyx_t_6 = (__pyx_v_update_geom != Py_None);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":107
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))             # <<<<<<<<<<<<<<
+ *             if n != update_ndim:
+ *                 raise ValueError(
+ */
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_v_update_geom); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __pyx_v_cs = GEOSGeom_getCoordSeq_r(__pyx_v_handle, __pyx_f_7shapely_8speedups_9_speedups_cast_geom(__pyx_t_3));
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":108
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:             # <<<<<<<<<<<<<<
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ */
+        __pyx_t_11 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_9 = PyObject_RichCompare(__pyx_t_11, __pyx_v_update_ndim, Py_NE); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":111
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ *                 % update_ndim)             # <<<<<<<<<<<<<<
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)
+ */
+          __pyx_t_9 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), __pyx_v_update_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_9));
+          __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_11));
+          PyTuple_SET_ITEM(__pyx_t_11, 0, ((PyObject *)__pyx_t_9));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_9));
+          __pyx_t_9 = 0;
+          __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
+          __Pyx_Raise(__pyx_t_9, 0, 0);
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          goto __pyx_L46;
+        }
+        __pyx_L46:;
+        goto __pyx_L45;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":113
+ *                 % update_ndim)
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)             # <<<<<<<<<<<<<<
+ * 
+ *         # add to coordinate sequence
+ */
+        __pyx_v_cs = GEOSCoordSeq_create_r(__pyx_v_handle, __pyx_v_m, __pyx_v_n);
+      }
+      __pyx_L45:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":116
+ * 
+ *         # add to coordinate sequence
+ *         for i in xrange(m):             # <<<<<<<<<<<<<<
+ *             coords = ob[i]
+ *             dx = coords[0]
+ */
+      __pyx_t_5 = __pyx_v_m;
+      for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_5; __pyx_t_10+=1) {
+        __pyx_v_i = __pyx_t_10;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":117
+ *         # add to coordinate sequence
+ *         for i in xrange(m):
+ *             coords = ob[i]             # <<<<<<<<<<<<<<
+ *             dx = coords[0]
+ *             dy = coords[1]
+ */
+        __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_ob, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_DECREF(__pyx_v_coords);
+        __pyx_v_coords = __pyx_t_9;
+        __pyx_t_9 = 0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":118
+ *         for i in xrange(m):
+ *             coords = ob[i]
+ *             dx = coords[0]             # <<<<<<<<<<<<<<
+ *             dy = coords[1]
+ *             dz = 0
+ */
+        __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_coords, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_9); if (unlikely((__pyx_t_14 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __pyx_v_dx = __pyx_t_14;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":119
+ *             coords = ob[i]
+ *             dx = coords[0]
+ *             dy = coords[1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_coords, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_9); if (unlikely((__pyx_t_14 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __pyx_v_dy = __pyx_t_14;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":120
+ *             dx = coords[0]
+ *             dy = coords[1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 if len(coords) != 3:
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":121
+ *             dy = coords[1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 if len(coords) != 3:
+ *                     raise ValueError("Inconsistent coordinate dimensionality")
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":122
+ *             dz = 0
+ *             if n == 3:
+ *                 if len(coords) != 3:             # <<<<<<<<<<<<<<
+ *                     raise ValueError("Inconsistent coordinate dimensionality")
+ *                 dz = coords[2]
+ */
+          __pyx_t_4 = PyObject_Length(__pyx_v_coords); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __pyx_t_6 = (__pyx_t_4 != 3);
+          if (__pyx_t_6) {
+
+            /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":123
+ *             if n == 3:
+ *                 if len(coords) != 3:
+ *                     raise ValueError("Inconsistent coordinate dimensionality")             # <<<<<<<<<<<<<<
+ *                 dz = coords[2]
+ * 
+ */
+            __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_7), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+            __Pyx_GOTREF(__pyx_t_9);
+            __Pyx_Raise(__pyx_t_9, 0, 0);
+            __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+            goto __pyx_L50;
+          }
+          __pyx_L50:;
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":124
+ *                 if len(coords) != 3:
+ *                     raise ValueError("Inconsistent coordinate dimensionality")
+ *                 dz = coords[2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_coords, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_9); if (unlikely((__pyx_t_14 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __pyx_v_dz = __pyx_t_14;
+          goto __pyx_L49;
+        }
+        __pyx_L49:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":128
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":129
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":130
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":131
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)             # <<<<<<<<<<<<<<
+ * 
+ *     if update_geom is not None:
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dz);
+          goto __pyx_L51;
+        }
+        __pyx_L51:;
+      }
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L7_exception_handled;
+    }
+    __pyx_L8_except_error:;
+    __Pyx_XGIVEREF(__pyx_save_exc_type);
+    __Pyx_XGIVEREF(__pyx_save_exc_value);
+    __Pyx_XGIVEREF(__pyx_save_exc_tb);
+    __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+    goto __pyx_L1_error;
+    __pyx_L7_exception_handled:;
+    __Pyx_XGIVEREF(__pyx_save_exc_type);
+    __Pyx_XGIVEREF(__pyx_save_exc_value);
+    __Pyx_XGIVEREF(__pyx_save_exc_tb);
+    __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+    __pyx_L13_try_end:;
+  }
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":133
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ *     if update_geom is not None:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_6 = (__pyx_v_update_geom != Py_None);
+  if (__pyx_t_6) {
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":134
+ * 
+ *     if update_geom is not None:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <long>GEOSGeom_createLineString_r(handle, cs), n
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L52;
+  }
+  /*else*/ {
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":136
+ *         return None
+ *     else:
+ *         return <long>GEOSGeom_createLineString_r(handle, cs), n             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_7 = PyInt_FromLong(((long)GEOSGeom_createLineString_r(__pyx_v_handle, __pyx_v_cs))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_7 = 0;
+    __pyx_t_1 = 0;
+    __pyx_r = ((PyObject *)__pyx_t_2);
+    __pyx_t_2 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L52:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("shapely.speedups._speedups.geos_linestring_from_py");
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_DECREF(__pyx_v_array);
+  __Pyx_DECREF(__pyx_v_coords);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":139
+ * 
+ * 
+ * def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):             # <<<<<<<<<<<<<<
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+ */
+
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_2geos_linearring_from_py(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_7shapely_8speedups_9_speedups_2geos_linearring_from_py = {__Pyx_NAMESTR("geos_linearring_from_py"), (PyCFunction)__pyx_pf_7shapely_8speedups_9_speedups_2geos_linearring_from_py, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_2geos_linearring_from_py(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_ob = 0;
+  PyObject *__pyx_v_update_geom = 0;
+  PyObject *__pyx_v_update_ndim = 0;
+  double *__pyx_v_cp;
+  struct GEOSContextHandle_HS *__pyx_v_handle;
+  GEOSCoordSequence *__pyx_v_cs;
+  double __pyx_v_dx;
+  double __pyx_v_dy;
+  double __pyx_v_dz;
+  int __pyx_v_i;
+  int __pyx_v_n;
+  int __pyx_v_m;
+  int __pyx_v_M;
+  PyObject *__pyx_v_array;
+  PyObject *__pyx_v_coords;
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  long __pyx_t_3;
+  Py_ssize_t __pyx_t_4;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  int __pyx_t_10;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_t_14;
+  double __pyx_t_15;
+  static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ob,&__pyx_n_s__update_geom,&__pyx_n_s__update_ndim,0};
+  __Pyx_RefNannySetupContext("geos_linearring_from_py");
+  __pyx_self = __pyx_self;
+  if (unlikely(__pyx_kwds)) {
+    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)Py_None);
+    values[2] = ((PyObject *)__pyx_int_0);
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      case  0: break;
+      default: goto __pyx_L5_argtuple_error;
+    }
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  0:
+      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob);
+      if (likely(values[0])) kw_args--;
+      else goto __pyx_L5_argtuple_error;
+      case  1:
+      if (kw_args > 0) {
+        PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__update_geom);
+        if (value) { values[1] = value; kw_args--; }
+      }
+      case  2:
+      if (kw_args > 0) {
+        PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__update_ndim);
+        if (value) { values[2] = value; kw_args--; }
+      }
+    }
+    if (unlikely(kw_args > 0)) {
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "geos_linearring_from_py") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    }
+    __pyx_v_ob = values[0];
+    __pyx_v_update_geom = values[1];
+    __pyx_v_update_ndim = values[2];
+  } else {
+    __pyx_v_update_geom = ((PyObject *)Py_None);
+    __pyx_v_update_ndim = ((PyObject *)__pyx_int_0);
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  3: __pyx_v_update_ndim = PyTuple_GET_ITEM(__pyx_args, 2);
+      case  2: __pyx_v_update_geom = PyTuple_GET_ITEM(__pyx_args, 1);
+      case  1: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 0);
+      break;
+      default: goto __pyx_L5_argtuple_error;
+    }
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("geos_linearring_from_py", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("shapely.speedups._speedups.geos_linearring_from_py");
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_v_array = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_v_coords = Py_None; __Pyx_INCREF(Py_None);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":141
+ * def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)             # <<<<<<<<<<<<<<
+ *     cdef GEOSCoordSequence *cs
+ *     cdef double dx, dy, dz
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__lgeos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__geos_handle); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_handle = __pyx_f_7shapely_8speedups_9_speedups_cast_handle(__pyx_t_3);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":145
+ *     cdef double dx, dy, dz
+ *     cdef int i, n, m, M
+ *     try:             # <<<<<<<<<<<<<<
+ *         # From array protocol
+ *         array = ob.__array_interface__
+ */
+  {
+    PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb;
+    __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb);
+    __Pyx_XGOTREF(__pyx_save_exc_type);
+    __Pyx_XGOTREF(__pyx_save_exc_value);
+    __Pyx_XGOTREF(__pyx_save_exc_tb);
+    /*try:*/ {
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":147
+ *     try:
+ *         # From array protocol
+ *         array = ob.__array_interface__             # <<<<<<<<<<<<<<
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]
+ */
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_ob, __pyx_n_s____array_interface__); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_v_array);
+      __pyx_v_array = __pyx_t_2;
+      __pyx_t_2 = 0;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":148
+ *         # From array protocol
+ *         array = ob.__array_interface__
+ *         assert len(array['shape']) == 2             # <<<<<<<<<<<<<<
+ *         m = array['shape'][0]
+ *         n = array['shape'][1]
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      if (unlikely(!(__pyx_t_4 == 2))) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":149
+ *         array = ob.__array_interface__
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]             # <<<<<<<<<<<<<<
+ *         n = array['shape'][1]
+ *         if m < 3:
+ */
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_v_m = __pyx_t_5;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":150
+ *         assert len(array['shape']) == 2
+ *         m = array['shape'][0]
+ *         n = array['shape'][1]             # <<<<<<<<<<<<<<
+ *         if m < 3:
+ *             raise ValueError(
+ */
+      __pyx_t_1 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__shape)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_v_n = __pyx_t_5;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":151
+ *         m = array['shape'][0]
+ *         n = array['shape'][1]
+ *         if m < 3:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ */
+      __pyx_t_6 = (__pyx_v_m < 3);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":152
+ *         n = array['shape'][1]
+ *         if m < 3:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert n == 2 or n == 3
+ */
+        __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_9), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_Raise(__pyx_t_2, 0, 0);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":154
+ *             raise ValueError(
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert n == 2 or n == 3             # <<<<<<<<<<<<<<
+ * 
+ *         # Make pointer to the coordinate array
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      switch (__pyx_v_n) {
+        case 2:
+        case 3:
+        __pyx_t_6 = 1;
+        break;
+        default:
+        __pyx_t_6 = 0;
+        break;
+      }
+      if (unlikely(!__pyx_t_6)) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":157
+ * 
+ *         # Make pointer to the coordinate array
+ *         if isinstance(array['data'], ctypes.Array):             # <<<<<<<<<<<<<<
+ *             cp = <double *><long>ctypes.addressof(array['data'])
+ *         else:
+ */
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__Array); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_6 = PyObject_IsInstance(__pyx_t_2, __pyx_t_7); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":158
+ *         # Make pointer to the coordinate array
+ *         if isinstance(array['data'], ctypes.Array):
+ *             cp = <double *><long>ctypes.addressof(array['data'])             # <<<<<<<<<<<<<<
+ *         else:
+ *             cp = <double *><long>array['data'][0]
+ */
+        __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_2 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__addressof); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
+        __Pyx_GIVEREF(__pyx_t_7);
+        __pyx_t_7 = 0;
+        __pyx_t_7 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_7); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_v_cp = ((double *)__pyx_t_3);
+        goto __pyx_L15;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":160
+ *             cp = <double *><long>ctypes.addressof(array['data'])
+ *         else:
+ *             cp = <double *><long>array['data'][0]             # <<<<<<<<<<<<<<
+ * 
+ *         # Add closing coordinates to sequence?
+ */
+        __pyx_t_7 = PyObject_GetItem(__pyx_v_array, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_7) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_7, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_v_cp = ((double *)__pyx_t_3);
+      }
+      __pyx_L15:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":163
+ * 
+ *         # Add closing coordinates to sequence?
+ *         if cp[0] != cp[m*n-n] or cp[1] != cp[m*n-n+1]:             # <<<<<<<<<<<<<<
+ *             M = m + 1
+ *         else:
+ */
+      __pyx_t_6 = ((__pyx_v_cp[0]) != (__pyx_v_cp[((__pyx_v_m * __pyx_v_n) - __pyx_v_n)]));
+      if (!__pyx_t_6) {
+        __pyx_t_8 = ((__pyx_v_cp[1]) != (__pyx_v_cp[(((__pyx_v_m * __pyx_v_n) - __pyx_v_n) + 1)]));
+        __pyx_t_9 = __pyx_t_8;
+      } else {
+        __pyx_t_9 = __pyx_t_6;
+      }
+      if (__pyx_t_9) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":164
+ *         # Add closing coordinates to sequence?
+ *         if cp[0] != cp[m*n-n] or cp[1] != cp[m*n-n+1]:
+ *             M = m + 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             M = m
+ */
+        __pyx_v_M = (__pyx_v_m + 1);
+        goto __pyx_L16;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":166
+ *             M = m + 1
+ *         else:
+ *             M = m             # <<<<<<<<<<<<<<
+ * 
+ *         # Create a coordinate sequence
+ */
+        __pyx_v_M = __pyx_v_m;
+      }
+      __pyx_L16:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":169
+ * 
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:             # <<<<<<<<<<<<<<
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:
+ */
+      __pyx_t_9 = (__pyx_v_update_geom != Py_None);
+      if (__pyx_t_9) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":170
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))             # <<<<<<<<<<<<<<
+ *             if n != update_ndim:
+ *                 raise ValueError(
+ */
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_v_update_geom); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __pyx_v_cs = GEOSGeom_getCoordSeq_r(__pyx_v_handle, __pyx_f_7shapely_8speedups_9_speedups_cast_geom(__pyx_t_3));
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":171
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:             # <<<<<<<<<<<<<<
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ */
+        __pyx_t_1 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_7 = PyObject_RichCompare(__pyx_t_1, __pyx_v_update_ndim, Py_NE); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        if (__pyx_t_9) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":174
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ *                 % update_ndim)             # <<<<<<<<<<<<<<
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, M, n)
+ */
+          __pyx_t_7 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), __pyx_v_update_ndim); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_7));
+          __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+          PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_7));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_7));
+          __pyx_t_7 = 0;
+          __pyx_t_7 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          __Pyx_GOTREF(__pyx_t_7);
+          __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+          __Pyx_Raise(__pyx_t_7, 0, 0);
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+          goto __pyx_L18;
+        }
+        __pyx_L18:;
+        goto __pyx_L17;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":176
+ *                 % update_ndim)
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, M, n)             # <<<<<<<<<<<<<<
+ * 
+ *         # add to coordinate sequence
+ */
+        __pyx_v_cs = GEOSCoordSeq_create_r(__pyx_v_handle, __pyx_v_M, __pyx_v_n);
+      }
+      __pyx_L17:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":179
+ * 
+ *         # add to coordinate sequence
+ *         for i in xrange(m):             # <<<<<<<<<<<<<<
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]
+ */
+      __pyx_t_5 = __pyx_v_m;
+      for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_5; __pyx_t_10+=1) {
+        __pyx_v_i = __pyx_t_10;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":180
+ *         # add to coordinate sequence
+ *         for i in xrange(m):
+ *             dx = cp[n*i]             # <<<<<<<<<<<<<<
+ *             dy = cp[n*i+1]
+ *             dz = 0
+ */
+        __pyx_v_dx = (__pyx_v_cp[(__pyx_v_n * __pyx_v_i)]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":181
+ *         for i in xrange(m):
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_v_dy = (__pyx_v_cp[((__pyx_v_n * __pyx_v_i) + 1)]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":182
+ *             dx = cp[n*i]
+ *             dy = cp[n*i+1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 dz = cp[n*i+2]
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":183
+ *             dy = cp[n*i+1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 dz = cp[n*i+2]
+ * 
+ */
+        __pyx_t_9 = (__pyx_v_n == 3);
+        if (__pyx_t_9) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":184
+ *             dz = 0
+ *             if n == 3:
+ *                 dz = cp[n*i+2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_v_dz = (__pyx_v_cp[((__pyx_v_n * __pyx_v_i) + 2)]);
+          goto __pyx_L21;
+        }
+        __pyx_L21:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":188
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":189
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":190
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ */
+        __pyx_t_9 = (__pyx_v_n == 3);
+        if (__pyx_t_9) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":191
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)             # <<<<<<<<<<<<<<
+ * 
+ *         # Add closing coordinates to sequence?
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dz);
+          goto __pyx_L22;
+        }
+        __pyx_L22:;
+      }
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":194
+ * 
+ *         # Add closing coordinates to sequence?
+ *         if M > m:             # <<<<<<<<<<<<<<
+ *             dx = cp[0]
+ *             dy = cp[1]
+ */
+      __pyx_t_9 = (__pyx_v_M > __pyx_v_m);
+      if (__pyx_t_9) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":195
+ *         # Add closing coordinates to sequence?
+ *         if M > m:
+ *             dx = cp[0]             # <<<<<<<<<<<<<<
+ *             dy = cp[1]
+ *             dz = 0
+ */
+        __pyx_v_dx = (__pyx_v_cp[0]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":196
+ *         if M > m:
+ *             dx = cp[0]
+ *             dy = cp[1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_v_dy = (__pyx_v_cp[1]);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":197
+ *             dx = cp[0]
+ *             dy = cp[1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 dz = cp[2]
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":198
+ *             dy = cp[1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 dz = cp[2]
+ * 
+ */
+        __pyx_t_9 = (__pyx_v_n == 3);
+        if (__pyx_t_9) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":199
+ *             dz = 0
+ *             if n == 3:
+ *                 dz = cp[2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_v_dz = (__pyx_v_cp[2]);
+          goto __pyx_L24;
+        }
+        __pyx_L24:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":203
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":204
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":205
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ * 
+ */
+        __pyx_t_9 = (__pyx_v_n == 3);
+        if (__pyx_t_9) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":206
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)             # <<<<<<<<<<<<<<
+ * 
+ *     except AttributeError:
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dz);
+          goto __pyx_L25;
+        }
+        __pyx_L25:;
+        goto __pyx_L23;
+      }
+      __pyx_L23:;
+    }
+    __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0;
+    __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0;
+    __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0;
+    goto __pyx_L13_try_end;
+    __pyx_L6_error:;
+    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":208
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ * 
+ *     except AttributeError:             # <<<<<<<<<<<<<<
+ *         # Fall back on list
+ *         m = len(ob)
+ */
+    __pyx_t_5 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError);
+    if (__pyx_t_5) {
+      __Pyx_AddTraceback("shapely.speedups._speedups.geos_linearring_from_py");
+      if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_1, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_t_2);
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":210
+ *     except AttributeError:
+ *         # Fall back on list
+ *         m = len(ob)             # <<<<<<<<<<<<<<
+ *         n = len(ob[0])
+ *         if m < 3:
+ */
+      __pyx_t_4 = PyObject_Length(__pyx_v_ob); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __pyx_v_m = __pyx_t_4;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":211
+ *         # Fall back on list
+ *         m = len(ob)
+ *         n = len(ob[0])             # <<<<<<<<<<<<<<
+ *         if m < 3:
+ *             raise ValueError(
+ */
+      __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_ob, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_4 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __pyx_v_n = __pyx_t_4;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":212
+ *         m = len(ob)
+ *         n = len(ob[0])
+ *         if m < 3:             # <<<<<<<<<<<<<<
+ *             raise ValueError(
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ */
+      __pyx_t_9 = (__pyx_v_m < 3);
+      if (__pyx_t_9) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":213
+ *         n = len(ob[0])
+ *         if m < 3:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert (n == 2 or n == 3)
+ */
+        __pyx_t_11 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_10), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_Raise(__pyx_t_11, 0, 0);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        goto __pyx_L28;
+      }
+      __pyx_L28:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":215
+ *             raise ValueError(
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert (n == 2 or n == 3)             # <<<<<<<<<<<<<<
+ * 
+ *         # Add closing coordinates if not provided
+ */
+      #ifndef CYTHON_WITHOUT_ASSERTIONS
+      switch (__pyx_v_n) {
+        case 2:
+        case 3:
+        __pyx_t_9 = 1;
+        break;
+        default:
+        __pyx_t_9 = 0;
+        break;
+      }
+      if (unlikely(!__pyx_t_9)) {
+        PyErr_SetNone(PyExc_AssertionError);
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+      }
+      #endif
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":218
+ * 
+ *         # Add closing coordinates if not provided
+ *         if m == 3 or ob[0][0] != ob[-1][0] or ob[0][1] != ob[-1][1]:             # <<<<<<<<<<<<<<
+ *             M = m + 1
+ *         else:
+ */
+      __pyx_t_9 = (__pyx_v_m == 3);
+      if (!__pyx_t_9) {
+        __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_ob, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_ob, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_13 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_13) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_11 = PyObject_RichCompare(__pyx_t_12, __pyx_t_13, Py_NE); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        if (!__pyx_t_6) {
+          __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_ob, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __pyx_t_13 = __Pyx_GetItemInt(__pyx_t_11, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_13) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_ob, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __pyx_t_12 = __Pyx_GetItemInt(__pyx_t_11, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __pyx_t_11 = PyObject_RichCompare(__pyx_t_13, __pyx_t_12, Py_NE); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __pyx_t_14 = __pyx_t_8;
+        } else {
+          __pyx_t_14 = __pyx_t_6;
+        }
+        __pyx_t_6 = __pyx_t_14;
+      } else {
+        __pyx_t_6 = __pyx_t_9;
+      }
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":219
+ *         # Add closing coordinates if not provided
+ *         if m == 3 or ob[0][0] != ob[-1][0] or ob[0][1] != ob[-1][1]:
+ *             M = m + 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             M = m
+ */
+        __pyx_v_M = (__pyx_v_m + 1);
+        goto __pyx_L29;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":221
+ *             M = m + 1
+ *         else:
+ *             M = m             # <<<<<<<<<<<<<<
+ * 
+ *         # Create a coordinate sequence
+ */
+        __pyx_v_M = __pyx_v_m;
+      }
+      __pyx_L29:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":224
+ * 
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:             # <<<<<<<<<<<<<<
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:
+ */
+      __pyx_t_6 = (__pyx_v_update_geom != Py_None);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":225
+ *         # Create a coordinate sequence
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))             # <<<<<<<<<<<<<<
+ *             if n != update_ndim:
+ *                 raise ValueError(
+ */
+        __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_v_update_geom); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __pyx_v_cs = GEOSGeom_getCoordSeq_r(__pyx_v_handle, __pyx_f_7shapely_8speedups_9_speedups_cast_geom(__pyx_t_3));
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":226
+ *         if update_geom is not None:
+ *             cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+ *             if n != update_ndim:             # <<<<<<<<<<<<<<
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ */
+        __pyx_t_11 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __pyx_t_12 = PyObject_RichCompare(__pyx_t_11, __pyx_v_update_ndim, Py_NE); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_12); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":229
+ *                 raise ValueError(
+ *                 "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+ *                 % update_ndim)             # <<<<<<<<<<<<<<
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, M, n)
+ */
+          __pyx_t_12 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_4), __pyx_v_update_ndim); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_12));
+          __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(((PyObject *)__pyx_t_11));
+          PyTuple_SET_ITEM(__pyx_t_11, 0, ((PyObject *)__pyx_t_12));
+          __Pyx_GIVEREF(((PyObject *)__pyx_t_12));
+          __pyx_t_12 = 0;
+          __pyx_t_12 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
+          __Pyx_Raise(__pyx_t_12, 0, 0);
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          goto __pyx_L31;
+        }
+        __pyx_L31:;
+        goto __pyx_L30;
+      }
+      /*else*/ {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":231
+ *                 % update_ndim)
+ *         else:
+ *             cs = GEOSCoordSeq_create_r(handle, M, n)             # <<<<<<<<<<<<<<
+ * 
+ *         # add to coordinate sequence
+ */
+        __pyx_v_cs = GEOSCoordSeq_create_r(__pyx_v_handle, __pyx_v_M, __pyx_v_n);
+      }
+      __pyx_L30:;
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":234
+ * 
+ *         # add to coordinate sequence
+ *         for i in xrange(m):             # <<<<<<<<<<<<<<
+ *             coords = ob[i]
+ *             dx = coords[0]
+ */
+      __pyx_t_5 = __pyx_v_m;
+      for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_5; __pyx_t_10+=1) {
+        __pyx_v_i = __pyx_t_10;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":235
+ *         # add to coordinate sequence
+ *         for i in xrange(m):
+ *             coords = ob[i]             # <<<<<<<<<<<<<<
+ *             dx = coords[0]
+ *             dy = coords[1]
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_ob, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_v_coords);
+        __pyx_v_coords = __pyx_t_12;
+        __pyx_t_12 = 0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":236
+ *         for i in xrange(m):
+ *             coords = ob[i]
+ *             dx = coords[0]             # <<<<<<<<<<<<<<
+ *             dy = coords[1]
+ *             dz = 0
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_v_dx = __pyx_t_15;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":237
+ *             coords = ob[i]
+ *             dx = coords[0]
+ *             dy = coords[1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_v_dy = __pyx_t_15;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":238
+ *             dx = coords[0]
+ *             dy = coords[1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 dz = coords[2]
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":239
+ *             dy = coords[1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 dz = coords[2]
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":240
+ *             dz = 0
+ *             if n == 3:
+ *                 dz = coords[2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          __pyx_v_dz = __pyx_t_15;
+          goto __pyx_L34;
+        }
+        __pyx_L34:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":244
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":245
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":246
+ *             GEOSCoordSeq_setX_r(handle, cs, i, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":247
+ *             GEOSCoordSeq_setY_r(handle, cs, i, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, i, dz)             # <<<<<<<<<<<<<<
+ * 
+ *         # Add closing coordinates to sequence?
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, __pyx_v_dz);
+          goto __pyx_L35;
+        }
+        __pyx_L35:;
+      }
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":250
+ * 
+ *         # Add closing coordinates to sequence?
+ *         if M > m:             # <<<<<<<<<<<<<<
+ *             coords = ob[0]
+ *             dx = coords[0]
+ */
+      __pyx_t_6 = (__pyx_v_M > __pyx_v_m);
+      if (__pyx_t_6) {
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":251
+ *         # Add closing coordinates to sequence?
+ *         if M > m:
+ *             coords = ob[0]             # <<<<<<<<<<<<<<
+ *             dx = coords[0]
+ *             dy = coords[1]
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_ob, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __Pyx_DECREF(__pyx_v_coords);
+        __pyx_v_coords = __pyx_t_12;
+        __pyx_t_12 = 0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":252
+ *         if M > m:
+ *             coords = ob[0]
+ *             dx = coords[0]             # <<<<<<<<<<<<<<
+ *             dy = coords[1]
+ *             dz = 0
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_v_dx = __pyx_t_15;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":253
+ *             coords = ob[0]
+ *             dx = coords[0]
+ *             dy = coords[1]             # <<<<<<<<<<<<<<
+ *             dz = 0
+ *             if n == 3:
+ */
+        __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_GOTREF(__pyx_t_12);
+        __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+        __pyx_v_dy = __pyx_t_15;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":254
+ *             dx = coords[0]
+ *             dy = coords[1]
+ *             dz = 0             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 dz = coords[2]
+ */
+        __pyx_v_dz = 0.0;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":255
+ *             dy = coords[1]
+ *             dz = 0
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 dz = coords[2]
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":256
+ *             dz = 0
+ *             if n == 3:
+ *                 dz = coords[2]             # <<<<<<<<<<<<<<
+ * 
+ *             # Because of a bug in the GEOS C API,
+ */
+          __pyx_t_12 = __Pyx_GetItemInt(__pyx_v_coords, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_12) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_GOTREF(__pyx_t_12);
+          __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L8_except_error;}
+          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+          __pyx_v_dz = __pyx_t_15;
+          goto __pyx_L37;
+        }
+        __pyx_L37:;
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":260
+ *             # Because of a bug in the GEOS C API,
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:
+ */
+        GEOSCoordSeq_setX_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dx);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":261
+ *             # always set X before Y
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)             # <<<<<<<<<<<<<<
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ */
+        GEOSCoordSeq_setY_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dy);
+
+        /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":262
+ *             GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:             # <<<<<<<<<<<<<<
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ * 
+ */
+        __pyx_t_6 = (__pyx_v_n == 3);
+        if (__pyx_t_6) {
+
+          /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":263
+ *             GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+ *             if n == 3:
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)             # <<<<<<<<<<<<<<
+ * 
+ *     if update_geom is not None:
+ */
+          GEOSCoordSeq_setZ_r(__pyx_v_handle, __pyx_v_cs, (__pyx_v_M - 1), __pyx_v_dz);
+          goto __pyx_L38;
+        }
+        __pyx_L38:;
+        goto __pyx_L36;
+      }
+      __pyx_L36:;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      goto __pyx_L7_exception_handled;
+    }
+    __pyx_L8_except_error:;
+    __Pyx_XGIVEREF(__pyx_save_exc_type);
+    __Pyx_XGIVEREF(__pyx_save_exc_value);
+    __Pyx_XGIVEREF(__pyx_save_exc_tb);
+    __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+    goto __pyx_L1_error;
+    __pyx_L7_exception_handled:;
+    __Pyx_XGIVEREF(__pyx_save_exc_type);
+    __Pyx_XGIVEREF(__pyx_save_exc_value);
+    __Pyx_XGIVEREF(__pyx_save_exc_tb);
+    __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
+    __pyx_L13_try_end:;
+  }
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":265
+ *                 GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+ * 
+ *     if update_geom is not None:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_6 = (__pyx_v_update_geom != Py_None);
+  if (__pyx_t_6) {
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":266
+ * 
+ *     if update_geom is not None:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <long>GEOSGeom_createLinearRing_r(handle, cs), n
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+    goto __pyx_L39;
+  }
+  /*else*/ {
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":268
+ *         return None
+ *     else:
+ *         return <long>GEOSGeom_createLinearRing_r(handle, cs), n             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __pyx_t_2 = PyInt_FromLong(((long)GEOSGeom_createLinearRing_r(__pyx_v_handle, __pyx_v_cs))); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(((PyObject *)__pyx_t_7));
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_2);
+    PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __pyx_t_2 = 0;
+    __pyx_t_1 = 0;
+    __pyx_r = ((PyObject *)__pyx_t_7);
+    __pyx_t_7 = 0;
+    goto __pyx_L0;
+  }
+  __pyx_L39:;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("shapely.speedups._speedups.geos_linearring_from_py");
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_DECREF(__pyx_v_array);
+  __Pyx_DECREF(__pyx_v_coords);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":271
+ * 
+ * 
+ * def coordseq_ctypes(self):             # <<<<<<<<<<<<<<
+ *     cdef int i, n, m
+ *     cdef double temp
+ */
+
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_3coordseq_ctypes(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_7shapely_8speedups_9_speedups_3coordseq_ctypes = {__Pyx_NAMESTR("coordseq_ctypes"), (PyCFunction)__pyx_pf_7shapely_8speedups_9_speedups_3coordseq_ctypes, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pf_7shapely_8speedups_9_speedups_3coordseq_ctypes(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+  int __pyx_v_i;
+  int __pyx_v_n;
+  int __pyx_v_m;
+  double __pyx_v_temp;
+  struct GEOSContextHandle_HS *__pyx_v_handle;
+  GEOSCoordSequence *__pyx_v_cs;
+  double *__pyx_v_data_p;
+  PyObject *__pyx_v_array_type;
+  PyObject *__pyx_v_data;
+  PyObject *__pyx_r = NULL;
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  long __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  __Pyx_RefNannySetupContext("coordseq_ctypes");
+  __pyx_self = __pyx_self;
+  __pyx_v_array_type = Py_None; __Pyx_INCREF(Py_None);
+  __pyx_v_data = Py_None; __Pyx_INCREF(Py_None);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":274
+ *     cdef int i, n, m
+ *     cdef double temp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)             # <<<<<<<<<<<<<<
+ *     cdef GEOSCoordSequence *cs
+ *     cdef double *data_p
+ */
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__lgeos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__geos_handle); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_2); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_handle = __pyx_f_7shapely_8speedups_9_speedups_cast_handle(__pyx_t_3);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":277
+ *     cdef GEOSCoordSequence *cs
+ *     cdef double *data_p
+ *     self._update()             # <<<<<<<<<<<<<<
+ *     n = self._ndim
+ *     m = self.__len__()
+ */
+  __pyx_t_2 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s___update); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":278
+ *     cdef double *data_p
+ *     self._update()
+ *     n = self._ndim             # <<<<<<<<<<<<<<
+ *     m = self.__len__()
+ *     array_type = ctypes.c_double * (m * n)
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s___ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_n = __pyx_t_4;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":279
+ *     self._update()
+ *     n = self._ndim
+ *     m = self.__len__()             # <<<<<<<<<<<<<<
+ *     array_type = ctypes.c_double * (m * n)
+ *     data = array_type()
+ */
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s____len__); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_m = __pyx_t_4;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":280
+ *     n = self._ndim
+ *     m = self.__len__()
+ *     array_type = ctypes.c_double * (m * n)             # <<<<<<<<<<<<<<
+ *     data = array_type()
+ * 
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__c_double); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = PyInt_FromLong((__pyx_v_m * __pyx_v_n)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_v_array_type);
+  __pyx_v_array_type = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":281
+ *     m = self.__len__()
+ *     array_type = ctypes.c_double * (m * n)
+ *     data = array_type()             # <<<<<<<<<<<<<<
+ * 
+ *     cs = cast_seq(self._cseq)
+ */
+  __pyx_t_5 = PyObject_Call(__pyx_v_array_type, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_v_data);
+  __pyx_v_data = __pyx_t_5;
+  __pyx_t_5 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":283
+ *     data = array_type()
+ * 
+ *     cs = cast_seq(self._cseq)             # <<<<<<<<<<<<<<
+ *     data_p = <double *><long>ctypes.addressof(data)
+ * 
+ */
+  __pyx_t_5 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s___cseq); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_5); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_v_cs = __pyx_f_7shapely_8speedups_9_speedups_cast_seq(__pyx_t_3);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":284
+ * 
+ *     cs = cast_seq(self._cseq)
+ *     data_p = <double *><long>ctypes.addressof(data)             # <<<<<<<<<<<<<<
+ * 
+ *     for i in xrange(m):
+ */
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__ctypes); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__addressof); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_5));
+  __Pyx_INCREF(__pyx_v_data);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_data);
+  __Pyx_GIVEREF(__pyx_v_data);
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_data_p = ((double *)__pyx_t_3);
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":286
+ *     data_p = <double *><long>ctypes.addressof(data)
+ * 
+ *     for i in xrange(m):             # <<<<<<<<<<<<<<
+ *         GEOSCoordSeq_getX_r(handle, cs, i, &temp)
+ *         data_p[n*i] = temp
+ */
+  __pyx_t_4 = __pyx_v_m;
+  for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_4; __pyx_t_6+=1) {
+    __pyx_v_i = __pyx_t_6;
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":287
+ * 
+ *     for i in xrange(m):
+ *         GEOSCoordSeq_getX_r(handle, cs, i, &temp)             # <<<<<<<<<<<<<<
+ *         data_p[n*i] = temp
+ *         GEOSCoordSeq_getY_r(handle, cs, i, &temp)
+ */
+    GEOSCoordSeq_getX_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, (&__pyx_v_temp));
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":288
+ *     for i in xrange(m):
+ *         GEOSCoordSeq_getX_r(handle, cs, i, &temp)
+ *         data_p[n*i] = temp             # <<<<<<<<<<<<<<
+ *         GEOSCoordSeq_getY_r(handle, cs, i, &temp)
+ *         data_p[n*i+1] = temp
+ */
+    (__pyx_v_data_p[(__pyx_v_n * __pyx_v_i)]) = __pyx_v_temp;
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":289
+ *         GEOSCoordSeq_getX_r(handle, cs, i, &temp)
+ *         data_p[n*i] = temp
+ *         GEOSCoordSeq_getY_r(handle, cs, i, &temp)             # <<<<<<<<<<<<<<
+ *         data_p[n*i+1] = temp
+ *         if n == 3: # TODO: use hasz
+ */
+    GEOSCoordSeq_getY_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, (&__pyx_v_temp));
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":290
+ *         data_p[n*i] = temp
+ *         GEOSCoordSeq_getY_r(handle, cs, i, &temp)
+ *         data_p[n*i+1] = temp             # <<<<<<<<<<<<<<
+ *         if n == 3: # TODO: use hasz
+ *             GEOSCoordSeq_getZ_r(handle, cs, i, &temp)
+ */
+    (__pyx_v_data_p[((__pyx_v_n * __pyx_v_i) + 1)]) = __pyx_v_temp;
+
+    /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":291
+ *         GEOSCoordSeq_getY_r(handle, cs, i, &temp)
+ *         data_p[n*i+1] = temp
+ *         if n == 3: # TODO: use hasz             # <<<<<<<<<<<<<<
+ *             GEOSCoordSeq_getZ_r(handle, cs, i, &temp)
+ *             data_p[n*i+2] = temp
+ */
+    __pyx_t_7 = (__pyx_v_n == 3);
+    if (__pyx_t_7) {
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":292
+ *         data_p[n*i+1] = temp
+ *         if n == 3: # TODO: use hasz
+ *             GEOSCoordSeq_getZ_r(handle, cs, i, &temp)             # <<<<<<<<<<<<<<
+ *             data_p[n*i+2] = temp
+ *     return data
+ */
+      GEOSCoordSeq_getZ_r(__pyx_v_handle, __pyx_v_cs, __pyx_v_i, (&__pyx_v_temp));
+
+      /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":293
+ *         if n == 3: # TODO: use hasz
+ *             GEOSCoordSeq_getZ_r(handle, cs, i, &temp)
+ *             data_p[n*i+2] = temp             # <<<<<<<<<<<<<<
+ *     return data
+ * 
+ */
+      (__pyx_v_data_p[((__pyx_v_n * __pyx_v_i) + 2)]) = __pyx_v_temp;
+      goto __pyx_L7;
+    }
+    __pyx_L7:;
+  }
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":294
+ *             GEOSCoordSeq_getZ_r(handle, cs, i, &temp)
+ *             data_p[n*i+2] = temp
+ *     return data             # <<<<<<<<<<<<<<
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_data);
+  __pyx_r = __pyx_v_data;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("shapely.speedups._speedups.coordseq_ctypes");
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_DECREF(__pyx_v_array_type);
+  __Pyx_DECREF(__pyx_v_data);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+    PyModuleDef_HEAD_INIT,
+    __Pyx_NAMESTR("_speedups"),
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
+  {&__pyx_n_s_11, __pyx_k_11, sizeof(__pyx_k_11), 0, 0, 1, 1},
+  {&__pyx_n_s_12, __pyx_k_12, sizeof(__pyx_k_12), 0, 0, 1, 1},
+  {&__pyx_n_s_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 0, 1, 1},
+  {&__pyx_n_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 1},
+  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+  {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0},
+  {&__pyx_kp_s_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 0, 1, 0},
+  {&__pyx_kp_s_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 1, 0},
+  {&__pyx_n_s__Array, __pyx_k__Array, sizeof(__pyx_k__Array), 0, 0, 1, 1},
+  {&__pyx_n_s__AttributeError, __pyx_k__AttributeError, sizeof(__pyx_k__AttributeError), 0, 0, 1, 1},
+  {&__pyx_n_s__IndexError, __pyx_k__IndexError, sizeof(__pyx_k__IndexError), 0, 0, 1, 1},
+  {&__pyx_n_s__TypeError, __pyx_k__TypeError, sizeof(__pyx_k__TypeError), 0, 0, 1, 1},
+  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____array_interface__, __pyx_k____array_interface__, sizeof(__pyx_k____array_interface__), 0, 0, 1, 1},
+  {&__pyx_n_s____len__, __pyx_k____len__, sizeof(__pyx_k____len__), 0, 0, 1, 1},
+  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
+  {&__pyx_n_s___cseq, __pyx_k___cseq, sizeof(__pyx_k___cseq), 0, 0, 1, 1},
+  {&__pyx_n_s___ndim, __pyx_k___ndim, sizeof(__pyx_k___ndim), 0, 0, 1, 1},
+  {&__pyx_n_s___update, __pyx_k___update, sizeof(__pyx_k___update), 0, 0, 1, 1},
+  {&__pyx_n_s__addressof, __pyx_k__addressof, sizeof(__pyx_k__addressof), 0, 0, 1, 1},
+  {&__pyx_n_s__c_double, __pyx_k__c_double, sizeof(__pyx_k__c_double), 0, 0, 1, 1},
+  {&__pyx_n_s__coordseq_ctypes, __pyx_k__coordseq_ctypes, sizeof(__pyx_k__coordseq_ctypes), 0, 0, 1, 1},
+  {&__pyx_n_s__ctypes, __pyx_k__ctypes, sizeof(__pyx_k__ctypes), 0, 0, 1, 1},
+  {&__pyx_n_s__data, __pyx_k__data, sizeof(__pyx_k__data), 0, 0, 1, 1},
+  {&__pyx_n_s__destroy, __pyx_k__destroy, sizeof(__pyx_k__destroy), 0, 0, 1, 1},
+  {&__pyx_n_s__geos_handle, __pyx_k__geos_handle, sizeof(__pyx_k__geos_handle), 0, 0, 1, 1},
+  {&__pyx_n_s__lgeos, __pyx_k__lgeos, sizeof(__pyx_k__lgeos), 0, 0, 1, 1},
+  {&__pyx_n_s__ob, __pyx_k__ob, sizeof(__pyx_k__ob), 0, 0, 1, 1},
+  {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
+  {&__pyx_n_s__shape, __pyx_k__shape, sizeof(__pyx_k__shape), 0, 0, 1, 1},
+  {&__pyx_n_s__update_geom, __pyx_k__update_geom, sizeof(__pyx_k__update_geom), 0, 0, 1, 1},
+  {&__pyx_n_s__update_ndim, __pyx_k__update_ndim, sizeof(__pyx_k__update_ndim), 0, 0, 1, 1},
+  {&__pyx_n_s__xrange, __pyx_k__xrange, sizeof(__pyx_k__xrange), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_IndexError = __Pyx_GetName(__pyx_b, __pyx_n_s__IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION >= 3
+  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #else
+  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  __pyx_builtin_AttributeError = __Pyx_GetName(__pyx_b, __pyx_n_s__AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_TypeError = __Pyx_GetName(__pyx_b, __pyx_n_s__TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants");
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":52
+ *         m = array['shape'][0]
+ *         if m < 2:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ */
+  __pyx_k_tuple_2 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_2));
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_1));
+  PyTuple_SET_ITEM(__pyx_k_tuple_2, 0, ((PyObject *)__pyx_kp_s_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":96
+ *         m = len(ob)
+ *         if m < 2:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "LineStrings must have at least 2 coordinate tuples")
+ *         try:
+ */
+  __pyx_k_tuple_5 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_5));
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_1));
+  PyTuple_SET_ITEM(__pyx_k_tuple_5, 0, ((PyObject *)__pyx_kp_s_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_5));
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":123
+ *             if n == 3:
+ *                 if len(coords) != 3:
+ *                     raise ValueError("Inconsistent coordinate dimensionality")             # <<<<<<<<<<<<<<
+ *                 dz = coords[2]
+ * 
+ */
+  __pyx_k_tuple_7 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_7));
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_6));
+  PyTuple_SET_ITEM(__pyx_k_tuple_7, 0, ((PyObject *)__pyx_kp_s_6));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_6));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":152
+ *         n = array['shape'][1]
+ *         if m < 3:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert n == 2 or n == 3
+ */
+  __pyx_k_tuple_9 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_9));
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
+  PyTuple_SET_ITEM(__pyx_k_tuple_9, 0, ((PyObject *)__pyx_kp_s_8));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_9));
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":213
+ *         n = len(ob[0])
+ *         if m < 3:
+ *             raise ValueError(             # <<<<<<<<<<<<<<
+ *                 "A LinearRing must have at least 3 coordinate tuples")
+ *         assert (n == 2 or n == 3)
+ */
+  __pyx_k_tuple_10 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_10));
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_8));
+  PyTuple_SET_ITEM(__pyx_k_tuple_10, 0, ((PyObject *)__pyx_kp_s_8));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_8));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_10));
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC init_speedups(void); /*proto*/
+PyMODINIT_FUNC init_speedups(void)
+#else
+PyMODINIT_FUNC PyInit__speedups(void); /*proto*/
+PyMODINIT_FUNC PyInit__speedups(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  #if CYTHON_REFNANNY
+  void* __pyx_refnanny = NULL;
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  __pyx_refnanny = __Pyx_RefNanny->SetupContext("PyMODINIT_FUNC PyInit__speedups(void)", __LINE__, __FILE__);
+  #endif
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __pyx_binding_PyCFunctionType_USED
+  if (__pyx_binding_PyCFunctionType_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_speedups"), __pyx_methods, 0, 0, PYTHON_API_VERSION);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  #if PY_MAJOR_VERSION < 3
+  Py_INCREF(__pyx_m);
+  #endif
+  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));
+  if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__pyx_module_is_main_shapely__speedups___speedups) {
+    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  }
+  /*--- Builtin init code ---*/
+  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  /*--- Type import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":8
+ * # Transcription to cython: Copyright (c) 2011, Oliver Tonnhofer
+ * 
+ * import ctypes             # <<<<<<<<<<<<<<
+ * from shapely.geos import lgeos
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__ctypes), 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__ctypes, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":9
+ * 
+ * import ctypes
+ * from shapely.geos import lgeos             # <<<<<<<<<<<<<<
+ * 
+ * cdef extern from "geos_c.h":
+ */
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__lgeos));
+  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__lgeos));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lgeos));
+  __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s_11), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__lgeos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__lgeos, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":37
+ *     return <GEOSCoordSequence *>handle_addr
+ * 
+ * def destroy(geom):             # <<<<<<<<<<<<<<
+ *     GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))
+ * 
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7shapely_8speedups_9_speedups_0destroy, NULL, __pyx_n_s_12); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__destroy, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":40
+ *     GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))
+ * 
+ * def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):             # <<<<<<<<<<<<<<
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7shapely_8speedups_9_speedups_1geos_linestring_from_py, NULL, __pyx_n_s_12); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_13, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":139
+ * 
+ * 
+ * def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):             # <<<<<<<<<<<<<<
+ *     cdef double *cp
+ *     cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7shapely_8speedups_9_speedups_2geos_linearring_from_py, NULL, __pyx_n_s_12); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_14, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":271
+ * 
+ * 
+ * def coordseq_ctypes(self):             # <<<<<<<<<<<<<<
+ *     cdef int i, n, m
+ *     cdef double temp
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7shapely_8speedups_9_speedups_3coordseq_ctypes, NULL, __pyx_n_s_12); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__coordseq_ctypes, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "/Users/olt/dev/shapely.git/shapely/speedups/_speedups.pyx":1
+ * # geos_linestring_from_py was transcribed from shapely.geometry.linestring             # <<<<<<<<<<<<<<
+ * # geos_linearring_from_py was transcribed from shapely.geometry.polygon
+ * # coordseq_ctypes was transcribed from shapely.coords.CoordinateSequence.ctypes
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  if (__pyx_m) {
+    __Pyx_AddTraceback("init shapely.speedups._speedups");
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init shapely.speedups._speedups");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* Runtime support code */
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result)
+        PyErr_SetObject(PyExc_NameError, name);
+    return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AS_STRING(kw_name));
+        #endif
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *number, *more_or_less;
+
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    number = (num_expected == 1) ? "" : "s";
+    PyErr_Format(PyExc_TypeError,
+        #if PY_VERSION_HEX < 0x02050000
+            "%s() takes %s %d positional argument%s (%d given)",
+        #else
+            "%s() takes %s %zd positional argument%s (%zd given)",
+        #endif
+        func_name, more_or_less, num_expected, number, num_found);
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+        } else {
+            #if PY_MAJOR_VERSION < 3
+            if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
+            #else
+            if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
+            #endif
+                goto invalid_keyword_type;
+            } else {
+                for (name = first_kw_arg; *name; name++) {
+                    #if PY_MAJOR_VERSION >= 3
+                    if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
+                        PyUnicode_Compare(**name, key) == 0) break;
+                    #else
+                    if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
+                        _PyString_Eq(**name, key)) break;
+                    #endif
+                }
+                if (*name) {
+                    values[name-argnames] = value;
+                } else {
+                    /* unexpected keyword found */
+                    for (name=argnames; name != first_kw_arg; name++) {
+                        if (**name == key) goto arg_passed_twice;
+                        #if PY_MAJOR_VERSION >= 3
+                        if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
+                            PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
+                        #else
+                        if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
+                            _PyString_Eq(**name, key)) goto arg_passed_twice;
+                        #endif
+                    }
+                    if (kwds2) {
+                        if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+                    } else {
+                        goto invalid_keyword;
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, **name);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%s() got an unexpected keyword argument '%s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *local_type, *local_value, *local_tb;
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    local_type = tstate->curexc_type;
+    local_value = tstate->curexc_value;
+    local_tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+    if (unlikely(tstate->curexc_type))
+        goto bad;
+    #if PY_MAJOR_VERSION >= 3
+    if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+        goto bad;
+    #endif
+    *type = local_type;
+    *value = local_value;
+    *tb = local_tb;
+    Py_INCREF(local_type);
+    Py_INCREF(local_value);
+    Py_INCREF(local_tb);
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = local_type;
+    tstate->exc_value = local_value;
+    tstate->exc_traceback = local_tb;
+    /* Make sure tstate is in a consistent state when we XDECREF
+       these objects (XDECREF may run arbitrary code). */
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+    return 0;
+bad:
+    *type = 0;
+    *value = 0;
+    *tb = 0;
+    Py_XDECREF(local_type);
+    Py_XDECREF(local_value);
+    Py_XDECREF(local_tb);
+    return -1;
+}
+
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->exc_type;
+    *value = tstate->exc_value;
+    *tb = tstate->exc_traceback;
+    Py_XINCREF(*type);
+    Py_XINCREF(*value);
+    Py_XINCREF(*tb);
+}
+
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = type;
+    tstate->exc_value = value;
+    tstate->exc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
+    PyObject *py_import = 0;
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    if (!py_import)
+        goto bad;
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    module = PyObject_CallFunctionObjArgs(py_import,
+        name, global_dict, empty_dict, list, NULL);
+bad:
+    Py_XDECREF(empty_list);
+    Py_XDECREF(py_import);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+}
+
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+}
+
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+    Py_XINCREF(type);
+    Py_XINCREF(value);
+    Py_XINCREF(tb);
+    /* First, check the traceback argument, replacing None with NULL. */
+    if (tb == Py_None) {
+        Py_DECREF(tb);
+        tb = 0;
+    }
+    else if (tb != NULL && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto raise_error;
+    }
+    /* Next, replace a missing value with None */
+    if (value == NULL) {
+        value = Py_None;
+        Py_INCREF(value);
+    }
+    #if PY_VERSION_HEX < 0x02050000
+    if (!PyClass_Check(type))
+    #else
+    if (!PyType_Check(type))
+    #endif
+    {
+        /* Raising an instance.  The value should be a dummy. */
+        if (value != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        /* Normalize to raise <class>, <instance> */
+        Py_DECREF(value);
+        value = type;
+        #if PY_VERSION_HEX < 0x02050000
+            if (PyInstance_Check(type)) {
+                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+                Py_INCREF(type);
+            }
+            else {
+                type = 0;
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception must be an old-style class or instance");
+                goto raise_error;
+            }
+        #else
+            type = (PyObject*) Py_TYPE(type);
+            Py_INCREF(type);
+            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "raise: exception class must be a subclass of BaseException");
+                goto raise_error;
+            }
+        #endif
+    }
+
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+
+#else /* Python 3+ */
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (!PyExceptionClass_Check(type)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+
+    PyErr_SetObject(type, value);
+
+    if (tb) {
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
+        }
+    }
+
+bad:
+    return;
+}
+#endif
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
+    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned char" :
+                    "value too large to convert to unsigned char");
+            }
+            return (unsigned char)-1;
+        }
+        return (unsigned char)val;
+    }
+    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
+    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned short" :
+                    "value too large to convert to unsigned short");
+            }
+            return (unsigned short)-1;
+        }
+        return (unsigned short)val;
+    }
+    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
+    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(unsigned int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(unsigned int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to unsigned int" :
+                    "value too large to convert to unsigned int");
+            }
+            return (unsigned int)-1;
+        }
+        return (unsigned int)val;
+    }
+    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
+    const char neg_one = (char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to char" :
+                    "value too large to convert to char");
+            }
+            return (char)-1;
+        }
+        return (char)val;
+    }
+    return (char)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
+    const short neg_one = (short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to short" :
+                    "value too large to convert to short");
+            }
+            return (short)-1;
+        }
+        return (short)val;
+    }
+    return (short)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
+    const signed char neg_one = (signed char)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed char) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed char)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed char" :
+                    "value too large to convert to signed char");
+            }
+            return (signed char)-1;
+        }
+        return (signed char)val;
+    }
+    return (signed char)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
+    const signed short neg_one = (signed short)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed short) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed short)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed short" :
+                    "value too large to convert to signed short");
+            }
+            return (signed short)-1;
+        }
+        return (signed short)val;
+    }
+    return (signed short)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
+    const signed int neg_one = (signed int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(signed int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(signed int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to signed int" :
+                    "value too large to convert to signed int");
+            }
+            return (signed int)-1;
+        }
+        return (signed int)val;
+    }
+    return (signed int)__Pyx_PyInt_AsSignedLong(x);
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
+    const int neg_one = (int)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (sizeof(int) < sizeof(long)) {
+        long val = __Pyx_PyInt_AsLong(x);
+        if (unlikely(val != (long)(int)val)) {
+            if (!unlikely(val == -1 && PyErr_Occurred())) {
+                PyErr_SetString(PyExc_OverflowError,
+                    (is_unsigned && unlikely(val < 0)) ?
+                    "can't convert negative value to int" :
+                    "value too large to convert to int");
+            }
+            return (int)-1;
+        }
+        return (int)val;
+    }
+    return (int)__Pyx_PyInt_AsLong(x);
+}
+
+static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
+    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned long");
+            return (unsigned long)-1;
+        }
+        return (unsigned long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned long");
+                return (unsigned long)-1;
+            }
+            return PyLong_AsUnsignedLong(x);
+        } else {
+            return PyLong_AsLong(x);
+        }
+    } else {
+        unsigned long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned long)-1;
+        val = __Pyx_PyInt_AsUnsignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
+    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to unsigned PY_LONG_LONG");
+            return (unsigned PY_LONG_LONG)-1;
+        }
+        return (unsigned PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to unsigned PY_LONG_LONG");
+                return (unsigned PY_LONG_LONG)-1;
+            }
+            return PyLong_AsUnsignedLongLong(x);
+        } else {
+            return PyLong_AsLongLong(x);
+        }
+    } else {
+        unsigned PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
+    const long neg_one = (long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to long");
+            return (long)-1;
+        }
+        return (long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to long");
+                return (long)-1;
+            }
+            return PyLong_AsUnsignedLong(x);
+        } else {
+            return PyLong_AsLong(x);
+        }
+    } else {
+        long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (long)-1;
+        val = __Pyx_PyInt_AsLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
+    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to PY_LONG_LONG");
+            return (PY_LONG_LONG)-1;
+        }
+        return (PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to PY_LONG_LONG");
+                return (PY_LONG_LONG)-1;
+            }
+            return PyLong_AsUnsignedLongLong(x);
+        } else {
+            return PyLong_AsLongLong(x);
+        }
+    } else {
+        PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
+    const signed long neg_one = (signed long)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed long");
+            return (signed long)-1;
+        }
+        return (signed long)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed long");
+                return (signed long)-1;
+            }
+            return PyLong_AsUnsignedLong(x);
+        } else {
+            return PyLong_AsLong(x);
+        }
+    } else {
+        signed long val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed long)-1;
+        val = __Pyx_PyInt_AsSignedLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
+    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_VERSION_HEX < 0x03000000
+    if (likely(PyInt_Check(x))) {
+        long val = PyInt_AS_LONG(x);
+        if (is_unsigned && unlikely(val < 0)) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "can't convert negative value to signed PY_LONG_LONG");
+            return (signed PY_LONG_LONG)-1;
+        }
+        return (signed PY_LONG_LONG)val;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+            if (unlikely(Py_SIZE(x) < 0)) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "can't convert negative value to signed PY_LONG_LONG");
+                return (signed PY_LONG_LONG)-1;
+            }
+            return PyLong_AsUnsignedLongLong(x);
+        } else {
+            return PyLong_AsLongLong(x);
+        }
+    } else {
+        signed PY_LONG_LONG val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (signed PY_LONG_LONG)-1;
+        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(const char *funcname) {
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    PyObject *py_globals = 0;
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(__pyx_filename);
+    #else
+    py_srcfile = PyUnicode_FromString(__pyx_filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (__pyx_clineno) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    py_code = PyCode_New(
+        0,            /*int argcount,*/
+        #if PY_MAJOR_VERSION >= 3
+        0,            /*int kwonlyargcount,*/
+        #endif
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple,  /*PyObject *consts,*/
+        __pyx_empty_tuple,  /*PyObject *names,*/
+        __pyx_empty_tuple,  /*PyObject *varnames,*/
+        __pyx_empty_tuple,  /*PyObject *freevars,*/
+        __pyx_empty_tuple,  /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        __pyx_lineno,   /*int firstlineno,*/
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    if (!py_code) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = __pyx_lineno;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        #if PY_MAJOR_VERSION < 3
+        if (t->is_unicode) {
+            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+        } else if (t->intern) {
+            *t->p = PyString_InternFromString(t->s);
+        } else {
+            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        }
+        #else  /* Python 3+ has unicode identifiers */
+        if (t->is_unicode | t->is_str) {
+            if (t->intern) {
+                *t->p = PyUnicode_InternFromString(t->s);
+            } else if (t->encoding) {
+                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+            } else {
+                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+            }
+        } else {
+            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+        }
+        #endif
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+/* Type Conversion Functions */
+
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+   int is_true = x == Py_True;
+   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+   else return PyObject_IsTrue(x);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+  PyNumberMethods *m;
+  const char *name = NULL;
+  PyObject *res = NULL;
+#if PY_VERSION_HEX < 0x03000000
+  if (PyInt_Check(x) || PyLong_Check(x))
+#else
+  if (PyLong_Check(x))
+#endif
+    return Py_INCREF(x), x;
+  m = Py_TYPE(x)->tp_as_number;
+#if PY_VERSION_HEX < 0x03000000
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Int(x);
+  }
+  else if (m && m->nb_long) {
+    name = "long";
+    res = PyNumber_Long(x);
+  }
+#else
+  if (m && m->nb_int) {
+    name = "int";
+    res = PyNumber_Long(x);
+  }
+#endif
+  if (res) {
+#if PY_VERSION_HEX < 0x03000000
+    if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+    if (!PyLong_Check(res)) {
+#endif
+      PyErr_Format(PyExc_TypeError,
+                   "__%s__ returned non-%s (type %.200s)",
+                   name, name, Py_TYPE(res)->tp_name);
+      Py_DECREF(res);
+      return NULL;
+    }
+  }
+  else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_TypeError,
+                    "an integer is required");
+  }
+  return res;
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+  Py_ssize_t ival;
+  PyObject* x = PyNumber_Index(b);
+  if (!x) return -1;
+  ival = PyInt_AsSsize_t(x);
+  Py_DECREF(x);
+  return ival;
+}
+
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+
+static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
+   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
+   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
+       return (size_t)-1;
+   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       PyErr_SetString(PyExc_OverflowError,
+                       "value too large to convert to size_t");
+       return (size_t)-1;
+   }
+   return (size_t)val;
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/shapely/speedups/_speedups.pyx b/shapely/speedups/_speedups.pyx
new file mode 100644
index 0000000..49c9804
--- /dev/null
+++ b/shapely/speedups/_speedups.pyx
@@ -0,0 +1,295 @@
+# geos_linestring_from_py was transcribed from shapely.geometry.linestring
+# geos_linearring_from_py was transcribed from shapely.geometry.polygon
+# coordseq_ctypes was transcribed from shapely.coords.CoordinateSequence.ctypes
+#
+# Copyright (c) 2007, Sean C. Gillies
+# Transcription to cython: Copyright (c) 2011, Oliver Tonnhofer
+
+import ctypes
+from shapely.geos import lgeos
+
+cdef extern from "geos_c.h":
+    ctypedef struct GEOSCoordSequence
+    ctypedef struct GEOSGeometry
+    cdef struct GEOSContextHandle_HS
+    GEOSCoordSequence *GEOSCoordSeq_create_r(GEOSContextHandle_HS *,double, double)
+    GEOSCoordSequence *GEOSGeom_getCoordSeq_r(GEOSContextHandle_HS *, GEOSGeometry *)
+    int GEOSCoordSeq_getSize_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int *)
+    int GEOSCoordSeq_setX_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double)
+    int GEOSCoordSeq_setY_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double)
+    int GEOSCoordSeq_setZ_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double)
+    int GEOSCoordSeq_getX_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double *)
+    int GEOSCoordSeq_getY_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double *)
+    int GEOSCoordSeq_getZ_r(GEOSContextHandle_HS *, GEOSCoordSequence *, int, double *)
+    GEOSGeometry *GEOSGeom_createLineString_r(GEOSContextHandle_HS *, GEOSCoordSequence *)
+    GEOSGeometry *GEOSGeom_createLinearRing_r(GEOSContextHandle_HS *, GEOSCoordSequence *)
+    void GEOSGeom_destroy_r(GEOSContextHandle_HS *, GEOSGeometry *)
+
+cdef inline GEOSGeometry *cast_geom(long geom_addr):
+    return <GEOSGeometry *>geom_addr
+
+cdef inline GEOSContextHandle_HS *cast_handle(long handle_addr):
+    return <GEOSContextHandle_HS *>handle_addr
+
+cdef inline GEOSCoordSequence *cast_seq(long handle_addr):
+    return <GEOSCoordSequence *>handle_addr
+
+def destroy(geom):
+    GEOSGeom_destroy_r(cast_handle(lgeos.geos_handle), cast_geom(geom))
+
+def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
+    cdef double *cp
+    cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+    cdef GEOSCoordSequence *cs
+    cdef double dx, dy, dz
+    cdef int i, n, m
+    try:
+        # From array protocol
+        array = ob.__array_interface__
+        assert len(array['shape']) == 2
+        m = array['shape'][0]
+        if m < 2:
+            raise ValueError(
+                "LineStrings must have at least 2 coordinate tuples")
+        try:
+            n = array['shape'][1]
+        except IndexError:
+            raise ValueError(
+                "Input %s is the wrong shape for a LineString" % str(ob))
+        assert n == 2 or n == 3
+
+        # Make pointer to the coordinate array
+        if isinstance(array['data'], ctypes.Array):
+            cp = <double *><long>ctypes.addressof(array['data'])
+        else:
+            cp = <double *><long>array['data'][0]
+
+        # Create a coordinate sequence
+        if update_geom is not None:
+            cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+            if n != update_ndim:
+                raise ValueError(
+                "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+                % update_ndim)
+        else:
+            cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)
+
+        # add to coordinate sequence
+        for i in xrange(m):
+            dx = cp[n*i]
+            dy = cp[n*i+1]
+            dz = 0
+            if n == 3:
+                dz = cp[n*i+2]
+                
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, i, dx)
+            GEOSCoordSeq_setY_r(handle, cs, i, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+    
+    except AttributeError:
+        # Fall back on list
+        m = len(ob)
+        if m < 2:
+            raise ValueError(
+                "LineStrings must have at least 2 coordinate tuples")
+        try:
+            n = len(ob[0])
+        except TypeError:
+            raise ValueError(
+                "Input %s is the wrong shape for a LineString" % str(ob))
+        assert n == 2 or n == 3
+
+        # Create a coordinate sequence
+        if update_geom is not None:
+            cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+            if n != update_ndim:
+                raise ValueError(
+                "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+                % update_ndim)
+        else:
+            cs = GEOSCoordSeq_create_r(handle, <int>m, <int>n)
+
+        # add to coordinate sequence
+        for i in xrange(m):
+            coords = ob[i]
+            dx = coords[0]
+            dy = coords[1]
+            dz = 0
+            if n == 3:
+                if len(coords) != 3:
+                    raise ValueError("Inconsistent coordinate dimensionality")
+                dz = coords[2]
+            
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, i, dx)
+            GEOSCoordSeq_setY_r(handle, cs, i, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+
+    if update_geom is not None:
+        return None
+    else:
+        return <long>GEOSGeom_createLineString_r(handle, cs), n
+
+
+def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
+    cdef double *cp
+    cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+    cdef GEOSCoordSequence *cs
+    cdef double dx, dy, dz
+    cdef int i, n, m, M
+    try:
+        # From array protocol
+        array = ob.__array_interface__
+        assert len(array['shape']) == 2
+        m = array['shape'][0]
+        n = array['shape'][1]
+        if m < 3:
+            raise ValueError(
+                "A LinearRing must have at least 3 coordinate tuples")
+        assert n == 2 or n == 3
+
+        # Make pointer to the coordinate array
+        if isinstance(array['data'], ctypes.Array):
+            cp = <double *><long>ctypes.addressof(array['data'])
+        else:
+            cp = <double *><long>array['data'][0]
+
+        # Add closing coordinates to sequence?
+        if cp[0] != cp[m*n-n] or cp[1] != cp[m*n-n+1]:
+            M = m + 1
+        else:
+            M = m
+
+        # Create a coordinate sequence
+        if update_geom is not None:
+            cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+            if n != update_ndim:
+                raise ValueError(
+                "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+                % update_ndim)
+        else:
+            cs = GEOSCoordSeq_create_r(handle, M, n)
+
+        # add to coordinate sequence
+        for i in xrange(m):
+            dx = cp[n*i]
+            dy = cp[n*i+1]
+            dz = 0
+            if n == 3:
+                dz = cp[n*i+2]
+        
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, i, dx)
+            GEOSCoordSeq_setY_r(handle, cs, i, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+
+        # Add closing coordinates to sequence?
+        if M > m:
+            dx = cp[0]
+            dy = cp[1]
+            dz = 0
+            if n == 3:
+                dz = cp[2]
+        
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+            GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+            
+    except AttributeError:
+        # Fall back on list
+        m = len(ob)
+        n = len(ob[0])
+        if m < 3:
+            raise ValueError(
+                "A LinearRing must have at least 3 coordinate tuples")
+        assert (n == 2 or n == 3)
+
+        # Add closing coordinates if not provided
+        if m == 3 or ob[0][0] != ob[-1][0] or ob[0][1] != ob[-1][1]:
+            M = m + 1
+        else:
+            M = m
+
+        # Create a coordinate sequence
+        if update_geom is not None:
+            cs = GEOSGeom_getCoordSeq_r(handle, cast_geom(update_geom))
+            if n != update_ndim:
+                raise ValueError(
+                "Wrong coordinate dimensions; this geometry has dimensions: %d" \
+                % update_ndim)
+        else:
+            cs = GEOSCoordSeq_create_r(handle, M, n)
+        
+        # add to coordinate sequence
+        for i in xrange(m):
+            coords = ob[i]
+            dx = coords[0]
+            dy = coords[1]
+            dz = 0
+            if n == 3:
+                dz = coords[2]
+        
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, i, dx)
+            GEOSCoordSeq_setY_r(handle, cs, i, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, i, dz)
+
+        # Add closing coordinates to sequence?
+        if M > m:
+            coords = ob[0]
+            dx = coords[0]
+            dy = coords[1]
+            dz = 0
+            if n == 3:
+                dz = coords[2]
+        
+            # Because of a bug in the GEOS C API, 
+            # always set X before Y
+            GEOSCoordSeq_setX_r(handle, cs, M-1, dx)
+            GEOSCoordSeq_setY_r(handle, cs, M-1, dy)
+            if n == 3:
+                GEOSCoordSeq_setZ_r(handle, cs, M-1, dz)
+
+    if update_geom is not None:
+        return None
+    else:
+        return <long>GEOSGeom_createLinearRing_r(handle, cs), n
+
+
+def coordseq_ctypes(self):
+    cdef int i, n, m
+    cdef double temp
+    cdef GEOSContextHandle_HS *handle = cast_handle(lgeos.geos_handle)
+    cdef GEOSCoordSequence *cs
+    cdef double *data_p
+    self._update()
+    n = self._ndim
+    m = self.__len__()
+    array_type = ctypes.c_double * (m * n)
+    data = array_type()
+    
+    cs = cast_seq(self._cseq)
+    data_p = <double *><long>ctypes.addressof(data)
+    
+    for i in xrange(m):
+        GEOSCoordSeq_getX_r(handle, cs, i, &temp)
+        data_p[n*i] = temp
+        GEOSCoordSeq_getY_r(handle, cs, i, &temp)
+        data_p[n*i+1] = temp
+        if n == 3: # TODO: use hasz
+            GEOSCoordSeq_getZ_r(handle, cs, i, &temp)
+            data_p[n*i+2] = temp
+    return data
+
diff --git a/shapely/tests/__init__.py b/shapely/tests/__init__.py
index 5bac818..2950d5c 100644
--- a/shapely/tests/__init__.py
+++ b/shapely/tests/__init__.py
@@ -3,7 +3,7 @@ from unittest import TestSuite
 import test_doctests, test_prepared, test_equality, test_geomseq, test_xy
 import test_collection, test_emptiness, test_singularity, test_validation
 import test_mapping, test_delegated, test_dlls, test_linear_referencing
-import test_products_z
+import test_products_z, test_box, test_speedups, test_cga
 
 def test_suite():
     suite = TestSuite()
@@ -21,5 +21,8 @@ def test_suite():
     suite.addTest(test_dlls.test_suite())
     suite.addTest(test_linear_referencing.test_suite())
     suite.addTest(test_products_z.test_suite())
+    suite.addTest(test_box.test_suite())
+    suite.addTest(test_speedups.test_suite())
+    suite.addTest(test_cga.test_suite())
     return suite
 
diff --git a/shapely/tests/test_box.py b/shapely/tests/test_box.py
new file mode 100644
index 0000000..761c288
--- /dev/null
+++ b/shapely/tests/test_box.py
@@ -0,0 +1,19 @@
+import unittest
+from shapely import geometry
+
+class BoxTestCase(unittest.TestCase):
+    def test_ccw(self):
+        b = geometry.box(0, 0, 1, 1, ccw=True)
+        self.assertEqual(b.exterior.coords[0], (1.0, 0.0))
+        self.assertEqual(b.exterior.coords[1], (1.0, 1.0))
+    def test_ccw_default(self):
+        b = geometry.box(0, 0, 1, 1)
+        self.assertEqual(b.exterior.coords[0], (1.0, 0.0))
+        self.assertEqual(b.exterior.coords[1], (1.0, 1.0))
+    def test_cw(self):
+        b = geometry.box(0, 0, 1, 1, ccw=False)
+        self.assertEqual(b.exterior.coords[0], (0.0, 0.0))
+        self.assertEqual(b.exterior.coords[1], (0.0, 1.0))
+
+def test_suite():
+    return unittest.TestLoader().loadTestsFromTestCase(BoxTestCase)
diff --git a/shapely/tests/test_cga.py b/shapely/tests/test_cga.py
new file mode 100644
index 0000000..87ef1c7
--- /dev/null
+++ b/shapely/tests/test_cga.py
@@ -0,0 +1,33 @@
+import unittest
+from shapely.geometry.polygon import LinearRing, orient, Polygon
+
+class RingOrientationTestCase(unittest.TestCase):
+    def test_ccw(self):
+        ring = LinearRing([(1,0),(0,1),(0,0)])
+        self.failUnless(ring.is_ccw)
+    def test_cw(self):
+        ring = LinearRing([(0,0),(0,1),(1,0)])
+        self.failIf(ring.is_ccw)
+
+class PolygonOrienterTestCase(unittest.TestCase):
+    def test_no_holes(self):
+        ring = LinearRing([(0,0),(0,1),(1,0)])
+        polygon = Polygon(ring)
+        self.failIf(polygon.exterior.is_ccw)
+        polygon = orient(polygon, 1)
+        self.failUnless(polygon.exterior.is_ccw)
+    def test_holes(self):
+        polygon = Polygon([(0,0),(0,1),(1,0)], 
+                        [[(0.5,0.25),(0.25,0.5),(0.25,0.25)]])
+        self.failIf(polygon.exterior.is_ccw)
+        self.failUnless(polygon.interiors[0].is_ccw)
+        polygon = orient(polygon, 1)
+        self.failUnless(polygon.exterior.is_ccw)
+        self.failIf(polygon.interiors[0].is_ccw)
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return unittest.TestSuite([
+        loader.loadTestsFromTestCase(RingOrientationTestCase),
+        loader.loadTestsFromTestCase(PolygonOrienterTestCase)])
+
diff --git a/shapely/tests/test_dlls.py b/shapely/tests/test_dlls.py
index 1fbfc42..7a2ca16 100644
--- a/shapely/tests/test_dlls.py
+++ b/shapely/tests/test_dlls.py
@@ -1,5 +1,3 @@
-import os
-import sys
 import unittest
 
 from shapely.geos import load_dll
@@ -9,8 +7,9 @@ class LoadingTestCase(unittest.TestCase):
         self.assertRaises(OSError, load_dll, 'geosh_c')
     def test_fallbacks(self):
         a = load_dll('geosh_c', fallbacks=[
-            '/opt/local/lib/libgeos_c.dylib',
-            'libgeos_c.so.1', 
+            '/opt/local/lib/libgeos_c.dylib', # MacPorts
+            '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X)
+            'libgeos_c.so.1',
             'libgeos_c.so'])
 
 def test_suite():
diff --git a/shapely/tests/test_speedups.py b/shapely/tests/test_speedups.py
new file mode 100644
index 0000000..ada3e3e
--- /dev/null
+++ b/shapely/tests/test_speedups.py
@@ -0,0 +1,38 @@
+import unittest
+
+from shapely import speedups
+from shapely.geometry import LineString, Polygon
+
+class SpeedupsTestCase(unittest.TestCase):
+    
+    def setUp(self):
+        self.assertFalse(speedups._orig)
+        speedups.enable()
+        self.assertTrue(speedups._orig)
+        
+    def tearDown(self):
+        self.assertTrue(speedups._orig)
+        speedups.disable()
+        self.assertFalse(speedups._orig)
+
+    def test_create_linestring(self):
+        ls = LineString([(0, 0), (1, 0), (1, 2)])
+        self.assertEqual(ls.length, 3)
+
+    def test_create_polygon(self):
+        p = Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
+        self.assertEqual(p.length, 8)
+
+    def test_create_polygon_from_linestring(self):
+        ls = LineString([(0, 0), (2, 0), (2, 2), (0, 2)])
+        p = Polygon(ls)
+        self.assertEqual(p.length, 8)
+
+
+def test_suite():
+    if speedups.available:
+        return unittest.TestLoader().loadTestsFromTestCase(
+            SpeedupsTestCase
+        )
+    else:
+        return lambda x: None
\ No newline at end of file
diff --git a/shapely/wkb.py b/shapely/wkb.py
index 6e3869b..5c882ab 100644
--- a/shapely/wkb.py
+++ b/shapely/wkb.py
@@ -1,8 +1,7 @@
 """Load/dump geometries using the well-known binary (WKB) format
 """
 
-from ctypes import byref, c_size_t, c_char_p, string_at
-from ctypes import c_void_p, c_size_t
+from ctypes import byref, c_size_t, c_char_p, c_void_p
 
 from shapely.geos import lgeos, ReadingError
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/python-shapely.git



More information about the Pkg-grass-devel mailing list