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

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

commit 8eb6d6f9dc3437826b23f2cd9a06fc445c88102e
Author: Pietro Battiston <m...@pietrobattiston.it>
Date:   Sat Mar 10 17:38:41 2012 +0100

    Imported Upstream version 1.2.14
---
 CHANGES.txt                         |  14 +++--
 CREDITS.txt                         |   1 +
 PKG-INFO                            |  46 ++++++++-------
 README.rst                          |  29 +++++----
 Shapely.egg-info/PKG-INFO           |  46 ++++++++-------
 Shapely.egg-info/SOURCES.txt        |   1 +
 docs/manual.txt                     |  51 ++++++++++++----
 setup.py                            |  10 +++-
 shapely/__init__.py                 |   2 +-
 shapely/coords.py                   |  59 ++++++++++++-------
 shapely/geometry/base.py            |  44 +++++++++-----
 shapely/geometry/multilinestring.py |   2 +-
 shapely/geometry/multipolygon.py    |   2 +-
 shapely/geometry/polygon.py         |  25 +++++---
 shapely/tests/MultiPolygon.txt      |  16 ++---
 shapely/tests/Point.txt             |   4 +-
 shapely/tests/Polygon.txt           |   6 +-
 shapely/tests/__init__.py           |   3 +-
 shapely/tests/test_getitem.py       | 113 ++++++++++++++++++++++++++++++++++++
 19 files changed, 338 insertions(+), 136 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 970ce91..ba2db87 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,10 +1,18 @@
 =======
-CHANGES
+Changes
 =======
 
+1.2.14 (2012-01-23)
+-------------------
+- A geometry's coords property is now sliceable, yielding a list of coordinate
+  values.
+- Homogeneous collections are now sliceable, yielding a new collection of the
+  same type.
+
 1.2.13 (2011-09-16)
 -------------------
-- Fixed errors in speedups on 32bit systems when GEOS references memory above 
2GB.
+- Fixed errors in speedups on 32bit systems when GEOS references memory above
+  2GB.
 - Add shapely.__version__ attribute.
 - Update the manual.
 
@@ -139,9 +147,7 @@ TODO: fill gap here
 - 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)
 -------------------
diff --git a/CREDITS.txt b/CREDITS.txt
index a496ced..94eeee9 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -12,6 +12,7 @@ Patches contributed by:
 * Eric Lemoine
 * Jonathan Tartley
 * Kristian Thy
+* Mike Toews (https://github.com/mwtoews)
 
 Additional help from:
 
diff --git a/PKG-INFO b/PKG-INFO
index 8a6a778..25243cd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,16 +1,17 @@
 Metadata-Version: 1.0
 Name: Shapely
-Version: 1.2.13
+Version: 1.2.14
 Summary: Geometric objects, predicates, and operations
 Home-page: https://github.com/sgillies/shapely
 Author: Sean Gillies
 Author-email: sean.gill...@gmail.com
 License: BSD
-Description: =======
-        Shapely
-        =======
+Description: ======
+        README
+        ======
         
-        PostGIS-ish operations outside a database context for Pythoneers and 
Pythonistas
+        PostGIS-ish operations outside a database context for Pythoneers and
+        Pythonistas.
         
         .. image:: 
http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
         :width: 800
@@ -107,7 +108,7 @@ Description: =======
         Testing
         =======
         
-        Shapely uses a Zope-stye suite of unittests and doctests, excercised 
via
+        Shapely uses a Zope-stye suite of unittests and doctests, exercised via
         setup.py.::
         
         $ python setup.py test
@@ -118,7 +119,7 @@ Description: =======
         Support
         =======
         
-        Bugs may be reported and questions asked via 
https://github.com/sgillies/shapely.
+        Bugs may be reported and questions asked via 
https://github.com/Toblerity/Shapely.
         
         Credits
         =======
@@ -128,22 +129,23 @@ Description: =======
         * Sean Gillies
         * Aron Bierbaum
         * Kai Lautaportti
+        * Oliver Tonnhofer
         
         Patches contributed by:
         
         * Howard Butler
-        * Fr |eacute| d |eacute| ric Junod
-        * |Eacute| ric Lemoine
+        * Frédéric Junod
+        * Éric Lemoine
         * Jonathan Tartley
         * Kristian Thy
-        * Oliver Tonnhofer
+        * Mike Toews (https://github.com/mwtoews)
         
         Additional help from:
         
         * Justin Bronn (GeoDjango) for ctypes inspiration
         * Martin Davis (JTS)
         * Jaakko Salli for the Windows distributions
-        * Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS Project)
+        * Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS_ Project)
         
         Major portions of this work were supported by a grant (for Pleiades_) 
