当前位置: 首页 > 知识库问答 >
问题:

识别Geopandas/Shapely中多边形的唯一分组

莫乐
2023-03-14

假设我有两个不相交的多边形组/“岛屿”(想想两个不相邻县的人口普查区)。我的数据可能看起来像这样:

>>> p1=Polygon([(0,0),(10,0),(10,10),(0,10)])
>>> p2=Polygon([(10,10),(20,10),(20,20),(10,20)])
>>> p3=Polygon([(10,10),(10,20),(0,10)])
>>> 
>>> p4=Polygon([(40,40),(50,40),(50,30),(40,30)])
>>> p5=Polygon([(40,40),(50,40),(50,50),(40,50)])
>>> p6=Polygon([(40,40),(40,50),(30,50)])
>>> 
>>> df=gpd.GeoDataFrame(geometry=[p1,p2,p3,p4,p5,p6])
>>> df
                                        geometry
0        POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
1  POLYGON ((10 10, 20 10, 20 20, 10 20, 10 10))
2          POLYGON ((10 10, 10 20, 0 10, 10 10))
3  POLYGON ((40 40, 50 40, 50 30, 40 30, 40 40))
4  POLYGON ((40 40, 50 40, 50 50, 40 50, 40 40))
5         POLYGON ((40 40, 40 50, 30 50, 40 40))
>>> 
>>> df.plot()

我希望每个岛内的多边形采用表示其组的ID(可以是任意的)。例如,左下角的3个多边形的IslandID为1,右上角的3个多边形的IslandID为2。

我已经开发了一种方法来做到这一点,但我想知道这是否是最好/最有效的方法。我做以下工作:

1) 创建一个几何体等于多多边形一元并集内多边形的地理数据框。这给了我两个多边形,每个“岛”一个。

>>> SepIslands=gpd.GeoDataFrame(geometry=list(df.unary_union))
>>> SepIslands.plot()

2)为每个组创建一个ID。

>>> SepIslands['IslandID']=SepIslands.index+1

3) 在空间上将孤岛连接到原始多边形,以便每个多边形都具有相应的孤岛id。

>>> Final=gpd.tools.sjoin(df, SepIslands, how='left').drop('index_right',1)
>>> Final
                                        geometry  IslandID
0        POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))         1
1  POLYGON ((10 10, 20 10, 20 20, 10 20, 10 10))         1
2          POLYGON ((10 10, 10 20, 0 10, 10 10))         1
3  POLYGON ((40 40, 50 40, 50 30, 40 30, 40 40))         2
4  POLYGON ((40 40, 50 40, 50 50, 40 50, 40 40))         2
5         POLYGON ((40 40, 40 50, 30 50, 40 40))         2

这真的是最好/最有效的方法吗?

共有1个答案

艾浩穰
2023-03-14

如果各组之间的差距相当大,另一个选择是sklearn。簇DBSCAN可以对多边形的质心进行聚类,并将其标记为簇。

DBSCAN代表基于密度的噪声应用空间聚类,它可以将紧密聚集在一起的点分组。在我们的例子中,一个岛屿中的多边形将聚集在同一个集群中。

这也适用于两个以上的岛屿。

import geopandas as gpd
import pandas as pd
from shapely.geometry import Polygon
from sklearn.cluster import DBSCAN

# Note, EPS_DISTANCE = 20 is a magic number and it needs to be
# * smaller than the gap between any two islands
# * large enough to cluster polygons in one island in same cluster
EPS_DISTANCE = 20
MIN_SAMPLE_POLYGONS = 1

p1=Polygon([(0,0),(10,0),(10,10),(0,10)])
p2=Polygon([(10,10),(20,10),(20,20),(10,20)])
p3=Polygon([(10,10),(10,20),(0,10)])
p4=Polygon([(40,40),(50,40),(50,30),(40,30)])
p5=Polygon([(40,40),(50,40),(50,50),(40,50)])
p6=Polygon([(40,40),(40,50),(30,50)])
df = gpd.GeoDataFrame(geometry=[p1, p2, p3, p4, p5, p6])

