利用pyproj将经纬度投影为平面坐标以及地理坐标系背景知识解读
作者:qiu_xingye
代码示例
import pyproj #定义投影坐标系 proj = pyproj.Proj(proj='tmerc', lon_0=120, lat_0=15, preserve_units=False) #将经纬度投影为平面坐标 print(proj(120, 15))#结果为(0.0, 0.0) #将平面坐标反投影为经纬度坐标 print(proj(0, 0, inverse=True))#结果为(119.99999999999999, 14.999999999999998)
背景知识
地球的三级逼近
地球的自然表面有高山也有洼地,是崎岖不平的,我们要使用数学法则来描述他,就必须找到一个相对规则的数学面。
为此,通过大地水准面 (geoid),参考椭球体(Reference ellipsoid),大地基准面(Geodetic datum)实现对地球表面的三级逼近。
一级逼近:大地水准面
大地水准面是地球表面的第一级逼近。
假设当海水处于完全静止的平衡状态时,从海平面延伸到所有大陆下部,而与地球重力方向处处正交的一个连续、闭合的曲面,这就是大地水准面。
二级逼近:参考椭球体
大地水准面表面仍然是“高低起伏”的,但可以近似成一个规则椭球体,其形状接近一个扁率极小的椭圆绕短轴旋转所形成的规则椭球体,这个椭球体称为地球椭球体。
它是地球的第二级逼近。
参考椭球体(Reference ellipsoid)是一个数学上定义的地球表面,因为是几何模型,可以用长半轴、短半轴和扁率来确定。
一方面,我们对地球形状的测量随着时间迁移而不断精确,另一方面,因为大地水准面并不规则,地球上不同地区往往需要使用不同的参考椭球体,来尽可能适合当地的大地水准面。
比较有名的参考椭球体包括克拉索夫斯基(Krasovsky)参考椭球,WGS-84参考椭球等。
三级逼近:大地基准面
由于参考椭球体是对地球的抽象,因此其并不能与地球表面完全重合,在设置参考椭球体的时候必然会出现有的地方贴近的好(参考椭球体与地球表面位置接近),有地地方贴近的不好的问题,因此这里还需要一个大地基准面来控制参考椭球和地球的相对位置。
这是地球表面的第三级逼近。
有以下两类基准面:
- 地心基准面:由卫星数据得到,使用地球的质心作为原点,使用最广泛的是 WGS1984基准面。
- 区域基准面(参心基准面):特定区域内与地球表面吻合,大地原点是参考椭球与大地水准面相切的点,例如Beijing54、Xian80。我们通常称谓的Beijing54、Xian80坐标系实际上指的是我国的两个大地基准面。
不同基准面通过该基准面向WGS1984基准面的7个转换参数来定义,转换通过相似变换方法实现,具体算法可参考科学出版社1999年出版的《城市地理信息系统标准化指南》第76至86页。
假设Xg、Yg、Zg表示WGS84地心坐标系的三坐标轴,Xt、Yt、Zt表示当地坐标系的三坐标轴,那么自定义基准面的7参数分别为:三个平移参数ΔX、ΔY、ΔZ表示两坐标原点的平移值;三个旋转参数εx、εy、εz表示当地坐标系旋转至与地心坐标系平行时,分别绕Xt、Yt、Zt的旋转角;最后是比例校正因子,用于调整椭球大小。
地理坐标系
地理坐标系包括天文坐标系和大地坐标系。大地坐标系是与地球固连在一起的,与地球同步运动,因而又称地固坐标系。天文坐标系是空间固定的坐标系,与地球自转无关,成为惯性坐标系或天球坐标系,主要用于描述卫星和地球的运动位置和状态。这两种坐标系都又可分为空间直角坐标系和经纬度坐标系。下面重点介绍大地坐标系。
大地坐标系是建立在基于参考椭球的大地基准面上的,因此又分为参心坐标系(建立在参心基准面上)和地心坐标系(建立在地心基准面上),其经纬高定义如下:
- 大地经度:参考椭球面上某点的大地子午面与本初子午面(与参考椭球无关)间的两面角。东正西负。
- 大地纬度 :参考椭球面上某点的法线与赤道平面(与参考椭球无关)的夹角。北正南负。
- 大地高: 指某点沿法线方向到参考椭球面的距离。
投影坐标系
在地球椭球面和平面之间建立点与点之间函数关系的数学方法,称为地图投影。
地球椭球表面是一种不可能展开的曲面,要把这样一个曲面表现到平面上,就会发生裂隙或褶皱。
在投影面上,可运用经纬线的“拉伸”或“压缩”(通过数学手段)来加以避免,以便形成一幅完整的地图,但不可避免会产生变形。
地图投影的变形通常有:长度变形、面积变形和角度变形。具体分类如下:
按变形性质分类:
- 等角投影:角度变形为零(Mercator)
- 等积投影:面积变形为零(Albers)
- 任意投影:长度、角度和面积都存在变形
其中,各种变形相互联系相互影响:等积与等角互斥,等积投影角度变形大,等角投影面积变形大。
从投影面类型划分:
- 横圆柱投影:投影面为横圆柱
- 圆锥投影:投影面为圆锥
- 方位投影:投影面为平面- 从投影面与地球位置关系划分为:
- 正轴投影:投影面中心轴与地轴相互重合
- 斜轴投影:投影面中心轴与地轴斜向相交
- 横轴投影:投影面中心轴与地轴相互垂直
- 相切投影:投影面与椭球体相切 - 相割投影:投影面与椭球体相割
具体的不同的投影变换可参考Projections
既然投影是在地球椭球面和平面之间建立点与点之间函数关系的数学方法,因此描述一个投影坐标系(Projected coordinate systems)须包括对应的大地坐标系(基于大地基准面)和投影方式及相关投影参数。
投影坐标系可以理解为是一个二维地图平面坐标系,在该坐标系下每个点都有一个对应的XY坐标和经纬度坐标。
主要的投影参数如下(不同的投影方式,投影参数一般不同):
标准线
- 概念:投影面与参考椭球的切线或割线。分为标准纬线与标准经线。
- 特点:没有变形,也称主比例尺。
中心线
- 概念:是指中央经线(原点经线)与中央纬线(原点纬线),用来定义图投影的中心或者原点。
- 特点:一般会有变形。 pyproj中的投影变换
在pyproj中Proj类负责地图投影变换(经纬度->XY坐标)和逆变换(XY坐标->经纬度)。Proj类主要由不同投影坐标系的相关参数来初始化。
打印示例代码
proj = pyproj.Proj(proj='tmerc', lon_0=120, lat_0=15, preserve_units=False)
中的proj
或proj.crs
,有:
In [4]: proj = pyproj.Proj(proj='tmerc', lon_0=120, lat_0=15, preserve_units=False) In [5]: proj Out[5]: Proj('+proj=tmerc +lat_0=15 +lon_0=120 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs', preserve_units=True) In [16]: proj.crs Out[16]: <Projected CRS: +proj=tmerc +lon_0=120 +lat_0=15 +type=crs> Name: unknown Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - undefined Coordinate Operation: - name: unknown - method: Transverse Mercator Datum: World Geodetic System 1984 - Ellipsoid: WGS 84 - Prime Meridian: Greenwich
可知该投影坐标系的大地基准面是WGS84,投影变换方式是’tmerc’(横轴魔卡托投影)及其它的一些参数。
Proj类初始化的主要参数如下表所示:
Parameter | Description |
---|---|
+a | Semimajor radius of the ellipsoid axis |
+axis | Axis orientation |
+b | Semiminor radius of the ellipsoid axis |
+ellps | Ellipsoid name (see pyproj.pj_ellps) |
+k | Scaling factor (deprecated) |
+k_0 | Scaling factor |
+lat_0 | Latitude of origin |
+lon_0 | Central meridian |
+lon_wrap | Center longitude to use for wrapping |
+over | Allow longitude output outside -180 to 180 range, disables wrapping (see below) |
+pm | Alternate prime meridian (typically a city name) |
+proj | Projection name (see pyproj.pj_list) |
+units | meters, US survey feet, etc. |
+vunits | vertical units. |
+x_0 | False easting |
+y_0 | False northing |
详细信息可参考Cartographic projection
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。