(一)Cartopy中的地图投影
本文将对 Cartopy 中支持的地图投影逐一进行简要介绍,这些投影都是 cartopy.crs 中的类。若要绘制某一类投影的地图,只需将其实例化之后传入 plt.axes()
方法的 projection
参数即可。本文不涉及投影的原理,旨在展示每种地图投影的效果和用法,以便在选择时参考。
1、PlateCarree
PlateCarree 这是Cartopy的默认投影,投影将地物投影到圆柱面上再展开,常用来绘制世界地图。该投影具有经线或纬线方向等度数的特点,因此我个人更喜欢称之为等经纬投影。在Cartopy中进行绘图代码如下:
import matplotlib.pyplot as plt import cartopy.crs as ccrs #1.等经纬投影 nplots = 2 fig = plt.figure(figsize=(6, 6)) for i in range(0, nplots): central_longitude = 0 if i == 0 else 180 ax = fig.add_subplot( nplots, 1, i+1, projection=ccrs.PlateCarree(central_longitude=central_longitude)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
2、AlbersEqualArea
阿尔伯斯投影,又名“正轴等积割圆锥投影”,“双标准纬线等积圆锥投影”。圆锥投影的一种,为阿伯斯(Albers)拟定。纬线为同心圆弧,经线为圆的半径,经线夹角与相应的经差成正比。两条割纬线投影后无任何变形。投影区域面积保持与实地相等。在Cartopy中进行绘图代码如下:
#2.Albers等面积投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(5.1299, 3)) ax = plt.axes(projection=ccrs.AlbersEqualArea()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
3、AzimuthalEquidistant
等距方位投影是指使图上面积和相应的实际地面面积相等的方位投影,分为正轴,横轴、斜轴投影。其中纬线为同心圆弧,经线为圆的半径。在Cartopy中进行绘图代码如下:
#3.等距方位投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.AzimuthalEquidistant( central_latitude=90)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
4、EquidistantConic
等距圆锥投影指沿经线方向长度没有变形的圆锥投影。在这种图上,纬线间距相等,沿经线方向长度没有变形。除经线方向外其它方向的长度都有变形,面积和角度也变形,但变形都不太大。这种投影适于编制各种教学用图和交通图。但在我国使用比较少。在中学使用的世界地图册中的苏联图是采用这种投影。在Cartopy中进行绘图代码如下:
#4.等距圆锥投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(4.9603, 3)) ax = plt.axes(projection=ccrs.EquidistantConic()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
5、LambertConformal
兰勃特投影是由德国数学家兰勃特(J.H.Lambert)拟定的正形圆锥投影。等角圆锥投影。设想用一个正圆锥切于或割于球面,应用等角条件将地球面投影到圆锥面上,然后沿一母线展开成平面。投影后纬线为同心圆圆弧,经线为同心圆半径。没有角度变形,经线长度比和纬线长度比相等。适于制作沿纬线分布的中纬度地区中、小比例尺地图。国际上用此投影编制1∶100万地形图和航空图;在Cartopy中进行绘图代码如下:
#5.兰伯特正形投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(4.2897, 3)) ax = plt.axes(projection=ccrs.LambertConformal()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
6、LambertCylindrical
兰伯特圆锥投影的特例,当圆锥顶角为0°,经线成为平行直线,这就成为圆柱投影了。具有等积的特点,在Cartopy中进行绘图代码如下:
#6.兰伯特圆柱投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(9.4248, 3)) ax = plt.axes(projection=ccrs.LambertCylindrical()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
7、Mercator
墨卡托投影,是正轴等角圆柱投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假想一个与地轴方向一致的圆柱切或割于地球,按等角条件,将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。墨卡托投影在切圆柱投影与割圆柱投影中,最早也是最常用的是切圆柱投影。在Cartopy中进行绘图代码如下:
#7.墨卡托投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3.5091, 3)) ax = plt.axes(projection=ccrs.Mercator()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
8、Miller
米勒圆柱投影是一种折衷圆柱地图投影。该投影是 墨卡托投影的改良型投影,因此,二者在赤道附近几乎相同。虽然米勒投影不会将极点投影到无穷大,但是极点处的畸变仍然非常严重。在Cartopy中进行绘图代码如下:
#8.米勒投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(4.0917, 3)) ax = plt.axes(projection=ccrs.Miller()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
9、Mollweide
摩尔威德投影(Mollweide Projection)是经线投影成为椭圆曲线的一种等面积伪圆柱投影。这一投影是德国数学家摩尔威德(K.B.Mollweide 1774~1825年)于1805年创拟的米勒圆柱投影是一种折衷圆柱地图投影。在Cartopy中进行绘图代码如下:
#9.摩尔威德投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.Mollweide()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
10、Orthographic
正射投影又称“直角投影”。属任意性质的透视方位投影。在Cartopy中进行绘图代码如下:
#10.正射投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.Orthographic()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
11、Robinson
伪圆柱投影。类似于椭圆弧的经线等间距分布,并且以中央子午线为中心向两侧凸出。中央子午线是一条直线,其长度为赤道的 0.51 倍。纬线是直线,在南北纬 38° 之间等间距分布,在此范围外的间距减小。极点的投影是长度为赤道 0.53 倍的直线。该投影基于图表坐标,而不是数学公式。在Cartopy中进行绘图代码如下:
#11.罗宾森投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(5.915, 3)) ax = plt.axes(projection=ccrs.Robinson()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
12、Sinusoidal
该投影也称为桑逊-弗兰斯蒂德地图投影,用于世界地图时,无论是否存在等角变形,它都能保持等积。其替代形式通过中断海洋投影的连续性,并使各大陆在各自中央子午线附近居中,来减小外侧子午线方向上的变形程度,反之亦然。在Cartopy中进行绘图代码如下:
#12.正弦投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6.0101, 3)) ax = plt.axes(projection=ccrs.Sinusoidal()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
13、Stereographic
又称平射投影或等角方位投影,透视方位投影的一种。视点位于地球球体表面,投影平面位于视点正对面。球面投影的投影特性为:地面上的圆投影后仍为一个圆,经纬线为相互正交的圆弧线。适于制作圆形区域的小比例尺地图。在Cartopy中进行绘图代码如下:
#13.球面投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.Stereographic()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
14、TransverseMercator
墨卡托投影,是正轴等角圆柱投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假想一个与地轴方向一致的圆柱切或割于地球,按等角条件,将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。投影面的轴(圆锥圆柱的轴线,平面的法线)与地球赤道面重合。在Cartopy中进行绘图代码如下:
#14.横轴墨卡托投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.TransverseMercator( approx=False)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
15、UTM
通用墨卡尔投影是英、美、日、加拿大等国地形图最通用的投影。简称“UTM投影”。属等角横轴割圆柱投影。因投影圆柱与地球相割,中央经线投影后的长度比为0.9996,投影带各部分的长度变形比较平稳,其6°带内长度变形小于0.1%。在Cartopy中进行绘图代码如下:
#15.UTM投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs nplots = 60 fig = plt.figure(figsize=(10, 3)) for i in range(0, nplots): ax = fig.add_subplot(1, nplots, i+1, projection=ccrs.UTM(zone=i+1, southern_hemisphere=True)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
16、InterruptedGoodeHomolosine
古德分瓣投影又称“古德投影”、“古德分瓣法”。美国地理学家古德于1923年提出,故名。一种用分瓣法表示的等积伪圆柱投影。在Cartopy中进行绘图代码如下:
#16.分瓣正弦古德投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6.9228, 3)) ax = plt.axes(projection=ccrs.InterruptedGoodeHomolosine()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
17、RotatedPole
旋转极投影,属于极投影的变体,常被用于天气预测模型中。在Cartopy中进行绘图代码如下:
#17.旋转极投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.RotatedPole( pole_latitude=37.5, pole_longitude=177.5)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
18、OSGB
这是一种投影于 Airy 旋转椭球体之上的横轴墨卡托投影。原点为 49° N 和 2° W。中央子午线的比例为 0.9996012717。如果两个数据集具有不同的比例尺因子值,它们将被视为不同的数据集。在Cartopy中进行绘图代码如下:
#18.英国军用测量大地网 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(1.6154, 3)) ax = plt.axes(projection=ccrs.OSGB( approx=False)) ax.coastlines(resolution='50m') ax.gridlines() plt.show()
19、EuroPP
用于绘制欧洲地图的一种等距圆锥投影。在Cartopy中进行绘图代码如下:
#19.绘制欧洲地图的一种等距圆锥投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(2.6154, 3)) ax = plt.axes(projection=ccrs.EuroPP()) ax.coastlines(resolution='50m') ax.gridlines() plt.show()
20、Geostationary
(地球同步卫星)视角,视点在赤道上空某一点处。这种投影好像在地球同步(GEO)卫星上观察到的地球。在Cartopy中进行绘图代码如下:
#20.地球同步卫星投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.Geostationary()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
21、NearsidePerspective
(驾驶员)视角,视点在地球外某一点处。这种投影好像在高空中某处宇宙飞船驾驶员的视角。在Cartopy中进行绘图代码如下:
#21.驾驶员投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.NearsidePerspective( central_latitude=50.72, central_longitude=-3.53, satellite_height=10000000.0)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
22、EckertI
一种伪圆柱投影,纬线和经线是等间距的直线。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#22.艾克特第一投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertI()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
23、EckertII
伪圆柱投影。纬线是非等间距的直线。经线是等间距的直线。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#23.艾克特第二投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertII()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
24、EckertIII
伪圆柱投影。纬线是等间距的直线。经线是等间距的椭圆曲线。从中央子午线算起 +/-180° 的经线是半圆形的。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#24.艾克特第三投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertIII()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
25、EckertIV
伪圆柱等积投影。纬线是非等间距的直线,在极点处较密。经线是等间距的椭圆弧。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#25.艾克特第四投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertIV()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
26、EckertV
伪圆柱投影。纬线是等间距的直线。经线是等间距的正弦曲线。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#26.艾克特第五投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertV()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
27、EckertVI
伪圆柱等积投影。纬线是非等间距的直线。它们在极点处较密。经线是等间距的正弦曲线。极点和中央子午线为直线,其长度是赤道长度的一半。在Cartopy中进行绘图代码如下:
#27.艾克特第六投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6, 3)) ax = plt.axes(projection=ccrs.EckertVI()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
28、EqualEarth
这个投影是伪圆柱的,面积相等。平行线是不等间隔的直线,而子午线是等间隔的弧。它是用来绘制世界地图的。在Cartopy中进行绘图代码如下:
#28.等地球投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(6.1637, 3)) ax = plt.axes(projection=ccrs.EqualEarth()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
29、Gnomonic
此方位投影将地心用作其透视点。无论方位如何,所有的大圆都将投影为直线。此投影适用于导航,因为大圆将突出显示距离最短的路线。在Cartopy中进行绘图代码如下:
#29.球心投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.Gnomonic()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
30、LambertAzimuthalEqualArea
此投影保留了各多边形的面积,同时也保留了中心的实际方向。变形的常规模式为径向。最适合按比例对称分割的单个地块(圆形或方形)。在Cartopy中进行绘图代码如下:
#30.(兰伯特方位等积)投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3.0066, 3)) ax = plt.axes(projection=ccrs.LambertAzimuthalEqualArea()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
31、NorthPolarStereo
一种由球面直角坐标系即经纬网通过投影转绘而成的平面网。以投影的极射点及投影平面位置的关系命名。又称乌尔夫网或吴氏网。乌尔夫于1902年首次为结晶学引用了这种投影坐标网图。以球面上一点为极作投影透视点,即极射,把以此点为极的另一个半球面投影在以此为极点的赤道平面上,即赤平。北极极射投影即为以北极为极点进行投影。在Cartopy中进行绘图代码如下:
#31.(北极极射)投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.NorthPolarStereo()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
32、OSNI
一种区域性质的等距圆锥投影,用于测绘北爱尔兰岛。在Cartopy中进行绘图代码如下:
#32.一种区域性质的等距圆锥投影,用于测绘北爱尔兰岛 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(2.4323, 3)) ax = plt.axes(projection=ccrs.OSNI( approx=False)) ax.coastlines(resolution='10m') ax.gridlines() plt.show()
33、SouthPolarStereo
一种由球面直角坐标系即经纬网通过投影转绘而成的平面网。以投影的极射点及投影平面位置的关系命名。又称乌尔夫网或吴氏网。乌尔夫于1902年首次为结晶学引用了这种投影坐标网图。以球面上一点为极作投影透视点,即极射,把以此点为极的另一个半球面投影在以此为极点的赤道平面上,即赤平。南极极射投影即为以南极为极点进行投影。在Cartopy中进行绘图代码如下:
#33.(南极极射)投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(3, 3)) ax = plt.axes(projection=ccrs.SouthPolarStereo()) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
34、epsg
除cartopy.crs内置的投影外,Cartopy还支持通过EPSG code获取投影信息,具体EPSG信息可在https://epsg.io/进行查询,在Cartopy也可通过联网获取。例如WebMercator的EPSG编号为3857,在Cartopy中示例如下:
#34.WebMercator投影 import matplotlib.pyplot as plt import cartopy.crs as ccrs from cartopy.crs import epsg plt.figure() ax = plt.axes(projection=epsg(3857)) ax.coastlines(resolution='110m') ax.gridlines() plt.show()
总结
当制图范围较小时,无论什么投影方式都无太大变形;对于范围广大的世界地图、半球地图、大洲地图、大国地图等,则需要慎重考虑。对表现大块区域常用的投影方式可总结为:
- 世界地图:正圆柱、伪圆柱和多圆锥投影;
- 东、西半球:常选用横轴方位投影;
- 南、北半球:常采用正轴方位投影;
- 水、陆半球:一般选用斜轴方位投影;
- 极地——正轴方位投影;
- 赤道附近——横轴方位投影或正轴圆柱投影;
- 中纬地区——正轴圆锥投影或斜轴方位投影。
参考
ArcGIS中的地图投影:https://desktop.arcgis.com/zh-cn/arcmap/10.3/guide-books/map-projections/what-are-map-projections.htm
各种投影接口介绍:http://gnss.help/2018/02/11/projection-in-cartopy/index.html
EPSG查询地址:https://epsg.io/?q=3857
Cartopy官方文档:https://scitools.org.uk/cartopy/docs/latest/crs/projections.html