shapely
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseShapely - Planar Geometry
Shapely - 平面几何
Shapely is the engine behind GeoPandas and many other GIS tools. It focuses on the geometry itself: calculating intersections, unions, distances, and checking spatial relationships (like "is this point inside this polygon?").
Shapely是GeoPandas及众多GIS工具的核心引擎,它专注于几何对象本身:计算交集、并集、距离,以及判断空间关系(例如“该点是否在多边形内部?”)。
When to Use
适用场景
- Precise manipulation of 2D geometric shapes.
- Performing set-theoretic operations (Intersection, Union, Difference).
- Checking spatial predicates (Contains, Within, Intersects, Touches).
- Cleaning and validating "dirty" geometry (fixing self-intersections).
- Calculating geometric properties (Area, Length, Centroid, Bounds).
- Generating buffers or simplifying complex lines.
- Linear referencing (finding points along a line).
- 精确操作2D几何形状
- 执行集合论运算(交集、并集、差集)
- 判断空间谓词(包含、在内部、相交、接触)
- 清理和验证“无效”几何对象(修复自相交问题)
- 计算几何属性(面积、长度、质心、边界范围)
- 生成缓冲区或简化复杂线条
- 线性参考(查找线条上的点位)
Reference Documentation
参考文档
Official docs: https://shapely.readthedocs.io/
GEOS (Engine): https://libgeos.org/
Search patterns:, ,
GEOS (Engine): https://libgeos.org/
Search patterns:
shapely.geometryshapely.ops.unary_unionshapely.validation.make_valid官方文档:https://shapely.readthedocs.io/
GEOS(核心引擎):https://libgeos.org/
常用搜索关键词:, ,
GEOS(核心引擎):https://libgeos.org/
常用搜索关键词:
shapely.geometryshapely.ops.unary_unionshapely.validation.make_validCore Principles
核心原则
Geometric Objects
几何对象
Objects are immutable. Once created, you don't change them; you perform an operation that returns a new object.
- Points: 0-dimensional.
- LineStrings: 1-dimensional curves.
- Polygons: 2-dimensional surfaces with optional holes.
对象是不可变的。一旦创建,就不能修改它们;需通过执行操作返回新对象。
- Points:0维对象
- LineStrings:1维曲线
- Polygons:带可选孔洞的2维面
Cartesian Geometry
笛卡尔几何
Shapely operates in a Cartesian plane. It does not know about Earth's curvature, latitudes, or longitudes. Distance is sqrt(dx² + dy²).
Shapely在笛卡尔平面中运行,不考虑地球曲率、纬度或经度。距离计算采用sqrt(dx² + dy²)公式。
Vectorization (Shapely 2.0+)
向量化(Shapely 2.0+)
Modern Shapely supports vectorized operations on NumPy arrays of geometry objects, making it significantly faster than older versions.
新版Shapely支持对几何对象的NumPy数组执行向量化操作,相比旧版本性能大幅提升。
Quick Reference
快速参考
Installation
安装
bash
pip install shapely numpybash
pip install shapely numpyStandard Imports
标准导入
python
import numpy as np
from shapely import Point, LineString, Polygon, MultiPoint, MultiPolygon
from shapely import ops, wkt, wkb
import shapelypython
import numpy as np
from shapely import Point, LineString, Polygon, MultiPoint, MultiPolygon
from shapely import ops, wkt, wkb
import shapelyBasic Pattern - Creation and Analysis
基础模式 - 创建与分析
python
from shapely.geometry import Point, Polygonpython
from shapely.geometry import Point, Polygon1. Create objects
1. Create objects
p = Point(0, 0)
poly = Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
p = Point(0, 0)
poly = Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
2. Check relationships
2. Check relationships
is_inside = p.within(poly) # True
is_on_border = p.touches(poly) # False (interior counts as within)
is_inside = p.within(poly) # True
is_on_border = p.touches(poly) # False (interior counts as within)
3. Calculate
3. Calculate
print(f"Area: {poly.area}")
print(f"Distance: {p.distance(Point(10, 10))}")
undefinedprint(f"Area: {poly.area}")
print(f"Distance: {p.distance(Point(10, 10))}")
undefinedCritical Rules
关键规则
✅ DO
✅ 建议做法
- Check Validity - Use before complex operations. Invalid geometry (like a self-intersecting polygon) will cause errors.
.is_valid - Use unary_union - When merging many polygons, is orders of magnitude faster than a loop of
ops.unary_union([list]).p1.union(p2) - Prefer Vectorized Functions - Use instead of loops for performance.
shapely.intersects(array_a, array_b) - Use prepare() - If you are checking many points against the same polygon, use to speed up subsequent queries.
shapely.prepare(poly) - Simplify for Analysis - Use for complex boundaries to improve performance if high precision isn't required.
.simplify(tolerance)
- 检查有效性 - 在执行复杂操作前使用检查。无效几何对象(如自相交多边形)会导致错误。
.is_valid - 使用unary_union - 合并多个多边形时,比循环执行
ops.unary_union([list])快几个数量级。p1.union(p2) - 优先使用向量化函数 - 为提升性能,使用替代循环。
shapely.intersects(array_a, array_b) - 使用prepare() - 如果要针对同一个多边形检查大量点,使用加速后续查询。
shapely.prepare(poly) - 简化几何对象以优化分析 - 如果不需要高精度,使用简化复杂边界以提升性能。
.simplify(tolerance)
❌ DON'T
❌ 避免做法
- Mix Cartesian and Spherical - Don't calculate distance on Lat/Lon points; the result will be in meaningless "degrees".
- Assume Polygon Orientation - While Shapely handles it, remember that exterior rings should ideally be counter-clockwise and holes clockwise.
- Use for 3D Math - Shapely supports Z-coordinates for storage, but most operations (like area, intersection) ignore Z and project onto the XY plane.
- Loop over large collections - Use NumPy-style vectorization provided in Shapely 2.0+.
- 混合笛卡尔与球面坐标 - 不要对经纬度点计算距离,结果会是无意义的“度数”单位。
- 假设多边形方向 - 虽然Shapely会处理,但请记住,外部环理想情况下应为逆时针方向,孔洞应为顺时针方向。
- 用于3D运算 - Shapely支持存储Z坐标,但大多数运算(如面积、交集)会忽略Z坐标,投影到XY平面执行。
- 循环处理大型集合 - 使用Shapely 2.0+提供的NumPy风格向量化操作。
Anti-Patterns (NEVER)
反模式(绝对避免)
python
from shapely.geometry import Point, Polygon
from shapely.ops import unary_unionpython
from shapely.geometry import Point, Polygon
from shapely.ops import unary_union❌ BAD: Merging geometries in a loop (O(n²) complexity)
❌ BAD: Merging geometries in a loop (O(n²) complexity)
result = geometries[0]
for g in geometries[1:]:
result = result.union(g)
result = geometries[0]
for g in geometries[1:]:
result = result.union(g)
✅ GOOD: Use unary_union (O(n log n) complexity)
✅ GOOD: Use unary_union (O(n log n) complexity)
result = unary_union(geometries)
result = unary_union(geometries)
❌ BAD: Checking many points without preparing
❌ BAD: Checking many points without preparing
for p in many_points:
if complex_poly.contains(p): # Slow for complex shapes
pass
for p in many_points:
if complex_poly.contains(p): # Slow for complex shapes
pass
✅ GOOD: Prepare the geometry (Builds a spatial index)
✅ GOOD: Prepare the geometry (Builds a spatial index)
from shapely import prepare
prepare(complex_poly)
for p in many_points:
if complex_poly.contains(p): # Much faster
pass
undefinedfrom shapely import prepare
prepare(complex_poly)
for p in many_points:
if complex_poly.contains(p): # Much faster
pass
undefinedGeometry Types and Creation
几何类型与创建
Standard Primitives
标准基本类型
python
undefinedpython
undefinedPoint (x, y, z)
Point (x, y, z)
pt = Point(1.0, 2.0)
pt = Point(1.0, 2.0)
LineString (Ordered sequence of points)
LineString (Ordered sequence of points)
line = LineString([(0, 0), (1, 1), (2, 0)])
line = LineString([(0, 0), (1, 1), (2, 0)])
Polygon (Shell, [Holes])
Polygon (Shell, [Holes])
shell = [(0, 0), (10, 0), (10, 10), (0, 10)]
hole = [(2, 2), (2, 4), (4, 4), (4, 2)]
poly = Polygon(shell, [hole])
shell = [(0, 0), (10, 0), (10, 10), (0, 10)]
hole = [(2, 2), (2, 4), (4, 4), (4, 2)]
poly = Polygon(shell, [hole])
Multi-Geometries (Collections)
Multi-Geometries (Collections)
points = MultiPoint([(0,0), (1,1)])
undefinedpoints = MultiPoint([(0,0), (1,1)])
undefinedSpatial Predicates (Relationships)
空间谓词(关系判断)
Checking how objects relate
判断对象间的关系
python
a = Point(1, 1).buffer(1.5) # A circle
b = Polygon([(0,0), (2,0), (2,2), (0,2)]) # A square
print(a.intersects(b)) # Shared space?
print(a.contains(b)) # B entirely inside A?
print(a.disjoint(b)) # No shared space?
print(a.overlaps(b)) # Same dimension, shared space, but not within?
print(a.touches(b)) # Only boundaries share space?
print(a.crosses(b)) # Line crossing a polygon?python
a = Point(1, 1).buffer(1.5) # A circle
b = Polygon([(0,0), (2,0), (2,2), (0,2)]) # A square
print(a.intersects(b)) # Shared space?
print(a.contains(b)) # B entirely inside A?
print(a.disjoint(b)) # No shared space?
print(a.overlaps(b)) # Same dimension, shared space, but not within?
print(a.touches(b)) # Only boundaries share space?
print(a.crosses(b)) # Line crossing a polygon?Set-Theoretic Operations
集合论运算
Creating new geometries from old ones
基于已有几何对象创建新对象
python
poly1 = Point(0, 0).buffer(1)
poly2 = Point(1, 0).buffer(1)python
poly1 = Point(0, 0).buffer(1)
poly2 = Point(1, 0).buffer(1)Intersection (Shared area)
Intersection (Shared area)
inter = poly1.intersection(poly2)
inter = poly1.intersection(poly2)
Union (Combined area)
Union (Combined area)
union = poly1.union(poly2)
union = poly1.union(poly2)
Difference (Area in poly1 NOT in poly2)
Difference (Area in poly1 NOT in poly2)
diff = poly1.difference(poly2)
diff = poly1.difference(poly2)
Symmetric Difference (Area in either but NOT both)
Symmetric Difference (Area in either but NOT both)
sdiff = poly1.symmetric_difference(poly2)
undefinedsdiff = poly1.symmetric_difference(poly2)
undefinedConstructive Methods
构造方法
Buffering, Splicing, and Simplifying
缓冲区、拼接与简化
python
undefinedpython
undefinedBuffer: Expand/shrink geometry
Buffer: Expand/shrink geometry
cap_style: 1=Round, 2=Flat, 3=Square
cap_style: 1=Round, 2=Flat, 3=Square
line_thick = line.buffer(0.5, cap_style=2)
line_thick = line.buffer(0.5, cap_style=2)
Centroid: Geometric center
Centroid: Geometric center
center = poly.centroid
center = poly.centroid
Representative Point: Guaranteed to be INSIDE the geometry
Representative Point: Guaranteed to be INSIDE the geometry
Useful for label placement in U-shaped polygons
Useful for label placement in U-shaped polygons
label_pt = poly.representative_point()
label_pt = poly.representative_point()
Simplify: Reduce number of vertices
Simplify: Reduce number of vertices
simple_line = complex_line.simplify(tolerance=0.1, preserve_topology=True)
simple_line = complex_line.simplify(tolerance=0.1, preserve_topology=True)
Convex Hull: Smallest convex box containing all points
Convex Hull: Smallest convex box containing all points
hull = MultiPoint(points).convex_hull
undefinedhull = MultiPoint(points).convex_hull
undefinedLinear Referencing
线性参考
Working with positions along a LineString
处理LineString上的点位
python
line = LineString([(0, 0), (0, 10), (10, 10)])python
line = LineString([(0, 0), (0, 10), (10, 10)])Find distance along line to the point nearest to (5, 5)
Find distance along line to the point nearest to (5, 5)
dist = line.project(Point(5, 5)) # returns 5.0 (it's at (0, 5))
dist = line.project(Point(5, 5)) # returns 5.0 (it's at (0, 5))
Find the actual point at a specific distance along the line
Find the actual point at a specific distance along the line
pt = line.interpolate(15.0) # returns Point(5, 10)
undefinedpt = line.interpolate(15.0) # returns Point(5, 10)
undefinedI/O: WKT, WKB, and NumPy
输入输出:WKT、WKB与NumPy
Serialization and Data Exchange
序列化与数据交换
python
undefinedpython
undefinedWKT (Well-Known Text) - Human readable
WKT (Well-Known Text) - Human readable
text = "POINT (10 20)"
p = wkt.loads(text)
print(p.wkt)
text = "POINT (10 20)"
p = wkt.loads(text)
print(p.wkt)
WKB (Well-Known Binary) - Fast and compact
WKB (Well-Known Binary) - Fast and compact
binary = wkb.dumps(p)
p_new = wkb.loads(binary)
binary = wkb.dumps(p)
p_new = wkb.loads(binary)
NumPy Integration (Shapely 2.0)
NumPy Integration (Shapely 2.0)
points_array = np.array([Point(0,0), Point(1,1), Point(2,2)])
areas = shapely.area(points_array) # Returns array of zeros
dist_matrix = shapely.distance(points_array[:, np.newaxis], points_array)
undefinedpoints_array = np.array([Point(0,0), Point(1,1), Point(2,2)])
areas = shapely.area(points_array) # Returns array of zeros
dist_matrix = shapely.distance(points_array[:, np.newaxis], points_array)
undefinedPractical Workflows
实用工作流
1. Cleaning Invalid Geometries
1. 修复无效几何对象
python
from shapely.validation import make_valid
def safe_area(geom):
"""Calculates area even for invalid/self-intersecting polygons."""
if not geom.is_valid:
geom = make_valid(geom)
# After make_valid, a Polygon might become a MultiPolygon or GeometryCollection
return geom.areapython
from shapely.validation import make_valid
def safe_area(geom):
"""Calculates area even for invalid/self-intersecting polygons."""
if not geom.is_valid:
geom = make_valid(geom)
# After make_valid, a Polygon might become a MultiPolygon or GeometryCollection
return geom.area2. Point-in-Polygon Search (Optimized)
2. 优化版点-in-多边形查询
python
from shapely import prepare
def find_points_in_poly(points, poly):
"""Efficiently filters points inside a complex polygon."""
prepare(poly) # Builds internal STRtree or spatial index
# Using vectorized intersection (much faster)
mask = shapely.contains(poly, points)
return points[mask]python
from shapely import prepare
def find_points_in_poly(points, poly):
"""Efficiently filters points inside a complex polygon."""
prepare(poly) # Builds internal STRtree or spatial index
# Using vectorized intersection (much faster)
mask = shapely.contains(poly, points)
return points[mask]3. Splitting a Polygon by a Line
3. 用线条分割多边形
python
from shapely.ops import split
def divide_land(polygon, line):
"""Splits a polygon into multiple parts using a LineString."""
result = split(polygon, line)
# Returns a GeometryCollection of the resulting parts
return list(result.geoms)python
from shapely.ops import split
def divide_land(polygon, line):
"""Splits a polygon into multiple parts using a LineString."""
result = split(polygon, line)
# Returns a GeometryCollection of the resulting parts
return list(result.geoms)Performance Optimization
性能优化
STRtree for Nearest Neighbors
用STRtree查找最近邻
If you have thousands of geometries and need to find which ones are near a point, use STRtree.
python
from shapely import STRtree
tree = STRtree(geometries)如果有数千个几何对象,需要查找某个点附近的对象,可使用STRtree。
python
from shapely import STRtree
tree = STRtree(geometries)Find indices of geometries whose bounding boxes intersect the point's buffer
Find indices of geometries whose bounding boxes intersect the point's buffer
indices = tree.query(Point(0,0).buffer(10))
indices = tree.query(Point(0,0).buffer(10))
Find the single nearest geometry index
Find the single nearest geometry index
nearest_idx = tree.nearest(Point(0,0))
undefinednearest_idx = tree.nearest(Point(0,0))
undefinedCommon Pitfalls and Solutions
常见陷阱与解决方案
The "Sliver Polygon" problem
“细长三角多边形”问题
Calculations like intersection can sometimes produce tiny, almost invisible polygons due to floating-point errors.
python
undefined交集等运算有时会因浮点误差产生极小的、几乎不可见的多边形。
python
undefined✅ Solution: Filter by area
✅ Solution: Filter by area
intersection = p1.intersection(p2)
if intersection.area < 1e-9:
intersection = None
undefinedintersection = p1.intersection(p2)
if intersection.area < 1e-9:
intersection = None
undefinedLatitude/Longitude Confusion
经纬度顺序混淆
Points are (x, y). In GIS, this usually means (Longitude, Latitude).
python
undefined点的格式是(x, y),在GIS中通常对应(经度,纬度)。
python
undefined❌ Error: Point(Latitude, Longitude)
❌ Error: Point(Latitude, Longitude)
This will plot your maps sideways!
This will plot your maps sideways!
✅ Solution: Always use (Lon, Lat) to match (X, Y)
✅ Solution: Always use (Lon, Lat) to match (X, Y)
nyc = Point(-74.006, 40.7128)
undefinednyc = Point(-74.006, 40.7128)
undefinedGeometryCollections
GeometryCollections
Operations like split or intersection can return GeometryCollection. This is a container for mixed types.
python
undefined分割或交集等操作可能返回GeometryCollection,这是一个混合类型的容器。
python
undefined❌ Problem: Calling .area on a collection with Lines and Polygons
❌ Problem: Calling .area on a collection with Lines and Polygons
✅ Solution: Filter for the type you want
✅ Solution: Filter for the type you want
polys = [g for g in collection.geoms if g.geom_type == 'Polygon']
undefinedpolys = [g for g in collection.geoms if g.geom_type == 'Polygon']
undefinedBest Practices
最佳实践
- Always validate geometry with before complex operations
.is_valid - Use instead of looping over unions
unary_union - Prepare geometries with when checking many points against the same shape
prepare() - Use vectorized operations in Shapely 2.0+ for performance
- Remember Shapely is Cartesian - don't use lat/lon directly for distance calculations
- Filter sliver polygons by area threshold after geometric operations
- Use STRtree for spatial indexing when working with many geometries
- Simplify complex geometries when high precision isn't required
- Handle GeometryCollections properly - filter by geometry type when needed
- Use representative_point() for guaranteed interior points in complex polygons
Shapely is a specialized, sharp tool. It doesn't care about your coordinate system or your file format — it only cares about the pure, mathematical relationship between shapes. Mastering it is the key to building advanced spatial algorithms.
- 执行复杂操作前,始终用验证几何对象
.is_valid - 使用替代循环执行并集操作
unary_union - 当针对同一形状检查大量点时,用预处理几何对象
prepare() - 为提升性能,使用Shapely 2.0+的向量化操作
- 记住Shapely基于笛卡尔坐标系 - 不要直接对经纬度计算距离
- 几何运算后,通过面积阈值过滤细长三角多边形
- 处理大量几何对象时,用STRtree做空间索引
- 不需要高精度时,简化复杂几何对象
- 正确处理GeometryCollection - 需要时按几何类型过滤
- 对复杂多边形,使用representative_point()获取确保在内部的点位
Shapely是一款专业且强大的工具,它不关心你的坐标系或文件格式——只专注于形状之间纯粹的数学关系。掌握它是构建高级空间算法的关键。