天天看點

Python子產品之Shapely

Shapely目錄

    • Introduction
    • DE-9IM
    • Geometric Object
      • Point
      • LineString
      • LinearRing
      • Polygon
      • Collections
      • MultiPoint
      • MultiLineString
      • MultiPolygon
    • General Attributes and Methods
      • General Attributes
      • Coordinate sequences
      • General Methods
    • Predicates and Relationships
      • Unary Predicates
      • Binary Predicates
      • DE-9IM Relationships
    • Spatial Analysis Methods
      • Set-theoretic Methods
      • Constructive Methods
    • Affine Transformations
    • Other Transformations
    • Other Operations
      • Merging Linear Features
      • Efficient Unions
      • Delaunay triangulation
      • Voronoi Diagram
      • Nearest points
      • Snapping
      • Shared paths
      • Splitting
      • Substring
      • Prepared Geometry Operations
      • Diagnostics
      • Polylabel
    • STR-packed R-tree
    • Interoperation
      • Well-Known Formats
      • Numpy and Python Arrays
      • Python Geo Interface
    • Performance

Introduction

Shapely 是通過Python的ctypes子產品,對平面特征進行集合理論分析和操作,使用的函數來自于GEOS庫.GEOS是Java Topology Suite (JTS)的移植,是PostgreSQL RDBMS的PostGIS空間擴充的幾何引擎。JTS和GEOS的設計主要是以Open Geospatial Consortium的Simple Features Access Specification 為指導,Shapely主要堅持了同一套标準類和操作。是以,Shapely深深植根于地理資訊系統(GIS)世界的慣例,但也希望對處理非正常問題的程式員同樣有用。

DE-9IM

要使用DE-9IM首先要建立幾何對象的interior,boundary和exterior。

首先boundary是指對幾何進行一次降維之後得到對象,舉例來說一個點的boundary為空,未封閉的線的boundary為其兩個端點,封閉線的boundary為空,多邊形的boundary為它的環狀邊界。

interior是指幾何對象的邊界被移除之後剩下的部分。

exterior則是指不在boundary和interior中點構成的幾何對象。

Geometric Object

Point

class

Point

(coordinates)

Point構造函數采用位置坐标值或點元組參數

from shapely.geometry import Point
point = Point(0.0, 0.0)
           

Point的面積area為0, 周長length為0

Point.coords: 傳回坐标值

Point.x,Point.y,Point.z : 擷取對應x,y,z坐标值

Point可以接受另一個Point執行個體進行複制

LineString

class

LineString

(coordinates)

構造的LineString對象表示點之間的一個或多個連接配接的線性樣條曲線。 允許在有序序列中重複點,但可能會導緻性能下降,應避免。 LineString可能會交叉(即複雜而不是簡單)

Python子產品之Shapely
from shapely.geometry import LineString
line = LineString([(0, 0), (1, 1)])
           
  • LineString的面積area為0, 周長length不為0
  • object.interpolate(distance[, normalized=False])
    • 傳回指定距離處的點
    • normalized=True, 則距離是幾何對象長度的一部分
>>> ip = LineString([(0, 0), (0, 1), (1, 1)]).interpolate(1.5)
>>> ip
<shapely.geometry.point.Point object at 0x740570>
>>> ip.wkt
'POINT (0.5000000000000000 1.0000000000000000)'
>>> LineString([(0, 0), (0, 1), (1, 1)]).interpolate(0.75, normalized=True).wkt
'POINT (0.5000000000000000 1.0000000000000000)'
           
  • object.project(other[, normalized=False])
    • 傳回該幾何對象到最接近另一個對象的點的距離
    • normalized=True, 歸一化為對象長度的距離
    • 是interpolate()的逆函數
>>> LineString([(0, 0), (0, 1), (1, 1)]).project(ip)
1.5
>>> LineString([(0, 0), (0, 1), (1, 1)]).project(ip, normalized=True)
0.75
           

舉個栗子: 在指定距離處切割線

def cut(line, distance):
    # Cuts a line in two at a distance from its starting point
    if distance <= 0.0 or distance >= line.length:
        return [LineString(line)]
    coords = list(line.coords)
    for i, p in enumerate(coords):
        pd = line.project(Point(p))
        if pd == distance:
            return [
                LineString(coords[:i+1]),
                LineString(coords[i:])]
        if pd > distance:
            cp = line.interpolate(distance)
            return [
                LineString(coords[:i] + [(cp.x, cp.y)]),
                LineString([(cp.x, cp.y)] + coords[i:])]
           
