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))
上一篇下一篇

猜你喜欢

热点阅读