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

使用gstat执行IDW插值失败,CRS不匹配问题求解

解决gstat执行IDW插值时的CRS不匹配问题

问题描述

执行IDW插值时触发错误:

Error in .local(formula, locations, ...) : sf::st_crs(locations) == sf::st_crs(newdata) is not TRUE

使用的样本数据:

name,long,lat,waterLevel,elevation,depth
EM_01,18.553392,-34.07027,14.4,20.358,63.0
EM_27,18.574777,-34.068709,16.196,19.966,48.0
EM_29,18.613985,-34.053271,18.766,25.477,39.0
EM_20,18.654089,-34.045177,20.102,36.502,45.0
EM_23,18.643495,-34.037468,22.915,32.715,33.0
EM_13,18.637267,-34.029194,25.516,29.716,33.0

错误原因

你将栅格对象grid2km转为普通数据框grid2km.df后,数据框仅保留了X/Y坐标数值,丢失了空间参考(CRS)信息。idw函数要求输入的newdata必须是带CRS的空间对象(sf/Spatial类),无法识别普通数据框的空间属性,因此触发CRS不匹配报错。

修正方案

以下两种方法均可解决问题,核心是确保插值网格保留CRS信息:

方法1:将栅格转为sf空间对象

install.packages("sf")
install.packages("gstat")
install.packages("units")
install.packages("terra")

library(sf) 
library(gstat)
library(units)
library(terra) 

file = 'text.txt'

# 导入数据
cfaq <- read.csv(file, header = 1, sep = ',', dec = '.') 

# 转为sf对象并设置初始CRS
cfaq.sf <- st_as_sf(cfaq, coords=c("long", "lat"), crs = 4326) 

# 转换为本地投影(32734)
cfaq.sf <- st_transform(cfaq.sf, crs = 32734)

# 计算栅格边界
min_x <- floor(min(st_coordinates(cfaq.sf)[,1])/1000)*1000
max_x <- ceiling(max(st_coordinates(cfaq.sf)[,1])/1000)*1000
min_y <- floor(min(st_coordinates(cfaq.sf)[,2])/1000)*1000
max_y <- ceiling(max(st_coordinates(cfaq.sf)[,2])/1000)*1000

# 构建空栅格(用WKT格式CRS更稳定)
grid2km <- rast(
  xmin=min_x, xmax=max_x,
  ymin=min_y, ymax=max_y, 
  crs = st_crs(cfaq.sf)$wkt,
  resolution = 2000, 
  names="waterLevel"
)

# 将栅格转为带CRS的sf点对象
grid_sf <- st_as_sf(grid2km, na.rm = FALSE)

# 执行IDW插值
idw_result <- idw(log(waterLevel) ~ 1, cfaq.sf, grid_sf, idp = 0.5)

# 可选:将插值结果转回栅格,方便可视化
idw_rast <- rasterize(idw_result, grid2km, field = "var1.pred")

方法2:使用terra::interpolate直接插值

# 前面数据导入、投影转换步骤和方法1一致

# 构建空栅格
grid2km <- rast(
  xmin=min_x, xmax=max_x,
  ymin=min_y, ymax=max_y, 
  crs = st_crs(cfaq.sf)$wkt,
  resolution = 2000, 
  names="waterLevel"
)

# 创建IDW模型
idw_model <- gstat(formula = log(waterLevel) ~ 1, data = cfaq.sf, idp = 0.5)

# 直接在栅格上执行插值
idw_rast <- interpolate(grid2km, idw_model)

关键注意事项

  • 不要随意将空间对象转为普通数据框,若必须转换,需手动将其转为带CRS的sf对象
  • 优先使用WKT格式的CRS(st_crs(obj)$wkt),proj4string格式已逐渐被弃用
  • 插值前可通过st_crs(cfaq.sf) == st_crs(grid_sf)检查样本点与网格的CRS是否一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:07:24