简单的点、线与多边形

class Point( coordinates) 

Point的构造函数采用坐标位置值或点元组参数。

In [1]:
from shapely.geometry import Point
point = Point(0.0, 0.0)
point.area
Out[1]:
0.0
In [2]:
point.length
Out[2]:
0.0
In [3]:
point.bounds
Out[3]:
(0.0, 0.0, 0.0, 0.0)

一个点的面积为0,长度为0。 它的边界是一个元组(minx,miny,maxx,maxy)

坐标值通过xyz属性获得。

In [4]:
list(point.coords)
Out[4]:
[(0.0, 0.0)]
In [5]:
point.x
Out[5]:
0.0
In [6]:
point.y
Out[6]:
0.0

点的构造同样接受另一个点的实例,从而得到一个副本。

In [7]:
Point(point)
Out[7]:

线

class LineString( coordinates) 

LineString的构造采用线性序列,一般采用2个或者多个(x,y[,z])点元组。

构造的LineString对象代表点与点之间的一个或多个直线样条。 有序序列内的点是允许重复的,但可能产生性能损失, 应该尽量避免。 一条线会相交。

image

图:简单与复杂的线中:左边是一条简单的线,右边是一条复杂的线。 每个边界显示为黑色,描述线的其它点显示为灰色。线的面积为0,但长度不为0。

In [8]:
from shapely.geometry import LineString
line = LineString([(0, 0), (1, 1)])
print(line.area)
0.0
In [9]:
print(line.length)
1.4142135623730951
In [10]:
print(line.bounds)
(0.0, 0.0, 1.0, 1.0)
In [11]:
len(line.coords)
Out[11]:
2
In [12]:
list(line.coords)
Out[12]:
[(0.0, 0.0), (1.0, 1.0)]
In [13]:
LineString(line)
Out[13]:

它的边界是一个(minx, miny, maxx, maxy)元组。

定义的坐标属性值通过坐标的属性来获得。也可是坐标的切片。

线的构造同样接受另一个线的实例,从而使用另一个副本。

Point的实例序列不是一个有效的构造函数的参数。线由点来描述, 但不是由点的实例组成。

class Polygon(exterior[,interiors=None]) 

多边形构造需要2个位置参数。 第一个位置参数是(x,y[,z])点元组的有序序列, 并且在LinearRing中被认为是准确的。 第二个位置参数是一个可选的、像ring的,无序序列,且位于要素内部, 指定边界或洞的环状序列。

一个有效的多边形的环不能相互交叉, 但可以在一个单点接触。

同样,Shapely不会阻止无效要素的创建, 但是当他们运行时,可能会有异常。

In [14]:
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])
In [15]:
polygon
Out[15]:
In [16]:
polygon.is_valid
Out[16]:
True
In [17]:
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]
In [18]:
from shapely.geometry import Polygon
polygon = Polygon(ext, [int])
In [19]:
polygon
Out[19]:
In [20]:
polygon.is_valid
Out[20]:
False
In [21]:
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])
In [22]:
polygon
Out[22]:
In [23]:
polygon.is_valid
Out[23]:
False
In [ ]:
 

image

图片[fig:valinvalpoly]:左边, 是一个有效的内部环和一个外部环接触于一点;右边, 是无效的多边形,因为它的内部环与外部环在多于一个点接触,描述环的点表现为灰色。

image

图片[fig:twoinval]:左边,多边形是无效的, 因为它的外部环和内部环相触于一条线;右边,是无效的多边形,因为 它的内部环相触于一条线。

多边形的面积不为0,长度不为0。

In [24]:
from shapely.geometry import  Polygon 
from shapely.geometry import LinearRing
polygon = Polygon([(0, 0), (1, 1), (1, 0)])
In [25]:
polygon
Out[25]:
In [ ]:
 
In [26]:
polygon.area
polygon.length
polygon.bounds
list(polygon.exterior.coords)
list(polygon.interiors)
coords = [(0, 0), (1, 1), (1, 0)]
r = LinearRing(coords)
In [27]:
r
Out[27]:
In [ ]:

In [28]:
s = Polygon(r)
s.area
Out[28]:
0.5
In [29]:
s
Out[29]:
In [ ]:
 
In [30]:
t = Polygon(s.buffer(1.0).exterior, [r])
t.area
Out[30]:
6.5507620529190325
In [31]:
t
Out[31]:

它的x-y边界是一个(minx, miny, maxx, maxy)元组。

