Расчет уклона

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

Формально:

  • вертикальное изменение: Δh
  • горизонтальная дистанция: d
  • уклон: s = Δh / d

В практических вычислениях уклон часто переводится в проценты:

s% = (Δh / d) × 100

или в градусы:

θ = arctan(Δh / d)

При работе с JavaScript-геометрией эти значения обычно вычисляются через библиотеку Turf.js, которая предоставляет инструменты для измерения расстояний, работы с координатами и геометрическими преобразованиями.


Геометрическая модель данных

Для расчёта уклона используются два базовых подхода:

Точка-точка (Point → Point)

Каждая точка содержит координаты:

[x, y, z]

где:

  • x — долгота
  • y — широта
  • z — высота (опционально)

Линия (LineString)

Набор точек:

{
  type: "LineString",
  coordinates: [
    [lng1, lat1, z1],
    [lng2, lat2, z2],
    ...
  ]
}

Если высота отсутствует, её необходимо подгружать из внешнего DEM или добавлять вручную.


Базовая формула уклона между двумя точками

Алгоритм:

  1. вычислить расстояние между точками
  2. вычислить разницу высот
  3. разделить вертикаль на горизонталь
import distance from "@turf/distance";

function slope(point1, point2) {
  const d = distance(point1, point2, { units: "meters" });

  const z1 = point1.geometry.coordinates[2] || 0;
  const z2 = point2.geometry.coordinates[2] || 0;

  const rise = z2 - z1;

  return rise / d;
}

Использование turf.distance для расчёта горизонтали

Функция distance в Turf.js учитывает кривизну Земли и возвращает геодезическое расстояние.

Пример:

import distance from "@turf/distance";

const a = turf.point([37.6173, 55.7558, 150]);
const b = turf.point([37.6250, 55.7600, 200]);

const horizontal = distance(a, b, { units: "meters" });

Важно: результат — именно горизонтальная проекция, а не 3D расстояние.


Уклон в процентах

Для инженерных задач чаще используется процентное выражение:

function slopePercent(point1, point2) {
  const d = distance(point1, point2, { units: "meters" });

  const z1 = point1.geometry.coordinates[2] || 0;
  const z2 = point2.geometry.coordinates[2] || 0;

  const rise = z2 - z1;

  return (rise / d) * 100;
}

Пример интерпретации:

  • 0% — горизонтальная поверхность
  • 5% — слабый подъём
  • 15% — заметный уклон
  • 30% — крутая поверхность


Расчёт уклона по LineString

Для линий уклон рассчитывается по сегментам.

Алгоритм:

  1. разбить LineString на пары точек
  2. вычислить уклон каждого сегмента
  3. агрегировать результат
import lineSliceAlong from "@turf/line-slice-along";
import length from "@turf/length";
import distance from "@turf/distance";

function lineSlope(line) {
  const coords = line.geometry.coordinates;

  const slopes = [];

  for (let i = 0; i < coords.length - 1; i++) {
    const p1 = turf.point(coords[i]);
    const p2 = turf.point(coords[i + 1]);

    const d = distance(p1, p2, { units: "meters" });

    const z1 = coords[i][2] || 0;
    const z2 = coords[i + 1][2] || 0;

    slopes.push((z2 - z1) / d);
  }

  return slopes;
}

Средний уклон линии

Средний уклон может вычисляться двумя способами:

1. Арифметическое среднее сегментов

const avg = slopes.reduce((a, b) => a + b, 0) / slopes.length;

2. Общий уклон (более корректный)

function totalSlope(line) {
  const coords = line.geometry.coordinates;

  const start = turf.point(coords[0]);
  const end = turf.point(coords[coords.length - 1]);

  const d = distance(start, end, { units: "meters" });

  const rise = coords[coords.length - 1][2] - coords[0][2];

  return rise / d;
}

Второй вариант используется чаще в инженерной геодезии.


Работа с отсутствующими высотами

При отсутствии z-координаты используются внешние источники:

  • цифровые модели рельефа (DEM)
  • API высот
  • растрированные слои

После получения высот координаты дополняются:

function addElevation(point, elevation) {
  const [lng, lat] = point.geometry.coordinates;

  return turf.point([lng, lat, elevation]);
}

Уклон в градусах

Для перевода отношения в угол используется арктангенс:

function slopeDegrees(point1, point2) {
  const d = distance(point1, point2, { units: "meters" });

  const z1 = point1.geometry.coordinates[2] || 0;
  const z2 = point2.geometry.coordinates[2] || 0;

  const rise = z2 - z1;

  return Math.atan(rise / d) * (180 / Math.PI);
}

Нормализация уклона и ограничения

При вычислениях возникают крайние случаи:

  • d → 0 (почти одинаковые точки)
  • отсутствующая высота
  • шум в DEM данных

Защита:

if (d < 0.001) return 0;

или сглаживание:

const smoothed = slopes.map((s, i, arr) =>
  (arr[i - 1] + s + arr[i + 1]) / 3
);

Применение в анализе рельефа

Уклон используется для:

  • анализа проходимости маршрутов
  • расчёта энергозатрат движения
  • проектирования дорог
  • моделирования водостока
  • оценки риска эрозии

При комбинировании с другими функциями Turf.js возможно построение комплексных моделей поверхности, включая профили высот и градиенты.


Сегментация маршрута по уклону

Маршрут можно классифицировать:

function classifySlope(value) {
  const percent = Math.abs(value) * 100;

  if (percent < 3) return "плоский";
  if (percent < 8) return "умеренный";
  if (percent < 15) return "крутой";
  return "очень крутой";
}

Применение к линии:

const segments = slopes.map(s => ({
  slope: s,
  type: classifySlope(s)
}));

Векторное представление уклона

Для более сложных расчётов уклон представляется как вектор:

  • направление движения
  • вертикальная составляющая

Это позволяет анализировать:

  • максимальный подъём
  • минимальный спуск
  • критические участки маршрута
function vectorSlope(p1, p2) {
  const d = distance(p1, p2, { units: "meters" });

  const rise = (p2.geometry.coordinates[2] || 0) -
               (p1.geometry.coordinates[2] || 0);

  return {
    slope: rise / d,
    direction: p1.geometry.coordinates
  };
}

Обобщённая схема вычисления

  1. Получение координат
  2. Подстановка высот
  3. Расчёт расстояния через геодезическую формулу
  4. Вычисление Δh
  5. Нормализация результата
  6. Классификация или агрегация