Skip to content

Commit 8ff1f59

Browse files
Refactor shapely.prepared to use prepared base geometries
1 parent d52edde commit 8ff1f59

2 files changed

Lines changed: 21 additions & 38 deletions

File tree

shapely/prepared.py

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
"""
22
Support for GEOS prepared geometry operations.
33
"""
4+
import pygeos
45

5-
from shapely.geos import lgeos
6-
from shapely.impl import DefaultImplementation, delegated
76
from pickle import PicklingError
87

98

@@ -20,75 +19,53 @@ class PreparedGeometry(object):
2019
True
2120
"""
2221

23-
impl = DefaultImplementation
24-
2522
def __init__(self, context):
2623
if isinstance(context, PreparedGeometry):
2724
self.context = context.context
2825
else:
26+
pygeos.prepare(context)
2927
self.context = context
30-
self.__geom__ = lgeos.GEOSPrepare(self.context._geom)
3128
self.prepared = True
3229

33-
def __del__(self):
34-
if self.__geom__ is not None:
35-
try:
36-
lgeos.GEOSPreparedGeom_destroy(self.__geom__)
37-
except AttributeError:
38-
pass # lgeos might be empty on shutdown.
39-
40-
self.__geom__ = None
41-
self.context = None
42-
self.prepared = False
43-
44-
@property
45-
def _geom(self):
46-
return self.__geom__
47-
48-
@delegated
4930
def contains(self, other):
5031
"""Returns True if the geometry contains the other, else False"""
51-
return bool(self.impl['prepared_contains'](self, other))
32+
return self.context.contains(other)
5233

53-
@delegated
5434
def contains_properly(self, other):
5535
"""Returns True if the geometry properly contains the other, else False"""
56-
return bool(self.impl['prepared_contains_properly'](self, other))
36+
# TODO temporary hack until pygeos exposes contains properly as predicate function
37+
from pygeos import STRtree
38+
tree = STRtree([other])
39+
idx = tree.query(self.context, predicate="contains_properly")
40+
return bool(len(idx))
5741

58-
@delegated
5942
def covers(self, other):
6043
"""Returns True if the geometry covers the other, else False"""
61-
return bool(self.impl['prepared_covers'](self, other))
44+
return self.context.covers(other)
6245

63-
@delegated
6446
def crosses(self, other):
6547
"""Returns True if the geometries cross, else False"""
66-
return bool(self.impl['prepared_crosses'](self, other))
48+
return self.context.crosses(other)
6749

68-
@delegated
6950
def disjoint(self, other):
7051
"""Returns True if geometries are disjoint, else False"""
71-
return bool(self.impl['prepared_disjoint'](self, other))
52+
return self.context.disjoint(other)
7253

73-
@delegated
7454
def intersects(self, other):
7555
"""Returns True if geometries intersect, else False"""
76-
return bool(self.impl['prepared_intersects'](self, other))
56+
return self.context.intersects(other)
7757

78-
@delegated
7958
def overlaps(self, other):
8059
"""Returns True if geometries overlap, else False"""
81-
return bool(self.impl['prepared_overlaps'](self, other))
60+
return self.context.overlaps(other)
8261

83-
@delegated
8462
def touches(self, other):
8563
"""Returns True if geometries touch, else False"""
86-
return bool(self.impl['prepared_touches'](self, other))
64+
return self.context.touches(other)
8765

88-
@delegated
8966
def within(self, other):
9067
"""Returns True if geometry is within the other, else False"""
91-
return bool(self.impl['prepared_within'](self, other))
68+
return self.context.within(other)
9269

9370
def __reduce__(self):
9471
raise PicklingError("Prepared geometries cannot be pickled.")

shapely/vectorized/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import numpy as np
44
import pygeos
55

6+
from shapely.prepared import PreparedGeometry
7+
68

79
def _construct_points(x, y):
810
x, y = np.asanyarray(x), np.asanyarray(y)
@@ -39,6 +41,8 @@ def contains(geometry, x, y):
3941
4042
"""
4143
points = _construct_points(x, y)
44+
if isinstance(geometry, PreparedGeometry):
45+
geometry = geometry.context
4246
pygeos.prepare(geometry)
4347
return pygeos.contains(geometry, points)
4448

@@ -65,5 +69,7 @@ def touches(geometry, x, y):
6569
6670
"""
6771
points = _construct_points(x, y)
72+
if isinstance(geometry, PreparedGeometry):
73+
geometry = geometry.context
6874
pygeos.prepare(geometry)
6975
return pygeos.touches(geometry, points)

0 commit comments

Comments
 (0)