>>> line = LineString([(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0)])
>>> pprint([list(x.coords) for x in cut(line, 1.0)])
[[(0.0, 0.0), (1.0, 0.0)],
 [(1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0), (5.0, 0.0)]]
>>> pprint([list(x.coords) for x in cut(line, 2.5)])
[[(0.0, 0.0), (1.0, 0.0), (2.0, 0.0), (2.5, 0.0)],
 [(2.5, 0.0), (3.0, 0.0), (4.0, 0.0), (5.0, 0.0)]]
           
  • LineString可以接受另一個LineString執行個體進行複制
  • LineString也可以使用一系列混合的Point執行個體或坐标元組構造

LinearRing

閉合線

class

LinearRing

(coordinates)

通過在第一個索引和最後一個索引中傳遞相同的值,可以顯式關閉該序列。 否則,通過将第一個元組複制到最後一個索引來隐式關閉序列。 與LineString一樣,允許有序序列中的重複點,但可能會導緻性能下降,應該避免。 LinearRing可能不會交叉,也不會在單個點上碰觸到自己。

Python子產品之Shapely

LinearRing的面積area為0, 周長length非0

LinearRing構造函數還接受另一個LineString或LinearRing執行個體,進而進行複制

Polygon

多邊形

class

Polygon

(shell[, holes=None])

Polygon構造函數采用兩個位置參數。 第一個是(x,y [,z])點元組的有序序列,其處理方式與LinearRing情況完全相同。 第二個是可選的無序環狀序列,用于指定特征的内部邊界或“孔”。

有效多邊形的環可能不會彼此交叉,而隻能在單個點接觸。不會阻止建立無效的功能,但是在對其進行操作時會引發異常

Python子產品之Shapely

a是一個有效的多邊形,其中一個内環在某一點上與外環接觸,

b是無效的多邊形,因為其内環在一個以上的點與外環接觸。

Python子產品之Shapely

c是一個無效的多邊形,因為它的外部和内部環沿線接觸

d是一個無效的多邊形,因為它的内環沿線接觸

Polygon的面積area非0, 周長length非0

from shapely.geometry import Polygon
polygon = Polygon([(0, 0), (1, 1), (1, 0)])
           
  • Polygon.exterior.coords: 外部輪廓的點
  • Polygon.interiors.coords: 内部輪廓的點
  • Polygon構造函數還接受LineString和LinearRing的執行個體
  • 建構矩形多邊形
from shapely.geometry import box
# box(minx, miny, maxx, maxy, ccw=True), 預設情況下右下角作為第一個點,為逆時針順序
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.geometry.polygon.orient(polygon, sign=1.0)
      • 傳回一個給定多邊形的正确方向的多邊形
      • sign=1.0: 生成的多邊形外環坐标 逆時針, 内環坐标 順時針

Collections

集合

多個幾何對象可以通過 geoms 或者

in

/

list()

, 進行疊代擷取GeometryCollection的成員

MultiPoint

多個點

class MultiPoint(points)

構造函數還接受另一個MultiPoint執行個體或Point執行個體的無序序列,進而進行複制

MultiLineString

多條線

class MultiLineString(lines)

構造函數還接受MultiLineString的另一個執行個體或LineString執行個體的無序序列,進而進行複制

MultiPolygon

多個多邊形

class MultiPolygon (polygons)

MultiPolygon構造函數采用一系列外部環和孔清單元組:[((a1, …, aM), [(b1, …, bN), …]), …]

構造函數還接受無序的Polygon執行個體序列,進而進行複制。

Python子產品之Shapely

a是有效的

b是無效的, 兩個多邊形沿線接觸

General Attributes and Methods

General Attributes

通用屬性和方法

object.area

  • 面積(float)

object.bounds

  • 邊界元組(Xmin, Ymin, Xmax, Ymax)

object.length

  • 周長

object.minimum_clearance

  • 最小間隙 傳回可以移動節點以産生無效幾何的最小距離 不存在最小間隙,則将傳回math.infinity

object.geom_type

  • 傳回幾何對象的類型

Coordinate sequences

坐标序列

描述幾何對象的坐标列是CoordinateSequence對象, 可進行索引,切片和疊代

Point / LineString / LinearRing 直接coords

Polygon 的外部(exterior)和内部(interior)都具有coords

