1 引言

最近终于将使用的GDAL 2.X升级到成了3.X版本,总结一下遇到的各种问题。

2 详论

2.1 数据路径

GDAL 3.X以后深度依赖PROJ库,以前只是可选构建项,现在已经是必须构建项了。最直接的体现是如果涉及到空间参考相关的内容时,除了要配置GDAL_DATA环境变量,还必须配置PROJ_DATA环境变量。GDAL_DATA和PROJ_DATA分别是GDAL和PROJ库的数据,里面存储了一些空间参考相关的参数,因此一般在使用GDAL之前,需要配置一下相关的路径:

string gdalDir = shareDataDir + string("/gdal");
CPLSetConfigOption("GDAL_DATA", gdalDir.c_str()); std::string projDir = shareDataDir + string("/proj");
CPLSetConfigOption("PROJ_DATA", projDir.c_str());

这些数据一般在构建的时候会安装到指定的目录的share文件夹内,如下图所示:

注意以下几点:

  1. 经过笔者的测试,一般设置PROJ_DATA目录就可以了。但是有的资料显示还必须继续设置GDAL_DATA目录。因为GDAL_DATA目录中可能保存的不仅仅是空间参考信息,可能保存了很多GIS相关的数据。
  2. 另外,很多资料推荐直接设置操作系统的环境变量。这样做不是不行,前提是与操作系统的其他GDAL环境不冲突。如果你安装过QGIS或者PostGIS等环境就知道,这些程序也会在操作系统中设置GDAL_DATA、PROJ_DATA环境变量,那么就只能像笔者这样在程序中配置。
  3. 在PROJ 9.1版本以前,PROJ数据的环境变量名为PROJ_LIB;在后续版本中优先使用PROJ_DATA,PROJ_LIB还会使用一段时间,但是最好替换成PROJ_DATA,避免后续的版本废弃。

2.2 坐标顺序

GDAL升级到3.X后另外一个问题就是坐标顺序的问题。例如如果要进行空间参考坐标转换:

// CGCS2000
gcs.importFromEPSG(4326); // Tm投影
pcs.importFromEPSG(3857); OGRCoordinateTransformation* lonLat2XY =
OGRCreateCoordinateTransformation(&gcs, &pcs);
OGRCoordinateTransformation* xy2LonLat =
OGRCreateCoordinateTransformation(&pcs, &gcs);
if (!lonLat2XY || !xy2LonLat) {
return 1;
} double x = 113.6;
double y = 38.8;
printf("经纬度坐标:%.9lf\t%.9lf\n", x, y);
if (!lonLat2XY->Transform(1, &x, &y)) {
return 1;
}
printf("平面坐标:%.9lf\t%.9lf\n", x, y); if (!xy2LonLat->Transform(1, &x, &y)) {
return 1;
}
printf("再次转换回的经纬度坐标:%.9lf\t%.9lf\n", x, y); OGRCoordinateTransformation::DestroyCT(lonLat2XY);
lonLat2XY = nullptr;
OGRCoordinateTransformation::DestroyCT(xy2LonLat);
xy2LonLat = nullptr;

这段代码在3.X的结果就不正确。原因是GDAL 3.X更换了坐标轴的顺序,认为y在前,x在后才是更加专业的坐标表达。不过这样就破坏了向后兼容性。解决方案是给空间参考设置轴策略为传统顺序[1]

// CGCS2000
gcs.importFromEPSG(4326); // Tm投影
pcs.importFromEPSG(3857); gcs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
pcs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); //...

想这样一个一个坐标参考修改很麻烦,另一个更加合适的办法是设置全局的坐标轴策略为传统顺序[2]

// 设置全局坐标顺序为传统GIS顺序(经度,纬度)
CPLSetConfigOption("OGR_CT_FORCE_TRADITIONAL_GIS_ORDER", "YES");

3 总结

最好的办法就是在程序的最开始阶段执行一个初始化函数:

void Init(const char *shareDataDir) { 

  GDALAllRegister();  //注册所有的格式
CPLSetConfigOption("SHAPE_ENCODING", ""); //解决中文乱码问题 string gdalDir = shareDataDir + string("/gdal");
CPLSetConfigOption("GDAL_DATA", gdalDir.c_str()); std::string projDir = shareDataDir + string("/proj");
CPLSetConfigOption("PROJ_DATA", projDir.c_str()); // 设置全局坐标顺序为传统GIS顺序(经度,纬度)
CPLSetConfigOption("OGR_CT_FORCE_TRADITIONAL_GIS_ORDER", "YES");
}

  1. GDAL 3.0 Coordinate transformation (backwards compatibility (?))

  2. Problem with GDAL >= 3.0

