【问题标题】:How to reconstruct an sf object from the coordinate matrix made by st_coordinates?如何从 st_coordinates 制作的坐标矩阵重建一个 sf 对象?
【发布时间】:2020-12-18 17:47:55
【问题描述】:

st_coordinates 为简单特征列中的所有环提供坐标矩阵(对于每个简单特征几何、所有多边形的外环和孔)。有没有办法进行相反的操作,即从与st_coordinates 的输出格式相同的矩阵构建 sfc?

提醒一下,这里是st_coordinates 输出的结构:

        X   Y L1 L2 L3
 [1,]   0   0  1  1  1
 [2,] -10   0  1  1  1
 [3,] -10 -10  1  1  1
 [4,]   0 -10  1  1  1
 [5,]   0   0  1  1  1
 [6,]   1   1  1  1  2
 [7,]  11   1  1  1  2
 [8,]  11  11  1  1  2
 [9,]   1  11  1  1  2
[10,]   1   1  1  1  2
[11,]   2   2  2  1  2
[12,]   3   2  2  1  2
[13,]   3   3  2  1  2
[14,]   2   3  2  1  2
[15,]   2   2  2  1  2
[16,]   5  -2  1  2  2
[17,]  10  -2  1  2  2
[18,]  10  -1  1  2  2
[19,]   5  -1  1  2  2
[20,]   5  -2  1  2  2

对应这张图片:

如何制作sf对象?

【问题讨论】:

    标签: coordinates sf


    【解决方案1】:

    通过使用 data.frame 可以做到:

    library(sf)
    library(tidyverse)
    d <- 
      structure(list(X = c(0L, -10L, -10L, 0L, 0L, 1L, 11L, 11L, 1L, 
                           1L, 2L, 3L, 3L, 2L, 2L, 5L, 10L, 10L, 5L, 5L), 
                     Y = c(0L, 0L, -10L, -10L, 0L, 1L, 1L, 11L, 11L, 1L, 2L, 2L, 3L, 
                           3L, 2L, -2L, -2L, -1L, -1L, -2L),
                     L1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
                            2L, 1L, 1L, 1L, 1L, 1L), 
                     L2 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
                            1L, 2L, 2L, 2L, 2L, 2L), 
                     L3 = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                            2L, 2L, 2L, 2L, 2L, 2L)), 
                class = "data.frame", row.names = c(NA, -20L))   %>% 
      st_as_sf(coords = c("X", "Y")) %>% 
      group_by(L1, L2, L3) %>% 
      summarise(do_union = FALSE) %>% 
      st_cast("LINESTRING")
    # to visualise
    d %>% 
      ggplot() +
      geom_sf()
    # to generate polygons
    d %>% 
      st_cast("POLYGON") %>% 
      ggplot() +
      geom_sf()
    

    附录

    对 Jean-Luc Dupouey 关于洞的正义评论的回应,我想这段代码应该解决这个问题:

    d.po <-
      d %>% 
      group_by(L2, L3) %>% 
      summarise(do_union = FALSE) %>% 
      st_cast("MULTILINESTRING") %>% 
      st_cast("MULTIPOLYGON") %>% 
      ungroup()
    # visualise
    d.po %>% 
      unite("group", L2:L3) %>% 
      ggplot() +
      geom_sf(aes(fill = group))
    

    【讨论】:

    • 感谢@einar 的提议。但是,它不会产生正确的对象。未渲​​染孔(L1 列,根据 sf 规范)。
    【解决方案2】:

    是的,你可以。一种可能的方法是使用sf::st_polygon() 调用。

    调用需要列表格式的参数 - 第一项是外边界,然后是所需的孔。

    以这个代码为例,它建立在广为人知且深受喜爱的 NC shapefile 之上。

    它所做的是将梅克伦堡县分解为边界坐标矩阵,然后将其构建为sfg >> sfc >> sf 对象。

    library(sf)
    library(dplyr)
    library(ggplot2)
    
    shape <- st_read(system.file("shape/nc.shp", package="sf")) %>%  
      filter(CNTY_ID == 2041) # Mecklenburg, as in Charlotte of Mecklenburg-Strelitz
    
    #coordinates of Mecklenburg cnty
    coords <- st_coordinates(shape)
    
    class(coords)
    [1] "matrix" "array" 
    
    head(coords)
                 X        Y L1 L2 L3
    [1,] -81.04930 35.15153  1  1  1
    [2,] -81.02396 35.14903  1  1  1
    [3,] -81.00728 35.16325  1  1  1
    [4,] -81.00152 35.19599  1  1  1
    [5,] -81.01405 35.24990  1  1  1
    [6,] -80.97964 35.33327  1  1  1
    
    #a polygon from coords
    meck_cnty <- st_polygon(x = list(coords[, 1:2])) %>%  # just X and Y please
      st_sfc() %>%  # from sfg to sfc
      st_sf() # from sfc to sf
    
    class(meck_cnty)
    [1] "sf"         "data.frame"
    
    plot(meck_cnty)
    

    【讨论】:

    • 谢谢。但是您的代码仅适用于一个多边形。我的问题是针对一般 sf 对象,例如最初问题中给出的矩阵(包括多面体、孔......)。
    • 原则上应该可以构建 st_multipolygon() 调用所需的列表列表 - 通过嵌套的 for 循环或 lapply 调用 - 基于 L1、L2 和 L3 返回值的组合st_coordinates打电话;唯一需要的假设似乎只是您是在重建多多边形还是多线。不幸的是,我手头上还没有准备好执行此操作的代码。
    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2021-04-01
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多