多個幾何對象沒有坐标序列, 集合内的單個對象具有坐标序列

General Methods

通用方法

object.distance(other)

  • 到另一個幾何對象的最小距離

object.hausdorff_distance(other)

  • 到另一個幾何對象的Hausdorff距離(到另一個幾何對象最近點的最大距離)

object.representative_point()

  • 傳回保證在幾何對象内的廉價計算點

Predicates and Relationships

Unary Predicates

一進制謂詞

object.has_z

  • 是否有z坐标

object.is_ccw

  • LinearRing對象是否逆時針

object.is_empty

  • 是否為空

object.is_ring

  • 是否為封閉且簡單的LineString

object.is_simple

  • 是否交叉

object.is_valid

  • 是否有效
  • 有效的

    LinearRing

    不能在一個點上交叉或接觸到自己
  • 有效的

    Polygon

    不能擁有任何重疊的外環或内環
  • 有效的

    MultiPolygon

    不能包含任何重疊的多邊形

Binary Predicates

二進制謂詞

object.__eq__(other)

  • 兩個對象幾何類型相同且坐标精确比對,傳回True

object.equals(other)

  • 兩個對象集合理論上的邊界,内部和外部一緻,傳回True

object.almost_equals(other[, decimal=6])

  • 兩個對象在指定點的小數點精度上的所有點都近似相等,則傳回True

object.contains(other)

  • 另一個對象沒有點在對象外部,并且至少有一個點在對象(a包含b), 傳回True

object.within(other)

  • 對象的邊界和内部僅與另一個的内部(而不是其邊界或外部)相交(a被包含于b)傳回True
  • contains 與within相反,

    a.contains(b)== b.within(a)

>>> coords = [(0, 0), (1, 1)]
>>> LineString(coords).contains(Point(0.5, 0.5))
True
>>> Point(0.5, 0.5).within(LineString(coords))
True
# 線的端點是其邊界的一部分,是以不包含在内
>>> LineString(coords).contains(Point(1.0, 1.0))
False
           

object.crosses(other)

  • 對象的内部與另一個的内部相交但不包含該對象,并且交集的尺寸小于一個或另一個的尺寸(a,b相交),則傳回True
>>> LineString(coords).crosses(LineString([(0, 1), (1, 0)]))
True
# 一條線不與它包含的點相交
>>> LineString(coords).crosses(Point(0.5, 0.5))
False
           

object.disjoint(other)

  • 對象的邊界和内部與其他對象都不相交(a,b不相交),則傳回True

object.intersects(other)

  • 如果對象的邊界或内部以任何方式相交與另一個對象(a,b相交),則傳回True
  • intersects 是 disjoint 的逆函數

object.overlaps(other)

  • 如果兩個對象相交intersects 但互相都不包含(a,b重疊),則傳回True

object.touches(other)

  • 如果兩個對象至少有一個公共點,并且它們的内部不與另一個的任何部分相交(a,b相切),則傳回True

DE-9IM Relationships

object.relate(other)

  • 傳回對象内部,邊界,外部與另一個幾何對象的DE-9IM關系矩陣的字元串表示

object.relate_pattern(other, pattern)

  • 如果幾何之間的關系的DE-9IM字元串滿足該模式,則傳回True

Spatial Analysis Methods

空間分析方法

Set-theoretic Methods

集合論方法

object.boundary

  • 傳回表示對象的集合論邊界的低維對象
>>> coords = [((0, 0), (1, 1)), ((-1, 0), (1, 0))]
>>> lines = MultiLineString(coords)
>>> lines.boundary
           

object.centroid

  • 傳回對象的幾何質心
LineString([(0, 0), (1, 1)])
LineString([(0, 0), (1, 1)]).centroid
           

object.difference(other)

  • 傳回組成該幾何對象的點的表示,這些點不組成另一個對象
  • a - (a,b相交的部分) 即 a - (a∩b)
Python子產品之Shapely

object.intersection(other)

  • 傳回此對象與另一個幾何對象的交集的表示形式
  • a,b相交的部分 即 a∩b

object.symmetric_difference(other)

  • 傳回此對象中不在另一個幾何對象中的點以及另一個不在此幾何對象中的點的表示
  • a,b的并集-a,b的交集 即 (a∪b) - (a∩b)
Python子產品之Shapely

object.union(other)

  • 傳回此對象和另一個幾何對象的點并集的表示形式
  • a,b的并集 即 a∪b
  • 更高效的方法:

    shapely.ops.unary_union()

