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

使用terra::extract处理矢量数据时如何保留XY坐标?

问题:将XY点与行政区划矢量数据关联时保留坐标

我有一组从栅格提取的XY坐标点,想要把它们和所属行政区划(比如点a在纽约、点b在佛蒙特州)关联起来。用terra包的extract函数可以实现点和栅格/矢量数据的关联,但处理矢量数据时,没法用xy=TRUE参数保留XY坐标(这个参数在处理栅格时有效),会报错unused argument (xy = TRUE)。想问处理矢量数据时怎么保留坐标,或者有没有更优化的关联方法?

library(terra)

# 加载示例数据
r <- rast(system.file("ex/elev.tif", package="terra")) # 栅格数据
v <- vect(system.file("ex/lux.shp", package="terra"))  # 矢量行政区划数据

# 生成区域内的采样点
points <- spatSample(r, 5, as.points=TRUE)    
# 查看点坐标
crds(points)
#>             x        y
#> [1,] 5.929167 49.67083
#> [2,] 6.279167 49.94583
#> [3,] 6.487500 49.84583
#> [4,] 6.004167 49.49583
#> [5,] 6.379167 49.62083

# 关联点与矢量数据,但结果不含XY坐标
terra::extract(v, points)
#>   id.y ID_1       NAME_1 ID_2           NAME_2 AREA    POP
#> 1    1    3   Luxembourg    8         Capellen  185  48187
#> 2    2   NA         <NA>   NA             <NA>   NA     NA
#> 3    3   NA         <NA>   NA             <NA>   NA     NA
#> 4    4    3   Luxembourg    9 Esch-sur-Alzette  251 176820
#> 5    5    2 Grevenmacher   12     Grevenmacher  210  29828

# 处理矢量数据时用xy=TRUE会报错
terra::extract(v, points, xy=TRUE)
#> Error in .local(x, y, ...) : unused argument (xy = TRUE)

# 处理栅格数据时xy=TRUE正常工作
terra::extract(r, points, xy=TRUE)
#>   ID elevation        x        y
#> 1  1       323 5.929167 49.67083
#> 2  2        NA 6.279167 49.94583
#> 3  3        NA 6.487500 49.84583
#> 4  4       358 6.004167 49.49583
#> 5  5       283 6.379167 49.62083

解决方案

方法1:手动提取坐标并合并结果

extract处理矢量时返回的结果里有id.y字段,对应输入点的序号,我们可以提取点的坐标后,通过这个序号合并:

# 提取矢量关联结果
vec_extract <- terra::extract(v, points)
# 提取点的坐标并转为数据框,添加id列对应id.y
point_crds <- as.data.frame(crds(points))
point_crds$id.y <- seq(nrow(point_crds))
# 合并坐标与矢量属性
result <- merge(vec_extract, point_crds, by = "id.y")
print(result)
#>   id.y ID_1       NAME_1 ID_2           NAME_2 AREA    POP        x        y
#> 1    1    3   Luxembourg    8         Capellen  185  48187 5.929167 49.67083
#> 2    2   NA         <NA>   NA             <NA>   NA     NA 6.279167 49.94583
#> 3    3   NA         <NA>   NA             <NA>   NA     NA 6.487500 49.84583
#> 4    4    3   Luxembourg    9 Esch-sur-Alzette  251 176820 6.004167 49.49583
#> 5    5    2 Grevenmacher   12     Grevenmacher  210  29828 6.379167 49.62083

方法2:使用terra::intersect直接关联

intersect函数可以直接将点与矢量图层相交,结果会保留点的几何信息(包含坐标)和矢量的属性:

# 点与矢量相交,结果为SpatVector对象
intersect_result <- terra::intersect(points, v)
# 转为数据框查看
as.data.frame(intersect_result)
#>        x        y ID_1       NAME_1 ID_2           NAME_2 AREA    POP
#> 1 5.929167 49.67083    3   Luxembourg    8         Capellen  185  48187
#> 2 6.004167 49.49583    3   Luxembourg    9 Esch-sur-Alzette  251 176820
#> 3 6.379167 49.62083    2 Grevenmacher   12     Grevenmacher  210  29828

注意:intersect只会返回落在矢量范围内的点,不在范围内的点会被过滤掉。如果需要保留所有点(包括无匹配的),可以用left_join:

# 将点转为带ID的数据框
points_df <- cbind(id = seq(nrow(points)), as.data.frame(crds(points)))
# 将矢量属性转为数据框
v_df <- as.data.frame(v)
# 空间连接(左连接保留所有点)
joined_result <- terra::left_join(points, v, by = "geometry")
as.data.frame(joined_result)
#>        x        y id ID_1       NAME_1 ID_2           NAME_2 AREA    POP
#> 1 5.929167 49.67083  1    3   Luxembourg    8         Capellen  185  48187
#> 2 6.279167 49.94583  2   NA         <NA>   NA             <NA>   NA     NA
#> 3 6.487500 49.84583  3   NA         <NA>   NA             <NA>   NA     NA
#> 4 6.004167 49.49583  4    3   Luxembourg    9 Esch-sur-Alzette  251 176820
#> 5 6.379167 49.62083  5    2 Grevenmacher   12     Grevenmacher  210  29828

方法3:使用terra::join进行属性连接

如果已经通过extract得到了关联结果,也可以用join函数将坐标合并进去,逻辑和方法1类似,但更简洁:

# 给points添加id字段
points$id <- seq(nrow(points))
# 提取矢量属性
vec_attr <- terra::extract(v, points)
# 合并点的属性(含坐标)与矢量属性
final_result <- merge(as.data.frame(points), vec_attr, by.x = "id", by.y = "id.y")
print(final_result)
#>   id        x        y ID_1       NAME_1 ID_2           NAME_2 AREA    POP
#> 1  1 5.929167 49.67083    3   Luxembourg    8         Capellen  185  48187
#> 2  2 6.279167 49.94583   NA         <NA>   NA             <NA>   NA     NA
#> 3  3 6.487500 49.84583   NA         <NA>   NA             <NA>   NA     NA
#> 4  4 6.004167 49.49583    3   Luxembourg    9 Esch-sur-Alzette  251 176820
#> 5  5 6.379167 49.62083    2 Grevenmacher   12     Grevenmacher  210  29828

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:56:02