or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

affinity.mdconstructive.mdcoordinates.mdcoverage-operations.mdcreation.mdgeometry-classes.mdgeometry-introspection.mdindex.mdio.mdlinear.mdmeasurements.mdpredicates.mdset-operations.mdspatial-indexing.md

set-operations.mddocs/

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

```