Работа с топологическими данными в веб-картографии опирается на компактное представление геометрии, где ключевым форматом выступает TopoJSON. В отличие от GeoJSON, который дублирует координаты для смежных объектов, TopoJSON хранит общие границы один раз и описывает объекты через ссылки на дуги. Такой подход уменьшает размер данных и ускоряет отрисовку карт, особенно при работе с административными границами и плотными географическими слоями.
Библиотека D3.js предоставляет инструменты для преобразования
TopoJSON в GeoJSON-совместимые структуры и извлечения геометрии для
отрисовки SVG или Canvas. Центральными функциями в этом процессе
выступают topojson.feature() и
topojson.mesh().
TopoJSON описывает геометрию через:
Пример упрощённой структуры:
{
"type": "Topology",
"transform": {
"scale": [0.1, 0.1],
"translate": [0, 0]
},
"arcs": [
[[0,0],[10,0],[10,10]],
[[10,10],[0,10],[0,0]]
],
"objects": {
"region": {
"type": "GeometryCollection",
"geometries": [
{ "type": "Polygon", "arcs": [[0,1]] }
]
}
}
}
topojson.feature() преобразует TopoJSON-объект в
стандартный GeoJSON, разворачивая топологические ссылки в полноценные
координаты.
topojson.feature(topology, object)
topology — исходный TopoJSON объектobject — конкретный элемент из
topology.objectsВозвращается объект GeoJSON:
FeatureFeatureCollectionGeometryПри вызове функции происходит:
TopoJSON хранит координаты как дельты, поэтому этап декодирования включает накопление значений:
[ x_i = x_{i-1} + x_i,y_i = y_{i-1} + y_i]
x_i = x_{i-1} + x_i
y_i = y_{i-1} + y_i
import * as topojson from "topojson-client";
d3.json("world.topojson").then(topology => {
const countries = topojson.feature(
topology,
topology.objects.countries
);
svg.selectAll("path")
.data(countries.features)
.enter()
.append("path")
.attr("d", pathGenerator);
});
GeoJSON-результат напрямую используется в
d3.geoPath():
После преобразования возможно:
topojson.mesh() извлекает линейную геометрию
(LineString/MultiLineString), представляющую границы между
объектами.
Функция не возвращает полигоны — только линии.
topojson.mesh(topology, object[, filter])
topology — TopoJSON объектobject — слой или коллекцияfilter — функция отбора границФункция анализирует общие arcs между соседними полигонами.
Если два объекта используют одну дугу, mesh позволяет:
const borders = topojson.mesh(topology, topology.objects.countries);
Результат:
const borders = topojson.mesh(
topology,
topology.objects.countries,
(a, b) => a !== b
);
В этом режиме возвращаются только линии, разделяющие разные объекты.
const internal = topojson.mesh(
topology,
topology.objects.states,
(a, b) => a === b
);
Используется для отображения внутренних административных границ.
svg.append("path")
.datum(topojson.mesh(topology, topology.objects.countries))
.attr("d", pathGenerator)
.attr("fill", "none")
.attr("stroke", "#333");
Типичная структура визуализации:
mesh используется как отдельный слой, чтобы:
TopoJSON позволяет уменьшить размер данных за счёт:
При использовании mesh дополнительно:
После преобразования TopoJSON в GeoJSON данные проходят через географические проекции:
const projection = d3.geoMercator();
const path = d3.geoPath().projection(projection);
geoPathpath без заливкиИспользование feature() без правильного object:
topojson.feature(topology, topology.objects)
Ошибка: требуется конкретный слой, а не весь objects.
Фильтр должен учитывать пары объектов:
(a, b) => a !== b
Иначе границы могут исчезнуть полностью или дублироваться.
TopoJSON требует применения transform для корректных координат. При
ручной обработке без feature() возникают смещения.
Типичная архитектура карты:
const countries = topojson.feature(topology, topology.objects.countries);
const borders = topojson.mesh(topology, topology.objects.countries);
svg.selectAll("countries")
.data(countries.features)
.enter()
.append("path")
.attr("d", path);
svg.append("path")
.datum(borders)
.attr("d", path)
.attr("fill", "none")
.attr("stroke", "#000");
TopoJSON особенно эффективен при:
mesh снижает нагрузку на рендеринг, так как заменяет множество внутренних границ одной геометрией.
mesh можно рассматривать как:
Это делает его полезным не только для визуализации, но и для анализа связности регионов.