0
# Set Operations
1
2
Boolean operations that combine geometries using mathematical set theory concepts: union, intersection, difference, and symmetric difference. These operations are fundamental for spatial analysis and geometry processing.
3
4
## Capabilities
5
6
### Binary Set Operations
7
8
Operations between two geometries or geometry arrays.
9
10
```python { .api }
11
def union(a, b, grid_size=None, **kwargs):
12
"""
13
Compute union of two geometries (A ∪ B).
14
15
Parameters:
16
- a: first geometry or array of geometries
17
- b: second geometry or array of geometries
18
- grid_size: precision grid size for snap-rounding
19
20
Returns:
21
Geometry or array: union result
22
"""
23
24
def intersection(a, b, grid_size=None, **kwargs):
25
"""
26
Compute intersection of two geometries (A ∩ B).
27
28
Parameters:
29
- a: first geometry or array of geometries
30
- b: second geometry or array of geometries
31
- grid_size: precision grid size for snap-rounding
32
33
Returns:
34
Geometry or array: intersection result (may be empty)
35
"""
36
37
def difference(a, b, grid_size=None, **kwargs):
38
"""
39
Compute difference of two geometries (A - B).
40
41
Parameters:
42
- a: first geometry or array of geometries
43
- b: second geometry or array of geometries
44
- grid_size: precision grid size for snap-rounding
45
46
Returns:
47
Geometry or array: difference result (may be empty)
48
"""
49
50
def symmetric_difference(a, b, grid_size=None, **kwargs):
51
"""
52
Compute symmetric difference of two geometries (A ⊕ B).
53
Result contains areas in A or B but not in both.
54
55
Parameters:
56
- a: first geometry or array of geometries
57
- b: second geometry or array of geometries
58
- grid_size: precision grid size for snap-rounding
59
60
Returns:
61
Geometry or array: symmetric difference result
62
"""
63
```
64
65
**Usage Example:**
66
67
```python
68
import shapely
69
from shapely.geometry import Polygon
70
71
# Create two overlapping rectangles
72
rect1 = Polygon([(0, 0), (3, 0), (3, 2), (0, 2)])
73
rect2 = Polygon([(1, 1), (4, 1), (4, 3), (1, 3)])
74
75
# Set operations
76
union_result = shapely.union(rect1, rect2)
77
intersection_result = shapely.intersection(rect1, rect2)
78
difference_result = shapely.difference(rect1, rect2)
79
symmetric_diff = shapely.symmetric_difference(rect1, rect2)
80
81
print(f"Rect1 area: {rect1.area}") # 6.0
82
print(f"Rect2 area: {rect2.area}") # 6.0
83
print(f"Union area: {union_result.area}") # 10.0
84
print(f"Intersection area: {intersection_result.area}") # 2.0
85
print(f"Difference area: {difference_result.area}") # 4.0
86
print(f"Symmetric diff area: {symmetric_diff.area}") # 8.0
87
```
88
89
### Unary Set Operations
90
91
Operations on single geometries or geometry collections.
92
93
```python { .api }
94
def unary_union(geometry, grid_size=None, **kwargs):
95
"""
96
Compute union of all geometries in a collection.
97
98
Parameters:
99
- geometry: geometry collection or array of geometries
100
- grid_size: precision grid size for snap-rounding
101
102
Returns:
103
Geometry: union of all input geometries
104
"""
105
106
# Alias for unary_union
107
def union_all(geometries, grid_size=None, axis=None, **kwargs):
108
"""
109
Compute union of multiple geometries.
110
111
Parameters:
112
- geometries: array of geometries
113
- grid_size: precision grid size
114
- axis: axis along which to compute union (for multidimensional arrays)
115
116
Returns:
117
Geometry or array: union result
118
"""
119
```
120
121
**Usage Example:**
122
123
```python
124
import shapely
125
import numpy as np
126
127
# Create multiple overlapping circles
128
centers = [(0, 0), (1, 0), (0.5, 0.8)]
129
circles = [shapely.Point(x, y).buffer(0.7) for x, y in centers]
130
131
# Union all circles
132
merged = shapely.unary_union(circles)
133
print(f"Individual areas: {[c.area for c in circles]}")
134
print(f"Union area: {merged.area:.2f}")
135
136
# Array-based union
137
circle_array = np.array(circles)
138
merged_array = shapely.union_all(circle_array)
139
print(f"Array union area: {merged_array.area:.2f}")
140
```
141
142
### Aggregate Operations
143
144
Operations that combine multiple geometries into single results.
145
146
```python { .api }
147
def intersection_all(geometries, axis=None, **kwargs):
148
"""
149
Compute intersection of all geometries.
150
151
Parameters:
152
- geometries: array of geometries
153
- axis: axis along which to compute intersection
154
155
Returns:
156
Geometry or array: intersection of all geometries
157
"""
158
159
def symmetric_difference_all(geometries, axis=None, **kwargs):
160
"""
161
Compute symmetric difference of all geometries.
162
Note: This function is deprecated.
163
164
Parameters:
165
- geometries: array of geometries
166
- axis: axis along which to compute operation
167
168
Returns:
169
Geometry or array: symmetric difference result
170
"""
171
```
172
173
**Usage Example:**
174
175
```python
176
import shapely
177
178
# Create overlapping rectangles
179
rects = [
180
shapely.box(0, 0, 3, 3),
181
shapely.box(1, 1, 4, 4),
182
shapely.box(2, 2, 5, 5)
183
]
184
185
# Find common area
186
common = shapely.intersection_all(rects)
187
print(f"Common intersection area: {common.area}") # Area where all overlap
188
189
# Union them all
190
total = shapely.union_all(rects)
191
print(f"Total union area: {total.area}")
192
```
193
194
### Coverage Operations
195
196
Optimized operations for non-overlapping geometry collections.
197
198
```python { .api }
199
def coverage_union(a, b, **kwargs):
200
"""
201
Optimized union for non-overlapping polygons.
202
Faster than regular union when polygons don't overlap.
203
204
Parameters:
205
- a: first geometry or array
206
- b: second geometry or array
207
208
Returns:
209
Geometry or array: union result
210
"""
211
212
def coverage_union_all(geometries, axis=None, **kwargs):
213
"""
214
Optimized union for collections of non-overlapping polygons.
215
216
Parameters:
217
- geometries: array of non-overlapping geometries
218
- axis: axis along which to compute union
219
220
Returns:
221
Geometry or array: union result
222
"""
223
```
224
225
**Usage Example:**
226
227
```python
228
import shapely
229
230
# Create non-overlapping squares (like a grid)
231
squares = []
232
for i in range(3):
233
for j in range(3):
234
square = shapely.box(i*2, j*2, i*2+1, j*2+1)
235
squares.append(square)
236
237
# Fast union for non-overlapping geometries
238
grid_union = shapely.coverage_union_all(squares)
239
print(f"Grid union area: {grid_union.area}") # Should be 9.0
240
241
# Compare with regular union (slower but same result)
242
regular_union = shapely.union_all(squares)
243
print(f"Regular union area: {regular_union.area}")
244
print(f"Results equal: {grid_union.equals(regular_union)}")
245
```
246
247
### Disjoint Subset Operations
248
249
Advanced operations for disjoint geometry collections (GEOS 3.12+).
250
251
```python { .api }
252
def disjoint_subset_union(a, b, **kwargs):
253
"""
254
Optimized union for disjoint geometry subsets.
255
Requires GEOS 3.12+.
256
257
Parameters:
258
- a: first geometry or array
259
- b: second geometry or array
260
261
Returns:
262
Geometry or array: union result
263
"""
264
265
def disjoint_subset_union_all(geometries, *, axis=None, **kwargs):
266
"""
267
Union of collections containing disjoint subsets.
268
Requires GEOS 3.12+.
269
270
Parameters:
271
- geometries: array of geometries with disjoint subsets
272
- axis: axis along which to compute union
273
274
Returns:
275
Geometry or array: union result
276
"""
277
```
278
279
### Precision and Robustness
280
281
Handle precision issues in set operations.
282
283
**Usage Example:**
284
285
```python
286
import shapely
287
288
# Create geometries with precision issues
289
# (coordinates that are almost but not exactly aligned)
290
poly1 = shapely.Polygon([(0, 0), (1.000000001, 0), (1, 1), (0, 1)])
291
poly2 = shapely.Polygon([(1, 0), (2, 0), (2, 1), (1.000000001, 1)])
292
293
# Without grid snapping - may create tiny slivers
294
union_default = shapely.union(poly1, poly2)
295
print(f"Default union area: {union_default.area:.10f}")
296
297
# With grid snapping - cleaner result
298
grid_size = 1e-6 # Snap to micrometer precision
299
union_snapped = shapely.union(poly1, poly2, grid_size=grid_size)
300
print(f"Snapped union area: {union_snapped.area:.10f}")
301
302
# The snapped version should be exactly 2.0
303
print(f"Snapped result clean: {abs(union_snapped.area - 2.0) < 1e-10}")
304
```
305
306
### Advanced Usage Patterns
307
308
Complex operations combining multiple set operations.
309
310
**Usage Example:**
311
312
```python
313
import shapely
314
import numpy as np
315
316
# Create complex scenario: buildings with setback requirements
317
building_footprints = [
318
shapely.box(0, 0, 10, 10), # Building 1
319
shapely.box(15, 0, 25, 10), # Building 2
320
shapely.box(5, 15, 15, 25) # Building 3
321
]
322
323
# Property boundary
324
property_boundary = shapely.box(-5, -5, 30, 30)
325
326
# Required setback from property line
327
setback_distance = 3
328
buildable_area = shapely.buffer(property_boundary, -setback_distance)
329
330
# Check which buildings violate setbacks
331
violations = []
332
compliant_buildings = []
333
334
for i, building in enumerate(building_footprints):
335
if buildable_area.contains(building):
336
compliant_buildings.append(building)
337
print(f"Building {i+1}: Compliant")
338
else:
339
violations.append(building)
340
# Calculate violation area
341
violation_area = shapely.difference(building, buildable_area)
342
print(f"Building {i+1}: Violation area = {violation_area.area:.1f}")
343
344
# Total built area
345
total_built = shapely.union_all(building_footprints)
346
print(f"Total built area: {total_built.area}")
347
348
# Remaining buildable area
349
remaining_buildable = shapely.difference(buildable_area, total_built)
350
print(f"Remaining buildable area: {remaining_buildable.area:.1f}")
351
```