Реальные задачи и стек инструментов

Итоговый урок собирает изученное в решение реальных задач и расставляет по местам инструменты профессионального ГИС-стека.

Реальная ГИС-задача почти всегда — это конвейер: загрузить данные, привести к одной системе координат, посчитать геометрию или анализ, визуализировать результат.

Мы прошли весь путь: от того, что такое геоданные, через координаты, проекции и геометрию к анализу, базам и картам. В этом уроке соберём кусочки в типичные прикладные задачи и покажем, какой инструмент за что отвечает. Все вычислительные ядра — гаверсинус, площадь, точка-в-полигоне — вы уже умеете писать; на практике их даёт стек, но понимание остаётся вашим главным активом.

Задача 1: расстояние между городами и точки в районе

Объединим два навыка: посчитаем расстояния от Москвы до набора городов и отберём те, что в радиусе 800 км, отсортировав по близости. Это конвейер «расстояние + фильтр + сортировка» из раздела 5:

import math

def haversine(lat1, lon1, lat2, lon2):
    R = 6371.0
    p1, p2 = math.radians(lat1), math.radians(lat2)
    dphi = math.radians(lat2 - lat1)
    dlam = math.radians(lon2 - lon1)
    a = (math.sin(dphi / 2) ** 2
         + math.cos(p1) * math.cos(p2) * math.sin(dlam / 2) ** 2)
    return 2 * R * math.asin(math.sqrt(a))

moscow = (55.7558, 37.6173)
cities = {
    "Тула": (54.2044, 37.6184),
    "Казань": (55.7963, 49.1088),
    "Нижний Новгород": (56.3269, 44.0059),
    "Самара": (53.1959, 50.1002),
    "Санкт-Петербург": (59.9343, 30.3351),
}

near = []
for name, (lat, lon) in cities.items():
    d = haversine(*moscow, lat, lon)
    if d <= 800:
        near.append((name, d))
near.sort(key=lambda t: t[1])

print("Города в радиусе 800 км от Москвы:")
for name, d in near:
    print(f"  {name}: {d:.0f} км")

Вывод:

Города в радиусе 800 км от Москвы:
  Тула: 173 км
  Нижний Новгород: 402 км
  Санкт-Петербург: 633 км
  Казань: 718 км

Задача 2: площадь региона

Региону соответствует полигон. Площадь считаем формулой шнуровки из раздела 4. Напомним: для Земли координаты сперва проецируют в метры; здесь возьмём уже спроецированный полигон (метры UTM) и получим площадь в квадратных километрах:

def polygon_area(poly):
    n = len(poly)
    s = 0.0
    for i in range(n):
        x1, y1 = poly[i]
        x2, y2 = poly[(i + 1) % n]
        s += x1 * y2 - x2 * y1
    return abs(s) / 2

# Контур района в метрах (UTM)
region = [(400000, 6100000), (430000, 6100000),
          (435000, 6125000), (410000, 6135000),
          (395000, 6118000)]
area_m2 = polygon_area(region)
print(f"Площадь: {area_m2:,.0f} кв. м")
print(f"Площадь: {area_m2 / 1e6:.1f} кв. км")

Вывод:

Площадь: 1,040,000,000 кв. м
Площадь: 1040.0 кв. км

Задача 3: план простой карты

Финальный шаг любой задачи — показать результат. План карты «города и зона радиуса» в псевдокоде folium (для чтения):

import folium

m = folium.Map(location=[55.7558, 37.6173], zoom_start=6)
folium.Circle([55.7558, 37.6173], radius=800000,
              color="red", fill=True).add_to(m)   # зона 800 км
for name, (lat, lon) in cities.items():
    folium.Marker([lat, lon], popup=name).add_to(m)
m.save("cities.html")

Стек инструментов: кто за что

