[1.5.x] Fixed #19366 -- Prevented GEOSIndexError when comparing geometries
Thanks Craig de Stigter for the report and collaboration on the
patch.
Backport of cc3c4a9d5
from master.
This commit is contained in:
parent
a21e8dee76
commit
89593048e2
|
@ -149,27 +149,30 @@ class ListMixin(object):
|
|||
return self
|
||||
|
||||
def __eq__(self, other):
|
||||
for i in range(len(self)):
|
||||
olen = len(other)
|
||||
for i in range(olen):
|
||||
try:
|
||||
c = self[i] == other[i]
|
||||
except IndexError:
|
||||
# must be other is shorter
|
||||
except self._IndexError:
|
||||
# self must be shorter
|
||||
return False
|
||||
if not c:
|
||||
return False
|
||||
return True
|
||||
return len(self) == olen
|
||||
|
||||
def __lt__(self, other):
|
||||
slen = len(self)
|
||||
for i in range(slen):
|
||||
olen = len(other)
|
||||
for i in range(olen):
|
||||
try:
|
||||
c = self[i] < other[i]
|
||||
except IndexError:
|
||||
# must be other is shorter
|
||||
return False
|
||||
except self._IndexError:
|
||||
# self must be shorter
|
||||
return True
|
||||
if c:
|
||||
return c
|
||||
return slen < len(other)
|
||||
elif other[i] < self[i]:
|
||||
return False
|
||||
return len(self) < olen
|
||||
|
||||
### Public list interface Methods ###
|
||||
## Non-mutating ##
|
||||
|
|
|
@ -451,6 +451,21 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
|
|||
self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt)
|
||||
self.assertEqual(poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt)
|
||||
|
||||
def test_polygon_comparison(self):
|
||||
p1 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
|
||||
p2 = Polygon(((0, 0), (0, 1), (1, 0), (0, 0)))
|
||||
self.assertTrue(p1 > p2)
|
||||
self.assertFalse(p1 < p2)
|
||||
self.assertFalse(p2 > p1)
|
||||
self.assertTrue(p2 < p1)
|
||||
|
||||
p3 = Polygon(((0, 0), (0, 1), (1, 1), (2, 0), (0, 0)))
|
||||
p4 = Polygon(((0, 0), (0, 1), (2, 2), (1, 0), (0, 0)))
|
||||
self.assertFalse(p4 < p3)
|
||||
self.assertTrue(p3 < p4)
|
||||
self.assertTrue(p4 > p3)
|
||||
self.assertFalse(p3 > p4)
|
||||
|
||||
def test_multipolygons(self):
|
||||
"Testing MultiPolygon objects."
|
||||
prev = fromstr('POINT (0 0)')
|
||||
|
|
|
@ -363,6 +363,7 @@ class ListMixinTest(unittest.TestCase):
|
|||
|
||||
pl, ul = self.lists_of_len()
|
||||
self.assertEqual(pl, ul, 'cmp for equal')
|
||||
self.assertFalse(ul == pl + [2], 'cmp for not equal')
|
||||
self.assertTrue(pl >= ul, 'cmp for gte self')
|
||||
self.assertTrue(pl <= ul, 'cmp for lte self')
|
||||
self.assertTrue(ul >= pl, 'cmp for self gte')
|
||||
|
@ -377,6 +378,14 @@ class ListMixinTest(unittest.TestCase):
|
|||
self.assertTrue(ul < pl + [2], 'cmp')
|
||||
self.assertTrue(ul <= pl + [2], 'cmp')
|
||||
|
||||
# Also works with a custom IndexError
|
||||
ul_longer = ul + [2]
|
||||
ul_longer._IndexError = TypeError
|
||||
ul._IndexError = TypeError
|
||||
self.assertFalse(ul_longer == pl)
|
||||
self.assertFalse(ul == ul_longer)
|
||||
self.assertTrue(ul_longer > ul)
|
||||
|
||||
pl[1] = 20
|
||||
self.assertTrue(pl > ul, 'cmp for gt self')
|
||||
self.assertTrue(ul < pl, 'cmp for self lt')
|
||||
|
|
|
@ -656,6 +656,17 @@ is returned instead.
|
|||
|
||||
Returns the number of interior rings in this geometry.
|
||||
|
||||
.. admonition:: Comparing Polygons
|
||||
|
||||
Note that it is possible to compare ``Polygon`` objects directly with ``<``
|
||||
or ``>``, but as the comparison is made through Polygon's
|
||||
:class:`LineString`, it does not mean much (but is consistent and quick).
|
||||
You can always force the comparison with the :attr:`~GEOSGeometry.area`
|
||||
property::
|
||||
|
||||
>>> if poly_1.area > poly_2.area:
|
||||
>>> pass
|
||||
|
||||
Geometry Collections
|
||||
====================
|
||||
|
||||
|
|
Loading…
Reference in New Issue