Python子產品之Shapely

Constructive Methods

産生新對象的方法,這些新對象不是從集合論分析中得出的

object.buffer(distance, resolution=16, cap_style=1, join_style=1, mitre_limit=5.0)

  • 傳回此幾何對象給定距離内所有點的近似表示
  • distance: 為正 擴張,為負侵蝕
  • resolution: 近似于圍繞一個點的四分之一圓的線段數 預設值16近似于圓形.面積的99.8%
  • cap_style 集合樣式 1 round 圓形, 2 flat 扁平, 3 square 正方形
  • join_style 線條相交處的樣式 1 round 圓角 2 mitre 方角 3 bevel 切掉頂角
    Python子產品之Shapely
# 正方形 1 * 4
Point(0, 0).buffer(10, resolution=1)
# 正八邊形 2 * 4
Point(0, 0).buffer(10, resolution=2)
# 正六十四邊形 預設 16 * 4
Point(0, 0).buffer(10)
           

object.convex_hull

  • 傳回包含對象中所有點的最小凸多邊形的表示形式,除非對象中的點數少于三個。對于兩點,傳回LineString;對于一點,傳回本身
Python子產品之Shapely

object.envelope

  • 傳回包含對象的點或最小矩形多邊形(邊與坐标軸平行)的表示形式

object.minimum_rotated_rectangle

  • 傳回包含對象的最小矩形多邊形(不一定平行于坐标軸)
  • 線或點, 傳回本身
    Python子產品之Shapely
    object.parallel_offset(distance, side, resolution=16, join_style=1, mitre_limit=5.0)
  • 僅适用于 LineString或LineRing
  • 傳回距對象左側或右側一定距離的LineString或MultiLineString
  • distance 必須是浮點數, 平行偏移量
  • side: 根據LineString的給定幾何點的方向來确定的方向(左右)
    • left: 與LineString或LineRing 同向
    • right: 與LineString或LineRing 反向
  • resolution: 近似于圍繞一個點的四分之一圓的線段數 預設值16
  • join_style: 線條相交處的樣式 1 round 圓角 2 mitre 方角 3 bevel 切掉頂角
  • mitre_limit: 平行線的距離與指定距離的比 就是斜角比, 超過,邊角會變成倒角
Python子產品之Shapely
  • mitre_limit的效果
Python子產品之Shapely

object.simplify(tolerance, preserve_topology=True)

  • 傳回幾何對象的簡化表示
  • 簡化後的對象中的所有點将在原始幾何體的公差距離内
  • preserve_topology
    • 預設為True, 使用較慢的算法保留拓撲結構
    • False, 使用更快的Douglas-Peucker 算法保留拓撲結構
      Python子產品之Shapely

Affine Transformations

仿射變換

shapely.affinity.affine_transform(geom, matrix)

  • 傳回經過仿射變換後的矩陣
  • 系數矩陣以2D或3D轉換的清單或元組形式分别提供6或12個項
  • 2D仿射變換, 矩陣為6個參數 [a, b, d, e, xoff, yoff]
  • 3D仿射變換, 矩陣為12個參數 [a, b, c, d, e, f, g, h, i, xoff, yoff, zoff]

shapely.affinity.rotate(geom, angle, origin=‘center’, use_radians=False)

  • 傳回二維平面上的旋轉幾何
>>> from shapely import affinity
>>> line = LineString([(1, 3), (1, 1), (4, 1)])
>>> rotated_a = affinity.rotate(line, 90)
>>> rotated_b = affinity.rotate(line, 90, origin='centroid')
           
Python子產品之Shapely

shapely.affinity.scale(geom, xfact=1.0, yfact=1.0, zfact=1.0, origin=‘center’)

  • 傳回沿每個次元按比例縮放的幾何圖形
  • origin: 縮放的原點,預設是center 即 2D幾何對象的邊界框中心centerid, 也可以是單個點對象 或者 坐标元組
  • xfact / yfact / zfact: 縮放比例. 設縮放原點為(X0,Y0, Z0 )
    • 正值, 直接縮放
    • 負值, 縮放後再沿着x=X0 / y=Y0 / z=Z0 對稱