from the
         U.S. National Endowment for the Humanities (http://www.neh.gov).
@@ -153,20 +155,24 @@ Description: =======
         .. _GEOS: http://trac.osgeo.org/geos/
         .. _example apps: http://trac.gispython.org/lab/wiki/Examples
         .. _wiki: http://trac.gispython.org/lab/wiki/Shapely
-        .. _manual: http://gispython.org/shapely/docs/1.2
-        .. |eacute| unicode:: U+00E9
-        :trim:
-        .. |Eacute| unicode:: U+00C9
-        :trim:
+        .. _manual: http://toblerity.github.com/shapely/manual.html
         .. _Pleiades: http://pleiades.stoa.org
         
+        
+        Changes
         =======
-        CHANGES
-        =======
+        
+        1.2.14 (2012-01-23)
+        -------------------
+        - A geometry's coords property is now sliceable, yielding a list of 
coordinate
+        values.
+        - Homogeneous collections are now sliceable, yielding a new collection 
of the
+        same type.
         
         1.2.13 (2011-09-16)
         -------------------
-        - Fixed errors in speedups on 32bit systems when GEOS references 
memory above 2GB.
+        - Fixed errors in speedups on 32bit systems when GEOS references 
memory above
+        2GB.
         - Add shapely.__version__ attribute.
         - Update the manual.
         
@@ -301,9 +307,7 @@ Description: =======
         - 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)
         -------------------
diff --git a/README.rst b/README.rst
index 5676ebd..b336670 100644
--- a/README.rst
+++ b/README.rst
@@ -1,8 +1,9 @@
-=======
-Shapely
-=======
+======
+README
+======
 
-PostGIS-ish operations outside a database context for Pythoneers and 
Pythonistas
+PostGIS-ish operations outside a database context for Pythoneers and
+Pythonistas.
 
 .. image:: http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
    :width: 800
@@ -99,7 +100,7 @@ Numpy arrays can also be adapted to Shapely linestrings::
 Testing
 =======
 
-Shapely uses a Zope-stye suite of unittests and doctests, excercised via
+Shapely uses a Zope-stye suite of unittests and doctests, exercised via
 setup.py.::
 
   $ python setup.py test
@@ -110,7 +111,7 @@ supported well by nose.
 Support
 =======
 
-Bugs may be reported and questions asked via 
https://github.com/sgillies/shapely.
+Bugs may be reported and questions asked via 
https://github.com/Toblerity/Shapely.
 
 Credits
 =======
@@ -120,22 +121,23 @@ Shapely is written by:
 * Sean Gillies
 * Aron Bierbaum
 * Kai Lautaportti
+* Oliver Tonnhofer
 
 Patches contributed by:
 
 * Howard Butler
-* Fr |eacute| d |eacute| ric Junod
-* |Eacute| ric Lemoine
+* Frédéric Junod
+* Éric Lemoine
 * Jonathan Tartley
 * Kristian Thy
