围绕标记坐标创建匀称多边形

问题描述

我有一个城市建筑物的熊猫数据框。这些建筑物有一个经纬度列,并被分组到单独的管理位置。

我已经成功地创建了一个 geopandas 数据框,其中包含每个建筑物的“几何”列的匀称点,并在地图上用不同的颜色为每个管理位置绘制这些点。但是,有没有办法按管理位置对地理数据框进行分组,并将“几何”列作为一个匀称的多边形,包含与每个管理位置内的每个建筑物对应的点?

我目前拥有:

geo_poly['geometry'] = geo_poly['geometry'].apply(lambda x: x.coords[0])
geo_poly = geo_poly.groupby('management location')['geometry'].apply(lambda x: polygon(x.tolist())).reset_index()
geo_poly = gpd.GeoDataFrame(geo_poly,geometry = 'geometry')

但是当我绘制它时:

geo_poly.plot(ax = ax)

它显然通过遍历 geopandas 数据框中的每个点绘制了一个多边形。

plot of polygons

我原以为 geopandas 会(或者某处会存在)一种更好的方法来围绕定义的集群边缘的点绘制多边形,但我很难找到。

如有任何帮助,我们将不胜感激, 谢谢

解决方法

您可以使用 GeoDataFrame 的 dissolve 函数“融合”组中的所有点,然后使用 convex_hull 属性提取所有分组/融合/溶解点周围的多边形。

>

这是一个可重现的小例子:

# Importing libraries used
import numpy as np
import geopandas as gpd
import shapely

# Setting the random seed
np.random.seed(6)

# Determining the number of points in the example
npoints = 15

# Generating the GeoDataFrame with random Points
mydf = gpd.GeoDataFrame({'id':range(npoints),'geometry':(pd.Series(list(np.random.rand(npoints,2)))
                                     .apply(shapely.geometry.Point)),'group':np.random.randint(1,3,npoints)})

# Plotting the GeoDataFrame according to the "group" column
mydf.plot(column='group',cmap='Set1')

# Fusing all of the Points based on the "group" column and 
# generating a Polygon that envelops all of the Points in
# each group
new_df = (mydf.dissolve(by='group')
          .convex_hull
          .reset_index()
          .rename({0:'geometry'},axis=1))

# Plotting the original Point and the newly-generated Polygons
ax = new_df.plot(column='group',cmap='tab20c',alpha=.7)
mydf.plot(ax = ax,column='group',cmap='Set1')

这是按组划分的原始点的图:

Points colored by group

这是包围点组的多边形图:

Polygons enclosing each group's points

因此,对于您的具体示例,您可以执行以下操作:

from shapely.geometry import Point

# Creating a new column with Point geometries
geo_poly['geometry_pt'] = geo_poly['geometry'].apply(lambda x: Point(x.coords[0]))

# Transforming into a GeoDataFrame
geo_poly = gpd.GeoDataFrame(geo_poly,geometry = 'geometry_pt')

# Dissolving and extracting the new Polygons
new_geo_poly = (geo_poly.dissolve(by='management location')
                .convex_hull
                .reset_index()
                .rename({0:'geometry'},axis=1))

关于创建新的“geometry_pt”列,您可能需要调整该行。但是一旦你解决了这个问题,剩下的就应该工作了 =)