我尝试编写一个函数,使用R中的lidR包,使用离散返回航空激光雷达数据来计算叶面积指数。我的函数遵循比尔-朗伯定律,并假设随机方向的叶子,以便罗斯-尼尔森间隙函数值计算消光系数时 = 0.5。使用离散回波数据,我计算截获的光合有效辐射与传输的光合有效辐射的比率,即冠层回波(定义为 3 米以上)与地面回波(定义为 2 米以下)的比率。我创建了一个名为
Calc_LAI()
的“低级 api”函数,它执行以下操作:
pixel_metrics()
我被两个问题难住了:
首先,我有一个名为 lai_func() 的辅助函数,它可以对叶面积指数进行算术计算。目前,我将其嵌套在条件中,对于
if(is(las,"LAS")){}.
但是,当我运行整个 Calc_LAI()
函数时,我收到一条错误,指出未找到 lai_func()
。如果我将辅助函数移出 Calc_LAI()
,此错误就会消失,但我在其他“低级 api”调用中拥有对 catalog_apply()
的辅助函数,它们嵌套在 if(is(las,"LAS")){}
条件中,没有错误。
其次,调用
pixel_metrics()
会导致以下错误Error: Duplicated elements found. At least one of the metrics was not a number. Each metric should be a single number.
,这让我很困惑,因为我通过在冠层比率中的分子和分母上都加1来确保仅从叶面积指数的计算中获得真实值返回地面返回以确保我永远不会被零除或取 0 的自然对数。
下面是我的可重现示例:
##Loading Necessary Package##
library(lidR)
##Reading in Example Lidar Dataset##
lasfile<- system.file("extdata", "MixedConifer.laz", package="lidR")
MixedConifer<-readLAS(lasfile)
##Low-level API function to calculate leaf area index##
Calc_LAI <- function(las)
{
if (is(las, "LAScatalog")) {
options <- list(automerge = TRUE, need_buffer = TRUE)
LAI <- catalog_apply(las, Calc_LAI, .options = options)
return(LAI)
}
else if (is(las, "LAScluster")) {
bbox <- st_bbox(las)
las <- readLAS(las)
if (is.empty(las)) return(NULL)
LAI <- Calc_LAI(las, param1, param2)
LAI <- sf::st_crop(LAI, bbox)
return(LAI)
}
else if (is(las, "LAS")) {
las<-add_attribute(las, paste(las$gpstime, las$ReturnNumber, sep="_"), "UID")
dem<-rasterize_terrain(las, res=1, algorithm = knnidw())
norm<-las-dem
lai_func<-function(ScanAngle, Z, UID){
nground<-length(unique(UID[Z <= 6.6]))
nveg<-length(unique(UID[Z >= 9.9]))
out<-log(nveg+1/(nground+1))*cos((ScanAngle*pi/180)/0.5)
return(list(LAI=out))
}
LAI<-pixel_metrics(las=norm, func=lai_func(ScanAngle=ScanAngleRank, Z=Z, UID=UID), res=9.9)
return(LAI)
}
else {
stop("This type is not supported.")
}
}
##First Attempt with lai_func() nested within Calc_LAI()##
Calc_LAI(MixedConifer)#throws error that lai_func() not found
##Second Attempt with lai_func() outside of Calc_LAI##
lai_func<-function(ScanAngle, Z, UID){
nground<-length(unique(UID[Z <= 6.6]))
nveg<-length(unique(UID[Z >= 9.9]))
out<-log(nveg+1/(nground+1))*cos((ScanAngle*pi/180)/0.5)
return(list(LAI=out))
}
Calc_LAI(MixedConifer)#throws error that Duplicate elements are found and at least one metric was not a number
##Running the function elements directly on example data set
las<-MixedConifer
las<-add_attribute(las, paste(las$gpstime, las$ReturnNumber, sep="_"), "UID")
dem<-rasterize_terrain(las, res=1, algorithm = knnidw())
norm<-las-dem
lai_func<-function(ScanAngle, Z, UID){
nground<-length(unique(UID[Z <= 6.6]))
nveg<-length(unique(UID[Z >= 9.9]))
out<-log(nveg+1/(nground+1))*cos((ScanAngle*pi/180)/0.5)
return(list(LAI=out))
}
LAI<-pixel_metrics(las=norm, func=lai_func(ScanAngle=ScanAngleRank, Z=Z, UID=UID), res=9.9) #throw the duplicate elements error again
抛出错误,发现重复元素并且至少有一个指标不是数字
out<-log(nveg+1/(nground+1))*cos((ScanAngle*pi/180)/0.5)
return(list(LAI=out))
在这里,显然
LAI
不是一个度量(即数字),而是一个大小为 length(ScanAngle)
的向量