TopoJSON

CesiumJS поддерживает работу с геопространственными данными в различных форматах, включая GeoJSON и его топологически оптимизированное расширение — TopoJSON. Последний представляет собой формат, в котором геометрия объектов хранится не как независимые координатные наборы, а как общая топологическая структура. Это позволяет значительно уменьшать размер данных и устранять дублирование границ между соседними полигонами.

TopoJSON особенно полезен при визуализации административных границ, карт стран, регионов и других объектов, где множество геометрий имеют общие ребра.


Принцип топологического хранения данных

В отличие от GeoJSON, где каждая геометрия содержит собственные координаты, TopoJSON вводит понятие арков (arcs) — общих сегментов линий.

Ключевые особенности:

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

Базовая идея заключается в переходе от:

Feature → Geometry → Coordinates

к структуре:

Topology → Arcs → Shared Geometries

Структура TopoJSON-документа

Типичный TopoJSON-файл включает несколько ключевых элементов:

  • type: "Topology" — объявление формата
  • objects — набор геометрических объектов
  • arcs — массив координатных цепочек
  • transform — параметры деквантования координат

Пример структуры:

{
  "type": "Topology",
  "transform": {
    "scale": [0.0001, 0.0001],
    "translate": [0, 0]
  },
  "objects": {
    "regions": {
      "type": "GeometryCollection",
      "geometries": [
        {
          "type": "Polygon",
          "arcs": [[0, 1]]
        }
      ]
    }
  },
  "arcs": [
    [[10, 10], [20, 10], [20, 20], [10, 20], [10, 10]]
  ]
}

Подготовка TopoJSON для CesiumJS

CesiumJS не использует TopoJSON напрямую как первичный формат данных. Обычно применяется промежуточное преобразование в GeoJSON или использование утилит декодирования.

Основной подход:

  1. загрузка TopoJSON
  2. преобразование в GeoJSON
  3. загрузка результата в Cesium через GeoJsonDataSource

Конвертация TopoJSON → GeoJSON

Для преобразования используется библиотека topojson-client.

import * as topojson from "topojson-client";

fetch("regions.topojson")
  .then(res => res.json())
  .then(topoData => {
    const geojson = topojson.feature(
      topoData,
      topoData.objects.regions
    );

    return Cesium.GeoJsonDataSource.load(geojson);
  })
  .then(dataSource => {
    viewer.dataSources.add(dataSource);
    viewer.zoomTo(dataSource);
  });

Ключевая функция:

topojson.feature(topology, object)

Она разворачивает топологическую структуру в стандартный GeoJSON FeatureCollection.


Загрузка данных в CesiumJS

После преобразования данные могут быть визуализированы стандартными средствами Cesium:

const viewer = new Cesium.Viewer("cesiumContainer");

Cesium.GeoJsonDataSource.load(geojson, {
  stroke: Cesium.Color.BLUE,
  fill: Cesium.Color.CYAN.withAlpha(0.4),
  strokeWidth: 2
}).then(dataSource => {
  viewer.dataSources.add(dataSource);
  viewer.zoomTo(dataSource);
});

Особенности визуализации TopoJSON-данных

При работе с такими данными в CesiumJS важно учитывать:

  • геометрии часто содержат множество вложенных полигонов
  • производительность зависит от сложности декодирования
  • оптимизация TopoJSON уменьшает сетевой трафик, но увеличивает CPU-нагрузку при распаковке
  • после конвертации данные становятся обычными GeoJSON-объектами

Использование квантования координат

Одно из ключевых преимуществ TopoJSON — квантование координат.

Формула деквантования:

x = x0 + (quantizedX * scaleX)
y = y0 + (quantizedY * scaleY)

Где:

  • scale задаёт шаг дискретизации
  • translate задаёт смещение координатной системы

Это уменьшает размер файлов до 80% по сравнению с GeoJSON при сложных административных картах.


Работа с многоуровневыми объектами

TopoJSON может содержать несколько слоёв данных:

  • страны
  • регионы
  • административные округа
  • географические зоны

Пример доступа к объекту:

const countries = topoData.objects.countries;
const geojsonCountries = topojson.feature(topoData, countries);

Далее каждый слой может быть загружен отдельно в Cesium как самостоятельный DataSource.


Оптимизация загрузки в CesiumJS

При интеграции больших TopoJSON наборов данных применяются следующие стратегии:

1. Ленивая загрузка

  • загрузка регионов по мере приближения камеры

2. Разделение на тайлы

  • разбиение TopoJSON на несколько файлов

3. Предобработка

  • упрощение геометрий через simplification algorithms

4. Кэширование GeoJSON

  • сохранение результата конвертации для повторного использования

Пример интеграции с динамической подгрузкой

async function loadRegion(url) {
  const topo = await fetch(url).then(r => r.json());

  const geo = topojson.feature(topo, topo.objects.region);

  const ds = await Cesium.GeoJsonDataSource.load(geo, {
    stroke: Cesium.Color.YELLOW,
    fill: Cesium.Color.ORANGE.withAlpha(0.3)
  });

  viewer.dataSources.add(ds);
  return ds;
}

Сравнение GeoJSON и TopoJSON

Характеристика GeoJSON TopoJSON
Дублирование границ есть отсутствует
Размер файла больше меньше
Скорость декодирования выше ниже
Подходит для Cesium напрямую через конвертацию

Типичные сценарии использования

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

Обработка ошибок при загрузке

При работе с TopoJSON в связке с CesiumJS часто возникают следующие проблемы:

  • некорректные ссылки на arcs
  • повреждённая структура objects
  • несовпадение координатных систем
  • чрезмерно сложные полигоны

Базовая проверка:

if (!topoData || topoData.type !== "Topology") {
  throw new Error("Invalid TopoJSON structure");
}

Координатные системы и проекции

CesiumJS использует WGS84 как базовую систему координат. TopoJSON обычно хранит данные в:

  • декартовых координатах
  • нормализованных координатах (после квантования)
  • иногда в EPSG:4326 до преобразования

При загрузке через GeoJSON необходимо обеспечить соответствие WGS84, иначе визуализация будет смещена.


Производственные рекомендации

  • избегать чрезмерно детализированных арок
  • применять упрощение геометрии перед экспортом
  • разбивать крупные TopoJSON-файлы
  • минимизировать глубину вложенности объектов
  • контролировать precision transform

Архитектурная роль TopoJSON в 3D-картах

В системах на базе CesiumJS TopoJSON выполняет роль промежуточного оптимизированного слоя хранения геометрии, который снижает нагрузку на сеть и ускоряет доставку данных, но требует дополнительного этапа декодирования перед рендерингом в 3D-сцене.