-* Oliver Tonnhofer
+* Mike Toews (https://github.com/mwtoews)
 
 Additional help from:
 
 * Justin Bronn (GeoDjango) for ctypes inspiration
 * Martin Davis (JTS)
 * Jaakko Salli for the Windows distributions
-* Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS Project)
+* Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS_ Project)
 
 Major portions of this work were supported by a grant (for Pleiades_) from the
 U.S. National Endowment for the Humanities (http://www.neh.gov).
@@ -145,9 +147,6 @@ U.S. National Endowment for the Humanities 
(http://www.neh.gov).
 .. _GEOS: http://trac.osgeo.org/geos/
 .. _example apps: http://trac.gispython.org/lab/wiki/Examples
 .. _wiki: http://trac.gispython.org/lab/wiki/Shapely
-.. _manual: http://gispython.org/shapely/docs/1.2
-.. |eacute| unicode:: U+00E9
-   :trim:
-.. |Eacute| unicode:: U+00C9
-   :trim:
+.. _manual: http://toblerity.github.com/shapely/manual.html
 .. _Pleiades: http://pleiades.stoa.org
+
diff --git a/Shapely.egg-info/PKG-INFO b/Shapely.egg-info/PKG-INFO
index 8a6a778..25243cd 100644
--- a/Shapely.egg-info/PKG-INFO
+++ b/Shapely.egg-info/PKG-INFO
@@ -1,16 +1,17 @@
 Metadata-Version: 1.0
 Name: Shapely
-Version: 1.2.13
+Version: 1.2.14
 Summary: Geometric objects, predicates, and operations
 Home-page: https://github.com/sgillies/shapely
 Author: Sean Gillies
 Author-email: sean.gill...@gmail.com
 License: BSD
-Description: =======
-        Shapely
-        =======
+Description: ======
+        README
+        ======
         
-        PostGIS-ish operations outside a database context for Pythoneers and 
Pythonistas
+        PostGIS-ish operations outside a database context for Pythoneers and
+        Pythonistas.
         
         .. image:: 
http://farm3.static.flickr.com/2738/4511827859_b5822043b7_o_d.png
         :width: 800
@@ -107,7 +108,7 @@ Description: =======
         Testing
         =======
         
-        Shapely uses a Zope-stye suite of unittests and doctests, excercised 
via
+        Shapely uses a Zope-stye suite of unittests and doctests, exercised via
         setup.py.::
         
         $ python setup.py test
@@ -118,7 +119,7 @@ Description: =======
         Support
         =======
         
-        Bugs may be reported and questions asked via 
https://github.com/sgillies/shapely.
+        Bugs may be reported and questions asked via 
https://github.com/Toblerity/Shapely.
         
         Credits
         =======
@@ -128,22 +129,23 @@ Description: =======
         * Sean Gillies
         * Aron Bierbaum
         * Kai Lautaportti
+        * Oliver Tonnhofer
         
         Patches contributed by:
         
         * Howard Butler
-        * Fr |eacute| d |eacute| ric Junod
-        * |Eacute| ric Lemoine
+        * Frédéric Junod
+        * Éric Lemoine
         * Jonathan Tartley
         * Kristian Thy
-        * Oliver Tonnhofer
+        * Mike Toews (https://github.com/mwtoews)
         
         Additional help from:
         
         * Justin Bronn (GeoDjango) for ctypes inspiration
         * Martin Davis (JTS)
         * Jaakko Salli for the Windows distributions
-        * Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS Project)
+        * Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS_ Project)
         
         Major portions of this work were supported by a grant (for Pleiades_) 
from the
         U.S. National Endowment for the Humanities (http://www.neh.gov).
@@ -153,20 +155,24 @@ Description: =======
         .. _GEOS: http://trac.osgeo.org/geos/
         .. _example apps: http://trac.gispython.org/lab/wiki/Examples
         .. _wiki: http://trac.gispython.org/lab/wiki/Shapely
-        .. _manual: http://gispython.org/shapely/docs/1.2
-        .. |eacute| unicode:: U+00E9
-        :trim:
-        .. |Eacute| unicode:: U+00C9
-        :trim:
+        .. _manual: http://toblerity.github.com/shapely/manual.html
         .. _Pleiades: http://pleiades.stoa.org
         
+        
+        Changes
         =======
-        CHANGES
-        =======
+        
+        1.2.14 (2012-01-23)
+        -------------------
+        - A geometry's coords property is now sliceable, yielding a list of 
coordinate
+        values.
+        - Homogeneous collections are now sliceable, yielding a new collection 
of the
+        same type.
         
         1.2.13 (2011-09-16)
         -------------------
-        - Fixed errors in speedups on 32bit systems when GEOS references 
memory above 2GB.
+        - Fixed errors in speedups on 32bit systems when GEOS references 
memory above
+        2GB.
         - Add shapely.__version__ attribute.
         - Update the manual.
         
@@ -301,9 +307,7 @@ Description: =======
         - 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)
         -------------------
diff --git a/Shapely.egg-info/SOURCES.txt b/Shapely.egg-info/SOURCES.txt
index 5326a5e..1f8cd3f 100644
--- a/Shapely.egg-info/SOURCES.txt
+++ b/Shapely.egg-info/SOURCES.txt
@@ -74,6 +74,7 @@ shapely/tests/test_doctests.py
 shapely/tests/test_emptiness.py
 shapely/tests/test_equality.py
 shapely/tests/test_geomseq.py
+shapely/tests/test_getitem.py
 shapely/tests/test_linear_referencing.py
 shapely/tests/test_mapping.py
 shapely/tests/test_prepared.py
diff --git a/docs/manual.txt b/docs/manual.txt
index 746c2aa..5ad9db7 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -1,10 +1,12 @@
+.. _manual:
+
 =======================
 The Shapely User Manual
 =======================
 
 :Author: Sean Gillies, <sean.gill...@gmail.com>
-:Revision: 1.2.13
-:Date: 15 September 2011
+:Revision: 1.2.14
+:Date: 21 January 2012
 :Copyright: 
   This work is licensed under a `Creative Commons Attribution 3.0
   United States License`__.
@@ -15,8 +17,6 @@ The Shapely User Manual
   This document explains how to use the Shapely Python package for
   computational geometry.
 
-.. sectnum::
-
 .. _intro:
 
 Introduction
@@ -267,6 +267,13 @@ Coordinate values are accessed via `coords`, `x`, `y`, and 
`z` properties.
   >>> point.y
   0.0
 
+Coordinates may also be sliced. `New in version 1.2.14`.
+
+.. sourcecode:: pycon
+
+  >>> point.coords[:]
+  [(0.0, 0.0)]
+
 The `Point` constructor also accepts another `Point` instance, thereby making
 a copy.
 
@@ -323,6 +330,15 @@ The defining coordinate values are accessed via the 
`coords` property.
   >>> list(line.coords)
   [(0.0, 0.0), (1.0, 1.0)]
 
+Coordinates may also be sliced. `New in version 1.2.14`.
+
+.. sourcecode:: pycon
+
+  >>> point.coords[:]
+  [(0.0, 0.0), (1.0, 1.0)]
+  >>> point.coords[1:]
+  [(1.0, 1.0)]
+
 The constructor also accepts another `LineString` instance, thereby making a
 copy.
 
@@ -509,12 +525,11 @@ To obtain a polygon with a known orientation, use
 Collections
 -----------
 
-Shapely provides frozenset_-like, immutable collections of geometric objects.
-The collections may be homogeneous (`MultiPoint` etc.) or heterogeneous.
-
 Heterogeneous collections of geometric objects may result from some Shapely
 operations. For example, two `LineStrings` may intersect along a line and at a
-point.
+point. To represent these kind of results, Shapely provides frozenset_-like,
+immutable collections of geometric objects.  The collections may be homogeneous
+(`MultiPoint` etc.) or heterogeneous.
 
 .. sourcecode:: python
 
@@ -547,6 +562,22 @@ the iterator protocol using ``in``  or ``list()``.
   [<shapely.geometry.point.Point object at 0x...>,
    <shapely.geometry.linestring.LineString object at 0x...>]
 
+Homogeneous collections can also be sliced, resulting in a new object of the
+same type.
+
+.. sourcecode:: pycon 
+
+  >>> from shapely.geometry import MultiPoint
+  >>> m = MultiPoint([(0, 0), (1, 1), (1,2), (2,2)])
+  >>> m[:1].wkt
+  'MULTIPOINT (0.0000000000000000 0.0000000000000000)'
+  >>> m[3:].wkt
+  'MULTIPOINT (2.0000000000000000 2.0000000000000000)'
+  >>> m[4:].wkt
+  'GEOMETRYCOLLECTION EMPTY'
+
+`New in version 1.2.14`.
+
 .. note::
   
   When possible, it is better to use one of the homogeneous collection types
@@ -1824,7 +1855,7 @@ Conclusion
 We hope that you will enjoy and profit from using Shapely. Questions and
 comments are welcome on the GIS-Python email list_. This manual will be updated
 and improved regularly. Its source is available at
-http://github.com/sgillies/shapely/tree/master/docs/. 
+http://github.com/Toblerity/Shapely/tree/master/docs/. 
 
 
 References
@@ -1857,7 +1888,7 @@ References
    1973, pp. 112-122.
 
 
-.. _GEOS: http://geos.refractions.net
+.. _GEOS: http://trac.osgeo.org/geos/
 .. _Java Topology Suite: http://www.vividsolutions.com/jts/jtshome.htm
 .. _JTS: http://www.vividsolutions.com/jts/jtshome.htm
 .. _PostGIS: http://postgis.refractions.net
diff --git a/setup.py b/setup.py
index aafca2e..328c0b6 100644
--- a/setup.py
+++ b/setup.py
@@ -17,13 +17,17 @@ from setuptools import setup, find_packages
 import sys
 import platform
 
-readme_text = file('README.rst', 'rb').read()
-changes_text = file('CHANGES.txt', 'rb').read()
+readme_text = open('README.rst', 'rb').read()
+
+# Skip the first line of the changes file to get the right header level
+f = open('CHANGES.txt', 'rb')
+f.readline()
+changes_text = f.read()
 
 setup_args = dict(
     metadata_version    = '1.2',
     name                = 'Shapely',
-    version             = '1.2.13',
+    version             = '1.2.14',
     requires_python     = '>=2.5,<3',
     requires_external   = 'libgeos_c (>=3.1)', 
     description         = 'Geometric objects, predicates, and operations',
diff --git a/shapely/__init__.py b/shapely/__init__.py
index a4b958d..a6df0ba 100644
--- a/shapely/__init__.py
+++ b/shapely/__init__.py
@@ -1,2 +1,2 @@
-__version__ = "1.2.13"
+__version__ = "1.2.14"
 
diff --git a/shapely/coords.py b/shapely/coords.py
index 131876a..505d67e 100644
--- a/shapely/coords.py
+++ b/shapely/coords.py
@@ -30,7 +30,7 @@ class CoordinateSequence(object):
     # _ndim : int
     #     Number of dimensions (2 or 3, generally)
     # __p__ : object
-    #     Parent (Shapely) geometry    
+    #     Parent (Shapely) geometry
     _cseq = None
     _ndim = None
     __p__ = None
@@ -41,7 +41,7 @@ class CoordinateSequence(object):
     def _update(self):
         self._ndim = self.__p__._ndim
         self._cseq = lgeos.GEOSGeom_getCoordSeq(self.__p__._geom)
-    
+
     def __len__(self):
         self._update()
         cs_len = c_uint(0)
@@ -53,38 +53,56 @@ class CoordinateSequence(object):
         dx = c_double()
         dy = c_double()
         dz = c_double()
-        for i in range(self.__len__()):
+        has_z = self._ndim == 3
+        for i in xrange(self.__len__()):
             lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(dx))
             lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(dy))
