从Python形状多边形中提取多边形内的所有坐标

时间:2017-06-06 21:00:11

标签: python shapely shapely.geometry

我需要在多边形内部找到所有点。

输入:

from shapely.geometry import Polygon, mapping
sh_polygon = Polygon(((0,0), (2,0), (2,2), (0,2)))

输出:

(0,0) , (1,0) , (2,0) , (0,1) , (1,1) , (2,1) , (0,2) , (1,2) , (2,2).

如果没有使用shapely,请建议是否有更好的方法。

我编写了这段代码,在多边形内部给出了点,但它没有给出点。也有更好的方法来做同样的事情:

from shapely.geometry import Polygon, Point

def get_random_point_in_polygon(poly):
    (minx, miny, maxx, maxy) = poly.bounds
    minx = int(minx)
    miny = int(miny)
    maxx = int(maxx)
    maxy = int(maxy)
    print("poly.bounds:", poly.bounds)
    a = []
    for x in range(minx, maxx+1):
        for y in range(miny, maxy+1):
            p = Point(x, y)
            if poly.contains(p):
                a.append([x, y])
    return a


p = Polygon([(0,0), (2,0), (2,2), (0,2)])
point_in_poly = get_random_point_in_polygon(p)

print(len(point_in_poly))
print(point_in_poly)

输出:

poly.bounds: (0.0, 0.0, 2.0, 2.0)
1
[[1, 1]]

我简化了我的问题。实际上,我需要找到角落里面和角落上的所有点:(77,97),(141,101),(136,165),(73,160)。

2 个答案:

答案 0 :(得分:1)

是否有一个函数可以找到位于 一行的格点?那些是你唯一缺少的。它们只是线段定义方程的解决方案。如果没有,那么很容易自己编写算法,通过暴力找到分数。

对多边形的每个边(p1,p2)执行以下操作。

p1 = (x1, y1)
p2 = (x2, y2)
xdiff = x2 - x1
ydiff = y2 - y1

# Find the line's equation, y = mx + b
m = ydiff / xdiff
b = y1 - m*x1

for xval in range(x1+1, x2):
    yval = m * xval + b
    if int(yval) == yval:
        # add (xval, yval) to your list of points

我已将细节留给您:确保x1< x2(或以其他方式适应),处理垂直段等。这不是特别优雅,但它快速,易于实现,并且易于调试。

答案 1 :(得分:0)

我将按以下方式处理该问题。

首先,定义网格点的网格。例如,可以使用itertools.product

from itertools import product
from shapely.geometry import MultiPoint

points = MultiPoint(list(product(range(5), repeat=2)))

enter image description here

points = MultiPoint(list(product(range(10), range(5))))

enter image description here

Cartesian product of x and y array points into single array of 2D points中的任何NumPy解决方案:

import numpy as np

x = np.linspace(0, 1, 5)
y = np.linspace(0, 1, 10)
points = MultiPoint(np.transpose([np.tile(x, len(y)), np.repeat(y, len(x))]))

enter image description here

然后,使用Shapely的intersection方法,可以获得位于给定多边形的内部和边界上的那些晶格点。

对于您给出的示例:

p = Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
xmin, ymin, xmax, ymax = p.bounds
x = np.arange(np.floor(xmin), np.ceil(xmax) + 1)  # array([0., 1., 2.])
y = np.arange(np.floor(ymin), np.ceil(ymax) + 1)  # array([0., 1., 2.])
points = MultiPoint(np.transpose([np.tile(x, len(y)), np.repeat(y, len(x))]))
result = points.intersection(p)

enter image description here

还有一个更复杂的示例:

p = Polygon([(-4.85571368308564, 37.1753007358263), 
             (-4.85520937147867, 37.174925051829), 
             (-4.85259349198842, 37.1783463712614),
             (-4.85258684662671, 37.1799609243756),
             (-4.85347524651836, 37.1804461589773),
             (-4.85343407576431, 37.182006629169),
             (-4.85516283166052, 37.1842384372115),
             (-4.85624511894443, 37.1837967179202),
             (-4.85533824429553, 37.1783762575331),
             (-4.85674599573635, 37.177038261295),
             (-4.85571368308564, 37.1753007358263)])
xmin, ymin, xmax, ymax = p.bounds  # -4.85674599573635, 37.174925051829, -4.85258684662671, 37.1842384372115
n = 1e3
x = np.arange(np.floor(xmin * n) / n, np.ceil(xmax * n) / n, 1 / n)  # array([-4.857, -4.856, -4.855, -4.854, -4.853])
y = np.arange(np.floor(ymin * n) / n, np.ceil(ymax * n) / n, 1 / n)  # array([37.174, 37.175, 37.176, 37.177, 37.178, 37.179, 37.18 , 37.181, 37.182, 37.183, 37.184, 37.185])
points = MultiPoint(np.transpose([np.tile(x, len(y)), np.repeat(y, len(x))]))
result = points.intersection(p)

enter image description here

相关问题