R语言按指定长度分割多段线并处理末尾短段的实现问题
多段线按指定长度拆分(末尾段不足时合并前一段对半拆分)实现方案
核心调整点:原有MergeLast函数仅实现了最后两段的合并逻辑,未执行对半拆分操作,我们通过新增长度计算辅助函数、修改合并拆分逻辑、补充触发判断条件三个步骤完成适配。
步骤1:新增通用线段长度计算辅助函数
避免重复写长度计算逻辑,统一计算规则:
# 计算坐标序列对应的线段总长度 CalcLineLength <- function(coords) { total_length <- 0 for (i in 1:(nrow(coords) - 1)) { d <- sqrt((coords[i, 1] - coords[i+1, 1])^2 + (coords[i, 2] - coords[i+1, 2])^2) total_length <- total_length + d } return(total_length) }
步骤2:修改MergeLast函数,新增对半拆分逻辑
合并最后两段后自动将合并段拆为等长的两段:
MergeLast <- function(lst) { l <- length(lst) # 合并最后两段并去重连接处的重复坐标点 merged_coords <- rbind(lst[[l-1]], lst[[l]][2:nrow(lst[[l]]), ]) merged_len <- CalcLineLength(merged_coords) # 对半拆分合并后的线段 half_len <- merged_len / 2 seg1 <- CreateSegment(merged_coords, 0, half_len) seg2 <- CreateSegment(merged_coords, half_len, merged_len) # 替换原有最后两段为拆分后的新段 lst[[l-1]] <- seg1 lst[[l]] <- seg2 return(lst) }
步骤3:调整SegmentSpatialLines触发逻辑
增加判断条件,仅当最后一段长度小于指定拆分长度时才执行合并拆分操作:
SegmentSpatialLines <- function(sl, length = 0, n.parts = 0, merge.last = FALSE) { stopifnot((length > 0 || n.parts > 0)) id <- 0 newlines <- list() sl <- as(sl, "SpatialLines") for (lines in sl@lines) { for (line in lines@Lines) { crds <- line@coords # 生成初始分段 segments <- CreateSegments(coords = crds, length, n.parts) if (merge.last && length(segments) > 1) { # 计算最后一段长度 last_seg_len <- CalcLineLength(segments[[length(segments)]]) # 仅最后一段小于指定拆分长度时触发合并拆分逻辑 if (last_seg_len < length) { segments <- MergeLast(segments) } } # 转换为SpatialLines格式输出 for (segment in segments) { newlines <- c(newlines, Lines(list(Line(unlist(segment))), ID = as.character(id))) id <- id + 1 } } } return(SpatialLines(newlines)) }
调用方式
和原有调用逻辑完全一致:
split_poly <- st_as_sf(SegmentSpatialLines(x, length = 6000, merge.last = TRUE))
适配效果说明
针对你提供的总长度13443英尺的多段线:
- 初始拆分为3段:6000英尺、6000英尺、1443英尺
- 检测到最后一段1443英尺小于指定的6000英尺,触发合并拆分
- 合并最后两段总长为7443英尺,对半拆分得到两段各3721.5英尺
- 最终输出3段长度分别为6000英尺、3721.5英尺、3721.5英尺,完全符合需求,同时适配最长不超过X、最短不低于Y的通用分段规则。
内容的提问来源于stack exchange,提问作者jsimpsno
相关产品推荐
相关产品推荐