-            if self._ndim == 3: # TODO: use hasz
+            if has_z:
                 lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(dz))
                 yield (dx.value, dy.value, dz.value)
             else:
                 yield (dx.value, dy.value)
 
-    def __getitem__(self, i):
+    def __getitem__(self, key):
         self._update()
-        M = self.__len__()
-        if i + M < 0 or i >= M:
-            raise IndexError("index out of range")
-        if i < 0:
-            ii = M + i
-        else:
-            ii = i
         dx = c_double()
         dy = c_double()
         dz = c_double()
-        lgeos.GEOSCoordSeq_getX(self._cseq, ii, byref(dx))
-        lgeos.GEOSCoordSeq_getY(self._cseq, ii, byref(dy))
-        if self._ndim == 3: # TODO: use hasz
-            lgeos.GEOSCoordSeq_getZ(self._cseq, ii, byref(dz))
-            return (dx.value, dy.value, dz.value)
+        m = self.__len__()
+        has_z = self._ndim == 3
+        if isinstance(key, int):
+            if key + m < 0 or key >= m:
+                raise IndexError("index out of range")
+            if key < 0:
+                i = m + key
+            else:
+                i = key
+            lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(dx))
+            lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(dy))
+            if has_z:
+                lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(dz))
+                return (dx.value, dy.value, dz.value)
+            else:
+                return (dx.value, dy.value)
+        elif isinstance(key, slice):
+            res = []
+            start, stop, stride = key.indices(m)
+            for i in xrange(start, stop, stride):
+                lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(dx))
+                lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(dy))
+                if has_z:
+                    lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(dz))
+                    res.append((dx.value, dy.value, dz.value))
+                else:
+                    res.append((dx.value, dy.value))
+            return res
         else:
