r-创建一个已知面积的圆



我想创建一个面积为100的圆作为sf对象。我原以为st_buffer((可以做到,但面积是略小于100。

pt.df   <- data.frame(pt = 1, x = 20, y = 20)
pt.sf   <- st_as_sf(pt.df, coords = c("x", "y")) 
circle1 <- st_buffer(pt.sf, dist = sqrt(100 / pi))
st_area(circle1)  # 99.95431 on my PC

我可以用一个模糊因子乘以半径,得到我想要的。

fudge    <- sqrt( 100 / st_area(circle1) )
circle2  <- st_buffer(pt.sf, dist = fudge * sqrt(100 / pi))
st_area(circle2)  # 100

但是,使用捏造因素似乎很愚蠢。

有没有一种方法可以在sf包中创建一个已知区域的圆圈st_buffer中的一个伪造因素?

用圆周率的截断形式计算半径是一个浮点精度问题。这将导致一个比你想要的输出稍小的圆圈。你可以看到π只能存储到机器精度:

.Machine$double.eps
# 2.22044604925031e-16
pi
# 3.14159265358979

如果要进行校正,可以对所需区域使用线性校正。请注意,这仍然是一个近似值,但它应该会让你更接近你想要的结果。

radius <- function(area){
A <- area + (area * 0.000457099999999997)
return(sqrt(A / pi))
}
system.file("shape/nc.shp", package="sf") %>% 
st_read() %>% 
st_centroid() %>% 
st_transform(st_crs(5070)) %>% 
st_buffer(radius(100)) %>%
st_area()

主要问题是st_buffer在内部处理多边形,而不是圆形。增加nQuadSegs参数(默认值=30(可以使用更好的圆近似值,但需要花费内存和计算时间(不知道这对你来说是否重要(:

library(sf)
pt.df   <- data.frame(pt = 1, x = 20, y = 20)
pt.sf   <- st_as_sf(pt.df, coords = c("x", "y")) 
get_area <- function(nq) {
circle1 <- st_buffer(pt.sf, dist = sqrt(100 / pi), nQuadSegs=nq)
st_area(circle1)
}
sapply(c(30,100,300,1000), get_area)
## [1] 99.95431 99.99589 99.99954 99.99996

如果你真的想要一个正好100的区域,那么你的问题(以及@AdamTrevisan的答案(所建议的"捏造"就是你的选择(因为将片段数量增加到100万仍然只能让你达到99.9999999999997200461621的区域(。要想真的聪明,你也许可以用内接多边形面积的公式来计算修正系数。。。

最新更新