GDAL 2.X升级3.X需要注意的问题总结的更多相关文章

  1. VS2015下编译64位GDAL总结

    使用VS2015编译最新的64位GDAL(最新gdal2.11),确实有一些问题,看来双方还是太新了,有点不兼容,特总结如下. 以前经常用的通过VisualStudio IDE进行编译的方式现在似乎不 ...

  2. GDAL库简介以及在Windows下编译过程

    GDAL(Geospatial Data Abstraction Library,地理空间数据抽象库)是一个在X/MIT许可协议下的开源栅格空间数据转换库.官网http://www.gdal.org/ ...

  3. Proj.4 升级新版本5.x和6.x

    目录 Proj.4 升级新版本5.x和6.x 0.缘起 1.5.x和6.x更新情况简述 PROJ 5.x 更新 PROJ 6.x 更新 2.从PROJ.4向新版本迁移 迁移到5.x版本 迁移到6.x版 ...

  4. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  5. 看完SQL Server 2014 Q/A答疑集锦:想不升级都难!

    看完SQL Server 2014 Q/A答疑集锦:想不升级都难! 转载自:http://mp.weixin.qq.com/s/5rZCgnMKmJqeC7hbe4CZ_g 本期嘉宾为微软技术中心技术 ...

  6. Entity Framework Core 1.1 升级通告

    原文地址:https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/ 翻译:杨晓东 ...

  7. ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录

    升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...

  8. SQL Server2016升级前几点自检

    SQL Server2016已经出来一段时间了,而且最新的SP1包也于2016年11月18日正式发布,各种新的特性推出让我们跃跃欲试.那么对于我们真实的业务环境,特别是生产环境要不要"跟风& ...

  9. 如何安全的将VMware vCenter Server使用的SQL Server Express数据库平滑升级到完整版

    背景: 由于建设初期使用的vSphere vCenter for Windows版,其中安装自动化过程中会使用SQL Server Express的免费版数据库进行基础环境构建.而此时随着业务量的增加 ...

  10. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 3.安装Clus ...

随机推荐

  1. PanWeiDB2.0异构数据库访问测试

    PanWeiDB2.0异构数据库访问测试 异构数据库访问兼容性测试一览表 No 访问路径 多维度结果 备注 1 PanWeiDB(集中式)-访问-PanWeiDB(集中式) √ 支持复杂SQL 2 P ...

  2. Nginx: stat() failed (13: permission denied)

    解决 server { listen [::]:80 default_server; # SSL configuration # # listen 443 ssl default_server; # ...

  3. Kubernetes的工作机制

    云计算时代的操作系统 Kubernetes 是一个生产级别的容器编排平台和集群管理系统,能够创建.调度容器,监控.管理服务器. Kubernetes 的基本架构 操作系统的一个重要功能就是抽象,从繁琐 ...

  4. MySQL REPLACE函数:字符串替换

    语法 REPLACE ( string_expression , string_pattern , string_replacement ) 替换字符串,接受3个参数,分别是原字符串,被替代字符串,替 ...

  5. docx4j转换HTML并生成word文档实践

    一.背景 在项目开发中,有一个需求需要将富文本编辑器中的内容转换为word文档.在网上看了很多开源第三方工具包的对比,最终选择了docx4j,主要原因有一下几点: 可以将html转换为word 对wo ...

  6. UML用例图-UML Use Case Diagram

    .wj_nav { display: inline-block; width: 100%; margin-top: 0; margin-bottom: 0.375rem } .wj_nav_1 { p ...

  7. 【JVM之内存与垃圾回收篇】本地方法栈

    本地方法栈 Java 虚拟机栈于管理 Java 方法的调用,而本地方法栈用于管理本地方法的调用. 本地方法栈,也是线程私有的. 允许被实现成固定或者是可动态扩展的内存大小.(在内存溢出方面是相同的) ...

  8. Sql Server执行情况

    --- 1.查找目前SQL Server所执行的SQL语法,并展示资源情况: SELECT s2.dbid , DB_NAME(s2.dbid) AS [数据库名] , --s1.sql_handle ...

  9. 记录-内网部署vllm分布式推理DeepSeekR1:70b

    背景 前段时间接到需求要在内网部署DeepSeekR1:70b,由于手里的服务器和显卡比较差(四台 四块Tesla T4- 16g显存的服务器),先后尝试了ollama.vllm.llamacpp等, ...

  10. FreeRTOS消息队列传递数组

    1.使用消息队列的发送和接收前,需要先创建消息队列 2.消息队列的深度和大小   深度 就是数组的元素个数   大小 就是整个数组占用的空间大小 消息队列的创建 static void AppObjC ...