Skip to content

Commit

Permalink
Warn about upcoming STRtree changes (#1097)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgillies committed Mar 3, 2021
1 parent 3c70019 commit 2d04ab9
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ version 2.0.0.
- geometry .empty()
- geometry .to_wkb() and .to_wkt()
- geometry .ctypes and .__array_interface__
- multi-part geometry .__len__

Geometry objects will become immutable in version 2.0.0.

The STRtree class will be entirely changed in 2.0.0. The exact future API is
not yet decided, but will be decided before 1.8.0 is released.

Deprecation warnings will be emitted in 1.8a1 when any of these features are
used.

Expand Down
13 changes: 11 additions & 2 deletions shapely/strtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
https://www.cs.odu.edu/~mln/ltrs-pdfs/icase-1997-14.pdf
"""

from shapely.geos import lgeos
import ctypes
from warnings import warn

from shapely.errors import ShapelyDeprecationWarning
from shapely.geos import lgeos


class STRtree:
"""
Expand Down Expand Up @@ -72,6 +76,11 @@ class STRtree:
"""

def __init__(self, geoms):
warn(
"STRtree will be completely changed in 2.0.0. The exact API is not yet decided, but will be documented before 1.8.0",
ShapelyDeprecationWarning,
stacklevel=2,
)
# filter empty geometries out of the input
geoms = [geom for geom in geoms if not geom.is_empty]
self._n_geoms = len(geoms)
Expand Down Expand Up @@ -217,7 +226,7 @@ def callback(item1, item2, distance, userdata):
dist = ctypes.cast(distance, ctypes.POINTER(ctypes.c_double))
lgeos.GEOSDistance(geom1._geom, geom2._geom, dist)
return 1
except:
except Exception:
return 0

item = lgeos.GEOSSTRtree_nearest_generic(self._tree_handle, ctypes.py_object(geom), envelope._geom, \
Expand Down
27 changes: 18 additions & 9 deletions tests/test_strtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
import subprocess
import sys

from shapely.strtree import STRtree
from shapely.geometry import Point, Polygon
import pytest

from shapely.errors import ShapelyDeprecationWarning
from shapely.geometry import Point, Polygon
from shapely import strtree
from shapely.strtree import STRtree

from tests.conftest import requires_geos_342
from .conftest import requires_geos_342


@requires_geos_342
def test_query():
points = [Point(i, i) for i in range(10)]
tree = STRtree(points)
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree(points)
results = tree.query(Point(2, 2).buffer(0.99))
assert len(results) == 1
results = tree.query(Point(2, 2).buffer(1.0))
Expand All @@ -30,7 +33,8 @@ def test_insert_empty_geometry():
"""
empty = Polygon()
geoms = [empty]
tree = STRtree(geoms)
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree(geoms)
assert tree._n_geoms == 0
query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)])
results = tree.query(query)
Expand All @@ -46,7 +50,8 @@ def test_query_empty_geometry():
empty = Polygon()
point = Point(1, 0.5)
geoms = [empty, point]
tree = STRtree(geoms)
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree(geoms)
assert tree._n_geoms == 1
query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)])
results = tree.query(query)
Expand All @@ -60,7 +65,8 @@ def test_references():
empty = Polygon()
point = Point(1, 0.5)
geoms = [empty, point]
tree = STRtree(geoms)
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree(geoms)
assert tree._n_geoms == 1

empty = None
Expand All @@ -75,7 +81,8 @@ def test_references():

@requires_geos_342
def test_safe_delete():
tree = STRtree([])
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree([])

_lgeos = strtree.lgeos
strtree.lgeos = None
Expand All @@ -90,7 +97,9 @@ def test_pickle_persistence():
"""
Don't crash trying to use unpickled GEOS handle.
"""
tree = STRtree([Point(i, i).buffer(0.1) for i in range(3)])

with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree([Point(i, i).buffer(0.1) for i in range(3)])
pickled_strtree = pickle.dumps(tree)
unpickle_script_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "unpickle-strtree.py")
proc = subprocess.Popen(
Expand Down
30 changes: 20 additions & 10 deletions tests/test_strtree_nearest.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
from . import unittest

import pytest

from shapely.errors import ShapelyDeprecationWarning
from shapely.geometry import Point, Polygon
from shapely.geos import geos_version
from shapely.strtree import STRtree


@unittest.skipIf(geos_version < (3, 6, 0), 'GEOS 3.6.0 required')
class STRTreeNearest(unittest.TestCase):
def test_nearest(self):
tree = STRtree([
Polygon([(1,0),(2,0),(2,1),(1,1)]),
Polygon([(0,2),(1,2),(1,3),(0,3)]),
Point(0,0.5)])
result = tree.nearest(Point(0,0))
self.assertEqual(result, Point(0,0.5))
result = tree.nearest(Point(0,4))
self.assertEqual(result, Polygon([(0,2),(1,2),(1,3),(0,3)]))
result = tree.nearest(Polygon([(-0.5,-0.5),(0.5,-0.5),(0.5,0.5),(-0.5,0.5)]))
self.assertEqual(result, Point(0,0.5))
with pytest.warns(ShapelyDeprecationWarning):
tree = STRtree(
[
Polygon([(1, 0), (2, 0), (2, 1), (1, 1)]),
Polygon([(0, 2), (1, 2), (1, 3), (0, 3)]),
Point(0, 0.5),
]
)
result = tree.nearest(Point(0, 0))
self.assertEqual(result, Point(0, 0.5))
result = tree.nearest(Point(0, 4))
self.assertEqual(result, Polygon([(0, 2), (1, 2), (1, 3), (0, 3)]))
result = tree.nearest(
Polygon([(-0.5, -0.5), (0.5, -0.5), (0.5, 0.5), (-0.5, 0.5)])
)
self.assertEqual(result, Point(0, 0.5))

0 comments on commit 2d04ab9

Please sign in to comment.