一、引言

最近研究了一下GIS、测绘学的坐标转换的问题,感觉大部分资料专业性太强,上来就是一通专业性论述;但感觉对于相关从业者来说,其实不必了解那么多背景知识的;就通过GDAL这个工具,来简单总结下坐标转换相关的问题。

GDAL坐标转换其实也是调用proj4来实现,但是proj4有个特别麻烦的地方,就是坐标系描述的部分特别繁复,需要对专业知识有一定的了解。使用GDAL则相对简单很多。

二、地理坐标系

地理坐标系就是常说的经纬度坐标系,比如用GPS直接获取的坐标就是在地理坐标系下获取的。一个真实坐标无论怎么变换,一定会有地理坐标系作为基准,也一定有可以转换出来的经纬度坐标。以国内的情况来说,常用到的地理坐标系有WGS84,beijing54,xian80,CGCS2000这四种。

GDAL可以像proj4那样自定义坐标系,也可以仅通过字符串定义一些常用的坐标系,但本文认为最方便的还是通过EPSG数据库定义的代码来定义一个地理坐标系统;毕竟很多时候需要兼容的地理坐标系很多,全部一个个自定义坐标系太麻烦。

OGRSpatialReference spatialReference;
//spatialReference.importFromEPSG(4326);//WGS84
//spatialReference.importFromEPSG(4214);//BeiJing54
spatialReference.importFromEPSG(4610);//XIAN80
//spatialReference.importFromEPSG(4490);//CGCS2000 char *pszWKT = nullptr;
spatialReference.exportToPrettyWkt(&pszWKT);
cout << pszWKT << endl;
CPLFree(pszWKT);
pszWKT = nullptr;

如上演示了GDAL定义地理坐标系并输出坐标系的信息。四种不同的坐标系只需要改变相应的代码编号,用起来十分方便。最终打印输出了的xian80坐标系信息:



在这里一定要注意,使用这种方式定义地理坐标系一定要通过配置GDAL_DATA路径,否则控制台会输出错误信息:

CPLSetConfigOption("GDAL_DATA", "gdaldata");

“gdaldata”表示一个路径(这里用的是相对路径,当然也可以设置成绝对路径),是GDAL编译完成后会生成的一个目录,里面记录了各种坐标系的参数文件。例如进入这个文件夹,用Excel打开pcs.csv这个文件,就可以看到各种坐标系的参数了。



除了这种方法,也可以在环境变量中设置GDAL_DATA变量来实现。

三、投影平面坐标系

经纬度坐标是曲面上的坐标,曲面上的坐标投影到平面,不同的投影方式就会产生不同的平面坐标;即使是同一种投影方式,不同的参数得到的平面坐标也会不同。也就是说,地理坐标系下的经纬度坐标与投影坐标系下的平面坐标,是一对多的关系而不是一对一的关系。以国内的情况来说,经常用到的投影有横轴墨卡托投影,高斯-克吕格投影和UTM投影。

在Global Mapper中三种投影设置方式如下:







可以看出,高斯-克吕格投影和UTM投影其实都是横轴墨卡托投影,两者都是通过设置带号(Zone)来实现设置横轴墨卡托投影的具体参数(Parameters)。在GDAL里面,高斯-克吕格投影就是通过设置横轴墨卡托投影来实现的。如下演示了一个xian80坐标系,3度带带号38的横轴墨卡托投影。

OGRSpatialReference spatialReference;
spatialReference.importFromEPSG(4610); //XIAN80
spatialReference.SetTM(0, 114, 1.0, 38500000, 0);

设置横轴墨卡托投影的函数SetTM()有六个参数:

参数 设置
dfCenterLat 一般为0
dfCenterLong 中央经线,决定了是哪一投影带
dfScale 一般为1.0,UTM设置为0.9996
dfFalseEasting 一般为500000,高斯-克吕格前面加上带号
dfFalseNorthing 一般为0

用之前方法得到坐标系信息并输出,信息如下:

四、坐标转换

定义好坐标系之后,就可以进行坐标转换了。如下为xian80地理坐标系下某点(113.6,38.8)用高斯-克吕格投影到带平面坐标系:

OGRSpatialReference* pLonLat = spatialReference.CloneGeogCS();
OGRCoordinateTransformation* LonLat2XY = OGRCreateCoordinateTransformation(pLonLat, &spatialReference);
if (!LonLat2XY)
{
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); OGRCoordinateTransformation::DestroyCT(LonLat2XY);
LonLat2XY = nullptr;

这里通过复制之前定义的高斯-克吕格投影平面坐标系得到相同的地理坐标系(当然也可以自定义新坐标系),然后使用OGRCoordinateTransformation::Transform()方法来进行坐标转换。最后的输出结果为:



通过Global Mapper的坐标转换工具来验证结果是否正确:





比较可以发现两者转换的结果基本一致。除此之外,将平面坐标逆投影到地理坐标也是可以的,只需要在OGRCreateCoordinateTransformation()的时候颠倒下顺序即可。

五、其他

1.GDAL默认不编译proj.4,使用的时候需要添加proj.4的支持。

2.同一地理坐标系的投影转换是严密的,但不同地理坐标系之间需要先转换到地心立体坐标系,然后通过七参数转换。

3.可以根据坐标值选择正确的分带,使用这个分带的上下几个分带进行投影问题也不是很大。但是分带差距太大可能有问题,因为投影公式只能在一定范围内有效;即不同的软件对的时候结果比较一致,错的时候结果可能不同。

以上三个问题有时间再做进一步的研究和总结。

