Python模塊之Shapely

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可能會交叉(即複雜而不是簡單)
LineString

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可能不會交叉,也不會在單個點上碰觸到自己。
LinearRing

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

LinearRing構造函數還接受另一個LineString或LinearRing實例,從而進行復制

Polygon

多邊形

class Polygon(shell[, holes=None])

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

有效多邊形的環可能不會彼此交叉,而只能在單個點接觸。不會阻止創建無效的功能,但是在對其進行操作時會引發異常
polygon1
a是一個有效的多邊形,其中一個內環在某一點上與外環接觸,
b是無效的多邊形,因爲其內環在一個以上的點與外環接觸。

_images / polygon2.png

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實例序列,從而進行復制。

_images/multipolygon.png

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

  • containswithin相反, 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

  • intersectsdisjoint 的逆函數

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)

_images/difference.png

object.intersection(other)

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

object.symmetric_difference(other)

  • 返回此對象中不在另一個幾何對象中的點以及另一個不在此幾何對象中的點的表示
  • a,b的並集-a,b的交集 即 (a∪b) - (a∩b)

_images/intersection-sym-difference.png

object.union(other)

  • 返回此對象和另一個幾何對象的點並集的表示形式
  • a,b的並集 即 a∪b
  • 更高效的方法: shapely.ops.unary_union()

_images/union.png

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 切掉頂角
    buffer
# 正方形 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;對於一點,返回本身

_images/convex_hull.png

object.envelope

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

object.minimum_rotated_rectangle

  • 返回包含對象的最小矩形多邊形(不一定平行於座標軸)

  • 線或點, 返回本身
    minimum_rotated_rectangle
    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: 平行線的距離與指定距離的比 就是斜角比, 超過,邊角會變成倒角

parallel_offset

  • mitre_limit的效果

_images/parallel_offset_mitre.png

object.simplify(tolerance, preserve_topology=True)

  • 返回幾何對象的簡化表示
  • 簡化後的對象中的所有點將在原始幾何體的公差距離內
  • preserve_topology
    • 默認爲True, 使用較慢的算法保留拓撲結構
    • False, 使用更快的Douglas-Peucker 算法保留拓撲結構
      simplify

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')

rotate

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)]

_images/scale.png

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

  • 返回傾斜的幾何體,沿x和y維度剪切角度。
  • use_radians=True, 以度或者弧度指定裁切角
  • origin: 默認是邊界框中心(幾何質心centerid),也可以是Point對象 或者座標元組

_images/skew.png

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)

unary_union
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)']

triangulate

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))']

_images/voronoi_diagram.png

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, coversintersects。與未準備好的幾何對象中的所有參數和用法完全相同。
  • 測試一個多邊形是否包含大量的點
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

  • 檢查是否開啓加速
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章