Работа с координатами

В геоинформационных системах базовой единицей данных выступает координатная пара, описывающая положение точки на поверхности Земли. В контексте Turf.js работа с координатами строится на строгом соблюдении формата GeoJSON, где порядок значений фиксирован: [долгота, широта].

Такой порядок принципиален. Ошибка в перестановке значений приводит к смещению объектов на тысячи километров, поскольку интерпретация координат становится некорректной относительно глобальной системы WGS84.


Формат координат GeoJSON

GeoJSON определяет координаты как массив чисел:

[longitude, latitude]

Примеры:

// Алматы
[76.8897, 43.2389]

// Караганда
[73.0850, 49.8060]

В Turf.js все геометрические операции опираются именно на этот стандарт, без исключений.


Создание точек

Базовая операция — создание геометрической точки.

import { point } from "@turf/turf";

const p = point([73.0850, 49.8060]);

Объект результата:

{
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [73.085, 49.806]
  },
  properties: {}
}

Точка является фундаментальной сущностью, от которой строятся остальные геометрии.


Извлечение координат из объектов

Получение координаты точки

import { getCoord } from "@turf/turf";

const coord = getCoord(p);

Результат:

[73.085, 49.806]

Функция работает только с Feature или Geometry.


Извлечение всех координат

Для сложных геометрий применяется:

import { coordAll } from "@turf/turf";

Пример с линией:

const line = {
  type: "Feature",
  geometry: {
    type: "LineString",
    coordinates: [
      [73.0, 49.8],
      [74.0, 50.0],
      [75.0, 50.2]
    ]
  }
};

coordAll(line);

Результат:

[
  [73.0, 49.8],
  [74.0, 50.0],
  [75.0, 50.2]
]

Для Polygon возвращаются все вершины всех колец.


Работа с линиями и полигонами

Координаты в сложных структурах имеют вложенную организацию:

LineString

[
  [lon, lat],
  [lon, lat]
]

Polygon

[
  [
    [lon, lat],
    [lon, lat],
    [lon, lat],
    [lon, lat]
  ]
]

Первое кольцо — внешний контур, последующие — отверстия.


Расчёт расстояний между координатами

Одна из ключевых операций — вычисление геодезического расстояния.

import { distance } from "@turf/turf";

const from = [73.0850, 49.8060];
const to = [76.8897, 43.2389];

distance(from, to, { units: "kilometers" });

Особенности:

  • учитывается кривизна Земли
  • используется сфера или эллипсоидное приближение
  • результат зависит от параметра units

Поддерживаемые единицы:

  • kilometers
  • meters
  • miles
  • radians
  • degrees

Направление между координатами

Азимут (bearing) определяет угол направления от одной точки к другой.

import { bearing } from "@turf/turf";

const angle = bearing(
  [73.0850, 49.8060],
  [76.8897, 43.2389]
);

Результат:

-145.32

Значение интерпретируется в градусах относительно северного направления.


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

Функция destination позволяет вычислить новую точку:

import { destination } from "@turf/turf";

const start = [73.0850, 49.8060];

const result = destination(start, 100, 90, {
  units: "kilometers"
});

Параметры:

  • исходная координата
  • расстояние
  • угол (bearing)
  • единицы измерения

Средняя точка между координатами

Для интерполяции используется midpoint:

import { midpoint } from "@turf/turf";

const a = [73.0850, 49.8060];
const b = [76.8897, 43.2389];

midpoint(a, b);

Результат — географически корректная середина с учётом кривизны Земли.


Работа с массивами координат

Координаты часто хранятся в виде массивов, требующих нормализации.

Фильтрация некорректных значений

const coords = [
  [73.08, 49.80],
  null,
  [74.00, 50.00],
  undefined
];

const clean = coords.filter(Boolean);

Округление координат

Избыточная точность приводит к росту объёма данных:

function roundCoord([lon, lat], precision = 5) {
  return [
    Number(lon.toFixed(precision)),
    Number(lat.toFixed(precision))
  ];
}

Bounding Box (границы координат)

Bounding box описывает минимальный прямоугольник, охватывающий геометрию.

import { bbox } from "@turf/turf";

const poly = {
  type: "Feature",
  geometry: {
    type: "Polygon",
    coordinates: [
      [
        [73, 49],
        [74, 49],
        [74, 50],
        [73, 50],
        [73, 49]
      ]
    ]
  }
};

bbox(poly);

Результат:

[minLon, minLat, maxLon, maxLat]

Построение полигона из bbox

import { bboxPolygon } from "@turf/turf";

const box = [73, 49, 74, 50];

bboxPolygon(box);

Проверка валидности координат

Типичные ошибки:

  • широта вне диапазона [-90, 90]
  • долгота вне диапазона [-180, 180]
  • перепутанный порядок координат

Пример проверки:

function isValid([lon, lat]) {
  return (
    typeof lon === "number" &&
    typeof lat === "number" &&
    lat >= -90 && lat <= 90 &&
    lon >= -180 && lon <= 180
  );
}

Преобразование форматов координат

Часто данные приходят в формате [lat, lon], что требует преобразования:

function toGeoJSONCoord([lat, lon]) {
  return [lon, lat];
}

Массовая конвертация:

const converted = coords.map(([lat, lon]) => [lon, lat]);

Нормализация координатных структур

Для унификации входных данных применяется приведение к Feature:

import { point } from "@turf/turf";

function normalize(input) {
  if (Array.isArray(input)) {
    return point(input);
  }
  return input;
}

Извлечение координат из сложных структур

Polygon → все точки:

import { coordAll } from "@turf/turf";

coordAll(polygonFeature);

FeatureCollection → все координаты:

coordAll(featureCollection);

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

При работе с наборами координат важны свойства:

  • замкнутость полигонов (первая и последняя точка совпадают)
  • непрерывность линий
  • отсутствие NaN и null значений
  • сохранение порядка обхода (clockwise / counterclockwise)

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

function isClosed(ring) {
  const a = ring[0];
  const b = ring[ring.length - 1];
  return a[0] === b[0] && a[1] === b[1];
}

Интерполяция координат

Для сглаживания маршрутов используется линейная интерполяция:

function interpolate(a, b, t) {
  return [
    a[0] + (b[0] - a[0]) * t,
    a[1] + (b[1] - a[1]) * t
  ];
}

Особенности работы с долгими цепочками координат

При обработке больших массивов:

  • предпочтительно использовать TypedArray для числовых операций
  • минимизировать копирование массивов
  • избегать глубокой вложенности
  • контролировать точность на этапе записи, а не вычислений

Координатная арифметика в геопространственных вычислениях

Несмотря на внешнюю простоту формата [lon, lat], операции над координатами требуют учета сферической модели Земли.

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

const shifted = [
  lon + deltaLon,
  lat + deltaLat
];

Для глобальных вычислений применяются функции типа destination, distance, bearing, обеспечивающие корректную геодезическую интерпретацию.