Уклон: производная рельефа

Урок выводит уклон (slope) из DEM — это мера крутизны поверхности, базовый продукт растрового анализа рельефа.

Уклон — угол наклона поверхности к горизонту; вычисляется из скорости изменения высоты по горизонтали (градиента DEM).

Высота сама по себе говорит немного — гораздо важнее, насколько круто она меняется. Уклон нужен везде: дорогу нельзя вести по склону круче нормы, вода стекает в сторону наибольшего уклона, эрозия и оползни привязаны к крутизне, солнечные панели ставят с учётом наклона. Уклон — это, по сути, производная рельефа.

От перепада высоты к углу

Если на горизонтали $L$ метров высота выросла на $\Delta h$, то тангенс угла наклона равен $\Delta h / L$, а сам угол — $\arctan(\Delta h / L)$. Это уклон вдоль одного направления:

$\text{уклон} = \arctan\!\left(\frac{\Delta h}{L}\right)$

Подъём 10 м на 100 м пути даёт $\arctan(0{,}1) \approx 5{,}7°$ — пологий склон. Подъём 100 м на 100 м это $\arctan(1) = 45°$ — очень круто.

Уклон по двум осям

В растре высота меняется и по $x$, и по $y$. Полный уклон считают из двух частных градиентов $g_x = \partial h/\partial x$ и $g_y = \partial h/\partial y$ по формуле:

$\text{slope} = \arctan\!\left(\sqrt{g_x^2 + g_y^2}\right)$

import math

def slope_deg(gx, gy):
    """gx, gy — изменение высоты на единицу длины по осям."""
    return math.degrees(math.atan(math.sqrt(gx ** 2 + gy ** 2)))

# Подъём 10 м на 100 м только по оси x
print(f"{slope_deg(10/100, 0):.2f}")
# Подъём и по x, и по y
print(f"{slope_deg(0.1, 0.1):.2f}")
# Крутой склон 45 градусов
print(f"{slope_deg(1.0, 0):.2f}")

Вывод:

5.71
8.05
45.00

Градиент из ячеек DEM

На практике $g_x$ и $g_y$ оценивают из соседних ячеек. Простейший вариант — центральная разность: $g_x = \frac{h_{\text{справа}} - h_{\text{слева}}}{2\,c}$, где $c$ — размер ячейки в метрах. Посчитаем уклон в центральной ячейке маленького DEM:

import math

dem = [
    [100, 102, 104],
    [101, 105, 110],
    [103, 108, 116],
]
cell = 30.0  # метров

# центральная ячейка (1,1)
gx = (dem[1][2] - dem[1][0]) / (2 * cell)
gy = (dem[2][1] - dem[0][1]) / (2 * cell)
slope = math.degrees(math.atan(math.sqrt(gx ** 2 + gy ** 2)))
print(f"gx = {gx:.4f}, gy = {gy:.4f}")
print(f"Уклон в центре: {slope:.2f} градуса")

Вывод:

gx = 0.1500, gy = 0.1000
Уклон в центре: 10.22 градуса

Как работает под капотом

Промышленные алгоритмы (например, метод Хорна, встроенный в QGIS и GDAL) берут не два, а все восемь соседей ячейки и считают взвешенный градиент — это устойчивее к шуму в данных. Помимо уклона из DEM выводят экспозицию (aspect) — направление, куда «смотрит» склон (важно для освещённости и снеготаяния), и отмывку рельефа (hillshade) — имитацию теней для красивой 3D-карты. Все они — производные одного и того же градиента высоты.

Частые ошибки

  • Не учитывать размер ячейки. Уклон зависит от $c$: те же перепады высот на ячейке 10 м и 90 м дают разную крутизну.
  • Считать уклон только по одной оси. Реальный склон наклонён в обе стороны; нужен общий градиент $\sqrt{g_x^2 + g_y^2}$.
  • Путать градусы и проценты. Уклон 100% (отношение 1:1) — это 45°, а не «полная вертикаль»; это разные шкалы.

Уклон в практических решениях

Уклон — один из самых востребованных производных продуктов рельефа, потому что от крутизны зависят почти все взаимодействия человека с ландшафтом. Дорожники нормируют максимальный продольный уклон трассы: слишком крутой подъём опасен зимой и непосилен для гружёного транспорта, поэтому проектируемую дорогу «протягивают» по склонам так, чтобы уклон нигде не превысил норму. Аграрии по уклону оценивают риск водной эрозии: на крутых склонах распашка ведёт к смыву плодородного слоя, и такие участки переводят под залужение или террасируют. Лавинщики и геологи по сочетанию крутизны и экспозиции картируют зоны схода лавин и оползней. Везде исходник один — DEM, а решение даёт его производная.

Тонкость, о которой забывают новички: уклон чувствителен к качеству и разрешению DEM. На грубой модели с шагом 90 метров реальный крутой обрыв «размажется» в пологий склон, потому что перепад высоты усредняется по большой ячейке, — и расчёт даст обманчиво безопасную картину. Шум в данных, наоборот, порождает ложную «бугристость» и завышает уклон на ровных местах, поэтому перед расчётом DEM часто сглаживают. И всегда помните про две шкалы: градусы и проценты. Уклон $100\%$ — это вовсе не вертикаль, а $45°$ (подъём равен горизонтальному пробегу); путаница этих шкал регулярно приводит к абсурдным выводам в проектной документации.

Итог

  • Уклон — это производная рельефа: $\arctan\sqrt{g_x^2 + g_y^2}$.
  • Градиенты $g_x, g_y$ оценивают из соседних ячеек DEM с учётом размера ячейки.
  • Из того же градиента выводят экспозицию (aspect) и отмывку (hillshade).
  • Не путайте уклон в градусах и в процентах: 100% — это 45°.
Проверьте себя
1. Уклон рельефа — это, по сути, что?
AСредняя высота
BПроизводная (скорость изменения) высоты по горизонтали
CПлощадь склона
DЦвет на карте
2. Чему равен уклон при подъёме 100 м на 100 м пути?
A10°
B45° (arctan(1))
C100°
D90°
3. Почему уклон считают по двум осям, а не по одной?
AДля скорости
BРеальный склон наклонён и по x, и по y; полная крутизна это √(gx²+gy²)
CТак требует GeoJSON
DПо одной оси нельзя