组成的环通过内部环和外部环的属性获得。多边形的构件同样接受线和环的实例。 矩形多边形出现,可以方便地使用shapely.geometry.box()函数构建。

shapely.geometry.box(minx,miny,maxx,maxy,ccw=True) 

通过提供的边界值来构造矩形多边形, 默认使用逆时针顺序。

例如:

In [32]:
from shapely.geometry import Polygon, box
b = box(0.0, 0.0, 1.0, 1.0)
list(b.exterior.coords)
Out[32]:
[(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表示 产品外部环的坐标将被逆时针导出。

对线状shapefile进行缓冲操作

对线状shapefile进行缓冲操作与上一节的对点状shapefile进行缓冲类似,本节我们来看一下如何对线进行缓冲操作。

注意看上面的结果。原始的线状shapefile是复杂线的类型。它由三段构成,但却是一个实体。 而结果却是分段生成的。 这样的结果对某些情况是有用的,比如说制图(不能显示边界), 是常用的情况,我们希望生成的结果也是一个多边形, 譬如说面积统计(总面积可不是分段面积的和)。 这个部分当然可以对上面的代码进行修改,但是在后面,我们会介绍shapely的另一个功能。

In [ ]:
 

线环(LinearRings)

LinearRing 的构造需要一个有序序列 (x, y[, z]) 的点元组。

序列可以通过第一个和最后一个指标的相同值显式关闭。 否则,该序列将通过第一个元组复制到最后一个指数来隐形关闭。与在 LineString 中一样,重复点在有序序列中是被允许的,但可能导致性能损失,应该尽量避免。 一条线环不能跨越它本身,并且不能在一个单点接触。

有效与无效的线环

上图:左边是一条有效线,右边是一个无效的 自接触线。描述环的点显示为灰色。环的边界是空的。

注意:

Shapely不会阻止这种环的创建,但是当他们运行的时候可能会产生异常。

线环的面积为0,但长度不为0。

In [1]:
from shapely.geometry import Polygon, LinearRing
# import LinearRing
ring = LinearRing([(0, 0), (1, 1), (1, 0)])
ring.area
ring.length
ring.bounds
len(ring.coords)
list(ring.coords)
LinearRing(ring)
Out[1]:

它的 x-y 边界框是一个 (minx, miny, maxx, maxy) 元组。

定义坐标系值通过坐标属性来获得。

线环的构建同样接受另一条线或线环为实例,因而可以得到另一个副本。

在线环中,点的实例序列不是一个有效的构建参数。

In [ ]:
 

集合(Collections)

Shapely的一些操作可能会出现多相几何对象的集合导致影响一些Shapely操作。

例如,2条线沿着一条线和一个点相交。 为了表示这类结果,Shapely提供了几何对象的不变集合。 集合可能是同质(多元点等)也可能是异质的。

In [1]:
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)
Out[1]:
2
In [2]:
type(x)
Out[2]:
shapely.geometry.collection.GeometryCollection

image

a)是指一条绿色和黄色的线沿着一条线和一个点相交;

b)是指交点(蓝色)是一个包含一条线和一个点的集合。

几何集合的成员通过访问 (geoms)属性, 或通过枚举接口,用inlist()来获得。

In [3]:
# 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
Out[3]:
'GEOMETRYCOLLECTION EMPTY'

同质集合可以被分为好几部分, 带来同一个类型的新对象。

注意:

当可能的话,最好用同质集合类型中的一个来描述下面的。

Collections of Points

class MultiPoint( points) 

多元点的构建需要点元组(x,y[,z])序列。

多元点面积为0,长度为0.

In [4]:
from shapely.geometry import MultiPoint
points = MultiPoint([(0.0, 0.0), (1.0, 1.0)])
points.area
points.length
points.bounds
Out[4]:
(0.0, 0.0, 1.0, 1.0)

它的x-y边界框是一个(minx, miny, maxx, maxy)元组。

一个多元点集合的成员通过geoms获得或者通过用in或者list()来枚举接口。

In [5]:
import pprint
pprint.pprint(list(points.geoms))
pprint.pprint(list(points))
[<shapely.geometry.point.Point object at 0x7fdc48682b70>,
 <shapely.geometry.point.Point object at 0x7fdc48682c18>]
[<shapely.geometry.point.Point object at 0x7fdc48682c18>,
 <shapely.geometry.point.Point object at 0x7fdc486829e8>]

