问题
最近遇到一个问题:一个建筑足迹可能对应多个POI点,并且其数量还不同,我想要计算POI点到对应建筑足迹(根据空间连接生成的uID
确定是否为对应建筑足迹)的距离。
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
# 绘图
ax = blg_tessellation[blg_tessellation.bID==2083].plot(ec='blue', fc='white', label='area', figsize=(10,10))
building[building.bID==2083].plot(ax=ax, color='k', label='building')
poi1[poi1.bID==2083].plot(ax=ax, markersize=10, color='r', label='POI')
# 图例映射:绘图的参数(主要是label)一一对应就可以显示图例
poi = mlines.Line2D([], [], color='r', marker='o', linestyle='None', markersize=3, label='POI')
area_patch = mpatches.Patch(ec='blue', fc='white', label='area')
building_patch = mpatches.Patch(color='k', label='building')
plt.legend(handles=[poi,building_patch,area_patch],
loc="upper right", # 图例位置
ncol=1, # 图例列数
shadow=False) # 是否带有阴影
plt.xticks([])
plt.yticks([])
plt.show()
- 基于上图问题计算POI到建筑足迹的距离
- 主要使用geopandas的
distance函数
代码
为了方便,我自定义几组数据进行演示
for循环
import geopandas as gpd
from shapely.geometry import Point
# 创建示例数据(替换为你自己的数据)
poi_data = {'uID': [1, 1, 2, 2, 3],
'geometry': [Point(0, 0), Point(0.5, 0.5), Point(1, 1), Point(1.5, 1.5), Point(2, 2)]}
building_data = {'uID': [1, 2, 3],
'geometry': [Point(1, 1), Point(2, 2), Point(3, 3)]}
# 创建 GeoDataFrames
gdf_poi = gpd.GeoDataFrame(poi_data, geometry='geometry')
gdf_building = gpd.GeoDataFrame(building_data, geometry='geometry')
# 计算距离并将结果添加到POI的GeoDataFrame中
for index, building in gdf_building.iterrows():
# 确定对应计算要素
related_pois = gdf_poi[gdf_poi['uID'] == building['uID']].copy()
# 计算距离
related_pois['distance_to_building'] = related_pois['geometry'].distance(building['geometry'])
# 将结果添加到POI的GeoDataFrame中
gdf_poi.loc[related_pois.index, 'distance_to_building'] = related_pois['distance_to_building']
gdf_poi
apply
import geopandas as gpd
from shapely.geometry import Point
# 创建示例数据(替换为你自己的数据)
poi_data = {'uID': [1, 1, 2, 2, 3],
'geometry': [Point(0, 0), Point(0.5, 0.5), Point(1, 1), Point(1.5, 1.5), Point(2, 2)]}
building_data = {'uID': [1, 2, 3],
'geometry': [Point(1, 1), Point(2, 2), Point(3, 3)]}
# 创建 GeoDataFrames
gdf_poi = gpd.GeoDataFrame(poi_data, geometry='geometry')
gdf_building = gpd.GeoDataFrame(building_data, geometry='geometry')
# 定义计算距离的函数
def calculate_distance(building_row):
# 确定对应计算要素
related_pois = gdf_poi[gdf_poi['uID'] == building_row['uID']]
# 计算距离
related_pois['distance_to_building'] = related_pois['geometry'].distance(building_row['geometry'])
# 返回包含距离信息的 Series 对象
return related_pois['distance_to_building']
# 使用 apply 应用函数,并将结果添加到POI的GeoDataFrame中
gdf_poi['distance_to_building'] = gdf_building.apply(calculate_distance, axis=1).sum()
gdf_poi
apply结合lambda
import geopandas as gpd
from shapely.geometry import Point
# 创建示例数据(替换为你自己的数据)
poi_data = {'uID': [1, 1, 2, 2, 3],
'geometry': [Point(0, 0), Point(0.5, 0.5), Point(1, 1), Point(1.5, 1.5), Point(2, 2)]}
building_data = {'uID': [1, 2, 3],
'geometry': [Point(1, 1), Point(2, 2), Point(3, 3)]}
# 创建 GeoDataFrames
gdf_poi = gpd.GeoDataFrame(poi_data, geometry='geometry')
gdf_building = gpd.GeoDataFrame(building_data, geometry='geometry')
# 使用 apply 和 lambda 计算距离并将结果添加到 POI 的 GeoDataFrame 中
gdf_poi['distance_to_building'] = gdf_building.apply(
lambda building_row: gdf_poi[gdf_poi['uID'] == building_row['uID']]['geometry'].distance(building_row['geometry']),
axis=1
).sum()
gdf_poi