Площади полигонов

В CesiumJS полигон рассматривается не как плоская фигура в двумерной декартовой системе координат, а как геометрический объект, наложенный на поверхность эллипсоида WGS84. Это фундаментально влияет на способы вычисления площади: классические формулы планиметрии становятся неточными при больших размерах или при расположении в высоких широтах.

Площадь полигона в CesiumJS определяется в зависимости от выбранной модели вычисления:

  • геодезическая (на поверхности эллипсоида) — наиболее корректная для глобальных координат;
  • плоская (в проекции или локальной системе координат) — приближённая, используется для небольших объектов;
  • трёхмерная аппроксимация — через разбиение на треугольники в мировых координатах.

Представление полигона: PolygonHierarchy

В CesiumJS полигон задаётся через структуру иерархии:

const polygon = new Cesium.Entity({
    polygon: {
        hierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray([
                30.0, 10.0,
                40.0, 10.0,
                40.0, 20.0,
                30.0, 20.0
            ])
        )
    }
});

PolygonHierarchy содержит:

  • внешний контур;
  • внутренние вырезы (holes), также задаваемые как вложенные иерархии.

Именно эта структура используется далее при вычислении площади, так как наличие отверстий требует вычитания соответствующих площадей.


Площадь на эллипсоиде: геодезический подход

Наиболее точный способ вычисления площади в CesiumJS основан на геодезических свойствах эллипсоида.

Ключевой инструмент — EllipsoidGeodesic, который позволяет работать с дугами большого круга и учитывать кривизну поверхности.

Идея вычисления:

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

CesiumJS не предоставляет одной универсальной функции площади полигона, поэтому используется комбинация низкоуровневых геодезических вычислений:

  • преобразование Cartesian3 → Cartographic;
  • вычисление сферического/эллипсоидального вклада;
  • суммирование ориентированных площадей.

Приближённый расчёт через триангуляцию в Cartesian3

Практически распространённый метод — разбиение полигона на треугольники в трёхмерном пространстве.

Каждый треугольник задаётся тремя точками:

  • A, B, C в системе Cartesian3.

Площадь вычисляется через векторное произведение:

function triangleArea3D(a, b, c) {
    const ab = Cesium.Cartesian3.subtract(b, a, new Cesium.Cartesian3());
    const ac = Cesium.Cartesian3.subtract(c, a, new Cesium.Cartesian3());
    const cross = Cesium.Cartesian3.cross(ab, ac, new Cesium.Cartesian3());
    return Cesium.Cartesian3.magnitude(cross) * 0.5;
}

Общая площадь полигона:

function polygonAreaCartesian(positions) {
    let area = 0.0;
    const origin = positions[0];

    for (let i = 1; i < positions.length - 1; i++) {
        area += triangleArea3D(origin, positions[i], positions[i + 1]);
    }

    return area;
}

Данный метод:

  • прост в реализации;
  • быстро работает;
  • даёт приближение, зависящее от кривизны поверхности.

Геодезическое вычисление площади через координаты

Более корректный подход использует перевод координат в географические:

function polygonAreaGeodesic(positions) {
    const ellipsoid = Cesium.Ellipsoid.WGS84;
    let total = 0.0;

    for (let i = 0; i < positions.length; i++) {
        const p1 = Cesium.Cartographic.fromCartesian(positions[i]);
        const p2 = Cesium.Cartographic.fromCartesian(
            positions[(i + 1) % positions.length]
        );

        const geodesic = new Cesium.EllipsoidGeodesic(p1, p2);
        const distance = geodesic.surfaceDistance;

        total += p1.longitude * p2.latitude - p2.longitude * p1.latitude;
    }

    return Math.abs(total) * ellipsoid.maximumRadius * ellipsoid.maximumRadius / 2.0;
}

Такой подход ближе к сферической модели и используется как основа для приближённых расчётов больших областей.


Динамические полигоны и CallbackProperty

В CesiumJS координаты полигона могут изменяться во времени. Для этого используется CallbackProperty, что влияет и на вычисление площади.

polygon: {
    hierarchy: new Cesium.CallbackProperty(function () {
        return new Cesium.PolygonHierarchy(dynamicPositions);
    }, false)
}

При динамическом обновлении:

  • площадь должна пересчитываться при каждом изменении координат;
  • кеширование становится критически важным;
  • частота пересчёта влияет на производительность сцены.

Погрешности и особенности вычислений

Основные источники погрешностей:

1. Кривизна эллипсоида

  • плоские методы дают искажения на больших расстояниях;
  • особенно заметно ближе к полюсам.

2. Разреженность вершин

  • чем меньше вершин, тем сильнее отклонение от реальной формы;
  • аппроксимация ломается на вогнутых участках.

3. Самопересечения

  • некорректные полигоны могут давать некорректную площадь;
  • требуется предварительная валидация геометрии.

4. Высотная компонента

  • наличие height у координат влияет на 3D-метод;
  • геодезическая площадь обычно игнорирует высоту.

Оптимизация вычислений площади

При работе с большим количеством полигонов в сцене CesiumJS важно учитывать производительность вычислений.

Применяются следующие подходы:

Кэширование результатов

  • сохранение площади при неизменной геометрии;
  • использование хэширования массива координат.

Упрощение геометрии

  • алгоритмы редукции вершин (Douglas–Peucker);
  • уменьшение плотности точек без потери формы.

Асинхронные вычисления

  • перенос расчётов вне рендера сцены;
  • использование Web Worker для тяжёлых операций.

Локальная система координат

  • перевод полигона в ENU (East-North-Up);
  • вычисление площади в плоской системе для малых объектов.
const center = Cesium.BoundingSphere.fromPoints(positions).center;
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

Комбинированные подходы

На практике часто используется гибридная стратегия:

  • малые полигоны → Cartesian3 триангуляция;
  • крупные полигоны → геодезический метод;
  • динамические сцены → адаптивный выбор метода.

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