构建新要素的方法

Shapely几何对象有一些方法产生新的要素,而不是由集理论得到的对象。

object.buffer(distance,resolution=16)

返回一个几何对象指定距离内所有点的近似代表。

一个正的距离有扩张的效果;一个负的距离有减少的效果。 可选的分辨率参数决定一个点周围近似四分之一圈的段数。

In [10]:
from shapely.geometry import LineString
line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
dilated = line.buffer(0.5)
eroded = dilated.buffer(-0.3)
In [11]:
dilated
Out[11]:
In [12]:
eroded
Out[12]:

图6.2:一条线的扩张和一个多边形的收缩。 新对象用蓝线表示。

一个点的默认缓冲区是与99.8%的圆盘面积的多边形补丁。

In [13]:
from shapely.geometry import Point
p = Point(0, 0).buffer(10.0)
len(p.exterior.coords)
Out[13]:
66
In [14]:
p.area
Out[14]:
313.6548490545939

分辨率为1,缓冲区是一个矩形补丁。例如:

In [15]:
q = Point(0, 0).buffer(10.0, 1)
len(q.exterior.coords)
Out[15]:
5
In [16]:
q
Out[16]:
In [17]:
q.area
Out[17]:
200.0

通过设定距离为0, buffer() 可清除自接触或者自交多边形,例如经典的“领结”。

In [33]:
from shapely.geometry import Polygon
coords = [(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)]
bowtie = Polygon(coords)
bowtie.is_valid
Out[33]:
False
In [34]:
bowtie
Out[34]:
In [19]:
clean = bowtie.buffer(0)
clean.is_valid
Out[19]:
True
In [20]:
clean
Out[20]:
In [21]:
len(clean)
Out[21]:
2
In [35]:
list(clean[0].exterior.coords)
Out[35]:
[(0.0, 0.0), (0.0, 2.0), (1.0, 1.0), (0.0, 0.0)]
In [37]:
clean[0].exterior
Out[37]:
In [39]:
list(clean[0].exterior.coords)
Out[39]:
[(0.0, 0.0), (0.0, 2.0), (1.0, 1.0), (0.0, 0.0)]
In [40]:
clean[0].exterior.coords
Out[40]:
<shapely.coords.CoordinateSequence at 0x7fba6445db38>
In [23]:
list(clean[1].exterior.coords)
Out[23]:
[(1.0, 1.0), (2.0, 2.0), (2.0, 0.0), (1.0, 1.0)]

缓冲区在它们接触的点的地方将多边形一分为二。

object.convex_hull

返回一个包含对象中所有点的表示为最小凸多边形,除非对象中点的数量少于三个。 对于2个点,凸包折叠为一条线;一个点则折叠为一点。

In [24]:
Point(0, 0).convex_hull
Out[24]:
In [25]:
from shapely.geometry import MultiPoint
MultiPoint([(0, 0), (1, 1)]).convex_hull
Out[25]:
In [26]:
from shapely.geometry import MultiPoint
MultiPoint([(0, 0), (1, 1), (1, -1)]).convex_hull
Out[26]:

图6.3:左边2个点的凸包(蓝),右边6个点的凸包。

object.envelope

返回那个点或包含那个对象的最小矩形多边形 (边平行于坐标轴)的代表。

In [27]:
from shapely.geometry import Point
Point(0, 0).envelope
Out[27]:
In [28]:
from shapely.geometry import MultiPoint
MultiPoint([(0, 0), (1, 1)]).envelope
Out[28]:

object.simplify(tolerance,preserve_topology=True)

返回一个几何对象的简化形式。

简化对象中的所有点将会在原始几何距离的容差内。 默认情况下,较慢的算法被用于保留拓扑结构。 如果保留拓扑结构设置为假,更快的道格拉斯 - 普克算法[6]将被采用。

In [29]:
p = Point(0.0, 0.0)
x = p.buffer(1.0)
x.area
Out[29]:
3.1365484905459384
In [30]:
len(x.exterior.coords)
Out[30]:
66
In [31]:
s = x.simplify(0.05, preserve_topology=False)
s.area
Out[31]:
3.0614674589207187
In [32]:
len(s.exterior.coords)
Out[32]:
17

图6.4:一个近圆形的多边形的容差为 0.2(左)和0.5(右)的简化。

注意;

无效的几何对象,可能会导致从不保留拓扑的简化。

集合论方法

几乎每一个二元谓词方法都有一个返回新几何对象的副本的方法。 且一个对象的集合论边界是作为只读属性得到的。

边界与中心

一个多边形的边界是一条线, 线的边界是一系列的点。一个点的边界是一个空集合。

In [1]:
from shapely.geometry import LineString, MultiLineString, Point
pprint=LineString
coords = [((0, 0), (1, 1)), ((-1, 0), (1, 0))]
lines = MultiLineString(coords)
lines.boundary
pprint(list(lines.boundary))
lines.boundary.boundary
lines.boundary.boundary.is_empty
Out[1]:
True

object.centroid

返回几何对象的质心的代表。

In [2]:
LineString([(0, 0), (1, 1)]).centroid
LineString([(0, 0), (1, 1)]).centroid.wkt
Out[2]:
'POINT (0.5 0.5)'

注意:

一个对象的质心可能是它点中的一个,但是并不保证所有对象的质心都是这样。

相减操作

object.difference(other)

返回组成这个几何对象的点的一个代表, 且这些点不组成其它对象。

In [3]:
a = Point(1, 1).buffer(1.5)
b = Point(2, 1).buffer(1.5)
a.difference(b)
Out[3]:

图6.1为两个近似圆形多边形的 difference()

注意:

Shapely不能代表一个对象和作为单个对象的低维数对象的不同 (例如一个多边形与一条线或一个点的差异) 在这些例子中,不同的方法返回 一个叫做‘self’的对象的副本。

相交操作

object.intersection(other) , 返回一个对象与另一个几何对象交集的代表。

In [4]:
a = Point(1, 1).buffer(1.5)
b = Point(2, 1).buffer(1.5)
a.intersection(b)
Out[4]:

object.symmetric\_difference(other) 返回一个在这个对象不在另一个几何对象的点的代表, 并且其它对象的点不在这个几何对象中。

In [5]:
a = Point(1, 1).buffer(1.5)
b = Point(2, 1).buffer(1.5)
a.symmetric_difference(b)
Out[5]:

image

object.union(other)

返回这个对象和其它几何对象间的点的集合的代表。

返回对象的类型取决于运算对象之间的关系。 例如多边形的合并,取决于它们是否相交, 结果则是一个多边形或者是一个的多元多边形。

In [6]:
a = Point(1, 1).buffer(1.5)
b = Point(2, 1).buffer(1.5)
a.union(b)
Out[6]:

这些操作的语义随着几何对象类型的不同而变化。例如, 比较合并之后多边形的边界,与多边形边界的合并结果。

In [7]:
a.union(b).boundary
Out[7]:
In [8]:
a.boundary.union(b.boundary)
Out[8]:

image

注意:

union() 是一个找到许多对象的累积集合的昂贵的方式。 shapely.ops.cascaded_union() 是一个更有效的方法。