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

如何将含结构化空间信息的DataFrame转换为Polygon?

问题描述

我有多张如下格式的表格(x、y为WGS84坐标系坐标):

structure(list(x = c(-0.652363144524641, -0.652363144524641, 
-0.626050598958539, -0.626050598958539), y = c(49.0745447700184, 
49.0562285023707, 49.0562285023707, 49.0745447700184), L1 = c(1, 
1, 1, 1), L2 = c(1, 1, 1, 1), id = c(1, 2, 3, 4)), row.names = c(NA, 
-4L), class = "data.frame")

这些表格是我用sf::st_coordinates函数从Polygon类型的原始空间数据转换来的,当时没考虑后续用途。现在我想把每张表格还原为空间Polygon对象,最终要基于这些多边形创建栅格。想请教:能不能把这些表格还原成Polygon,还是必须重新创建原始多边形?欢迎提供建议。

编辑补充:
为回应疑问,以下是sf::st_coordinates处理前的正方形Polygon数据:

structure(list(patches = 1L, geometry = structure(list(structure(list(
    structure(c(3.61026923718395, 3.61026923718395, 3.63658178275005, 
    3.63658178275005, 3.61026923718395, 50.466581111243, 50.4482648435953, 
    50.4482648435953, 50.466581111243, 50.466581111243), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg"))), class = c("sfc_POLYGON", 
"sfc"), precision = 0, bbox = structure(c(xmin = 3.61026923718395, 
ymin = 50.4482648435953, xmax = 3.63658178275005, ymax = 50.466581111243
), class = "bbox"), crs = structure(list(input = "GEOGCRS[\"unknown\",\n    DATUM[\"World Geodetic System 1984\",\n        ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n            LENGTHUNIT[\"metre\",1]],\n        ID[\"EPSG\",6326]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"degree\",0.0174532925199433,\n            ID[\"EPSG\",8901]],\n    CS[ellipsoidal,2],\n        AXIS[\"longitude\",east,\n            ORDER[1],\n            ANGLEUNIT[\"degree\",0.0174532925199433,\n                ID[\"EPSG\",9122]]],\n        AXIS[\"latitude\",north,\n            ORDER[2],\n            ANGLEUNIT[\"degree\",0.0174532925199433,\n                ID[\"EPSG\",9122]]]]", 
    wkt = "GEOGCRS[\"unknown\",\n    DATUM[\"World Geodetic System 1984\",\n        ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n            LENGTHUNIT[\"metre\",1]],\n        ID[\"EPSG\",6326]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"degree\",0.0174532925199433,\n            ID[\"EPSG\",8901]],\n    CS[ellipsoidal,2],\n        AXIS[\"longitude\",east,\n            ORDER[1],\n            ANGLEUNIT[\"degree\",0.0174532925199433,\n                ID[\"EPSG\",9122]]],\n        AXIS[\"latitude\",north,\n            ORDER[2],\n            ANGLEUNIT[\"degree\",0.0174532925199433,\n                ID[\"EPSG\",9122]]]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(patches = NA_integer_), levels = c("constant", 
"aggregate", "identity"), class = "factor"), row.names = 1L, class = c("sf", 
"data.frame"))

处理后的DataFrame数据如下:

structure(list(x = c(3.61026923718395, 3.61026923718395, 3.63658178275005, 
3.63658178275005, 3.61026923718395), y = c(50.466581111243, 50.4482648435953, 
50.4482648435953, 50.466581111243, 50.466581111243), L1 = c(1, 
1, 1, 1, 1), L2 = c(1, 1, 1, 1, 1), id = c("1", "2", "3", "4", 
"5")), row.names = c(NA, -5L), class = "data.frame")
解决方案

完全可以把这些表格还原为Polygon对象,不需要重新创建原始多边形,具体步骤如下:

  1. 补全闭合坐标点
    原始Polygon的坐标是首尾闭合的(比如你提供的正方形示例有5个点,首尾点相同),但st_coordinates处理后的部分表格可能丢失了闭合点。需要手动补全:

    # 以处理后的4点DataFrame为例
    df <- structure(list(x = c(3.61026923718395, 3.61026923718395, 3.63658178275005, 
    3.63658178275005), y = c(50.466581111243, 50.4482648435953, 
    50.4482648435953, 50.466581111243), L1 = c(1, 1, 1, 1), L2 = c(1, 1, 1, 1), id = c(1, 2, 3, 4)), row.names = c(NA, -4L), class = "data.frame")
    
    # 复制第一行到末尾,完成坐标闭合
    df_closed <- rbind(df, df[1, ])
    
  2. 转换为sf Polygon对象
    使用sf包的函数重新构建空间对象:

    library(sf)
    
    # 提取坐标并转为矩阵
    coords <- matrix(c(df_closed$x, df_closed$y), ncol = 2)
    
    # 创建单个多边形的sfg对象
    poly_sfg <- st_polygon(list(coords))
    
    # 创建sfc对象并设置WGS84坐标系(EPSG:4326)
    poly_sfc <- st_sfc(poly_sfg, crs = 4326)
    
    # 结合属性列生成完整的sf数据框
    poly_sf <- st_sf(
      L1 = unique(df$L1), 
      L2 = unique(df$L2), 
      geometry = poly_sfc
    )
    
  3. 批量处理多张表格
    如果有多个这类DataFrame,可以用循环或purrr批量转换:

    library(purrr)
    
    # 假设所有表格都存在df_list列表中
    df_list <- list(df1, df2, df3)
    
    # 定义通用转换函数
    df_to_poly <- function(df) {
      df_closed <- rbind(df, df[1, ])
      coords <- matrix(c(df_closed$x, df_closed$y), ncol = 2)
      poly_sfg <- st_polygon(list(coords))
      poly_sfc <- st_sfc(poly_sfg, crs = 4326)
      st_sf(
        L1 = unique(df$L1), 
        L2 = unique(df$L2), 
        geometry = poly_sfc
      )
    }
    
    # 批量转换
    poly_list <- map(df_list, df_to_poly)
    
    # 合并为单个sf对象(按需选择)
    all_polys <- do.call(rbind, poly_list)
    
  4. 验证与栅格化
    转换完成后可检查多边形有效性,再用terra或raster包创建栅格:

    library(terra)
    
    # 检查多边形有效性
    st_is_valid(poly_sf)
    
    # 创建空栅格模板
    r <- rast(all_polys, resolution = 0.001)
    
    # 将多边形栅格化
    rasterized <- rasterize(all_polys, r, field = "L1")
    

注意事项:

  • 确保每个DataFrame对应单个多边形,坐标点按顺序排列(顺时针/逆时针均可)。
  • 如果原始多边形包含洞,st_coordinates会输出hole列,需要额外分组处理环的坐标,你的示例无此情况,暂无需考虑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:35:56