Расчёт расстояний и площадей: d3.geoDistance(), d3.geoArea()

Работа с географическими данными в D3.js опирается на сферическую модель Земли, где вычисления выполняются не в декартовой плоскости, а на сфере. Это принципиально меняет подход к расстояниям и площадям: вместо привычной евклидовой геометрии используются угловые величины, выраженные в радианах, а результаты интерпретируются через радиус Земли или через нормированные сферические единицы.


Географические функции D3 работают с координатами в формате GeoJSON, где точки задаются как:

[долгота, широта]

Все вычисления предполагают:

  • сферическую модель Земли
  • координаты в градусах на входе (внутри преобразуются в радианы)
  • использование единичной сферы радиуса 1

Это означает, что любые результаты из d3.geoDistance() и d3.geoArea() возвращаются в радианах или стерадианах и требуют интерпретации.


d3.geoDistance(): расстояние по большой окружности

Математический смысл

d3.geoDistance(a, b) вычисляет угловое расстояние по поверхности сферы между двумя точками, следуя кратчайшему пути по большой окружности.

Фактически возвращается:

[ ]

где θ — центральный угол между радиус-векторами точек.


Формат входных данных

Функция принимает два GeoJSON-координатных массива:

const a = [lon1, lat1];
const b = [lon2, lat2];

const d = d3.geoDistance(a, b);

Интерпретация результата

Результат — это радианы. Чтобы получить привычные единицы расстояния, применяется радиус Земли:

[ distance = R ]

где:

  • R ≈ 6371 км (средний радиус Земли)
  • θ — результат d3.geoDistance

Пример вычисления

import * as d3 from "d3-geo";

const london = [-0.1276, 51.5072];
const newYork = [-74.0060, 40.7128];

const angle = d3.geoDistance(london, newYork);
const distanceKm = 6371 * angle;

console.log(distanceKm);

Геометрические особенности

  • используется формула гаверсинуса или эквивалентная векторная модель
  • результат всегда кратчайший путь по поверхности сферы
  • антиподы дают значение близкое к π (≈ 3.14159)
  • чувствительно к точности координат на полюсах

Частые особенности поведения

  • при одинаковых точках возвращается 0
  • при пересечении даталинии корректно учитывается переход через ±180°
  • не учитывает рельеф или эллипсоидальность Земли

d3.geoArea(): площадь географических объектов

Математический смысл

d3.geoArea() вычисляет сферическую площадь GeoJSON-объекта, выраженную в стерадианах.

Для единичной сферы:

  • вся поверхность сферы = (4) стерадиан
  • полушарие = (2)
  • значение всегда находится в диапазоне ([0, 4])

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

Функция принимает любой GeoJSON-объект:

  • Polygon
  • MultiPolygon
  • Feature
  • FeatureCollection

Пример:

const polygon = {
  type: "Polygon",
  coordinates: [
    [
      [-10, 0],
      [10, 0],
      [10, 10],
      [-10, 10],
      [-10, 0]
    ]
  ]
};

const area = d3.geoArea(polygon);

Геометрический смысл результата

Результат — доля поверхности сферы:

[ A = ]

где Ω — телесный угол (solid angle).

Чтобы перевести в долю поверхности Земли:

[ fraction = ]

Чтобы получить площадь в км²:

[ area_{km^2} = A R^2]


Пример перевода в физические единицы

const earthRadius = 6371;

const areaSteradians = d3.geoArea(polygon);
const areaKm2 = areaSteradians * earthRadius * earthRadius;

Особенности вычисления полигонов

Ориентация кольца

  • внешние кольца обычно считаются против часовой стрелки
  • внутренние кольца (holes) вычитаются

MultiPolygon

  • площади всех частей суммируются
  • отверстия учитываются как отрицательные области

Поведение на сложных формах

  • самопересекающиеся полигоны приводят к неоднозначностям
  • алгоритм использует сферическую триангуляцию
  • возможны численные погрешности на больших полигонах

Сравнение d3.geoDistance и d3.geoArea

Функция Вход Выход Геометрический смысл
geoDistance 2 точки радианы угол большой окружности
geoArea GeoJSON объект стерадианы площадь на сфере

Численные особенности и точность

Обе функции работают в условиях:

  • ограниченной численной точности IEEE-754
  • преобразования градусов в радианы
  • векторных операций на сфере

Потенциальные источники ошибок:

  • очень малые расстояния (потеря точности)
  • почти антиподальные точки
  • полигоны с тысячами вершин
  • вырожденные геометрии

Географическая интерпретация результатов

Расстояние

Угловая мера позволяет:

  • сравнивать расстояния независимо от масштаба
  • строить ранжирование близости
  • выполнять кластеризацию точек на сфере

Площадь

Стерадианная мера позволяет:

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

Использование в вычислительных цепочках

Фильтрация объектов по расстоянию

const filtered = points.filter(p =>
  d3.geoDistance(p, center) < 0.5
);

Оценка площади региона перед рендерингом

if (d3.geoArea(region) > 1) {
  renderHighDetail(region);
} else {
  renderSimplified(region);
}

Связь с проекциями

Важно учитывать, что:

  • d3.geoDistance() и d3.geoArea() не зависят от проекций
  • вычисления выполняются в географических координатах
  • проекции применяются только на этапе визуализации

Это позволяет:

  • отделить геометрию от отображения
  • сохранять точность при смене проекций
  • использовать единые расчёты для разных картографических стилей