Визуализация географических данных в D3.js основана на преобразовании
координат сферической модели Земли (широта/долгота) в двумерные
координаты экрана. Этот процесс выполняется с помощью географических
проекций, каждая из которых определяет математическое отображение
поверхности сферы на плоскость. В D3.js проекции реализованы как
функции, принимающие координаты вида [λ, φ] (долгота,
широта) и возвращающие координаты [x, y].
Основной набор проекций находится в модуле d3-geo. Он
предоставляет широкий выбор методов, различающихся по характеру
искажений, назначению и вычислительной модели.
Проекция в D3.js представляет собой функцию:
projection([longitude, latitude]) → [x, y]
Дополнительно каждая проекция поддерживает обратное преобразование:
projection.invert([x, y]) → [longitude, latitude]
Ключевые параметры географических проекций:
Типичный конвейер построения карты:
d3.geoPath(projection)Проекция Меркатора — одна из самых распространённых в веб-картографии.
Проекция основана на преобразовании:
где λ — долгота, φ — широта в радианах.
const projection = d3.geoMercator()
.scale(150)
.translate([width / 2, height / 2]);
const path = d3.geoPath().projection(projection);
Ортографическая проекция имитирует вид Земли из космоса.
Точка отображается через ортогональное проецирование:
const projection = d3.geoOrthographic()
.scale(200)
.translate([width / 2, height / 2])
.rotate([0, -30]);
Специальная составная проекция для США.
geoAlbersUsa — не единая математическая модель, а
композиция нескольких проекций:
const projection = d3.geoAlbersUsa()
.scale(1000)
.translate([width / 2, height / 2]);
Базовая коническая равновеликая проекция.
const projection = d3.geoAlbers()
.center([0, 55])
.rotate([4, 0])
.parallels([50, 60])
.scale(1200)
.translate([width / 2, height / 2]);
Простейшая проекция (Plate Carrée).
const projection = d3.geoEquirectangular()
.scale(140)
.translate([width / 2, height / 2]);
Проекция Natural Earth
const projection = d3.geoNaturalEarth1()
.scale(160)
.translate([width / 2, height / 2]);
Стереографическая проекция
Проекция строится через пересечение линии от точки сферы к противоположной точке проекции с плоскостью.
const projection = d3.geoStereographic()
.scale(250)
.translate([width / 2, height / 2])
.rotate([0, -30]);
Равновеликая азимутальная проекция
const projection = d3.geoAzimuthalEqualArea()
.scale(200)
.translate([width / 2, height / 2])
.center([20, 0]);
projection.scale(200);
Масштаб влияет на размер всей карты без изменения геометрии.
projection.center([longitude, latitude]);
Определяет географическую точку, которая будет находиться в центре отображения.
projection.rotate([λ, φ, γ]);
Используется для:
D3.js предоставляет автоматическую подгонку:
projection.fitSize([width, height], geojson);
или
projection.fitExtent([[x0, y0], [x1, y1]], geojson);
Эти методы:
Проекции редко используются напрямую. Основной интерфейс рендеринга —
d3.geoPath.
const path = d3.geoPath().projection(projection);
Он:
Для Canvas:
const path = d3.geoPath(projection).context(canvasContext);
Каждая проекция сохраняет одни свойства ценой других:
Фундаментальное ограничение:
любая проекция сферической поверхности на плоскость неизбежно вносит искажения, поэтому выбор определяется задачей визуализации.
D3 позволяет создавать пользовательские проекции:
const projection = d3.geoProjection(function(lambda, phi) {
return [
lambda * 200,
phi * 200
];
});
Также возможна инверсия:
projection.invert = function(x, y) {
return [
x / 200,
y / 200
];
};
Это открывает возможность:
projection.precision(0.1);
Для сложных GeoJSON важно балансировать:
projection.clipAngle(90);
Ограничивает отображение полусферой (актуально для globes).
projection.clipExtent([[0, 0], [width, height]]);
Обрезает всё за пределами прямоугольника экрана.
Внутри d3-geo каждая проекция:
Геометрические преобразования включают:
При работе с GeoJSON структура данных не изменяется, изменяется только визуальное представление:
d3.json("world.geojson").then(data => {
svg.selectAll("path")
.data(data.features)
.join("path")
.attr("d", path);
});
Проекция остаётся независимым слоем между данными и визуализацией, что позволяет: