>>> from env_helper import info; info()
页面更新时间: 2023-06-24 11:31:07
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-9-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
7.2. Shapely 中几何要素的操作¶
7.2.1. 一般的属性与方法¶
object.area
返回对象的面积
object.bounds
返回一个元组(minx,miny,maxx,maxy)
,即对象的界限。
object.length
返回对象的长度。
object.geom_type
返回一个字符串,指定对象的几何类型,按照OpenGIS的格式进行。
>>> from shapely.geometry import Point
>>> Point(0,0).geom_type
'Point'
输出点(0,0)
的几何类型。
object.distance(other)
返回到其他类型几何对象之间的浮点型最短距离。
>>> Point(0,0).distance(Point(1,1))
1.4142135623730951
object.representative_point()
返回一个在几何对象内的易得到的计算点。
注意:质点的不同, 这个点得到的是依照所需计算量最小而定的,只要在几何对象内部即可。
>>> donut = Point(0, 0).buffer(2.0).difference(Point(0, 0).buffer(1.0))
>>> donut.centroid.wkt
'POINT (0 0)'
>>> donut.representative_point().wkt
'POINT (1.4975923633360986 0.0490085701647802)'
7.2.2. 点¶
Point
的构造函数采用坐标位置值或点元组参数。
>>> from shapely.geometry import Point
>>> point = Point(0.0, 0.0)
>>> point.area
0.0
>>> point.length
0.0
>>> point.bounds
(0.0, 0.0, 0.0, 0.0)
一个点的面积为0,长度为0。
它的边界是一个元组(minx,miny,maxx,maxy)
。
坐标值通过x
,y
,z
属性获得。
>>> list(point.coords)
[(0.0, 0.0)]
>>> point.x
0.0
>>> point.y
0.0
点的构造同样接受另一个点的实例,从而得到一个副本。
>>> Point(point)
7.2.3. 线¶
class LineString( coordinates)
LineString
的构造采用线性序列,一般采用2个或者多个(x,y[,z])
点元组。
构造的LineString
对象代表点与点之间的一个或多个直线样条。
有序序列内的点是允许重复的,但可能产生性能损失,应该尽量避免。
一条线可能会自相交,是有效的。
>>> from shapely.geometry import LineString
>>> line = LineString([(0, 0), (1, 1)])
>>> print(line.area)
0.0
>>> print(line.length)
1.4142135623730951
>>> print(line.bounds)
(0.0, 0.0, 1.0, 1.0)
>>> len(line.coords)
2
>>> list(line.coords)
[(0.0, 0.0), (1.0, 1.0)]
>>> LineString(line)
它的边界是一个(minx, miny, maxx, maxy)元组。
定义的坐标属性值通过坐标的属性来获得。也可是坐标的切片。
线的构造同样接受另一个线的实例,从而使用另一个副本。
Point
的实例序列不是一个有效的构造函数的参数。线由点来描述,
但不是由点的实例组成。
7.2.4. 面¶
class Polygon(exterior[,interiors=None])
多边形构造需要2个位置参数。
第一个位置参数是(x,y[,z])
点元组的有序序列,
并且在LinearRing
中被认为是准确的。
第二个位置参数是一个可选的、像ring的,无序序列,且位于要素内部,
指定边界或洞的环状序列。
一个有效的多边形的环不能相互交叉, 但可以在一个单点接触。
同样,Shapely不会阻止无效要素的创建, 但是当他们运行时,可能会有异常。
>>> from shapely.geometry import Polygon
>>>
>>> ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
>>> int = [(1, 0), (0.5, 0.5), (1, 1), (1.5, 0.5), (1, 0)][::-1]
>>> polygon = Polygon(ext, [int])
>>> polygon
>>> polygon.is_valid
True
>>> ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
>>> int = [(1, 0), (0, 1), (0.5, 1.5), (1.5, 0.5), (1, 0)][::-1]
>>> from shapely.geometry import Polygon
>>> polygon = Polygon(ext, [int])
>>> polygon
>>> polygon.is_valid
False
>>>
>>> ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
>>> int = [(0.5, 0), (1.5, 0), (1.5, 1), (0.5, 1), (0.5, 0)]
>>> polygon = Polygon(ext, [int])
>>> polygon
>>> polygon.is_valid
False
图片[fig:valinvalpoly]:左边, 是一个有效的内部环和一个外部环接触于一点;右边, 是无效的多边形,因为它的内部环与外部环在多于一个点接触,描述环的点表现为灰色。
图片[fig:twoinval]:左边,多边形是无效的, 因为它的外部环和内部环相触于一条线;右边,是无效的多边形,因为 它的内部环相触于一条线。
多边形的面积不为0,长度不为0。
>>> from shapely.geometry import Polygon
>>> from shapely.geometry import LinearRing
>>> polygon = Polygon([(0, 0), (1, 1), (1, 0)])
>>> polygon
>>> polygon.area
>>> polygon.length
>>> polygon.bounds
>>> list(polygon.exterior.coords)
>>> list(polygon.interiors)
>>> coords = [(0, 0), (1, 1), (1, 0)]
>>> r = LinearRing(coords)
>>> r
>>> s = Polygon(r)
>>> s.area
0.5
>>> s
>>> t = Polygon(s.buffer(1.0).exterior, [r])
>>> t.area
6.5507620529190325
>>> t
它的x-y边界是一个(minx, miny, maxx, maxy)元组。
组成的环通过内部环和外部环的属性获得。多边形的构件同样接受线和环的实例。
矩形多边形出现,可以方便地使用shapely.geometry.box()
函数构建。
shapely.geometry.box(minx,miny,maxx,maxy,ccw=True)
通过提供的边界值来构造矩形多边形, 默认使用逆时针顺序。
例如:
>>> from shapely.geometry import Polygon, box
>>> b = box(0.0, 0.0, 1.0, 1.0)
>>> list(b.exterior.coords)
[(1.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.0, 0.0), (1.0, 0.0)]
这是在Shapely多边形中惯用的,且第一次出现。
为获得一个已知方向的多边形,用shapely.geometry.polygon.orient()
函数:
shapely.geometry.polygon.orient(polygon,sign=1.0)
返回一个给定多边形正式方向的副本。
有符面积(使用正负号的面积)将会有给定的符号。符号1.0
表示
产品外部环的坐标将被逆时针导出。
7.2.5. 对线状shapefile进行缓冲操作¶
对线状shapefile进行缓冲操作与上一节的对点状shapefile进行缓冲类似,本节我们来看一下如何对线进行缓冲操作。
注意看上面的结果。原始的线状shapefile是复杂线的类型。它由三段构成,但却是一个实体。 而结果却是分段生成的。 这样的结果对某些情况是有用的,比如说制图(不能显示边界), 是常用的情况,我们希望生成的结果也是一个多边形, 譬如说面积统计(总面积可不是分段面积的和)。 这个部分当然可以对上面的代码进行修改,但是在后面,我们会介绍shapely的另一个功能。
7.2.6. 线环(LinearRings)¶
LinearRing
的构造需要一个有序序列 (x, y[, z])
的点元组。
序列可以通过第一个和最后一个指标的相同值显式关闭。
否则,该序列将通过第一个元组复制到最后一个指数来隐形关闭。与在
LineString
中一样,重复点在有序序列中是被允许的,但可能导致性能损失,应该尽量避免。
一条线环不能跨越它本身,并且不能在一个单点接触。
上图:左边是一条有效线,右边是一个无效的 自接触线。描述环的点显示为灰色。环的边界是空的。
注意:
Shapely不会阻止这种环的创建,但是当他们运行的时候可能会产生异常。
线环的面积为0,但长度不为0。
它的 x-y
边界框是一个 (minx, miny, maxx, maxy)
元组。
定义坐标系值通过坐标属性来获得。
线环的构建同样接受另一条线或线环为实例,因而可以得到另一个副本。
在线环中,点的实例序列不是一个有效的构建参数。
7.2.7. 集合(Collections)¶
Shapely的一些操作可能会出现多相几何对象的集合导致影响一些Shapely操作。
例如,2条线沿着一条线和一个点相交。 为了表示这类结果,Shapely提供了几何对象的不变集合。 集合可能是同质(多元点等)也可能是异质的。
>>> from shapely.geometry import LineString
>>> a = LineString([(0, 0), (1,1), (1,2), (2,2)])
>>> b = LineString([(0, 0), (1,1), (2,1), (2,2)])
>>> x = a.intersection(b)
>>> from pprint import pprint
>>> len(x)
/tmp/ipykernel_65127/1232873787.py:6: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry. len(x)
2
>>> type(x)
shapely.geometry.collection.GeometryCollection
a)是指一条绿色和黄色的线沿着一条线和一个点相交;
b)是指交点(蓝色)是一个包含一条线和一个点的集合。
几何集合的成员通过访问 (geoms
)属性,
或通过枚举接口,用in
或 list()
来获得。
>>> from pprint import pprint
>>> pprint(list(x))
>>> from shapely.geometry import MultiPoint
>>> m = MultiPoint([(0, 0), (1, 1), (1,2), (2,2)])
>>> m[:1].wkt
>>> m[3:].wkt
>>> m[4:].wkt
[<shapely.geometry.linestring.LineString object at 0x7f1c28166890>,
<shapely.geometry.point.Point object at 0x7f1c28154f50>]
/tmp/ipykernel_65127/3428894420.py:2: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. pprint(list(x)) /tmp/ipykernel_65127/3428894420.py:2: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry. pprint(list(x)) /tmp/ipykernel_65127/3428894420.py:5: ShapelyDeprecationWarning: __getitem__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. m[:1].wkt /tmp/ipykernel_65127/3428894420.py:6: ShapelyDeprecationWarning: __getitem__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. m[3:].wkt /tmp/ipykernel_65127/3428894420.py:7: ShapelyDeprecationWarning: __getitem__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. m[4:].wkt
'GEOMETRYCOLLECTION EMPTY'
同质集合可以被分为好几部分, 带来同一个类型的新对象。
注意:
当可能的话,最好用同质集合类型中的一个来描述下面的。
Collections of Points¶
class MultiPoint( points)
多元点的构建需要点元组(x,y[,z])
序列。
多元点面积为0,长度为0.
>>> from shapely.geometry import MultiPoint
>>> points = MultiPoint([(0.0, 0.0), (1.0, 1.0)])
>>> points.area
>>> points.length
>>> points.bounds
(0.0, 0.0, 1.0, 1.0)
它的x-y边界框是一个(minx, miny, maxx, maxy)
元组。
一个多元点集合的成员通过geoms
获得或者通过用in或者list()来枚举接口。
>>> import pprint
>>> pprint.pprint(list(points.geoms))
>>> pprint.pprint(list(points))
[<shapely.geometry.point.Point object at 0x7f1c11d4f990>,
<shapely.geometry.point.Point object at 0x7f1c2cc00ed0>]
[<shapely.geometry.point.Point object at 0x7f1c11df7ed0>,
<shapely.geometry.point.Point object at 0x7f1c11dda1d0>]
/tmp/ipykernel_65127/253965190.py:3: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. pprint.pprint(list(points)) /tmp/ipykernel_65127/253965190.py:3: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry. pprint.pprint(list(points))
构件同样需要另一个(多元点) 实例或者点实例的无序序列,从而使用副本。
MultiPoint([Point(0, 0), Point(1, 1)])
Collections of Lines(多元线)¶
class MultiLineString( lines)
多元线的构建需要 线性元组序列或对象。
图:左边,是一个简单的,不连接的 多元线,右边,是一个不简单的多元线环。定义对象的点 显示为灰色,对象的边界是黑色。 多元环的面积为0,长度不为0。
>>> from shapely.geometry import MultiLineString
>>> coords = [((0, 0), (1, 1)), ((-1, 0), (1, 0))]
>>> lines = MultiLineString(coords)
>>> lines.area
>>> lines.length
>>> lines.bounds
>>> len(lines.geoms)
2
它的x-y边界框是一个(minx, miny, maxx, maxy)
元组。
它的成员是线的实例,可以通过geoms
得到,
也可以用in或list()命令来迭代协议获得。
>>> pprint.pprint(list(lines.geoms))
>>> pprint.pprint(list(lines))
[<shapely.geometry.linestring.LineString object at 0x7f1c11dba990>,
<shapely.geometry.linestring.LineString object at 0x7f1c11de8090>]
[<shapely.geometry.linestring.LineString object at 0x7f1c11df7e50>,
<shapely.geometry.linestring.LineString object at 0x7f1c11debb50>]
/tmp/ipykernel_65127/654406357.py:2: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry. pprint.pprint(list(lines)) /tmp/ipykernel_65127/654406357.py:2: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry. pprint.pprint(list(lines))
构造函数可以接受另一个多元线(MultiLineString)的实例, 也可以接受线(LineString)实例的无序序列, 从而得到一个副本。
>>> MultiLineString(lines)
>>> MultiLineString(lines.geoms)
Collection of Polygons(多元多边形)¶
class MultiPolygon( polygons)
多元多边形的构建需要外部环和洞元组序列元组:
[((a1, ..., aM), [(b1, ..., bN),...]), ...]
。
更清楚地说,构件同样接受线实例的无序序列,从而得到一个副本。
>>> polygon = [(0, 0), (1,1), (1,2), (2,2),(0,0)]
>>> s = [(10, 0), (21,1), (31,2), (24,2),(10,0)]
>>> t = [(0, 50), (1,21), (1,22), (32,2),(0,50)]
>>> from shapely.geometry import Polygon
>>> p_a, s_a, t_a = [Polygon(x) for x in [polygon, s, t]]
>>> from shapely.geometry import MultiPolygon
>>> polygons = MultiPolygon([p_a, s_a, t_a])
>>> len(polygons.geoms)
>>>
>>> len(polygons)
>>>
>>> polygons.bounds
/tmp/ipykernel_65127/223419790.py:10: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry. len(polygons)
(0.0, 0.0, 32.0, 50.0)
>>> p_a
>>> s_a
>>> t_a
>>> polygons
>>> uu = polygons.geoms
>>> uu[0]
它的x-y边界框是一个(minx, miny, maxx, maxy)元组。
7.2.8. 其他问题¶
空要素¶
一个空值要素是指一个点集里恰巧是空集,不是None
,如同 set([])
。 空值要素能够通过调用不带参数的各种构造。
空值要素几乎不支持任何操作。
>>> from shapely.geometry import LineString
>>> line = LineString()
>>> line.is_empty
>>> line.length
>>> line.bounds
>>> line.coords
<shapely.coords.CoordinateSequence at 0x7f1c11db3a50>
可以设置一个空值要素的坐标,在这之后几何坐标不再是空的。
>>> line.coords = [(0, 0), (1, 1)]
>>> line.is_empty
>>> line.length
>>> line.bounds
(0.0, 0.0, 1.0, 1.0)