构件同样需要另一个(多元点) 实例或者点实例的无序序列,从而使用副本。

MultiPoint([Point(0, 0), Point(1, 1)])

Collections of Lines(多元线)

class MultiLineString( lines) 

多元线的构建需要 线性元组序列或对象。

image

图[fig:mullinek4]:左边,是一个简单的,不连接的 多元线,右边,是一个不简单的多元线环。定义对象的点 显示为灰色,对象的边界是黑色。 多元环的面积为0,长度不为0。

In [6]:
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)
Out[6]:
2

它的x-y边界框是一个(minx, miny, maxx, maxy)元组。

它的成员是线的实例,可以通过geoms得到, 也可以用in或list()命令来迭代协议获得。

In [7]:
pprint.pprint(list(lines.geoms))
pprint.pprint(list(lines))
[<shapely.geometry.linestring.LineString object at 0x7fdc48682c18>,
 <shapely.geometry.linestring.LineString object at 0x7fdc486829e8>]
[<shapely.geometry.linestring.LineString object at 0x7fdc486829e8>,
 <shapely.geometry.linestring.LineString object at 0x7fdc48682c88>]

构造函数可以接受另一个多元线(MultiLineString)的实例, 也可以接受线(LineString)实例的无序序列, 从而得到一个副本。

In [8]:
MultiLineString(lines)
MultiLineString(lines.geoms)
Out[8]:

Collection of Polygons(多元多边形)

class MultiPolygon( polygons) 

多元多边形的构建需要外部环和洞元组序列元组: [((a1, ..., aM), [(b1, ..., bN),...]), ...]

更清楚地说,构件同样接受线实例的无序序列,从而得到一个副本。

In [9]:
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
Out[9]:
(0.0, 0.0, 32.0, 50.0)
In [10]:
p_a
Out[10]:
In [11]:
s_a
Out[11]:
In [12]:
t_a
Out[12]:
In [13]:
polygons
Out[13]:
In [14]:
uu = polygons.geoms
In [15]:
uu[0]
Out[15]:

它的x-y边界框是一个(minx, miny, maxx, maxy)元组。

image

图[fig:valinvalmulpolyvk]:右边, 是一个有效的有2个成员的多元多边形;右边,是一个无效的多元多边形,因为它的成员沿着一条线在无数多个点接触。

它的成员是Polygon的实例,可以通过geoms或通过用inlist() 迭代协议获得。

In [ ]:
 

其他问题

空要素

一个空值要素是指一个点集里恰巧是空集,不是None,但是如同 set([])。空值要素能够通过调用不带参数的各种构造。

空值要素几乎不支持任何操作。

In [1]:
from shapely.geometry import LineString
line = LineString()
line.is_empty
line.length
line.bounds
line.coords
# The coordinates of a empty feature can be set, 可以设置一个空值要素的坐标,
# after which the geometry is no longer empty.在这之后几何坐标不再是空的。
line.coords = [(0, 0), (1, 1)]
line.is_empty
line.length
line.bounds
Out[1]:
(0.0, 0.0, 1.0, 1.0)

一般的属性与方法

shapely一般的属性与方法

object.area 为返回对象的面积

object.bounds 为返回一个元组(minx,miny,maxx,maxy),即对象的界限。

object.length 为返回对象的长度。

object.geom_type 为返回一个字符串,指定对象的几何类型,按照OpenGIS的格式进行。

In [1]:
from shapely.geometry import Point
Point(0,0).geom_type
Out[1]:
'Point'

输出点(0,0)的几何类型。

object.distance(other) 返回到其他类型几何对象之间的浮点型最短距离。

In [2]:
Point(0,0).distance(Point(1,1))  
Out[2]:
1.4142135623730951

object.representative_point() 返回一个在几何对象内的易得到的计算点。

注意:质点的不同, 这个点得到的是依照所需计算量最小而定的,只要在几何对象内部即可。

In [3]:
donut = Point(0, 0).buffer(2.0).difference(Point(0, 0).buffer(1.0))
donut.centroid.wkt
Out[3]:
'POINT (-2.26143213395106e-17 -3.945215842382012e-17)'
In [4]:
donut.representative_point().wkt
Out[4]:
'POINT (-1.5 4.119267568565299e-15)'

对点状Shapefile进行缓冲操作

对点状Shapefile进行缓冲操作不失一般性,下面来看一个针对点状要素进行缓冲操作的实例。