You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cartopy中将屏幕坐标转换为Lambert投影地理坐标(解交错)

如何用Cartopy计算Lambert投影下屏幕显示的左上角与右下角坐标

已知Lambert投影下的左下角(BL)和右上角(TR)经纬度坐标,要计算屏幕上显示的矩形左上角(TL)和右下角(BR)对应的地理坐标,可通过以下步骤实现:

Lambert投影下的矩形坐标

实现思路

核心是完成屏幕像素坐标 ↔ 投影坐标 ↔ 地理坐标的转换:

  • 先获取绘图区域的屏幕像素边界
  • 将屏幕左上角、右下角的像素坐标转换为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:52:55