如何获取python中多边形内的点列表?

Far*_*eed 8 python gis algorithm polygon fill

我搜索了很多,无法找到我的问题的任何实际答案.我有一个多边形.例如:

    [(86, 52), (85, 52), (81, 53), (80, 52), (79, 48), (81, 49), (86, 53),
     (85, 51), (82, 54), (84, 54), (83, 49), (81, 52), (80, 50), (81, 48),
     (85, 50), (86, 54), (85, 54), (80, 48), (79, 50), (85, 49), (80, 51),
     (85, 53), (82, 49), (83, 54), (82, 53), (84, 49), (79, 49)]
Run Code Online (Sandbox Code Playgroud)

我想得到这个边界多边形内的所有点的列表.我听说很多关于多边形三角测量技术或线性/泛光/交叉/ ......填充算法.但我真的想出一个有效的方法来实现这一点.这个多边形很小,想象一个有10亿个点的多边形.我现在使用PIL绘制多边形用红色填充多边形并在其中循环以找到红点.这是一种非常缓慢的技术:

def render(poly, z):
    xs = [i[0] for i in poly]
    ys = [i[1] for i in poly]
    minx, maxx = min(xs), max(xs)
    miny, maxy = min(ys), max(ys)
    X = maxx - minx + 1
    Y = maxy - miny + 1
    newPoly = [(x - minx, y - miny) for (x, y) in polygons]
    i = Image.new("RGB", (X, Y))
    draw = ImageDraw.Draw(i)
    draw.polygon(newPoly, fill="red")
    # i.show()
    tiles = list()
    w, h = i.size
    print w, h
    for x in range(w):
        for y in range(h):
            data = i.getpixel((x, y))
            if data != (0, 0, 0):
                tiles.append((x + minx, y + miny))

    return tiles
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种解决这个问题的Pythonic方法.谢谢你们.

Sta*_*pol 12

我建议使用matplotlib contains_points()

from matplotlib.path import Path

tupVerts=[(86, 52), (85, 52), (81, 53), (80, 52), (79, 48), (81, 49), (86, 53),
 (85, 51), (82, 54), (84, 54), (83, 49), (81, 52), (80, 50), (81, 48),
 (85, 50), (86, 54), (85, 54), (80, 48), (79, 50), (85, 49), (80, 51),
 (85, 53), (82, 49), (83, 54), (82, 53), (84, 49), (79, 49)]


x, y = np.meshgrid(np.arange(300), np.arange(300)) # make a canvas with coordinates
x, y = x.flatten(), y.flatten()
points = np.vstack((x,y)).T 

p = Path(tupVerts) # make a polygon
grid = p.contains_points(points)
mask = grid.reshape(300,300) # now you have a mask with points inside a polygon
Run Code Online (Sandbox Code Playgroud)


Rem*_*ich 3

我认为绘制多边形并填充它是一个好的开始,无论如何你都需要类似的东西,并且这些算法通常在 C 中进行微调。但是不要使用 RGB 图像,使用黑/白图像,并且用于numpy.where()查找为 1 的像素。

根据这个问题,该mahotas库有一个fill_polygon与 numpy 数组一起使用的函数。

我从您的函数中开始以下代码(我也会减去minxmaxx),但请注意,我根本无法测试它,我不在我的开发机器上。

import numpy as np
import mahotas

def render(poly): # removed parameter 'z'
    xs = [i[0] for i in poly]
    ys = [i[1] for i in poly]
    minx, maxx = min(xs), max(xs)
    miny, maxy = min(ys), max(ys)
    X = maxx - minx + 1
    Y = maxy - miny + 1
    newPoly = [(x - minx, y - miny) for (x, y) in poly]           

    grid = np.zeros((X, Y), dtype=np.int8)
    mahotas.polygon.fill_polygon(newPoly, grid)

    return [(x + minx, y + miny) for (x, y) in np.where(grid)]
Run Code Online (Sandbox Code Playgroud)