如何在Cartopy中将屏幕坐标转换为Lambert投影地理坐标(解交错)
如何用Cartopy计算Lambert投影下屏幕显示的左上角与右下角坐标
已知Lambert投影下的左下角(BL)和右上角(TR)经纬度坐标,要计算屏幕上显示的矩形左上角(TL)和右下角(BR)对应的地理坐标,可通过以下步骤实现:

实现思路
核心是完成屏幕像素坐标 ↔ 投影坐标 ↔ 地理坐标的转换:
- 先获取绘图区域的屏幕像素边界
- 将屏幕左上角、右下角的像素坐标转换为Lambert投影坐标
- 再将投影坐标转换为经纬度坐标(WGS84,对应PlateCarree)
修改后的代码
import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.pyplot as plt # 已知的左下角和右上角经纬度 ll_lon, ll_lat = -10, 40 ur_lon, ur_lat = 10, 60 c_lon, c_lat = (ll_lon + ur_lon)/2, (ll_lat + ur_lat)/2 plt.figure(figsize=[12,12]) # 定义Lambert投影 proj = ccrs.LambertConformal(central_longitude=c_lon, central_latitude=c_lat) ax = plt.axes(projection=proj) ax.set_extent([-25, +25, 35, 65], ccrs.PlateCarree()) # 获取Axes的屏幕边界(像素坐标) bbox = ax.get_window_extent() # 屏幕四个顶点的像素坐标:左下角、左上角、右上角、右下角 screen_points = [ (bbox.x0, bbox.y0), # BL (bbox.x0, bbox.y1), # TL (bbox.x1, bbox.y1), # TR (bbox.x1, bbox.y0) # BR ] # 将屏幕像素坐标转换为投影坐标,再转为经纬度 geo_points = [] for x, y in screen_points: # 像素转投影坐标 proj_x, proj_y = ax.transData.inverted().transform((x, y)) # 投影坐标转经纬度 lon, lat = proj.transform_point(proj_x, proj_y, ccrs.PlateCarree()) geo_points.append((lon, lat)) # 提取四个顶点的经纬度 bl_lon, bl_lat = geo_points[0] tl_lon, tl_lat = geo_points[1] tr_lon, tr_lat = geo_points[2] br_lon, br_lat = geo_points[3] # 绘制所有四个顶点 ax.scatter(bl_lon, bl_lat, color='red', label='BL', transform=ccrs.PlateCarree()) ax.scatter(tl_lon, tl_lat, color='green', label='TL', transform=ccrs.PlateCarree()) ax.scatter(tr_lon, tr_lat, color='blue', label='TR', transform=ccrs.PlateCarree()) ax.scatter(br_lon, br_lat, color='orange', label='BR', transform=ccrs.PlateCarree()) ax.scatter(c_lon, c_lat, color='purple', label='中心', transform=ccrs.PlateCarree()) # 添加地图要素 ax.add_feature(cfeature.OCEAN, facecolor='paleturquoise', alpha=0.4) ax.add_feature(cfeature.BORDERS, edgecolor='black') ax.add_feature(cfeature.COASTLINE, edgecolor='black') # 添加网格和标签 gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, x_inline=False, y_inline=False, linewidth=0.33, color='k', alpha=0.5) gl.right_labels = gl.top_labels = False ax.legend() plt.show() # 打印计算得到的TL和BR坐标 print(f"左上角(TL)经纬度: {tl_lon:.2f}, {tl_lat:.2f}") print(f"右下角(BR)经纬度: {br_lon:.2f}, {br_lat:.2f}")
关键步骤说明
ax.get_window_extent():获取Axes在屏幕上的像素边界,得到左下角(x0,y0)和右上角(x1,y1)的像素坐标ax.transData.inverted().transform():将屏幕像素坐标转换为当前投影(Lambert)下的坐标proj.transform_point():将投影坐标转换为经纬度坐标,转换时需指定目标坐标系为ccrs.PlateCarree()
内容的提问来源于stack exchange,提问作者TheGitPuller
相关产品推荐
相关产品推荐