-            return (dx.value, dy.value)
+            raise TypeError("key must be an index or slice")
 
     @property
     def ctypes(self):
         self._update()
+        has_z = self._ndim == 3
         n = self._ndim
         m = self.__len__()
         array_type = c_double * (m * n)
@@ -95,7 +113,7 @@ class CoordinateSequence(object):
             data[n*i] = temp.value
             lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(temp))
             data[n*i+1] = temp.value
-            if n == 3: # TODO: use hasz
+            if has_z:
                 lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(temp))
                 data[n*i+2] = temp.value
         return data
@@ -133,7 +151,7 @@ class CoordinateSequence(object):
             lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(temp))
             y.append(temp.value)
         return x, y
-            
+
 
 class BoundsOp(Validating):
 
@@ -163,4 +181,3 @@ class BoundsOp(Validating):
             if y < miny: miny = y
             if y > maxy: maxy = y
         return (minx, miny, maxx, maxy)
-
diff --git a/shapely/geometry/base.py b/shapely/geometry/base.py
index 1a2bb70..af1bb31 100644
--- a/shapely/geometry/base.py
+++ b/shapely/geometry/base.py
@@ -12,13 +12,13 @@ from shapely import wkb, wkt
 
 GEOMETRY_TYPES = [
     'Point',
-       'LineString',
-       'LinearRing',
-       'Polygon',
-       'MultiPoint',
-       'MultiLineString',
-       'MultiPolygon',
-       'GeometryCollection'
+    'LineString',
+    'LinearRing',
+    'Polygon',
+    'MultiPoint',
+    'MultiLineString',
+    'MultiPolygon',
+    'GeometryCollection'
     ]
 
 def geometry_type_name(g):
@@ -548,23 +548,35 @@ class GeometrySequence(object):
 
     def __iter__(self):
         self._update()
-        for i in range(self.__len__()):
+        for i in xrange(self.__len__()):
             yield self._get_geom_item(i)
 
     def __len__(self):
         self._update()
         return lgeos.GEOSGetNumGeometries(self._geom)
 
-    def __getitem__(self, i):
+    def __getitem__(self, key):
         self._update()
-        M = self.__len__()
-        if i + M < 0 or i >= M:
-            raise IndexError("index out of range")
-        if i < 0:
-            ii = M + i
+        m = self.__len__()
+        if isinstance(key, int):
+            if key + m < 0 or key >= m:
+                raise IndexError("index out of range")
+            if key < 0:
+                i = m + key
+            else:
+                i = key
+            return self._get_geom_item(i)
+        elif isinstance(key, slice):
+            if type(self) == HeterogeneousGeometrySequence:
+                raise TypeError(
+                    "Heterogenous geometry collections are not sliceable")
+            res = []
+            start, stop, stride = key.indices(m)
+            for i in xrange(start, stop, stride):
+                res.append(self._get_geom_item(i))
+            return type(self.__p__)(res or None)
         else:
-            ii = i
-        return self._get_geom_item(i)
+            raise TypeError("key must be an index or slice")
 
     @property
     def _longest(self):
diff --git a/shapely/geometry/multilinestring.py 
b/shapely/geometry/multilinestring.py
index f3d5234..8f34c17 100644
--- a/shapely/geometry/multilinestring.py
+++ b/shapely/geometry/multilinestring.py
@@ -41,7 +41,7 @@ class MultiLineString(BaseMultipartGeometry):
         super(MultiLineString, self).__init__()
 
         if lines is None:
-            # allow creation of null lines, to support unpickling
+            # allow creation of empty multilinestrings, to support unpickling
             pass
         else:
             self._geom, self._ndim = geos_multilinestring_from_py(lines)
diff --git a/shapely/geometry/multipolygon.py b/shapely/geometry/multipolygon.py
index 6625d68..4597364 100644
--- a/shapely/geometry/multipolygon.py
+++ b/shapely/geometry/multipolygon.py
@@ -51,7 +51,7 @@ class MultiPolygon(BaseMultipartGeometry):
         super(MultiPolygon, self).__init__()
 
         if polygons is None:
-            # allow creation of null collections, to support unpickling
+            # allow creation of empty multipolygons, to support unpickling
             pass
         elif context_type == 'polygons':
             self._geom, self._ndim = geos_multipolygon_from_polygons(polygons)
diff --git a/shapely/geometry/polygon.py b/shapely/geometry/polygon.py
index 8c0d6f8..8d9a435 100644
--- a/shapely/geometry/polygon.py
+++ b/shapely/geometry/polygon.py
@@ -124,15 +124,24 @@ class InteriorRingSequence(object):
     def __len__(self):
         return lgeos.GEOSGetNumInteriorRings(self._geom)
 
