使用gdal_translate裁剪Sentinel-1影像时出现负宽高错误求助
嘿,我来帮你搞定这个头疼的问题!你遇到的ERROR 1: Error: Computed -srcwin 4.5 52 0 0 has negative width and/or height错误,大概率和坐标系不匹配、projwin参数的细节没注意有关——毕竟Sentinel-1的产品坐标系经常是UTM,而你用的是经纬度坐标,咱们一步步排查解决:
1. 先确认输入TIFF的坐标系
首先得搞清楚你的Sentinel-1 TIFF用的是什么坐标系,因为projwin的坐标必须和文件坐标系完全对应才有效。你可以在R里用这几行代码快速查看:
library(raster) r <- raster('from.tiff') crs(r) # 输出会显示坐标系信息,比如UTM或者WGS84
如果输出不是+proj=longlat +datum=WGS84 +no_defs这类经纬度格式,那你直接用c(4.5, 52.4, 4.7, 52.2)(经纬度)作为projwin参数肯定会出错——因为gdal会把经纬度当成UTM坐标来计算,自然得出无效的窗口范围。
2. 匹配坐标系再调用gdal_translate
如果你的TIFF是UTM坐标系(Sentinel-1多数产品默认用这个),有两种解决思路:
思路A:把裁剪窗口转成UTM坐标
先把你要的经纬度窗口转换成TIFF对应的UTM坐标系,再传入projwin:
library(sf) # 用经纬度定义裁剪窗口 win_poly <- st_sfc(st_polygon(list(rbind( c(4.5,52.2), c(4.7,52.2), c(4.7,52.4), c(4.5,52.4), c(4.5,52.2) )))) st_crs(win_poly) <- 4326 # 声明这是WGS84经纬度 # 转换成TIFF的UTM坐标系(假设你的TIFF是EPSG:32631,要换成你实际的EPSG码) win_utm <- st_transform(win_poly, crs = 32631) # 提取projwin需要的参数:xmin, ymax, xmax, ymin win_bbox <- st_bbox(win_utm) projwin_args <- c(win_bbox$xmin, win_bbox$ymax, win_bbox$xmax, win_bbox$ymin) # 重新调用gdal_translate gdal_translate('from.tiff', 'to.tiff', projwin = projwin_args)
思路B:先把TIFF转成WGS84再裁剪
如果你不想折腾坐标转换,也可以先把TIFF转成经纬度坐标系,再用你原来的projwin参数:
gdalwarp('from.tiff', 'from_wgs84.tiff', t_srs = 'EPSG:4326') # 现在用原来的projwin参数裁剪 gdal_translate('from_wgs84.tiff', 'to.tiff', projwin = c(4.5, 52.4, 4.7, 52.2))
3. 排查窗口是否完全超出TIFF范围
还有一种小概率情况:你指定的裁剪窗口和TIFF的覆盖范围完全不重叠,导致gdal计算出的宽高为0或负数。你可以用这个代码查看TIFF的范围:
extent(r)
对比你的projwin坐标,确认窗口确实落在TIFF的范围内。
4. 换个更直观的工具:用raster包的crop函数
如果gdal的参数实在绕不清,试试R的raster包裁剪,它会自动处理坐标系匹配(只要你给的范围和TIFF坐标系一致),步骤更简单:
library(raster) r <- raster('from.tiff') # 定义裁剪范围:xmin, xmax, ymin, ymax crop_range <- extent(4.5, 4.7, 52.2, 52.4) # 裁剪并保存 r_cropped <- crop(r, crop_range) writeRaster(r_cropped, 'to.tiff', format = 'GTiff')
内容的提问来源于stack exchange,提问作者Daan

