【问题标题】:Python cartopy map, clip area outside country (polygon)Python cartopy 地图,国家以外的剪辑区域(多边形)
【发布时间】:2020-10-08 10:37:11
【问题描述】:

我用 NaturalEarth 的国家边界创建了一张 Stamen 地形图。 现在我想从国家边界之外删除所有数据(在这种情况下是地形)。 我该怎么做?

我的例子是瑞士内外的地形可见:

from cartopy.io import shapereader
import cartopy.io.img_tiles as cimgt
import cartopy.crs as ccrs
import geopandas
import matplotlib.pyplot as plt


resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'

shpfilename = shapereader.natural_earth(resolution, category, name)

df = geopandas.read_file(shpfilename)

poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]

stamen_terrain = cimgt.Stamen('terrain-background')

fig = plt.figure(figsize=(8,6))

ax = fig.add_subplot(1, 1, 1, projection=stamen_terrain.crs)
ax.add_geometries(poly, crs=ccrs.PlateCarree(), facecolor='none', edgecolor='r')
exts = [poly[0].bounds[0], poly[0].bounds[2], poly[0].bounds[1], poly[0].bounds[3]]
ax.set_extent(exts, crs=ccrs.Geodetic())

ax.add_image(stamen_terrain, 8)
fig.tight_layout()
plt.show()

如何仅将边界内的地形显示为白色/透明,而将其余的地形显示为白色/透明?

尝试使用这个方向,但到目前为止没有成功: https://scitools.org.uk/cartopy/docs/latest/gallery/logo.html

【问题讨论】:

    标签: python dictionary clip cartopy


    【解决方案1】:

    您需要一个蒙版来隐藏图像中不需要的部分。这是一个可运行的代码,演示了获取预期绘图的所有步骤。

    from shapely.geometry import Polygon
    from cartopy.io import shapereader
    import cartopy.io.img_tiles as cimgt
    import cartopy.crs as ccrs
    import geopandas
    import matplotlib.pyplot as plt
    
    def rect_from_bound(xmin, xmax, ymin, ymax):
        """Returns list of (x,y)'s for a rectangle"""
        xs = [xmax, xmin, xmin, xmax, xmax]
        ys = [ymax, ymax, ymin, ymin, ymax]
        return [(x, y) for x, y in zip(xs, ys)]
    
    # request data for use by geopandas
    resolution = '10m'
    category = 'cultural'
    name = 'admin_0_countries'
    
    shpfilename = shapereader.natural_earth(resolution, category, name)
    df = geopandas.read_file(shpfilename)
    
    # get geometry of a country
    poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]
    
    stamen_terrain = cimgt.Stamen('terrain-background')
    
    # projections that involved
    st_proj = stamen_terrain.crs  #projection used by Stamen images
    ll_proj = ccrs.PlateCarree()  #CRS for raw long/lat
    
    # create fig and axes using intended projection
    fig = plt.figure(figsize=(8,6))
    ax = fig.add_subplot(1, 1, 1, projection=st_proj)
    ax.add_geometries(poly, crs=ll_proj, facecolor='none', edgecolor='black')
    
    pad1 = .1  #padding, degrees unit
    exts = [poly[0].bounds[0] - pad1, poly[0].bounds[2] + pad1, poly[0].bounds[1] - pad1, poly[0].bounds[3] + pad1];
    ax.set_extent(exts, crs=ll_proj)
    
    # make a mask polygon by polygon's difference operation
    # base polygon is a rectangle, another polygon is simplified switzerland
    msk = Polygon(rect_from_bound(*exts)).difference( poly[0].simplify(0.01) )
    msk_stm  = st_proj.project_geometry (msk, ll_proj)  # project geometry to the projection used by stamen
    
    # get and plot Stamen images
    ax.add_image(stamen_terrain, 8) # this requests image, and plot
    
    # plot the mask using semi-transparency (alpha=0.65) on the masked-out portion
    ax.add_geometries( msk_stm, st_proj, zorder=12, facecolor='white', edgecolor='none', alpha=0.65)
    
    ax.gridlines(draw_labels=True)
    
    plt.show()
    

    结果图:

    还有面具:

    编辑1

    以上代码适用于单个国家/地区。如果多个连续国家是我们的新目标,我们需要选择所有这些国家和dissolve 到一个几何体中。只需要修改几行代码。

    示例:新的目标国家:['Norway','Sweden','Finland']

    要替换的代码行:

    poly = [df.loc[df['ADMIN'] == 'Switzerland']['geometry'].values[0]]
    

    要替换的新代码行:

    scan3 = df[ df['ADMIN'].isin(['Norway','Sweden', 'Finland']) ]
    scan3_dissolved = scan3.dissolve(by='LEVEL')
    poly = [scan3_dissolved['geometry'].values[0]]
    

    示例输出图:

    【讨论】:

    • 也感谢我,这正是我想要的!
    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2023-03-20
    • 1970-01-01
    • 2011-06-20
    • 2013-04-04
    相关资源
    最近更新 更多