使用Cartopy获取投影地图中的坐标

时间:2018-01-10 21:59:49

标签: python-3.x matplotlib map-projections cartopy

我试图使用获取地图要素的坐标,但我想获取地图投影坐标,而不是原始投影中的数据。

例如:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=ccrs.epsg(3857))
fig.add_axes(ax)
ax.coastlines()
ax.set_global()
lines = ax.plot((0, 360), (-85.06, 85.06), transform=ccrs.PlateCarree())
fig.show()

前面的代码显示了使用地图投影的两行地图,但lines(带有matplotlib.lines.Line2D个实例的列表)只是一个对象,其坐标位于数据的原始投影中({ {1}} ---> lines[0].get_data()

在交互式绘图上,(array([ 0, 360]), array([-85.06, 85.06])))之后获得的Qt5后端,当光标在地图上时我可以看到fig.show()EPSG:3857中的坐标,所以我想知道是否有在PlateCarree坐标中获取lines的简便方法。

编辑:以上示例非常简化。我试图简单地做到更好地理解,但也许更好地展示真正的问题。

我有一个数据网格,其经度在[0,360]范围内。我可以修改数组,以便使用 / 在[-180,180]范围和I' m中输入以绘制轮廓。从轮廓中我获得EPSG:3857几个matplotlib.contour.QuadContourSet。从每个matplotlib.collections.LineCollection我可以获得matplotlib.collections.LineCollection,我希望matplotlib.path.Path中的每个路径的坐标而不是原始EPSG:3857中的坐标,因此我可以使用PlateCarree 1}}将每个路径转换为cartopy.mpl.patch.path_to_geos投影中的几何对象,而不必从每个路径中提取EPSG:3857,将它们从vertices转换为PlateCarree然后使用转换后的坐标创建一个新路径,以使用EPSG:3857来获取我需要的crs中的几何。

我希望现在我的问题更清楚了。

1 个答案:

答案 0 :(得分:1)

这个问题要求使用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

编辑2

根据建设性意见,上述转换函数可写如下:

def coordXform(orig_crs, target_crs, x, y):
    return target_crs.transform_points( orig_crs, x, y )
相关问题