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

为何自定义PROJ变换管线在GDALReprojectImage中未生效?

问题描述

我在使用GDAL的GDALReprojectImage对GeoTIFF影像重投影时,应用了基于PROJ的+proj=pipeline定义的自定义变换管线。代码能生成输出影像,但管线定义的变换未生效——输出与默认重投影结果一致。

PROJ调试日志(PROJ_TRACE)显示管线已被正确解析,但变换步骤被忽略。使用gdalwarp测试该管线时结果正常。

自定义变换管线(无需验证正确性)

+proj=pipeline
+step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel
+step +inv +proj=hgridshift +grids=Slovakia_JTSK03_to_JTSK.gsb
+step +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel
+step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel
+step +proj=push +v_3
+step +proj=cart +ellps=bessel
+step +proj=helmert +x=485.021 +y=169.465 +z=483.839 +rx=-7.786342 +ry=-4.397554 +rz=-4.102655 +s=0 +convention=coordinate_frame
+step +inv +proj=cart +ellps=WGS84
+step +proj=pop +v_3
+step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84

Rust代码片段(基于gdal-sys)

unsafe {
    let source_wkt = CString::new("EPSG:8353").unwrap();
    let target_wkt = CString::new("EPSG:3857").unwrap();

    let warp_options = GDALCreateWarpOptions();

    let option1 = CString::new(format!("COORDINATE_OPERATION={pipeline}")).unwrap();
    let mut options: Vec<*mut i8> = vec![option1.into_raw(), ptr::null_mut()];

    let gen_img_proj_transformer = GDALCreateGenImgProjTransformer2(
        source_ds.c_dataset(),
        target_dataset.c_dataset(),
        options.as_mut_ptr(),
    );

    if gen_img_proj_transformer.is_null() {
        panic!("Failed to create image projection transformer");
    }

    (*warp_options).pTransformerArg = gen_img_proj_transformer;
    (*warp_options).pfnTransformer = Some(GDALGenImgProjTransform);
    (*warp_options).eResampleAlg = GDALResampleAlg::GRA_Lanczos;
    (*warp_options).hSrcDS = source_ds.c_dataset();
    (*warp_options).hDstDS = target_dataset.c_dataset();

    let warp_result = GDALReprojectImage(
        source_ds.c_dataset(),
        source_wkt.as_ptr(),
        target_dataset.c_dataset(),
        target_wkt.as_ptr(),
        GDALResampleAlg::GRA_Lanczos,
        0.0,
        0.0,
        None,
        ptr::null_mut(),
        warp_options,
    );

    drop(CString::from_raw(options[0]));
    GDALDestroyWarpOptions(warp_options);
    GDALDestroyGenImgProjTransformer(gen_img_proj_transformer);

    assert!(warp_result == CPLErr::CE_None, "Reprojection failed");
}

调试详情

PROJ调试日志显示管线已被正确解析:

PROJ_TRACE: pipeline: Pipeline: init - inv, 9
PROJ_TRACE: pipeline:     proj=krovak
PROJ_TRACE: pipeline:     lat_0=49.5
PROJ_TRACE: pipeline:     lon_0=24.8333333333333
...
PROJ_TRACE: pipeline: Pipeline: Building arg list for step no. 1
PROJ_TRACE: pipeline: Pipeline: init - inv, 3
PROJ_TRACE: pipeline:     proj=hgridshift
PROJ_TRACE: pipeline:     grids=Slovakia_JTSK03_to_JTSK.gsb
PROJ_TRACE: hgridshift: pj_ellipsoid - final: a=6378137.000 f=1/298.257, errno=0
PROJ_TRACE: hgridshift: pj_ellipsoid - final:    ellps=GRS80

已确认使用相同参数的gdalwarp命令可生成正确输出:

gdalwarp -s_srs EPSG:8353 -t_srs EPSG:3857 -ct "+proj=pipeline ..." source.tif warped.tif

执行过程中无日志错误或返回值错误。


核心问题

  1. 为何自定义变换管线在GDALReprojectImage中被忽略?
  2. 是否需要额外步骤或配置以确保管线正确应用?
  3. 是否应使用其他GDAL函数(如GDALWarp)来实现此需求?

希望获得GDAL开发者或有PROJ自定义变换管线使用经验的用户指导,任何建议都将不胜感激。


内容的提问来源于stack exchange,提问作者Martin Ždila

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:39:59