利用gdal进行RPC经纬度与像素坐标转换问题记录

这两天测试发现了一个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
相关推荐
Ghost Face...2 小时前
深入解析Loongson LSDC DRM驱动:从原理到实现
linux
用户805533698032 小时前
嵌入式Linux模块学习——`insmod` 底层全流程解剖:从用户命令到内核内存
linux
aningx2 小时前
开机自启modprobe -r kvm_intel
linux
D4c-lovetrain2 小时前
linux实战之多配置部署(ansible、nginx、keepalived、dhcp、dns多元化操作)
linux·运维·服务器
我爱学习好爱好爱2 小时前
Ansible force_handlers delegate委托 playbook语法格式 template模块
linux·运维·ansible
cpp_learners2 小时前
Linux ARM架构 使用 linuxdeployqt 打包QT程序
linux·arm开发·qt
2401_827499992 小时前
python项目实战07-DeepSeek调用测试(本地部署)
linux·运维·服务器
longxibo2 小时前
【Ubuntu datasophon1.2.1 二开之九:验证离线数据入湖】
大数据·linux·运维·ubuntu
似水এ᭄往昔2 小时前
【Linux】--命令行参数和环境变量
linux·运维·服务器