# preparation for dbscan
df['x'] = df['geometry'].centroid.x
df['y'] = df['geometry'].centroid.y
coords = df.as_matrix(columns=['x', 'y'])

# dbscan
dbscan = DBSCAN(eps=EPS_DISTANCE, min_samples=MIN_SAMPLE_POLYGONS)
clusters = dbscan.fit(coords)

# add labels back to dataframe
labels = pd.Series(clusters.labels_).rename('IslandID')
df = pd.concat([df, labels], axis=1)

> df
                                        geometry  ...  IslandID
0        POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))  ...         0
1  POLYGON ((10 10, 20 10, 20 20, 10 20, 10 10))  ...         0
2          POLYGON ((10 10, 10 20, 0 10, 10 10))  ...         0
3  POLYGON ((40 40, 50 40, 50 30, 40 30, 40 40))  ...         1
4  POLYGON ((40 40, 50 40, 50 50, 40 50, 40 40))  ...         1
5         POLYGON ((40 40, 40 50, 30 50, 40 40))  ...         1
[6 rows x 4 columns]
 类似资料:
  • 我不熟悉geopandas,只想绘制多边形的轮廓,类似于PostGIS中的函数 我有一个地理数据框包含每个状态的多边形 当我按一个状态划分子集时,我能够绘制该状态: 我只对轮廓感兴趣,但在留档中不清楚如何将多边形转换为线几何。在或其他空间库中是否有有用的方法可以帮助将多边形转换为线性字符串?

  • 我试图在GeoPandas中找到两个多边形的并集,并输出一个包含两个多边形的点作为其顶点的单个几何体。函数为每个单独的并集提供多边形,但我想要一个多边形。 在上下文中,我使用它将两个行政区域合并为一个区域(即包括一个国家内的一个城镇区)。 下面的例子来自geopandas网站,说明了我想要的: 没有一个输出几何是我所期望的,这是以下内容: 首先,如何使用GeoPandas或shapely从输入多边

  • 我有一个geopandas数据框,由一个id和一个由2D点填充的几何列组成。我想为每个唯一id连接点以创建一个多边形,以便我的新数据帧将多边形作为其几何体。我的代码当前看起来像这样: 它创建了一个多边形,但当我指定新变量时,它会显示 这很有意义,因为它仍然只是一个坐标列表,而不是实际的多边形对象。有人知道如何将它变成一个实际的多边形对象,我可以将它添加到geopandas上的列中吗 提前感谢:)

  • 我正在寻找一种方法来创建一组多边形(rechtangles),沿着一条线在多个多边形中创建一组多边形(rechtangles),并将其水平隔开,如图所示。 我尝试生成点并将其用作多边形的中点,但问题是,通过创建等间距的点光栅,除了180度之外,不可能以任何其他方向旋转。 例子 给出了一个多多边形形状的对象和由宽度和高度以及每个多边形之间的垂直和水平间距定义的多边形。多边形应仅放置在多多边形内,且不

  • 我有点形状文件和多边形形状文件。我想找出每个多边形内的最高点。我做了一个交集,以确定哪些点属于每个多边形: 现在我想为每个索引选择最高点。我认为这是一个在几何列中按Z值排序的问题,但我在做这件事时遇到了问题。我不知道如何使用geopandas从几何体中提取Z坐标。最后,我想进行空间连接,并将Z值填充到最近的点(另一个shapefile)。 非常感谢。

  • 我有一个带有lat和lon的商店位置csv文件。我还有一个geojson文件,其中包含美国人口普查区的多边形特征。我想使用Python查看每个位置存在哪些多边形。 我使用Shapely Python库的包含()来循环通过存储位置的csv文件,获取lat和lon坐标,然后检查这些坐标是否存在于Geojson文件中的一个多边形中。 如果我先遍历每个位置/坐标,然后遍历每个多边形,使用contains(