问题描述
我有一个城市建筑物的熊猫数据框。这些建筑物有一个经纬度列,并被分组到单独的管理位置。
我已经成功地创建了一个 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 数据框中的每个点绘制了一个多边形。
我原以为 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')
这是按组划分的原始点的图:
这是包围点组的多边形图:
因此,对于您的具体示例,您可以执行以下操作:
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”列,您可能需要调整该行。但是一旦你解决了这个问题,剩下的就应该工作了 =)