从 Shapely 中的多边形中删除重复点

phi*_*hem 3 python polygon geospatial shapely

要从列表中删除重复的列表,Python 中有几种不错的方法 -例如

a = [[ 9.1514622, 47.1166004 ], [ 9.1513045, 47.1164599 ], [ 9.1516278, 47.1163001 ], [ 9.1517832, 47.1164408 ], [ 9.1514622, 47.1166004 ] ] 

print len(a) # 5
b_set = set(map(tuple,a))
b = map(list,b_set)
print len(b) # 4
Run Code Online (Sandbox Code Playgroud)

但不幸的是,我不得不将我的列表转换为Shapely Polygon对象,我需要在其中简化几何图形并执行一些其他地理功能。

from shapely.geometry import Polygon
a = [[[ 9.1514622, 47.1166004 ], [ 9.1513045, 47.1164599 ], [ 9.1516278, 47.1163001 ], [ 9.1517832, 47.1164408 ], [ 9.1514622, 47.1166004 ] ] ]
polys = [Polygon(item) for item in a] # convert list to polygon
print len(polys) # prints 5
Run Code Online (Sandbox Code Playgroud)

这个答案显示了如何从多边形列表中删除重复的多边形,但是如何从点列表中删除重复的点,作为一个匀称的多边形?

我想可以将其转换回列表,删除重复项,然后重新转换为多边形。

但这似乎过于复杂。关于如何做到这一点的任何想法?

ewc*_*wcz 6

让我们以您问题中的数据为例。你有一个坐标列表:

L = [[ 9.1514622, 47.1166004 ], [ 9.1513045, 47.1164599 ], [ 9.1516278, 47.1163001 ], [ 9.1517832, 47.1164408 ], [ 9.1514622, 47.1166004 ]]
Run Code Online (Sandbox Code Playgroud)

然后将其转换为Polygon

P = Polygon(L)
Run Code Online (Sandbox Code Playgroud)

现在,这似乎L是多余的,因为最后一点与第一点相同。但这实际上不是问题,因为否则 Shapely 无论如何都会复制第一个点(为了关闭多边形的边界)。你可以看到这个:

P = Polygon(L)
print(list(P.exterior.coords))
#[(9.1514622, 47.1166004), (9.1513045, 47.1164599), (9.1516278, 47.1163001), (9.1517832, 47.1164408), (9.1514622, 47.1166004)]

#now skip the last point
P = Polygon(L[:-1])
print(list(P.exterior.coords))
#[(9.1514622, 47.1166004), (9.1513045, 47.1164599), (9.1516278, 47.1163001), (9.1517832, 47.1164408), (9.1514622, 47.1166004)]
Run Code Online (Sandbox Code Playgroud)

如果有一些重复的点 "inside" L,例如:

L = [[ 9.1514622, 47.1166004 ], [ 9.1513045, 47.1164599 ], [ 9.1513045, 47.1164599 ], [ 9.1516278, 47.1163001 ], [ 9.1517832, 47.1164408 ], [9.1514622, 47.1166004 ]]
Run Code Online (Sandbox Code Playgroud)

那么可以使用simplify零容忍的方法来消除它(为了不引入副作用):

print(list(Polygon(L).simplify(0).exterior.coords))
#[(9.1514622, 47.1166004), (9.1513045, 47.1164599), (9.1516278, 47.1163001), (9.1517832, 47.1164408), (9.1514622, 47.1166004)]
Run Code Online (Sandbox Code Playgroud)

  • `simplify(0)` 将删除恰好落在另外两个点之间的线上的点,例如 `[(0,1),(0,2),(0,3)] -> [(0,1),(0 ,3)]`。这可能对您来说没问题,但会破坏这些顶点有意义的情况,例如 openstreetmap 道路连接规则。 (4认同)