一、引言

最近研究了一下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. 对SVN的落地与实践总结

    现今最为流行的Git是管理很几套很成熟的分支管理策略.而SVN确实也有,但结合现公司的实际场景还是做了些调整和变动. 一.分支命名规则 所有分支命名采用小写字母 + 数字 + 特殊符号 组成 项目分支 ...

  2. 为什么设置overflow为hidden可以清除浮动带来的影响

    1.问题起源 在平时的业务开发写CSS中,为了满足页面布局,元素的浮动特性我们用的不能再多了.使用浮动的确能够解决一些布局问题,但是也带了一些副作用影响,比如,父元素高度塌陷,我们有好几种可以清除浮动 ...

  3. Jedis异常解决:NOAUTH Authentication required

    引言 之前项目能够正常运行,因为默认选择db0,后来新的需求来了,不是默认db0,而是给参数选择db. 修改后代码如下,却报错NOAUTH Authentication required. 解决方法 ...

  4. SpringBoot系列——利用系统环境变量与配置文件的分支选择实现“智能部署”

    前言 通过之前的博客:SpringBoot系列——jar包与war包的部署,我们已经知道了如果实现项目的简单部署,但项目部署的时候最烦的是什么?修改成发布环境对应的配置!数据库连接地址.Eureka注 ...

  5. Spring Boot 2.X 如何快速集成单元测试?

    本文将详细介绍下使用Spring Boot 2.X 集成单元测试,对API(Controller)测试的过程. 一.实现原理 使用MockMvc发起请求,然后执行API中相应的代码,在执行的过程中使m ...

  6. 设计模式之桥接模式——Java语言描述

    桥接适用于把抽象化和实现化解耦,使得二者可以独立变化.这种类型的设计模式属于结构性模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦 这种模式设计到一个作为桥接的接口,使得实体类的功能独立 ...

  7. js 原型,原型链,原型链继承浅析

    对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面

  8. a标签伪类选择器以及伪元素:hover的案例

    1.通过我们的观察发现a标签存在一定的状态1.1默认状态, 从未被访问过1.2被访问过的状态1.3鼠标长按状态1.4鼠标悬停在a标签上状态 2.什么是a标签的伪类选择器?a标签的伪类选择器是专门用来修 ...

  9. C#异步编程----Thread

    一.问题由来 多线程能实现的基础: 1.CPU运行速度太快,硬件处理速度跟不上,所以操作系统进行分时间片管理.这样,宏观角度来说是多线程并发 ,看起来是同一时刻执行了不同的操作.但是从微观角度来讲,同 ...

  10. 每日分享!~ vue JavaScript中为什么可以读取到字符串的长度!(包装对象)

    首先需要知道什么是包装对象? 对象是JavaScript语言下最主要的数据类型,三种原始的值-----数值,字符串,布尔值,在一定条件下会自动的转为对象.也就是原始类型的包装对象: 也就是通过如下方式 ...