如何组合Cartopy投影,实现日落线垂直的正射投影地球可视化
解决方案
要实现晨昏线(日落线)垂直且保留正射投影与目标中心坐标,可利用Nightshade自带的旋转极投影做坐标系转换,基于该坐标系创建正射投影,具体实现如下:
修改后代码
from typing import NamedTuple import cartopy.crs import cartopy.feature.nightshade import cartopy.mpl.geoaxes from matplotlib import pyplot as plt class Hemisphere(NamedTuple): coord: tuple[float, float] crs: cartopy.crs.Orthographic ax: cartopy.mpl.geoaxes.GeoAxes @classmethod def make( cls, coord: tuple[float, float], figure: plt.Figure, rotated_globe: cartopy.crs.Globe, rotated_center: tuple[float, float], ) -> 'Hemisphere': # 基于旋转极坐标系创建正射投影,中心为转换后的坐标 crs = cartopy.crs.Orthographic( central_longitude=rotated_center[0], central_latitude=rotated_center[1], globe=rotated_globe, ) ax = figure.add_subplot(projection=crs) return cls(coord=coord, crs=crs, ax=ax) def plot( self, night: cartopy.feature.nightshade.Nightshade, ) -> None: self.ax.stock_img() self.ax.add_feature(night) self.ax.gridlines() def plot( home_coord: tuple[float, float], ) -> plt.Figure: fig: plt.Figure = plt.figure() # 创建Nightshade并获取其旋转极投影 night = cartopy.feature.nightshade.Nightshade() rotated_pole_crs = night.crs # 将原始中心坐标转换到旋转极坐标系 geodetic = cartopy.crs.Geodetic() home_rotated = rotated_pole_crs.transform_point( x=home_coord[0], y=home_coord[1], src_crs=geodetic ) # 创建Hemisphere实例,传入旋转后的坐标系参数 home_hemi = Hemisphere.make( coord=home_coord, figure=fig, rotated_globe=rotated_pole_crs.globe, rotated_center=(home_rotated[0], home_rotated[1]), ) home_hemi.plot(night=night) return fig def main() -> None: home_coord = -80, 40 plot(home_coord=home_coord) plt.show() if __name__ == '__main__': main()
核心逻辑说明
- 复用Nightshade的旋转极投影:Nightshade内部用
RotatedPole投影计算晨昏线,该投影的地轴垂直于晨昏线,天然保证晨昏线在该坐标系下呈南北垂直方向。 - 坐标转换:将目标中心坐标从地理坐标系转换到旋转极坐标系,以此作为正射投影的中心,确保原始坐标仍为视图中心。
- 自定义正射投影:基于旋转极投影的地球参数创建正射投影,既保留正射投影的视觉特性,又继承了旋转极坐标系下晨昏线垂直的属性。
- 自动投影转换:Cartopy会自动处理所有地理特征(底图、夜影、网格线)的投影转换,无需手动操作底层Matplotlib变换。
内容的提问来源于stack exchange,提问作者Reinderien
相关产品推荐
相关产品推荐

