R i 有没有一种方法可以基于代表 2 个不同常量值的两个多边形创建一个新的多边形(代表某个常量值)

问题描述 投票:0回答:1
  1. 我有两个多边形,一个外多边形和一个内多边形
  2. 内部多边形是参数的多边形
    pol1
    (红色) 与
    value = 10
  3. 外多边形是参数的多边形
    pol2
    (蓝色) 与
    value = 20
  4. 我需要为位于某处的
    value = 15
    绘制一个多边形
    pol1
    pol2
  5. 之间
  6. 这几乎就像缓冲,但又不完全一样,因为缓冲会 只给我一个恒定的距离。这是某种插值。
  7. 我认为解决方案就像计算从内部多边形
    pol1
    中的颂歌到
    pol2
  8. 最近的边缘的距离
  9. 然后为每个节点插入
    value = 13
    的距离。
  10. 然后计算
    pol3
    的多边形
    value= 13
    的新点。
  11. 我可以乏味地尝试编写这个代码,但我想可能会有一个 更快/更简单的解决方案 有没有任何工具可以帮助我解决 这。我想要一些可以与 R 中的 sf 对象一起使用的东西。

下面的代码仅用于生成

pol1
pol2
我希望有人可以使用它们来创建解决方案。

(实际上,我有一个从 .shp 文件读取的更复杂的 sf 对象,所以如果您有此类文件的示例,我将不胜感激)

 library(sf)


    #polygon1 value=10
    lon = c(21, 22,23,24,22,21)
    lat = c(1,2,1,2,3,1)
    Poly_Coord_df = data.frame(lon, lat)
    pol1 = st_polygon(
        list(
            cbind(
                Poly_Coord_df$lon,
                Poly_Coord_df$lat)
        )
    )
    
    
    
    #polygon2 value =20
    lon = c(21, 20,22,25,22,21)
    lat = c(0,3,5,4,-3,0)
    Poly_Coord_df = data.frame(lon, lat)
    pol2 = st_polygon(
        list(
            cbind(
                Poly_Coord_df$lon,
                Poly_Coord_df$lat)
        )
    )
    
    
    plot(pol2,border="blue")
    plot(pol1,border="red",add=T)

# How to create pol3 with value = 13?
r polygon spatial-interpolation
1个回答
0
投票

正如你所说,这很像缓冲。在我看来,我们可以将其视为在

value
大小的内部多边形周围创建一个缓冲区,并剪切该缓冲区以确保它永远不会在外部多边形之外。

我定义了一个函数来执行此操作,

interpolate_polygon()
。它首先使用
st_buffer()
,然后使用
st_intersection()
与外部多边形进行裁剪。您可以像这样绘制为选定值创建的多边形(原始多边形红色和蓝色,插值多边形为绿色):

vals_to_interpolate <- c(11, 13, 15, 17)
par(mfrow = c(2, 2))
for (val in vals_to_interpolate) {
    plot(pol2, border = "blue", main = sprintf("value: %s", val), cex.main = 3, lwd = 3)
    plot(pol1, border = "red", , lwd = 3, add = T)
    plot(interpolate_polygon(pol2, pol1, val),
        border = "green", , lwd = 3, add = T
    )
}

函数定义

这是

interpolate_polygon()
的定义。

interpolate_polygon <- function(
    p_outer, p_inner, scale_val = 15,
    p_inner_val = 10, p_outer_val = 20,
    outer_buffer = 0.95) {
    # Just return outer polygon if you scale
    # all the way up

    if (scale_val == p_outer_val) {
        return(p_outer)
    }

    # Create a polygon that the inner polygon
    # can never extend past
    p_outer_scaled <- p_outer * outer_buffer
    p_outer_scaled <- p_outer_scaled - st_centroid(p_outer_scaled) + st_centroid(p_outer)

    p_inner_range <- as.matrix(p_inner) |>
        apply(2, range)

    p_outer_range <- as.matrix(p_outer) |>
        apply(2, range)

    max_stretch <- max(abs(p_outer_range - p_inner_range))

    # Create a buffer of appropriate size
    # cubic scaling seems to work
    buffer_val <- scales::rescale(
        scale_val^3,
        c(0, max_stretch),
        c(p_inner_val^3, p_outer_val^3)
    )

    p_scaled <- st_intersection(
        st_buffer(p_inner, buffer_val, joinStyle = "MITRE"),
        p_outer_scaled
    )

    p_scaled
}
© www.soinside.com 2019 - 2024. All rights reserved.