You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算瑞士分形维度的R代码报错:Ruler is longer than maximum distance found

瑞士海岸线分形维度计算报错解决办法

问题说明

运行R代码计算瑞士海岸线分形维度时,出现报错:

Error in measure_with_ruler(b, rulers[i] * 1000) : Ruler is longer than maximum distance found

但相同逻辑的哈萨克斯坦计算代码可正常运行,期望实现多尺子测量海岸线的可视化效果。

报错原因

瑞士国土面积远小于哈萨克斯坦,当前设置的最小尺子长度(25km)换算为米后(25000),在瑞士的矢量边界数据中,存在从当前点出发到后续所有点的距离都小于该尺子长度的情况,导致measure_with_ruler函数中which(pd > stick_length)[1]返回NA,触发报错。

解决办法

1. 缩小尺子长度范围

将尺子长度调整为更适合瑞士尺度的数值,比如把rulers从c(25,50,100,150,200,250)改为c(5,10,15,20,25,30),确保最小尺子长度小于边界上相邻点的最大距离。

2. 修改measure_with_ruler函数,兼容长尺子场景

修改函数逻辑,当剩余路径的最大距离小于尺子长度时,直接将终点加入测量点,避免报错。修改后的函数如下:

measure_with_ruler <- function(pols, stick_length, lonlat=FALSE) {
    stopifnot(inherits(pols, "SpatVector"))
    stopifnot(length(pols) == 1)
    g <- geom(pols)[, c('x', 'y')]
    nr <- nrow(g)
    pts <- 1
    newpt <- 1
    while(TRUE) {
        p <- newpt
        j <- p:(p+nr-1)
        j[j > nr] <- j[j > nr] - nr
        gg <- g[j,]
        pd <- distance(gg[1,,drop=FALSE], gg, lonlat)
        pd <- as.vector(pd)
        i <- which(pd > stick_length)[1]
        if(is.na(i)) {
            # 当尺子过长时,直接跳到终点
            newpt <- nr
            pts <- c(pts, newpt)
            break
        }
        newpt <- i + p
        if(newpt >= nr) {
            break
        }
        pts <- c(pts, newpt)
    }
    pts <- c(pts, 1)
    g[pts,]
}

3. 修正代码笔误

瑞士代码的绘图部分存在笔误:rules[i]应改为rulers[i],否则会出现变量未定义的错误。

修改后的完整瑞士代码

library(terra)
library(geodata)
w <- world(path=".", resolution = 3)
switz <- w[w$GID_0=="CHE",]
plot(switz)
as.data.frame(switz)
prj <- "epsg:4149"
gswitz <- project(switz, prj)
dswitz <- disagg(gswitz)
head(dswitz)
a <- expanse(dswitz)
i <- which.max(a)
a[i] / 1000000
b <- dswitz[i,]
par(mai=rep(0,4))
plot(b)

measure_with_ruler <- function(pols, stick_length, lonlat=FALSE) {
    stopifnot(inherits(pols, "SpatVector"))
    stopifnot(length(pols) == 1)
    g <- geom(pols)[, c('x', 'y')]
    nr <- nrow(g)
    pts <- 1
    newpt <- 1
    while(TRUE) {
        p <- newpt
        j <- p:(p+nr-1)
        j[j > nr] <- j[j > nr] - nr
        gg <- g[j,]
        pd <- distance(gg[1,,drop=FALSE], gg, lonlat)
        pd <- as.vector(pd)
        i <- which(pd > stick_length)[1]
        if(is.na(i)) {
            # 处理尺子过长的情况,直接跳到终点
            newpt <- nr
            pts <- c(pts, newpt)
            break
        }
        newpt <- i + p
        if(newpt >= nr) {
        break
        }
        pts <- c (pts, newpt)
    }
    pts <- c(pts, 1)
    g[pts,]
}

y <- list()
# 调整为适合瑞士的尺子长度
rulers <- c(5,10,15,20,25,30)
for (i in 1:length(rulers)) {
    y[[i]] <- measure_with_ruler(b, rulers[i]*1000)
}

par(mfrow=c(2,3), mai=rep(0,4))
for(i in 1:length(y)) {
    plot(b, col='lightgray', lwd=2)
    p <- y[[i]]
    lines(p, col='red', lwd=3)
    points(p, pch=20, col='blue', cex=2)
    # 修正笔误:rules[i]改为rulers[i]
    bar <- rbind(cbind(525000, 900000), cbind(525000, 900000-rulers[i]*1000))
    lines(bar, lwd=2)
    points(bar, pch=20, cex=1.5)
    text(525000, mean(bar[,2]), paste(rulers[i], ' km'), cex=1.5)
    text(525000, bar[2,2]-50000, paste0('(', nrow(p),')'), cex=1.25)
}

内容的提问来源于stack exchange,提问作者SpamThomasWinning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:43:09