-    def __getitem__(self, i):
-        M = self.__len__()
-        if i + M < 0 or i >= M:
-            raise IndexError("index out of range")
-        if i < 0:
-            ii = M + i
+    def __getitem__(self, key):
+        m = self.__len__()
+        if isinstance(key, int):
+            if key + m < 0 or key >= m:
+                raise IndexError("index out of range")
+            if key < 0:
+                i = m + key
+            else:
+                i = key
+            return self._get_ring(i)
+        elif isinstance(key, slice):
+            res = []
+            start, stop, stride = key.indices(m)
+            for i in xrange(start, stop, stride):
+                res.append(self._get_ring(i))
+            return res
         else:
-            ii = i
-        return self._get_ring(i)
+            raise TypeError("key must be an index or slice")
 
     @property
     def _longest(self):
diff --git a/shapely/tests/MultiPolygon.txt b/shapely/tests/MultiPolygon.txt
index 8b8723a..376ddb6 100644
--- a/shapely/tests/MultiPolygon.txt
+++ b/shapely/tests/MultiPolygon.txt
@@ -9,23 +9,23 @@ Initialization
 From coordinate tuples
 
   >>> geom = MultiPolygon( [
-  ... (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.1,0.1), 
(0.1,0.2), (0.2,0.2), (0.2,0.1))])
+  ... (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.25,0.25), 
(0.25,0.5), (0.5,0.5), (0.5,0.25))])
   ... ] )
   >>> geom # doctest: +ELLIPSIS
   <shapely.geometry.multipolygon.MultiPolygon object at ...>
   >>> len(geom.geoms)
   1
   >>> geom.wkt
-  'MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.1000000000000000 
0.1000000000000000, 0.1000000000000000 0.2000000000000000, 0.2000000000000000 
0.2000000000000000, 0.2000000000000000 0.1000000000000000, 0.1000000000000000 
0.1000000000000000)))'
+  'MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.2500000000000000 
0.2500000000000000, 0.2500000000000000 0.5000000000000000, 0.5000000000000000 
0.5000000000000000, 0.5000000000000000 0.2500000000000000, 0.2500000000000000 
0.2500000000000000)))'
 
 Or from polygons
 
-  >>> p = Polygon(((0, 0), (0, 1), (1, 1), (1, 0)), [((0.1,0.1), (0.1,0.2), 
(0.2,0.2), (0.2,0.1))])
+  >>> p = Polygon(((0, 0), (0, 1), (1, 1), (1, 0)), [((0.25,0.25), (0.25,0.5), 
(0.5,0.5), (0.5,0.25))])
   >>> geom = MultiPolygon([p])
   >>> len(geom.geoms)
   1
   >>> print geom.wkt
-  MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.1000000000000000 
0.1000000000000000, 0.1000000000000000 0.2000000000000000, 0.2000000000000000 
0.2000000000000000, 0.2000000000000000 0.1000000000000000, 0.1000000000000000 
0.1000000000000000)))
+  MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.2500000000000000 
0.2500000000000000, 0.2500000000000000 0.5000000000000000, 0.5000000000000000 
0.5000000000000000, 0.5000000000000000 0.2500000000000000, 0.2500000000000000 
0.2500000000000000)))
 
 Or from another multi-polygon
 
@@ -33,7 +33,7 @@ Or from another multi-polygon
   >>> len(geom2.geoms)
   1
   >>> print geom2.wkt
-  MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.1000000000000000 
0.1000000000000000, 0.1000000000000000 0.2000000000000000, 0.2000000000000000 
0.2000000000000000, 0.2000000000000000 0.1000000000000000, 0.1000000000000000 
0.1000000000000000)))
+  MULTIPOLYGON (((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.2500000000000000 
0.2500000000000000, 0.2500000000000000 0.5000000000000000, 0.5000000000000000 
0.5000000000000000, 0.5000000000000000 0.2500000000000000, 0.2500000000000000 
0.2500000000000000)))
 
 Sub-geometry Access
 -------------------
@@ -41,7 +41,7 @@ Sub-geometry Access
   >>> geom.geoms[0] # doctest: +ELLIPSIS
   <shapely.geometry.polygon.Polygon object at ...>
   >>> geom.geoms[0].wkt
-  'POLYGON ((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.1000000000000000 
0.1000000000000000, 0.1000000000000000 0.2000000000000000, 0.2000000000000000 
0.2000000000000000, 0.2000000000000000 0.1000000000000000, 0.1000000000000000 
0.1000000000000000))'
+  'POLYGON ((0.0000000000000000 0.0000000000000000, 0.0000000000000000 
1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 
0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.2500000000000000 
0.2500000000000000, 0.2500000000000000 0.5000000000000000, 0.5000000000000000 
0.5000000000000000, 0.5000000000000000 0.2500000000000000, 0.2500000000000000 
0.2500000000000000))'
   >>> geom.geoms[1]
   Traceback (most recent call last):
   ...
@@ -51,14 +51,14 @@ Geo interface
 -------------
 
   >>> geom.__geo_interface__
