Геодезические вычисления в контексте визуализации в deck.gl опираются на представление координат на сфере и их последующую трансформацию в экранное пространство через проекцию Web Mercator. Базовая проблема заключается в том, что географические координаты (долгота, широта) задаются на эллипсоиде WGS84, тогда как большинство визуальных операций выполняется в декартовой системе координат после проецирования.
В deck.gl исходные данные почти всегда представлены в виде пар:
Эти значения интерпретируются как точки на сфере, где радиус Земли принимается константой, а вычисления выполняются в геодезической модели приближённо сферического типа.
Ключевое преобразование:
Web Mercator используется как стандарт де-факто для WebGL-визуализации, поскольку обеспечивает линейность локальных масштабов и удобство работы с тайловыми системами.
Проекция задаётся следующими преобразованиями:
[ x = R ]
[ y = R (( + ))]
где:
Особенность заключается в экспоненциальном растяжении областей около полюсов, что напрямую влияет на визуальные артефакты при интерполяции геодезических линий.
Линейная интерполяция в экранных координатах приводит к искажению маршрутов. Поэтому в deck.gl применяется сферическая интерполяция.
Для двух точек (A) и (B) на сфере используется интерполяция по великому кругу:
[ (A, B, t) = A + B]
где:
Такой подход обеспечивает корректное построение дуг, соответствующих кратчайшему пути на сфере.
В слое ArcLayer геодезия реализуется через построение дуг между источником и целью.
Основная особенность:
Фрагмент вычисления промежуточной точки:
function interpolateGreatCircle(p0, p1, t) {
const [lng0, lat0] = p0;
const [lng1, lat1] = p1;
const φ0 = lat0 * Math.PI / 180;
const λ0 = lng0 * Math.PI / 180;
const φ1 = lat1 * Math.PI / 180;
const λ1 = lng1 * Math.PI / 180;
const x0 = Math.cos(φ0) * Math.cos(λ0);
const y0 = Math.cos(φ0) * Math.sin(λ0);
const z0 = Math.sin(φ0);
const x1 = Math.cos(φ1) * Math.cos(λ1);
const y1 = Math.cos(φ1) * Math.sin(λ1);
const z1 = Math.sin(φ1);
const dot = x0 * x1 + y0 * y1 + z0 * z1;
const θ = Math.acos(Math.min(Math.max(dot, -1), 1));
const sinθ = Math.sin(θ);
const a = Math.sin((1 - t) * θ) / sinθ;
const b = Math.sin(t * θ) / sinθ;
const x = a * x0 + b * x1;
const y = a * y0 + b * y1;
const z = a * z0 + b * z1;
return [
Math.atan2(y, x) * 180 / Math.PI,
Math.asin(z) * 180 / Math.PI
];
}
Прямолинейная интерполяция:
lng = lng0 + (lng1 - lng0) * t;
lat = lat0 + (lat1 - lat0) * t;
Такая модель приводит к:
deck.gl избегает этого через использование геодезических преобразований в слоях, где важна точность траектории (ArcLayer, GreatCircleLayer).
Проблема возникает при переходе через ±180° долготы. Без коррекции линия строится через весь глобус.
Алгоритм нормализации:
Пример логики:
function normalizeLngDiff(lng0, lng1) {
let delta = lng1 - lng0;
if (delta > 180) lng1 -= 360;
if (delta < -180) lng1 += 360;
return lng1;
}
Это предотвращает разрыв дуги при визуализации потоков между Азией и Америкой.
В deck.gl часто используется параметр altitude для визуального поднятия линий над поверхностью карты.
Важно различать:
В слоях типа ArcLayer высота задаётся как скаляр:
getHeight: d => d.value * scaleFactor
Это значение не влияет на геодезию, но влияет на z-буферизацию и глубину сцены.
GeoJsonLayer работает с геометриями:
Для LineString применяется сегментация:
При включённой опции greatCircle:
В связке с deck.gl используется H3-гексагональная система индексации.
Особенность:
Преимущество:
Расстояние между двумя точками на сфере вычисляется через формулу гаверсинуса:
[ a = ^2() + (_1)(_2)^2()]
[ c = 2 (, )]
[ d = R c]
Этот метод используется при:
При работе с WebGL и float32 возникают ограничения:
Меры стабилизации:
В ряде слоёв deck.gl часть вычислений переносится в vertex shader:
Типичный фрагмент GLSL-логики:
vec3 projectPoint(vec2 lngLat, float radius) {
float lon = radians(lngLat.x);
float lat = radians(lngLat.y);
return vec3(
radius * cos(lat) * cos(lon),
radius * cos(lat) * sin(lon),
radius * sin(lat)
);
}
Это обеспечивает согласованность геодезической модели между CPU и GPU.
Для визуализации потоков используется нормализация векторов:
Такой подход применяется при генерации плавных кривых потоков между регионами, где важна непрерывность направления на глобусе.