该问题要求使用 Cartopy 的功能进行坐标转换,也许还有其他功能。
这里我提供了执行坐标变换和计算检查的代码。
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
# Test data in geographic lon, lat (degrees)
lons = np.array((0, 360.01)) # any number of longitude
lats = np.array((-85.06, 85.06)) # .. longitude
# define all CRS
crs_longlat = ccrs.PlateCarree()
crs_3857 = ccrs.epsg(3857)
# Transformation function
def coordXform(orig_crs, target_crs, x, y):
"""
Converts array of (y,x) from orig_crs -> target_crs
y, x: numpy array of float values
orig_crs: source CRS
target_crs: target CRS
"""
# original code is one-liner
# it leaves an open axes that need to plt.close() later
# return plt.axes( projection = target_crs ).projection.transform_points( orig_crs, x, y )
# new improved code follows
xys = plt.axes( projection = target_crs ).projection.transform_points( orig_crs, x, y )
# print(plt.gca()) # current axes: GeoAxes: _EPSGProjection(3857)
plt.close() # Kill GeoAxes
# print(plt.gca()) # AxesSubplot (new current axes)
return xys
# Transform geographic (lon-lat) to (x, y) of epsg(3857)
xys = coordXform(crs_longlat, crs_3857, lons, lats)
for ea in xys:
print("(x, y) meters: " + str(ea[0]) + ', ' + str(ea[1]))
#Output(1)
#(x, y) meters: 0.0, -20006332.4374
#(x, y) meters: 1113.19490794, 20006332.4374
# Computation check
# Transform (x, y) of epsg(3857) to geographic (lon-lat), degrees
xs = xys[:,0] # all x's
ys = xys[:,1] # all y's
lls = coordXform(crs_3857, crs_longlat, xs, ys)
for ea in lls:
print("(lon, lat) degrees: " + str(ea[0]) + ', ' + str(ea[1]))
#Output(2)
#(lon, lat) degrees: 0.0, -85.06
#(lon, lat) degrees: 0.01, 85.06
# plt.close() # no need now
Edit 2
根据建设性意见,上面的变换函数可以写成如下:
def coordXform(orig_crs, target_crs, x, y):
return target_crs.transform_points( orig_crs, x, y )