如何将含结构化空间信息的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对象,不需要重新创建原始多边形,具体步骤如下:
补全闭合坐标点
原始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, ])转换为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 )批量处理多张表格
如果有多个这类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)验证与栅格化
转换完成后可检查多边形有效性,再用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
相关产品推荐
相关产品推荐

