异质点密度sf多边形平滑:物种分布图需陆地平滑且贴合海岸线
针对物种分布图:保留海岸线细节同时平滑陆地侧边缘的解决方案
核心思路
你的痛点在于平滑操作会同时破坏海岸线的精细细节,所以关键是把多边形边界拆分为「海岸线贴合段」和「陆地自由边缘段」,只对后者做平滑处理,再重新拼接成完整多边形。以下是三种可落地的实现方法:
方法1:拆分边界针对性平滑(最精准)
通过空间拓扑识别,分离出多边形与海岸线重合的部分,仅平滑陆地侧边缘:
- 利用
sf包的拓扑工具拆分边界 - 用
smoothr平滑陆地边缘后,重新拼接生成多边形
library(sf) library(smoothr) # 假设已有sf格式的对象: # dist_poly:物种分布多边形 # coast_line:海岸线线串 # 1. 提取多边形的边界线 poly_boundary <- st_boundary(dist_poly) # 2. 识别边界中与海岸线重合的线段 coast_matching_segments <- st_intersection(poly_boundary, coast_line) # 3. 分离出陆地侧边缘(边界减去海岸线重合段) land_edge <- st_difference(poly_boundary, coast_matching_segments) # 4. 平滑陆地侧边缘(调整span控制平滑程度,值越大越平滑) smoothed_land_edge <- smooth(land_edge, method = "ksmooth", span = 0.1) # 5. 拼接平滑后的陆地边缘与原海岸线,生成新的分布多边形 new_full_boundary <- st_union(smoothed_land_edge, coast_matching_segments) smoothed_dist_poly <- st_polygonize(new_full_boundary)
方法2:基于距离的选择性平滑(更简便)
通过计算顶点到海岸线的距离,只对远离海岸线的顶点做平滑:
- 筛选出距离海岸线超过阈值的顶点,单独平滑后再合并
library(sf) library(smoothr) # 提取多边形所有顶点坐标 poly_coords <- st_coordinates(dist_poly)[, 1:2] # 计算每个顶点到海岸线的距离(转换为数值向量) dist_to_coast <- as.vector(st_distance( st_sfc(st_multipoint(poly_coords), crs = st_crs(dist_poly)), coast_line )) # 设定距离阈值(比如1000米,根据你的坐标系单位调整) coast_threshold <- 1000 # 拆分并分别处理顶点 coast_vertices <- poly_coords[dist_to_coast <= coast_threshold, ] land_vertices <- poly_coords[dist_to_coast > coast_threshold, ] # 平滑陆地侧顶点 smoothed_land_points <- smooth(st_multipoint(land_vertices), method = "ksmooth", span = 0.1) smoothed_land_coords <- st_coordinates(smoothed_land_points)[, 1:2] # 合并顶点并生成闭合多边形 all_coords <- rbind(smoothed_land_coords, coast_vertices) smoothed_poly <- st_polygon(list(rbind(all_coords, all_coords[1, ]))) smoothed_poly <- st_sfc(smoothed_poly, crs = st_crs(dist_poly))
方法3:terra包的缓冲区裁剪法(适合大尺度数据)
利用terra包的空间操作,先保留海岸线附近的细节,再平滑陆地区域:
- 通过缓冲区+裁剪保留海岸线精度,再与平滑后的陆地部分合并
library(terra) library(sf) # 转换为terra格式对象 dist_poly_terra <- vect(dist_poly) coast_line_terra <- vect(coast_line) # 1. 生成海岸线附近的缓冲区(保留细节) coast_buffer <- buffer(dist_poly_terra, width = 500) # 500米缓冲区,按需调整 coast_buffer <- crop(coast_buffer, coast_line_terra, mask = TRUE) # 2. 平滑整个多边形,然后删除海岸线附近区域 smoothed_land <- smooth(dist_poly_terra, method = "ksmooth", window = 3) smoothed_land <- erase(smoothed_land, coast_buffer) # 3. 合并平滑陆地与海岸线缓冲区,得到最终结果 final_dist_poly <- merge(smoothed_land, coast_buffer) # 如需转回sf格式:final_dist_poly_sf <- st_as_sf(final_dist_poly)
内容的提问来源于stack exchange,提问作者Victor Cz
相关产品推荐
相关产品推荐