-  {'type': 'MultiPolygon', 'coordinates': [[((0.0, 0.0), (0.0, 1.0), (1.0, 
1.0), (1.0, 0.0), (0.0, 0.0)), ((0.10000000000000001, 0.10000000000000001), 
(0.10000000000000001, 0.20000000000000001), (0.20000000000000001, 
0.20000000000000001), (0.20000000000000001, 0.10000000000000001), 
(0.10000000000000001, 0.10000000000000001))]]}
+  {'type': 'MultiPolygon', 'coordinates': [[((0.0, 0.0), (0.0, 1.0), (1.0, 
1.0), (1.0, 0.0), (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 
0.25), (0.25, 0.25))]]}
 
 Adapter
 -------
 
   >>> from shapely.geometry import asMultiPolygon
   >>> coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))
-  >>> holes_coords = [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))]
+  >>> holes_coords = [((0.25,0.25), (0.25,0.5), (0.5,0.5), (0.5,0.25))]
   >>> mpa = asMultiPolygon([(coords, holes_coords)])
   >>> len(mpa.geoms)
   1
diff --git a/shapely/tests/Point.txt b/shapely/tests/Point.txt
index 2325afe..7ef16cb 100644
--- a/shapely/tests/Point.txt
+++ b/shapely/tests/Point.txt
@@ -121,8 +121,8 @@ Adapter
   >>> coords[0] = 1.0
   >>> pa.wkt
   'POINT (1.0000000000000000 4.0000000000000000)'
-  >>> pa.distance(p)
-  4.1231056256176606
+  >>> '%.10f' % pa.distance(p)
+  '4.1231056256'
 
   Now, the inverse
   
diff --git a/shapely/tests/Polygon.txt b/shapely/tests/Polygon.txt
index 4a9e5dd..93721b5 100644
--- a/shapely/tests/Polygon.txt
+++ b/shapely/tests/Polygon.txt
@@ -77,7 +77,7 @@ Ring Access
 Interior rings (holes)
 ----------------------
 
-  >>> polygon = Polygon(coords, [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))])
+  >>> polygon = Polygon(coords, [((0.25,0.25), (0.25,0.5), (0.5,0.5), 
(0.5,0.25))])
   >>> len(polygon.exterior.coords)
   5
   >>> len(polygon.interiors[0].coords)
@@ -103,13 +103,13 @@ Geo interface
 -------------
 
   >>> polygon.__geo_interface__
-  {'type': 'Polygon', 'coordinates': (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), 
(2.0, -1.0), (0.0, 0.0)), ((0.10000000000000001, 0.10000000000000001), 
(0.10000000000000001, 0.20000000000000001), (0.20000000000000001, 
0.20000000000000001), (0.20000000000000001, 0.10000000000000001), 
(0.10000000000000001, 0.10000000000000001)))}
+  {'type': 'Polygon', 'coordinates': (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), 
(2.0, -1.0), (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), 
(0.25, 0.25)))}
 
 
 Adapter
 -------
 
-  >>> hole_coords = [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))]
+  >>> hole_coords = [((0.25,0.25), (0.25,0.5), (0.5,0.5), (0.5,0.25))]
   >>> from shapely.geometry import asPolygon
   >>> pa = asPolygon(coords, hole_coords)
   >>> len(pa.exterior.coords)
diff --git a/shapely/tests/__init__.py b/shapely/tests/__init__.py
index 2950d5c..627df68 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, test_box, test_speedups, test_cga
+import test_products_z, test_box, test_speedups, test_cga, test_getitem
 
 def test_suite():
     suite = TestSuite()
@@ -24,5 +24,6 @@ def test_suite():
     suite.addTest(test_box.test_suite())
     suite.addTest(test_speedups.test_suite())
     suite.addTest(test_cga.test_suite())
+    suite.addTest(test_getitem.test_suite())
     return suite
 
