这两天测试发现了一个gdal在RPC转换的极端的问题,其他大部分数据可能也不会出现这个问题。现在特此记录。
目录
问题复现
我在测试转换的时候出现如下情况
我有两个像素点坐标要转换成经纬度,利用gdal自带的方法进行转换,参考代码:
cpp
char** papszTransOption = NULL;
papszTransOption = CSLSetNameValue(papszTransOption, "RPC_DEM", demPath);
void *pRPCTransform = GDALCreateRPCTransformer(&oInfo, FALSE, 0, papszTransOption);
double* dZ = new double[num] { 0 };
int* nSuccess = new int[num] { FALSE };
GDALRPCTransform(pRPCTransform, FALSE, num, PixX, PixY, dZ, nSuccess);//FALSE
memcpy(lon, PixX, sizeof(double)*num);
memcpy(lat, PixY, sizeof(double)*num);
对结果进行观察的时候发现有些是inf的问题,如下图。

出现这个问题,一般是DEM有问题导致,经过测试,更换DEM影像,这里可以计算出来正确结果。
以前从来没有注意过这个问题,同时我还怀疑是不是gdal版本太低导致的,将gdal升级为最新的3.12.0进行测试,这里计算出来的结果依然如此,所以可以说明这种方法计算出来的经纬度并不牢靠,需要对计算的结果进一步进行inf判断才行,否则极端条件下可能会莫名出错。
cpp
for(int i = 0;i< num;i++)
{
if(std::isinf(lon[i])||std::isinf(lat[i]))
{
printf("Error: fail Pix2Geo_GDALRPC !\n");
printf("PixX:%lf,PixY:%lf -> Lng:%lf,Lat:%lf\n",PixX[i],PixY[i],lon[i],lat[i]);
return false;
}
}
另一种解决方案就是通过算法来自己拟合计算,我后面要进一步验证
用gdal 3.12.0测试遇到的一些问题
经纬度颠倒的问题
平时使用的是gdal2版本,这次在升级到最新的gdal3,测试发现大部分功能是没有问题的,主要一个问题是经纬度转换的时候,输出的经纬度坐标反过来了

解决方案
经过百度查询:

用了它给出的解决方案,需要在代码中加入强制转换经度、纬度顺序,经过设置后转换的结果正确了
bash
OGRSpatialReference srcSRS;
srcSRS.SetWellKnownGeogCS("WGS84");
// 强制使用 longitude, latitude 顺序
srcSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); // 关键!
OGRSpatialReference dstSRS;
// ... 设置目标坐标系
dstSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); // 同样设置
OGRCoordinateTransformation* trans = OGRCreateCoordinateTransformation(&srcSRS, &dstSRS);
编译过程
下载安装包
bash
# 进入工作目录
cd ~/gdal_build
# 下载 GDAL
wget https://github.com/OSGeo/gdal/releases/download/v3.12.0/gdal-3.12.0.tar.gz
# 下载 PROJ 9.7.1
wget https://download.osgeo.org/proj/proj-9.7.1.tar.gz
# 下载 GEOS 3.12.0
wget https://download.osgeo.org/geos/geos-3.12.0.tar.bz2
编译PROJ 9.7.1
编译顺序
bash
tar -xzf proj-9.7.1.tar.gz
cd proj-9.7.1
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
sudo make -j$(nproc)
sudo make install
# 刷新动态库缓存
sudo ldconfig
验证是否编译成功
bash
# 检查 PROJ 版本
proj --version
# 预期输出:Rel. 9.7.1, December 1st, 2025
# 检查库文件
ls -la /usr/local/lib/libproj*
# 应该看到 libproj.so.29.1.1 等文件
编译geos
编译顺序:
bash
tar -xjf geos-3.12.0.tar.bz2
cd geos-3.12.0
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
make -j$(nproc)
sudo make install
# 刷新动态库缓存
sudo ldconfig
验证是否编译成功
bash
# 方法1:检查 geos-config 工具
geos-config --version
# 预期输出:3.12.0
# 方法2:运行 geosop 工具
geosop --version
# 预期输出:3.12.0
# 方法3:检查库文件
ls -la /usr/local/lib/libgeos*
# 应该看到 libgeos.so.3.12.0 等文件
编译gdal
bash
# 解压并进入 GDAL 源码
tar -xzf gdal-3.12.0.tar.gz
cd gdal-3.12.0
mkdir build && cd build
# 关键配置:指定依赖库路径
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DPROJ_ROOT=/usr/local \
-DGEOS_ROOT=/usr/local \
-DGDAL_USE_MUPARSER=ON
# 编译并安装
make -j$(nproc)
sudo make install
# 刷新动态库缓存
sudo ldconfig
如果配置出错,有可能是muparser 开发库没有安装的问题
bash
# 安装 muparser 开发包(测试成功了)
sudo apt install libmuparser-dev
#或者在配置gdal的时候禁用muparser (我没有测试,AI提醒可以这么设置)
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DPROJ_ROOT=/usr/local \
-DGEOS_ROOT=/usr/local \
-DGDAL_USE_MUPARSER=OFF
验证编译是否成功
bash
# 检查 GDAL 版本
gdalinfo --version
# 预期输出:GDAL 3.12.0, released 2025/xx/xx