前言
在做物种分布模型预测过程中,往往需要删除一些造成信息冗余的密集物种分布点,在减少模型数据量的同时也可以减少样本采样偏差造成的影响,而设置一个怎么的阈值去过滤掉过度空间自相关的物种点则需要结合自己的数据去考虑。我这里以2km为例去删除掉小于2km距离以内的点。
思路
为每个点生成一个2km的换车缓冲区,若有点与其相交,则随机删除一个点,遍历所有点,直到任意两个点之间的范围都大于2km为止。
- 出现的问题:生成缓冲区需要投影坐标系
- 解决办法:随便定义一个世界墨卡托投影进行用于计算距离,删好点之后又把坐标转回来!
数据准备
将物种点转换成shp格式之后需要删除空点(这一步为必须,若要素中包含空白信息代码则会报错)
代码实现
import geopandas as gpd
## 过滤掉距离小于min_distance的点。
def filter_points(gdf, min_distance):
gdf_copy = gdf.copy()
to_remove = []
for index, row in gdf_copy.iterrows():
if index not in to_remove:
distances = gdf_copy.geometry.distance(row.geometry)
close_points = distances[distances < min_distance].index.tolist()
close_points.remove(index)
to_remove.extend(close_points)
gdf_copy.drop(index=to_remove, inplace=True)
return gdf_copy
# 读取shp文件
gdf = gpd.read_file(r'F:\bird\shaung_pri.shp')
# 记录原始坐标系
original_crs = gdf.crs
# 将数据转换为Web Mercator
gdf = gdf.to_crs('EPSG:3857')
# 过滤掉距离小于2km的点
filtered_gdf = filter_points(gdf, 2000) # 2km
# 将数据还原为原始坐标系
filtered_gdf = filtered_gdf.to_crs(original_crs)
# 保存到新的shp文件
filtered_gdf.to_file(r'F:\bird\shaung_2km.shp')
print("完成任务!")
若你的数据为投影坐标系则直接删除后面投影变换的三行代码即可!
结果
感谢大家花时间来阅读本文 作者水平有限 有失误之处请大家斧正!