diff --git a/shapely/tests/test_getitem.py b/shapely/tests/test_getitem.py
new file mode 100644
index 0000000..382156c
--- /dev/null
+++ b/shapely/tests/test_getitem.py
@@ -0,0 +1,113 @@
+import unittest
+from shapely import geometry
+
+class CoordsGetItemTestCase(unittest.TestCase):
+    def test_index_2d_coords(self):
+        c = [(float(x), float(-x)) for x in range(4)]
+        g = geometry.LineString(c)
+        for i in range(-4,4):
+            self.assertTrue(g.coords[i] == c[i])
+        self.assertRaises(IndexError, lambda: g.coords[4])
+        self.assertRaises(IndexError, lambda: g.coords[-5])
+
+    def test_index_3d_coords(self):
+        c = [(float(x), float(-x), float(x*2)) for x in range(4)]
+        g = geometry.LineString(c)
+        for i in range(-4,4):
+            self.assertTrue(g.coords[i] == c[i])
+        self.assertRaises(IndexError, lambda: g.coords[4])
+        self.assertRaises(IndexError, lambda: g.coords[-5])
+
+    def test_index_coords_misc(self):
+        g = geometry.LineString() # empty
+        self.assertRaises(IndexError, lambda: g.coords[0])
+        self.assertRaises(TypeError, lambda: g.coords[0.0])
+
+    def test_slice_2d_coords(self):
+        c = [(float(x), float(-x)) for x in range(4)]
+        g = geometry.LineString(c)
+        self.assertTrue(g.coords[1:] == c[1:])
+        self.assertTrue(g.coords[:-1] == c[:-1])
+        self.assertTrue(g.coords[::-1] == c[::-1])
+        self.assertTrue(g.coords[::2] == c[::2])
+        self.assertTrue(g.coords[:4] == c[:4])
+        self.assertTrue(g.coords[4:] == c[4:] == [])
+
+    def test_slice_3d_coords(self):
+        c = [(float(x), float(-x), float(x*2)) for x in range(4)]
+        g = geometry.LineString(c)
+        self.assertTrue(g.coords[1:] == c[1:])
+        self.assertTrue(g.coords[:-1] == c[:-1])
+        self.assertTrue(g.coords[::-1] == c[::-1])
+        self.assertTrue(g.coords[::2] == c[::2])
+        self.assertTrue(g.coords[:4] == c[:4])
+        self.assertTrue(g.coords[4:] == c[4:] == [])
+
+class MultiGeomGetItemTestCase(unittest.TestCase):
+    def test_index_multigeom(self):
+        c = [(float(x), float(-x)) for x in range(4)]
+        g = geometry.MultiPoint(c)
+        for i in range(-4,4):
+            self.assertTrue(g[i].equals(geometry.Point(c[i])))
+        self.assertRaises(IndexError, lambda: g[4])
+        self.assertRaises(IndexError, lambda: g[-5])
+
+    def test_index_multigeom_misc(self):
+        g = geometry.MultiLineString() # empty
+        self.assertRaises(IndexError, lambda: g[0])
+        self.assertRaises(TypeError, lambda: g[0.0])
+
+    def test_slice_multigeom(self):
+        c = [(float(x), float(-x)) for x in range(4)]
+        g = geometry.MultiPoint(c)
+        self.failUnlessEqual(type(g[:]), type(g))
+        self.failUnlessEqual(len(g[:]), len(g))
+        self.failUnless(g[1:].equals(geometry.MultiPoint(c[1:])))
+        self.failUnless(g[:-1].equals(geometry.MultiPoint(c[:-1])))
+        self.failUnless(g[::-1].equals(geometry.MultiPoint(c[::-1])))
+        self.failUnless(g[4:].is_empty)
+
+class LinearRingGetItemTestCase(unittest.TestCase):
+    def test_index_linearring(self):
+        shell = geometry.polygon.LinearRing([(0.0, 0.0), (70.0, 120.0),
+                                             (140.0, 0.0), (0.0, 0.0)])
+        holes = [geometry.polygon.LinearRing([(60.0, 80.0), (80.0, 80.0),
+                                              (70.0, 60.0), (60.0, 80.0)]),
+                 geometry.polygon.LinearRing([(30.0, 10.0), (50.0, 10.0),
+                                              (40.0, 30.0), (30.0, 10.0)]),
+                 geometry.polygon.LinearRing([(90.0, 10), (110.0, 10.0),
+                                              (100.0, 30.0), (90.0, 10.0)])]
+        g = geometry.Polygon(shell, holes)
+        for i in range(-3,3):
+            self.assertTrue(g.interiors[i].equals(holes[i]))
+        self.assertRaises(IndexError, lambda: g.interiors[3])
+        self.assertRaises(IndexError, lambda: g.interiors[-4])
+
+    def test_index_linearring_misc(self):
+        g = geometry.Polygon() # empty
+        self.assertRaises(IndexError, lambda: g.interiors[0])
+        self.assertRaises(TypeError, lambda: g.interiors[0.0])
+
+    def test_slice_linearring(self):
+        shell = geometry.polygon.LinearRing([(0.0, 0.0), (70.0, 120.0),
+                                             (140.0, 0.0), (0.0, 0.0)])
+        holes = [geometry.polygon.LinearRing([(60.0, 80.0), (80.0, 80.0),
+                                              (70.0, 60.0), (60.0, 80.0)]),
+                 geometry.polygon.LinearRing([(30.0, 10.0), (50.0, 10.0),
+                                              (40.0, 30.0), (30.0, 10.0)]),
+                 geometry.polygon.LinearRing([(90.0, 10), (110.0, 10.0),
+                                              (100.0, 30.0), (90.0, 10.0)])]
+        g = geometry.Polygon(shell, holes)
+        self.assertTrue(all([a.equals(b) for (a, b) in zip(g.interiors[1:], 
holes[1:])]))
+        self.assertTrue(all([a.equals(b) for (a, b) in zip(g.interiors[:-1], 
holes[:-1])]))
+        self.assertTrue(all([a.equals(b) for (a, b) in zip(g.interiors[::-1], 
holes[::-1])]))
+        self.assertTrue(all([a.equals(b) for (a, b) in zip(g.interiors[::2], 
holes[::2])]))
+        self.assertTrue(all([a.equals(b) for (a, b) in zip(g.interiors[:3], 
holes[:3])]))
+        self.assertTrue(g.interiors[3:] == holes[3:] == [])
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return unittest.TestSuite([
+        unittest.TestLoader().loadTestsFromTestCase(CoordsGetItemTestCase),
+        unittest.TestLoader().loadTestsFromTestCase(MultiGeomGetItemTestCase),
+        
unittest.TestLoader().loadTestsFromTestCase(LinearRingGetItemTestCase)])

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

_______________________________________________
Pkg-grass-devel mailing list
Pkg-grass-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

Reply via email to