Shapely 教程
2018-07-08 本文已影响127人
谢小帅
The Shapely User Manual - 官方文档
from shapely.geometry import Point, LineString
p = Point(0, 0)
print(p.geom_type) # Point
print(p.distance(Point(1, 1))) # 1.4142135623730951
line = LineString([(2, 0), (2, 4), (3, 4)])
print(p.hausdorff_distance(line)) # 5.0 点p到直线line上的最远距离
print(p.distance(line)) # 2.0 最近距离
Point
from shapely.geometry import Point, LineString
# Point
point = Point(1, 2)
print(point.area) # 0.0
print(point.length) # 0.0
print(point.bounds) # (1.0, 2.0, 1.0, 2.0)
# 获得坐标点
print(point.coords) # <shapely.coords.CoordinateSequence object at 0x105e662e8>
print(list(point.coords)) # [(1.0, 2.0)]
# 另一种获取方式 切片获取
print(point.coords[:]) # [(1.0, 2.0)]
LineString
from matplotlib import pyplot
from shapely.geometry import LineString
COLOR = {
True: '#6699cc',
False: '#ffcc33'
}
def v_color(ob):
return COLOR[ob.is_simple]
# 画坐标点
def plot_coords(ax, ob):
x, y = ob.xy
ax.plot(x, y, 'o', color='#999999', zorder=1)
# 画边界点 黑色
def plot_bounds(ax, ob):
x, y = zip(*list((p.x, p.y) for p in ob.boundary))
ax.plot(x, y, 'o', color='#000000', zorder=1)
# 画线
def plot_line(ax, ob):
x, y = ob.xy
ax.plot(x, y, color=v_color(ob), alpha=0.7, linewidth=3, solid_capstyle='round', zorder=2)
fig = pyplot.figure(1, figsize=[5, 5], dpi=90)
# 1: simple line
ax = fig.add_subplot(121) # 1行2列,共2个子图,第1个子图
line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
plot_coords(ax, line)
plot_bounds(ax, line)
plot_line(ax, line)
ax.set_title('a) simple')
# 设定坐标轴范围
xrange = [-1, 4]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_yticks(list(range(*yrange)) + [yrange[-1]])
ax.set_aspect(1)
# 2: complex line 复杂连线 会交叉
ax = fig.add_subplot(122)
line2 = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (-1, 1), (1, 0)])
plot_coords(ax, line2)
plot_bounds(ax, line2)
plot_line(ax, line2)
ax.set_title('b) complex')
xrange = [-2, 3]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_yticks(list(range(*yrange)) + [yrange[-1]])
ax.set_aspect(1)
pyplot.show()
print(line.is_simple)
print(line2.is_simple)
print(line.area) # 0.0
print(line.length) # 8.478708664619074
print(line.bounds) # (0.0, 0.0, 3.0, 2.0) 边界是一个能将line框起来的矩形
print(line.boundary) # MULTIPOINT (0 0, 1 0) 普通的坐标点
print(line2.area) # 0.0
print(line2.length) # 10.22677276241436
print(line2.bounds) # (-1.0, 0.0, 2.0, 2.0)
print(line2.boundary) # MULTIPOINT (0 0, 1 0)
LinearRing
from matplotlib import pyplot
from shapely.geometry.polygon import LinearRing
COLOR = {
True: '#6699cc',
False: '#ff3333'
}
def v_color(ob):
return COLOR[ob.is_valid]
def plot_coords(ax, ob):
x, y = ob.xy
ax.plot(x, y, 'o', color='#999999', zorder=1)
def plot_line(ax, ob):
x, y = ob.xy
ax.plot(x, y, color=v_color(ob), alpha=0.7, linewidth=3, solid_capstyle='round', zorder=2)
fig = pyplot.figure(1, figsize=[5, 5], dpi=90)
# 1: valid ring
ax = fig.add_subplot(121)
ring = LinearRing([(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 0.8), (0, 0)])
plot_coords(ax, ring)
plot_line(ax, ring)
ax.set_title('a) valid')
xrange = [-1, 3]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_aspect(1)
# 2: invalid self-touching ring 自身接触
ax = fig.add_subplot(122)
ring2 = LinearRing([(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)])
plot_coords(ax, ring2)
plot_line(ax, ring2)
ax.set_title('b) invalid')
xrange = [-1, 3]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_aspect(1)
pyplot.show()
print(ring.area) # 0.0
print(ring.length) # 9.389676819719329 < 4 + 4√2
print(ring.bounds) # (0.0, 0.0, 2.0, 2.0)
print(ring.boundary) # MULTIPOINT EMPTY 连起来了 所以没有
print(ring2.area) # 0.0
print(ring2.length) # 9.656854249492381 = 4 + 4√2
print(ring2.bounds) # (0.0, 0.0, 2.0, 2.0)
print(ring2.boundary) # MULTIPOINT EMPTY
Polygon
from matplotlib import pyplot
from shapely.geometry import Polygon
from descartes.patch import PolygonPatch
COLOR = {
True: '#6699cc',
False: '#ff3333'
}
def v_color(ob):
return COLOR[ob.is_valid]
def plot_coords(ax, ob):
x, y = ob.xy
ax.plot(x, y, 'o', color='#999999', zorder=1)
fig = pyplot.figure(1, figsize=[5, 5], dpi=90)
# 1: valid polygon
ax = fig.add_subplot(121)
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(shell=ext, holes=[int]) # 外壳,洞
# 做点
plot_coords(ax, polygon.interiors[0])
plot_coords(ax, polygon.exterior)
# 做方块图
patch = PolygonPatch(polygon, facecolor=v_color(polygon), edgecolor=v_color(polygon), alpha=0.5, zorder=2)
ax.add_patch(patch)
ax.set_title('a) valid')
xrange = [-1, 3]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_aspect(1)
# 2: invalid self-touching ring
ax = fig.add_subplot(122)
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]
polygon2 = Polygon(ext, [int])
plot_coords(ax, polygon2.interiors[0])
plot_coords(ax, polygon2.exterior)
patch = PolygonPatch(polygon2, facecolor=v_color(polygon2), edgecolor=v_color(polygon2), alpha=0.5, zorder=2)
ax.add_patch(patch)
ax.set_title('b) invalid')
xrange = [-1, 3]
yrange = [-1, 3]
ax.set_xlim(*xrange)
ax.set_ylim(*yrange)
ax.set_aspect(1)
pyplot.show()
print(polygon.area) # 3.5
print(polygon.length) # 10.82842712474619=8+2√2
print(polygon.bounds) # (0.0, 0.0, 2.0, 2.0)
print(polygon.boundary) # MULTILINESTRING ((0 0, 0 2, 2 2, 2 0, 0 0), (1 0, 1.5 0.5, 1 1, 0.5 0.5, 1 0))
print(polygon2.area) # 3.0
print(polygon2.length) # 12.242640687119286
print(polygon2.bounds) # (0.0, 0.0, 2.0, 2.0)
print(polygon2.boundary) # MULTILINESTRING ((0 0, 0 2, 2 2, 2 0, 0 0), (1 0, 1.5 0.5, 0.5 1.5, 0 1, 1 0))