Як візуалізувати контур країни в Jupyter за допомогою GeoPandas, Cartopy та Natural Earth

Цей простий приклад показує, як візуалізувати контур країни в Jupyter. Для цього прикладу ми покажемо контур Німеччини. Щоб зробити це візуально привабливішим, ми також додаємо контури інших країн та океан на фоні.

Ми використовуємо набор даних Natural Earth 10m, який тут завантажується автоматично. Варіанти більш дрібного масштабу, такі як 1:110M, просто не забезпечують достатньої роздільної здатності в цьому масштабі, щоб бути візуально привабливими.

Germany with rivers.avif

VisualizeCountry.py
# Імпортувати потрібні бібліотеки
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

# Створити карту з проєкцією Plate Carree
proj = ccrs.PlateCarree()
ax = plt.axes(projection=proj)
# Завантажимо Natural Earth вищої роздільної здатності (10m), де доступно
# Використати 10m 'admin_0_countries' та берегову лінію/озера/річки для деталізації
try:
    # Прочитати країни Natural Earth 10m і витягти геометрію Німеччини через geopandas для кращої точності
    countries = gpd.read_file(shpreader.natural_earth(resolution='10m', category='cultural', name='admin_0_countries'))
    germany = countries[countries['ISO_A3'] == 'DEU'].iloc[0].geometry
    # Буфер 0, щоб виправити будь-які некоректні геометрії
    germany = germany.buffer(0)
    # Визначити щільний екстент з геометрії з невеликим відступом у градусах
    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())

    # Додати берегову лінію, кордони та озера/річки з високою роздільною здатністю
    # ПРИМІТКА: Усе це необов'язково — просто закоментуйте те, що вам не потрібно
    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)

    # Додати полігон Німеччини з приємнішим стилем
    germany_feature = ShapelyFeature([germany], ccrs.PlateCarree(), facecolor='none', edgecolor='red', linewidth=1.2)
    ax.add_feature(germany_feature)

    # Додати лінії сітки та заголовок
    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('Контур Німеччини — Natural Earth 10m (детально)')

    plt.show()
except Exception as e:
    print(f"Помилка: {e}")
    print("Не вдалося завантажити дані Natural Earth 10m. Перехід до вбудованих записів shapereader з роздільною здатністю 110m.")
    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('Запасний варіант також не вдався:', e2)

Дивіться схожі статті за категоріями: Geoinformatics