ИнструментРоль
QGISнастольная ГИС: ручной анализ, вёрстка и печать карт, плагины
GeoPandasвекторный анализ в Python (Pandas + геометрия)
Shapelyгеометрические операции (буфер, пересечение, предикаты)
Rasterioчтение и анализ растров (GeoTIFF, DEM, снимки)
pyprojперепроецирование между системами координат
Folium / Leafletинтерактивные веб-карты
PostGISхранение и пространственные запросы в базе

Под капотом почти всех них — два движка на C: GDAL/OGR (чтение десятков форматов) и GEOS (геометрия). Так что geopandas, shapely, QGIS и PostGIS под капотом часто вызывают один и тот же код.

Дистанционное зондирование: общая картина

Отдельная большая ветвь ГИС — дистанционное зондирование (remote sensing): анализ Земли по спутниковым и аэроснимкам. Из многоканальных снимков (Sentinel, Landsat) считают индексы (NDVI для растительности, NDWI для воды), классифицируют типы покрова, отслеживают изменения во времени. Это растровый анализ в чистом виде, и его ядро — поэлементные операции над каналами, которые вы видели на примере NDVI. Промышленно это делают в rasterio/numpy, а для огромных архивов — в облаке (Google Earth Engine).

Частые ошибки (итоговые)

  • Пропустить приведение к одной системе координат. Самая частая причина «данные не совпадают» во всём ГИС.
  • Мерить в градусах. Расстояния — гаверсинусом, площади — после проекции в метры.
  • Писать геометрию руками в продакшене. Реализации учебны; в бою берите проверенные shapely/GEOS.

Что отличает специалиста от новичка

Пройдя курс, легко решить, что суть ГИС — в формулах и функциях. Но реальные проекты показывают другое: алгоритмы давно реализованы в библиотеках, а ценность специалиста в том, как он собирает их в корректный конвейер и где расставляет проверки. Новичок зовёт buffer и intersection и получает «результат»; специалист сначала убеждается, что оба слоя в одной системе координат, что буфер строится в метрах, а не в градусах, что геометрия валидна, и только потом доверяет числу. Большинство провалов в геоаналитике — не от незнания формулы гаверсинуса, а от пропущенного приведения CRS, перепутанного порядка координат или измерения в градусах. Дисциплина важнее эрудиции.

Второе отличие — умение видеть задачу как композицию простых шагов. «Найти участки под детскую площадку» раскладывается на буфер вокруг школ, вычитание промзон, пересечение с жилыми кварталами, фильтр по площади — каждый шаг элементарен, искусство в их сборке. «Оценить охват доставки» — это геокодирование адресов, построение изохрон по дорожному графу, spatial join с переписными данными. Ни одна из этих задач не требует нового алгоритма; все они — комбинации того, что вы уже умеете. Поэтому, закрывая курс, унесите не столько конкретные формулы, сколько способ мышления: данные привести к общей основе, задачу разложить на пространственные операции, результат честно показать на карте — и на каждом шаге спросить себя, в каких единицах и в какой системе координат вы считаете.

Итог

  • Реальная задача — конвейер: загрузка, приведение CRS, анализ, визуализация.
  • Изученные ядра (гаверсинус, шнуровка, точка-в-полигоне) лежат в основе стека.
  • Стек: QGIS, GeoPandas, Shapely, Rasterio, pyproj, Folium, PostGIS — поверх GDAL/GEOS.
  • Дистанционное зондирование — растровый анализ снимков (индексы, классификация, изменения).
Проверьте себя
1. Что обычно представляет собой реальная ГИС-задача?
AОдин вызов одной функции
BКонвейер: загрузка данных, приведение к одной системе координат, анализ, визуализация
CТолько рисование карты
DТолько запрос в базу
2. Какой инструмент стека отвечает за чтение и анализ растров (GeoTIFF, DEM)?
AShapely
BRasterio
CFolium
Dpyproj
3. Что лежит под капотом большинства ГИС-инструментов Python и QGIS?
AJavaScript
BДвижки GDAL/OGR (форматы) и GEOS (геометрия) на C
CТолько Excel
DОтдельный код в каждом