>>> triangle = Polygon([(1, 1), (2, 3), (3, 1)])
>>> triangle_a = affinity.scale(triangle, xfact=1.5, yfact=-1)
>>> triangle_a.exterior.coords[:]
[(0.5, 3.0), (2.0, 1.0), (3.5, 3.0), (0.5, 3.0)]
>>> triangle_b = affinity.scale(triangle, xfact=2, origin=(1,1))
>>> triangle_b.exterior.coords[:]
[(1.0, 1.0), (3.0, 3.0), (5.0, 1.0), (1.0, 1.0)]
           
Python子產品之Shapely

shapely.affinity.skew(geom,xs=0.0, ys=0.0, origin=‘center’, use_radians=False)

  • 傳回傾斜的幾何體,沿x和y次元剪切角度。
  • use_radians=True, 以度或者弧度指定裁切角
  • origin: 預設是邊界框中心(幾何質心centerid),也可以是Point對象 或者坐标元組
Python子產品之Shapely

shapely.affinity.translate(geom,xs=0.0, ys=0.0, origin=‘center’, use_radians=False)

  • 傳回沿每個方向偏移量的平移幾何體

Other Transformations

地圖投影和轉換

shapely.ops.transform(func, geom)

  • 将func應用于geom的所有坐标,并從轉換後的坐标中傳回相同類型的新幾何

Other Operations

其他操作

Merging Linear Features

shapely.ops.polygonize(lines)

  • 傳回多邊形疊代器

shapely.ops.polygonize_full(lines)

  • 傳回多邊形和剩餘的幾何形狀
  • 輸入可以是 MultiLineString / LineString對象序列 / 可以适應 LineString的對象序列
  • 傳回對象的元組:(多邊形,懸挂,切割邊,無效的環形線)。每個都是幾何集合

shapely.ops.linemerge(lines)

  • 傳回一個LineString或MultiLineString,表示所有線的連續元素的合并

Efficient Unions

高效聯合

shapely.ops.unary_union(geoms)

  • 傳回給定幾何對象的并集表示
  • 重疊的多邊形将被合并.線會溶解并結點, 重複的點将被合并
  • 比**union()**更有效
  • 可用于嘗試修複無效的MultiPolygons, 面積可能會不一樣
from shapely.ops import unary_union
polygons = [Point(i, 0).buffer(0.7) for i in range(5)]
unary_union(polygons)
           
Python子產品之Shapely

shapely.ops.cascaded_union(geoms)

  • 傳回給定幾何對象的并集表示
  • 在1.2.16中, 如果使用了GEOS 3.3+,則會将shapely.ops.cascaded_union()透明地替換為shapely.ops.unary_union()

Delaunay triangulation

shapely.ops.triangulate(geoms, tolerance=0.0, edges=False)

  • 傳回輸入幾何圖形的頂點的Delaunay三角剖分
  • geoms: 任何的幾何類型,所有頂點将用作三角剖分的點
  • tolerance: 提高三角剖分計算的魯棒性的捕捉公差, 0.0表示不會發生貼緊
  • edges:
    • False: 傳回被剖分的三角形的清單
    • True: 傳回LineString邊緣的清單
