gpt4 book ai didi

python - 在 GeoDataFrame 中查找不重叠的多边形

转载 作者:行者123 更新时间:2023-12-05 02:17:31 28 4
gpt4 key购买 nike

我有一个包含 shapely.polygons 列的 GeoDataFrame。其中有些截然不同,有些则不同:

In [1]: gdf
Out[2]:
geometry
1 POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))
2 POLYGON ((1 3, 1 4, 2 4, 2 3, 1 3))
3 POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))
4 POLYGON ((3 1, 3 2, 4 2, 4 1, 3 1))
5 POLYGON ((1 3, 1 4, 2 4, 2 3, 1 3))

我只需要找到不同的(非重叠的)多边形:

In [1]: gdf_distinct
Out[2]:
geometry
1 POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))
2 POLYGON ((1 3, 1 4, 2 4, 2 3, 1 3))
4 POLYGON ((3 1, 3 2, 4 2, 4 1, 3 1))

由于多边形不可散列,我不能在 Pandas 中使用简单的方法:

In [1]: gdf_distinct = gdf['geometry'].unique()

TypeError: unhashable type: 'Polygon'

是否有任何简单有效的方法来获得仅包含不同多边形的新 GeoDataFrame?

附言:

我找到了一种方法,但它只适用于完全复制的多边形,而且我认为效率不高:

In [1]: m = []
for index, row in gdf.iterrows():]
if row['geometry'] not in m:
m.append(row['geometry'])
gdf_distinct = GeoDataFrame(geometry=m)

最佳答案

让我们从 4 个多边形的列表开始,其中三个与其他多边形重叠:

from shapely.geometry import Polygon
import geopandas

polygons = [
Polygon([[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]]),
Polygon([[1, 3], [1, 5], [3, 5], [3, 3], [1, 3]]),
Polygon([[2, 2], [2, 3.5], [3.5, 3.5], [3.5, 2], [2, 2]]),
Polygon([[3, 1], [3, 2], [4, 2], [4, 1], [3, 1]]),
]
gdf = geopandas.GeoDataFrame(data={'A': list('ABCD')}, geometry=polygons)
gdf.plot(column='A', alpha=0.75)

它们看起来像这样:

enter image description here

因此我们可以循环遍历每一个,然后循环遍历所有其他对象并使用 shapely API 检查重叠。如果没有任何重叠,我们会将其附加到我们的输出列表中:

non_overlapping = []
for p in polygons:
overlaps = []
for g in filter(lambda g: not g.equals(p), polygons):
overlaps.append(g.overlaps(p))

if not any(overlaps):
non_overlapping.append(p)

任何给我的:

['POLYGON ((3 1, 3 2, 4 2, 4 1, 3 1))']

这是我所期望的。

但这实际上是 O(N^2),我认为它不一定是。

所以让我们尽量不要对同一对检查两次:

non_overlapping = []
for n, p in enumerate(polygons[:-1], 1): # don't include the last element
overlaps = []
for g in polygons[n:]: # loop from the next element to the end
overlaps.append(g.overlaps(p))

if not any(overlaps):
non_overlapping.append(str(p))

我得到了相同的结果,而且在我的机器上速度稍快。

我们可以通过在 if 语句中使用生成器而不是普通的 for block 来稍微压缩循环:

non_overlapping = []
for n, p in enumerate(polygons[:-1], 1):
if not any(p.overlaps(g) for g in polygons[n:]):
non_overlapping.append(p)

同样的故事。

关于python - 在 GeoDataFrame 中查找不重叠的多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47471872/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com