我试图使用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]范围内。我可以修改数组,以便使用cartopy / matplotlib在[-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
投影中的shapely几何对象,而不必从每个路径中提取EPSG:3857
,将它们从vertices
转换为PlateCarree
然后使用转换后的坐标创建一个新路径,以使用EPSG:3857
来获取我需要的crs中的几何。
我希望现在我的问题更清楚了。
答案 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 )