from shapely.ops import triangulate
points = MultiPoint([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
triangles = triangulate(points)
print([triangle.wkt for triangle in triangles])
['POLYGON ((0 2, 0 0, 1 1, 0 2))',
 'POLYGON ((0 2, 1 1, 2 2, 0 2))',
 'POLYGON ((2 2, 1 1, 3 1, 2 2))',
 'POLYGON ((3 1, 1 1, 1 0, 3 1))',
 'POLYGON ((1 0, 1 1, 0 0, 1 0))']

triangles2 = triangulate(points, edges=True)
print([triangle.wkt for triangle in triangles2])
['LINESTRING (2 2, 3 1)',
 'LINESTRING (0 2, 2 2)',
 'LINESTRING (0 0, 0 2)',
 'LINESTRING (0 0, 1 0)',
 'LINESTRING (1 0, 3 1)',
 'LINESTRING (1 0, 1 1)',
 'LINESTRING (1 1, 3 1)',
 'LINESTRING (1 1, 2 2)',
 'LINESTRING (0 2, 1 1)',
 'LINESTRING (0 0, 1 1)']
           
Python子產品之Shapely

Voronoi Diagram

shapely.ops.voronoi_diagram(geoms, envelope=None, tolerance=0.0, edges=False)

  • 根據輸入幾何的頂點構造Voronoi圖(v1.18才支援)
  • geoms: 任何的幾何類型,所有頂點将用作三角剖分的點
  • envelope: 提供一個信封,用于裁剪結果圖,None自動計算.會被裁剪到所提供的較大的信封或站點周圍的信封
  • tolerance: 提高三角剖分計算的魯棒性的捕捉公差, 0.0表示不會發生貼緊
  • edges:
    • False: 傳回被剖分的三角形的清單
    • True: 傳回LineString邊緣的清單
from shapely.ops import voronoi_diagram
points = MultiPoint([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
regions = voronoi_diagram(points)
print([region.wkt for region in regions])
['POLYGON ((2 1, 2 0.5, 0.5 0.5, 0 1, 1 2, 2 1))',
 'POLYGON ((6 5, 6 -3, 3.75 -3, 2 0.5, 2 1, 6 5))',
 'POLYGON ((0.5 -3, -3 -3, -3 1, 0 1, 0.5 0.5, 0.5 -3))',
 'POLYGON ((3.75 -3, 0.5 -3, 0.5 0.5, 2 0.5, 3.75 -3))',
 'POLYGON ((-3 1, -3 5, 1 5, 1 2, 0 1, -3 1))',
 'POLYGON ((1 5, 6 5, 2 1, 1 2, 1 5))']
           
Python子產品之Shapely

Nearest points

shapely.ops.nearest_points(geoms1, geoms2)

  • 傳回輸入幾何中最近點的元組, 與輸入相同的順序傳回
from shapely.ops import nearest_points
triangle = Polygon([(0, 0), (1, 0), (0.5, 1), (0, 0)])
square = Polygon([(0, 2), (1, 2), (1, 3), (0, 3), (0, 2)])
[o.wkt for o in nearest_points(triangle, square)]
['POINT (0.5 1)', 'POINT (0.5 2)']
           

Snapping

shapely.ops.snap(geoms1, geoms2, tolerance)

  • 将geom1中的頂點對齊到geom2中的頂點。傳回捕捉的幾何體的副本。輸入的幾何形狀未修改。
  • tolerance: 指定頂點之間的最小距離
>>> from shapely.ops import snap
>>> square = Polygon([(1,1), (2, 1), (2, 2), (1, 2), (1, 1)])
>>> line = LineString([(0,0), (0.8, 0.8), (1.8, 0.95), (2.6, 0.5)])
>>> result = snap(line, square, 0.5)
>>> result.wkt
'LINESTRING (0 0, 1 1, 2 1, 2.6 0.5)'
           

Shared paths

shapely.ops.shared_paths(geoms1, geoms2, tolerance)

  • 查找兩個線性幾何之間的共享路徑
  • geoms1/geoms2: LineStrings類型
  • 傳回值是一個集合: 同向的MultiLineString 和 反向的MultiLineString
>>> from shapely.ops import shared_paths
>>> g1 = LineString([(0, 0), (10, 0), (10, 5), (20, 5)])
>>> g2 = LineString([(5, 0), (30, 0), (30, 5), (0, 5)])
>>> forward, backward = shared_paths(g1, g2)
>>> forward.wkt
'MULTILINESTRING ((5 0, 10 0))'
>>> backward.wkt
'MULTILINESTRING ((10 5, 20 5))'
           

Splitting

shapely.ops.split(geoms, splitter)

  • 将一個幾何體分割成另一個幾何體,并傳回一個幾何體集合。這個函數理論上與被拆分的幾何體部分的聯合相反。如果拆分器不拆分幾何體,則傳回一個與輸入幾何體相等的單個幾何體集合。
  • 通過 (Multi)Point or (Multi)LineString or (Multi)Polygon的邊界去拆分 (Multi)LineString
  • 通過LineString分割(Multi)Polygon
>>> pt = Point((1, 1))
>>> line = LineString([(0,0), (2,2)])
>>> result = split(line, pt)
>>> result.wkt
'GEOMETRYCOLLECTION (LINESTRING (0 0, 1 1), LINESTRING (1 1, 2 2))'
           

Substring

shapely.ops.substring(geom, start_dist, end_dist[, normalized=False])

  • 沿線性幾何傳回指定距離之間的線段
  • 負距離值是從幾何形狀的末端沿相反方向測量的。超出範圍的索引值可通過将它們限制在值的有效範圍内進行處理
  • 起始距離等于終止距離,則傳回一個點
  • normalized:True, 距離将被解釋為幾何長度的一部分
>>> line = LineString(([0, 0], [2, 0]))
>>> result = substring(line, 0.5, 0.6)
>>> result.wkt
'LINESTRING (0.5 0, 0.6 0)'
           

Prepared Geometry Operations

shapely.prepared.prep(geom)

  • 建立并傳回準備好的幾何對象
  • 準備好的幾何執行個體具有以下方法:

    contains

    ,

    contains_properly

    ,

    covers

    intersects

    。與未準備好的幾何對象中的所有參數和用法完全相同。
  • 測試一個多邊形是否包含大量的點
from shapely.geometry import Point
from shapely.prepared import prep
points = MultiPoint([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
polygon = Point(0.0, 0.0).buffer(2.0)
prepared_polygon = prep(polygon)
hits = filter(prepared_polygon.contains, points)
for i in list(hits):
    print(i.wkt)
"""
POINT (0 0)
POINT (1 1)
POINT (1 0)
"""
           

Diagnostics

shapely.validation.explain_validity(geom)

  • 傳回幾何對象是否有效的字元串(無效對象傳回問題點)
>>> coords = [(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)]
>>> p = Polygon(coords)
>>> from shapely.validation import explain_validity
>>> explain_validity(p)
'Ring Self-intersection[1 1]'
           

shapely.__version__

  • 檢視shapely版本

shapely.geos.geos_version

  • 檢視GEOS庫版本

shapely.geos.geos_version_string

  • 檢視GEOS C API版本

Polylabel

shapely.ops.polylabel(polygon, tolerance)

  • 傳回多邊形的極點
>>> from shapely.ops import polylabel
>>> polygon = LineString([(0, 0), (50, 200), (100, 100), (20, 50),
... (-100, -20), (-150, -200)]).buffer(100)
>>> label = polylabel(polygon, tolerance=10)
>>> label.wkt
'POINT (59.35615556364569 121.8391962974644)'
           

STR-packed R-tree

Shapely提供隻查詢的GEOS R-tree接口去使用Sort-Tile-Recursive算法.将幾何對象清單傳遞給STRtree構造函數以建立空間索引,使用另一個幾何對象進行查詢.query-only意味着一旦建立STRtree,就是不可變的,無法添加或者删除幾何對象.

class strtree.STRtree(geometries)

  • STRtree構造函數采用一系列幾何對象, 幾何對象的引用将保留并存儲在R-tree中
  • strtree.query(geom)
    • 傳回strtree中所有幾何體的外延與geom的外延相交的幾何體的清單
    • 後續使用所需的二進制謂語(intersects相交、crosses交叉、contains包含、overlaps重疊)對傳回的子集進行搜尋,可能需要根據特定的空間關系進一步篩選結果
>>> from shapely.strtree import STRtree
>>> points = [Point(i, i) for i in range(10)]
>>> tree = STRtree(points)
>>> query_geom = Point(2,2).buffer(0.99)
>>> [o.wkt for o in tree.query(query_geom)]
['POINT (2 2)']
>>> query_geom = Point(2, 2).buffer(1.0)
>>> [o.wkt for o in tree.query(query_geom)]
['POINT (1 1)', 'POINT (2 2)', 'POINT (3 3)']
>>> [o.wkt for o in tree.query(query_geom) if o.intersects(query_geom)]
['POINT (2 2)']
           
  • 擷取查詢結果的原始索引,需要建立一個輔助字典,使用幾何ID作為鍵,因為形狀幾何本身不可哈希
>>> index_by_id = dict((id(pt), i) for i, pt in enumerate(points))
>>> [(index_by_id[id(pt)], pt.wkt) for pt in tree.query(Point(2,2).buffer(1.0))]
[(1, 'POINT (1 1)'), (2, 'POINT (2 2)'), (3, 'POINT (3 3)')]
           
  • strtree.nearest(geom)
    • 傳回在strtree中離geom最近的對象
    >>> tree = STRtree([Point(i, i) for i in range(10)])
    >>> tree.nearest(Point(2.2, 2.2)).wkt
    'Point (2 2)'
               

Interoperation

shapely提供了4種與其他軟體進行互相操作的途徑

Well-Known Formats

可以通過wkt/wkb 屬性擷取幾何對象的wkt 或者 wkb
>>> Point(0, 0).wkt
'POINT (0.0000000000000000 0.0000000000000000)'
>>> Point(0, 0).wkb.encode('hex')
'010100000000000000000000000000000000000000'
           

shapely.wkb.dumps(geom)

  • 将幾何對象序列化為wkb形式

shapely.wkb.loads(wkb)

  • 将wkb形式轉為幾何對象
>>> from shapely.wkb import dumps, loads
>>> ob_wkb = dumps(Point(0, 0))
>>> ob_wkb.encode('hex')
'010100000000000000000000000000000000000000'
>>> loads(ob_wkb).wkt
'POINT (0.0000000000000000 0.0000000000000000)'
           

shapely.wkt.dumps(geom)

  • 将幾何對象序列化為wkt形式

shapely.wkt.loads(wkb)

  • 将wkt形式轉為幾何對象
>>> from shapely.wkt import dumps, loads
>>> ob_wkt = dumps(Point(0, 0))
>>> ob_wkt
'POINT (0.0000000000000000 0.0000000000000000)'
>>> loads(ob_wkt).wkt
'POINT (0 0)'
           

Numpy and Python Arrays

所有具有坐标序列(點,線性環,線串)的幾何對象都提供了Numpy數組接口,是以可以将其轉換或調整為Numpy數組
>>> from numpy import array
>>> array(Point(0, 0))
array([ 0.,  0.])
>>> array(LineString([(0, 0), (1, 1)]))
array([[ 0.,  0.],
       [ 1.,  1.]])
           

numpy

.

asarray()

不會複制坐标值,代價就是Numpy通路Shapely對象的坐标速度較慢

可以通過xy屬性将相同類型的幾何對象的坐标作為x和y值的标準Python數組

>>> Point(0, 0).xy
(array('d', [0.0]), array('d', [0.0]))
>>> LineString([(0, 0), (1, 1)]).xy
(array('d', [0.0, 1.0]), array('d', [0.0, 1.0]))
           

shape.geometry.asShape()系列函數可以包裝Numpy坐标數組,以便于使用Shapely進行分析,同時保持原始存儲

>>> from shapely.geometry import asPoint, asLineString, asMultiPoint, asPolygon
>>> import numpy as np

# 1 X 2 數組可以轉成 Point
>>> pa = asPoint(array([0.0, 0.0]))
>>> pa.wkt
'POINT (0.0000000000000000 0.0000000000000000)'

# N X 2 數組可以轉成 LineString / MultiPoint / Polygon
>>> la = asLineString(np.array([[1.0, 2.0], [3.0, 4.0]]))
>>> la.wkt
'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'

>>> ma = asMultiPoint(np.array([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]]))
>>> ma.wkt
'MULTIPOINT (1.1 2.2, 3.3 4.4, 5.5 6.6)'

>>> pa = asPolygon(np.array([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]]))
>>> pa.wkt
'POLYGON ((1.1 2.2, 3.3 4.4, 5.5 6.6, 1.1 2.2))'
           

Python Geo Interface

任何提供類似于GeoJSON的Python geo接口的對象都可以使用shapely.geometry.asShape()或shapely.geometry.shape()函數進行調整,并用作Shapely幾何。

shape.geometry.asShape(context)

  • 使context适應幾何接口。坐标保留在context中

shape.geometry.shape(context)

  • 傳回一個新的幾何對象,其坐标是從context中複制的

舉個栗子: 一個字典

>>> from shapely.geometry import shape
>>> data = {"type": "Point", "coordinates": (0.0, 0.0)}
>>> geom = shape(data)
>>> geom.geom_type
'Point'
>>> list(geom.coords)
[(0.0, 0.0)]
           

再舉個栗子: 一個簡單的地标類型的對象

>>> class GeoThing(object):
...     def __init__(self, d):
...         self.__geo_interface__ = d
>>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
>>> geom = shape(thing)
>>> geom.geom_type
'Point'
>>> list(geom.coords)
[(0.0, 0.0)]
           

shape.geometry.mapping(ob)

  • 獲得幾何對象的類似于GeoJSON的映射
  • 傳回一個新的幾何對象,其坐标是從context中複制的
>>> from shapely.geometry import mapping
>>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
>>> m = mapping(thing)
>>> m['type']
'Point'
>>> m['coordinates']
(0.0, 0.0)}
           

Performance

Shapely使用GEOS庫進行所有操作。GEOS是用C++編寫的。shapely.speedups子產品包含用C編寫的性能增強。當Python在安裝過程中通路編譯器和GEOS開發标頭時,将自動安裝它們

shapely.speedups.available

  • 檢查是否安裝了加速

shapely.speedups.enable()

  • 開啟加速

shapely.speedups.disable()

  • 關閉加速

shapely.speedups.enabled

  • 檢查是否開啟加速