从一组点我使用scipy构建了Voronoi曲面细分:
from scipy.spatial import Voronoi
vor = Voronoi(points)
现在我想从Voronoi算法创建的区域构建一个Polygon in Shapely。问题是Polygon类需要一个逆时针顶点列表。虽然我知道如何order these vertices,但我无法解决问题,因为这通常是我的结果:
(重叠多边形)。这是代码(ONE RANDOM EXAMPLE):
def order_vertices(l):
mlat = sum(x[0] for x in l) / len(l)
mlng = sum(x[1] for x in l) / len(l)
# https://stackoverflow.com/questions/1709283/how-can-i-sort-a-coordinate-list-for-a-rectangle-counterclockwise
def algo(x):
return (math.atan2(x[0] - mlat, x[1] - mlng) + 2 * math.pi) % 2*math.pi
l.sort(key=algo)
return l
a = np.asarray(order_vertices([(9.258054711746084, 45.486245994138976),
(9.239284166975443, 45.46805963143515),
(9.271640747003861, 45.48987234571072),
(9.25828782103321, 45.44377372506324),
(9.253993275176263, 45.44484395950612),
(9.250114174032936, 45.48417979682819)]))
plt.plot(a[:,0], a[:,1])
我该如何解决这个问题?
答案 0 :(得分:29)
如果你刚刚收集了一些多边形,那么你就不需要预先订购它来构建它们。
scipy.spatial.Voronoi
对象具有ridge_vertices
属性,其中包含形成Voronoi脊线的顶点索引。如果指数为-1
,则脊将变为无穷大。
首先从一些随机点开始构建Voronoi对象。
import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
import shapely.geometry
import shapely.ops
points = np.random.random((10, 2))
vor = Voronoi(points)
voronoi_plot_2d(vor)
您可以使用它来构建Shapely LineString对象的集合。
lines = [
shapely.geometry.LineString(vor.vertices[line])
for line in vor.ridge_vertices
if -1 not in line
]
shapely.ops
模块有polygonize
,它返回Shapely Polygon对象的生成器。
for poly in shapely.ops.polygonize(lines):
#do something with each polygon
或者,如果您想要从Voronoi tesselation所包围的区域形成单个多边形,则可以使用Shapely unary_union
方法:
shapely.ops.unary_union(list(shapely.ops.polygonize(lines)))
答案 1 :(得分:1)
正如其他人所说,这是因为你必须根据索引正确地从结果点重建多边形。虽然你有解决方案,我想我应该提一下,还有另一个支持pypi的tesselation包名为Pytess(免责声明:我是包维护者),其中voronoi函数返回完全为你构建的voronoi多边形。
答案 2 :(得分:0)
该库能够生成有序的坐标列表,您只需要使用提供的索引列表即可:
import numpy as np
from scipy.spatial import Voronoi
...
ids = np.array(my_points_list)
vor = Voronoi(points)
polygons = {}
for id, region_index in enumerate(vor.point_region):
points = []
for vertex_index in vor.regions[region_index]:
if vertex_index != -1: # the library uses this for infinity
points.append(list(vor.vertices[vertex_index]))
points.append(points[0])
polygons[id]=points
polygons
词典中的每个多边形都可以导出到geojson或整形,我能够在QGIS中正确渲染它们
答案 3 :(得分:-1)
你实现的函数(order_vertices())在你的情况下不能工作,因为它只需要一个已经有序的坐标序列,它构建一个矩形,并反转多边形的方向(也许只适用于矩形。 ..)。 但是你有一个没有有序的坐标序列
一般来说,您无法从非有序顶点的任意序列构建多边形,因为凹多边形没有唯一解,如下例所示:https://stackoverflow.com/a/7408711/4313133
但是,如果您确定您的多边形总是凸出的,则可以使用以下代码构建凸包:https://stackoverflow.com/a/15945375/4313133(现在测试,它对我有效)
也许你可以用scipy建造凸包,但我测试它:scipy.spatial.ConvexHull