Como visualizar o contorno de um país no Jupyter usando GeoPandas, Cartopy e Natural Earth

Este exemplo simples mostra como visualizar o contorno de um país no Jupyter. Para este exemplo, mostraremos o contorno da Alemanha. Para torná-lo visualmente mais atraente, também adicionamos contornos de outros países e o oceano no fundo.

Usamos o dataset Natural Earth 10m, que é automaticamente baixado aqui. As variantes em menor escala como 1:110M simplesmente não fornecem resolução suficiente nesta escala para serem visualmente atraentes.

Germany with rivers.avif

VisualizeCountry.py
# Importar bibliotecas necessárias
import cartopy.crs as ccrs
import cartopy.feature as cf
from cartopy.feature import ShapelyFeature
import cartopy.io.shapereader as shpreader
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.ops import unary_union

# Criar o mapa com projeção Plate Carree
proj = ccrs.PlateCarree()
ax = plt.axes(projection=proj)
# Usaremos Natural Earth de maior resolução (10m) onde disponível
# Usar 'admin_0_countries' 10m e coastline/lakes/rivers para detalhes
try:
    # Ler países Natural Earth 10m e extrair geometria da Alemanha via geopandas para melhor precisão
    countries = gpd.read_file(shpreader.natural_earth(resolution='10m', category='cultural', name='admin_0_countries'))
    germany = countries[countries['ISO_A3'] == 'DEU'].iloc[0].geometry
    # Buffer por 0 para corrigir quaisquer geometrias inválidas
    germany = germany.buffer(0)
    # Determinar uma extensão ajustada da geometria com um pequeno padding em graus
    minx, miny, maxx, maxy = germany.bounds
    pad_deg = 0.4
    extent = [minx - pad_deg, maxx + pad_deg, miny - pad_deg, maxy + pad_deg]
    ax.set_extent(extent, crs=ccrs.PlateCarree())

    # Adicionar coastline e bordas e lagos/rios de alta resolução
    # NOTA: Todos esses são opcionais - apenas comente o que você não precisa
    ax.add_feature(cf.LAND.with_scale('10m'), facecolor='lightgray')
    ax.add_feature(cf.OCEAN.with_scale('10m'), facecolor='lightblue')
    ax.add_feature(cf.COASTLINE.with_scale('10m'), lw=0.6)
    ax.add_feature(cf.BORDERS.with_scale('10m'), linestyle=':', lw=0.6)
    ax.add_feature(cf.LAKES.with_scale('10m'), facecolor='none', edgecolor='blue', lw=0.4)
    ax.add_feature(cf.RIVERS.with_scale('10m'), edgecolor='blue', lw=0.4)

    # Adicionar polígono da Alemanha com estilização mais agradável
    germany_feature = ShapelyFeature([germany], ccrs.PlateCarree(), facecolor='none', edgecolor='red', linewidth=1.2)
    ax.add_feature(germany_feature)

    # Adicionar gridlines e título
    gl = ax.gridlines(draw_labels=True, linestyle='--', linewidth=0.3)
    gl.top_labels = False
    gl.right_labels = False
    plt.gcf().set_size_inches(12, 10)
    ax.set_title('Outline of Germany — Natural Earth 10m (detailed)')

    plt.show()
except Exception as e:
    print(f"Error: {e}")
    print("Could not load 10m Natural Earth data. Falling back to built-in shapereader records with 110m resolution.")
    try:
        reader = shpreader.Reader(shpreader.natural_earth(resolution='110m', category='cultural', name='admin_0_countries'))
        germany = [c for c in reader.records() if c.attributes['NAME_LONG'] == 'Germany'][0]
        shape_feature = ShapelyFeature([germany.geometry], ccrs.PlateCarree(), facecolor='none', edgecolor='red', lw=2)
        ax.add_feature(cf.COASTLINE, lw=0.5)
        ax.add_feature(cf.BORDERS, linestyle=':', lw=0.5)
        ax.add_feature(shape_feature)
        plt.show()
    except Exception as e2:
        print('Fallback also failed:', e2)

Check out similar posts by category: Geoinformatics