六、参考文献

1.GDAL源码剖析(十一)之OGR投影说明

2.墨卡托投影、高斯-克吕格投影、UTM投影及我国分带方法

3.GDAL库学习笔记(五):坐标系之间的转化

4.GIS坐标转换库Proj.4的使用

5.GDAL影像投影转换

GDAL坐标转换的更多相关文章

  1. osgEarth使用笔记1——显示一个数字地球

    目录 1. 概述 2. 实现 2.1. 三维显示 2.2. 二维显示 1. 概述 osgEarth支持.earth格式的文件,里面保存了数字地球相关信息的配置XML,只需要读取这个配置文件,就可以直接 ...

  2. 使用GDAL进行RPC坐标转换

    使用GDAL进行RPC坐标转换 对于高分辨率遥感卫星数据而言,目前几乎都提供了有理函数模型(RFM)来进行图像校正(SPOT系列提供了有理函数模型之外还提供了严格轨道模型).对遥感影像进行校正目前最常 ...

  3. GDAL编译(转)

    一.简单的编译 1.使用VisualStudio IDE编译 首先进入GDAL的源代码目录,可以看到有几个sln为后缀的文件名,比如makegdal10.sln,makegdal80.sln,make ...

  4. C++、GDAL创建shapefile,并向矢量文件中添加网格

    //总体来说这个过程就是构建数据源->构建层->构建要素->构建形状->关闭数据源. //要包含的GDAL头文件 #include <gdal_priv.h> #i ...

  5. GPS坐标转换

    由于经常涉及到GPS程序的编写,现在貌似这个GPS是越来越火,越来越多的朋友在编写GPS程序,估计是个人都会遇到这个GPS坐标转换的问题,很惭愧的是,作为一个测量专业出身的学生,我还得时不时的要把这些 ...

  6. GDAL显示线性shp文件

    http://pan.baidu.com/s/1qWIDphU  (工程文件在vs2008中编写) 1.使用到的技术 GDAL:读取矢量数据 GDI:    绘制矢量数据 2.详细解释 GDI绘图: ...

  7. GDAL的安装和配置(编译proj.4)

    1.下载地址 http://trac.osgeo.org/gdal/wiki/DownloadSource 下面是两个版本: http://pan.baidu.com/s/1bntuXER  (1.1 ...

  8. gdal库的三个使用心得

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近使用gdal库比较多,就谈谈gdal库的一些使用心得. 第一个是GDALOpen的访问权限参数会影响图像的创建金字 ...

  9. AE + GDAL实现影像按标准图幅分割(上)

    最近有个项目,其中有个功能是要将遥感影像按标准图幅分割,一开始用AE的接口,慢的让人抓狂,就改用GDAL,速度提升很大.我主要通过http://blog.csdn.net/liminlu0314/学习 ...

随机推荐

  1. Netty4.x整合SpringBoot2.x使用Protobuf3详解

    前言 本篇文章主要介绍的是SpringBoot整合Netty以及使用Protobuf进行数据传输的相关内容.Protobuf会介绍下用法,至于Netty在netty 之 telnet HelloWor ...

  2. FreeSql 新查询功能介绍

    FreeSql FreeSql 是一个功能强大的 NETStandard 库,用于对象关系映射程序(O/RM),提供了 CodeFirst/DbFirst/CURD/表达式函数/读写分离 等基础封装. ...

  3. renren-fast开源项目解析日志—1、项目的部署

    renren_fast项目解析日志 一.环境搭建 1.后端部署 (1)下载源码 按照步骤,从码云上down了fast,zip的(引maven项目)项目包. (2)安装lombok插件 安装lombok ...

  4. 【原】javascript笔记之this用法

    javascript中的this学习起来相对复杂,最近花了点时间研究,总结起来大概这只有5种情况,相信只要熟悉这5种用法,基本是可以解决所有的this问题,文本不介绍this设计原理,只介绍用法,阅读 ...

  5. DSAPI多功能.NET函数库组件

    DSAPI.dll不定期更新,增加功能,故无法每次都发到网上,如果需要获得最新版DSAPI.dll的,请到QQ群:419130936群共享里下载. 简介     dsapi.dll是一款基于.net平 ...

  6. 对于一个WEB前端初学者,学前端应该注意,有什么技巧

    web前端经验总结需要注意的地方和技巧如下: 1.编程思维 学习web前端开发核心在于一个“编程思维”,因为每段代码都不一样,都需要分别去看,所以只要你掌握了学习web前端的编程思维,那么写程序对于你 ...

  7. SQL学习(1)初学实验:SQL Server基本配置及基本操作

    网络配置.远程连接配置: 防火墙设置: SQL Server的默认端口号是1433. 网络配置: SQLServer Configuration Manager中的客户端协议,众多IP中随便选一个,比 ...

  8. 今年开搞了,搭建一下vue开发环境

    首先-->搞了几天的SpringBoot玩的差不多了,领导直接说, 别项目组需要做前后端分离,说前端缺少人手,没有办法咯,只能硬着头皮去了, 说先学一下'vue',给我个文档让我学学,说是前半年 ...

  9. OutOfMemoryError/OOM/内存溢出异常实例分析--虚拟机栈和本地方法栈溢出

    关于虚拟机栈和本地方法栈,在JVM规范中描述了两种异常: 1.如果线程请求的栈深度大于JVM所允许的深度,将抛出StackOverflowError异常: 2.如果虚拟机在扩展栈时无法申请到足够的内存 ...

  10. Jdk1.8中的HashMap实现原理

    HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. HashM ...