Как визуализировать контур страны в 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:
    # Чтение 10m Natural Earth стран и извлечение геометрии Германии через 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)

Check out similar posts by category: Geoinformatics