3

我需要找到多边形内部和多边形上的所有格点。

输入:

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

4

2 回答 2

3

我将按如下方式解决问题。

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

from itertools import product
from shapely.geometry import MultiPoint

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

在此处输入图像描述

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

在此处输入图像描述

或从x 和 y 数组点的笛卡尔积中的任何 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))]))

在此处输入图像描述

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

对于您给定的示例:

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)

在此处输入图像描述

还有一个更复杂的例子:

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)

在此处输入图像描述

于 2019-11-14T14:00:51.413 回答
2

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

对多边形的每条边 (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(或以其他方式调整)、处理垂直段等。这不是特别优雅,但它快速、易于实现且易于调试。

于 2017-06-06T21:52:16.410 回答