В основе отслеживания перемещения в Mapbox GL JS лежит постоянное обновление источника данных и синхронизация состояния карты с поступающими координатами. Основные сценарии включают отображение текущего положения объекта, построение траектории движения, управление камерой карты и плавную анимацию перемещения маркера.
Ключевым элементом становится GeoJSON source, который
динамически изменяет координаты точки или линии. Структура обычно
строится вокруг объекта Feature:
const geojsonSource = {
type: "geojson",
data: {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [0, 0]
}
}
]
}
};
Добавление источника на карту:
map.addSource("tracked-point", geojsonSource);
Дальнейшее обновление координат выполняется через
setData, что обеспечивает полную перерисовку связанного
слоя:
map.getSource("tracked-point").setData({
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [lng, lat]
}
}
]
});
Для получения данных о перемещении используется браузерный API геолокации:
navigator.geolocation.watchPosition(
(position) => {
const lng = position.coords.longitude;
const lat = position.coords.latitude;
},
(error) => {
console.error(error);
},
{
enableHighAccuracy: true,
maximumAge: 0,
timeout: 5000
}
);
Метод watchPosition обеспечивает потоковое обновление
координат, что позволяет реализовать непрерывное отслеживание
движения.
Для визуализации перемещения часто используется Marker,
синхронизируемый с координатами:
const marker = new mapboxgl.Marker()
.setLngLat([0, 0])
.addTo(map);
Обновление позиции маркера:
marker.setLngLat([lng, lat]);
При высокочастотных обновлениях предпочтительно использовать оптимизацию через ограничение частоты перерисовки, чтобы избежать перегрузки рендеринга.
Для отображения маршрута используется линия LineString,
которая расширяется при поступлении новых координат.
const route = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: []
}
};
Обновление траектории:
route.geometry.coordinates.push([lng, lat]);
map.getSource("route").setData(route);
Такой подход формирует непрерывную линию перемещения объекта на карте.
Резкие скачки координат устраняются через интерполяцию. Базовый
подход основан на requestAnimationFrame:
function animate(from, to, progress) {
return [
from[0] + (to[0] - from[0]) * progress,
from[1] + (to[1] - from[1]) * progress
];
}
Цикл анимации:
let start;
const duration = 1000;
function step(timestamp) {
if (!start) start = timestamp;
const progress = Math.min((timestamp - start) / duration, 1);
const current = animate(prevCoords, nextCoords, progress);
marker.setLngLat(current);
if (progress < 1) {
requestAnimationFrame(step);
}
}
Этот механизм сглаживает перемещение и делает визуализацию более стабильной.
Для удержания объекта в центре экрана используется изменение центра карты:
map.setCenter([lng, lat]);
При необходимости добавляется плавность:
map.easeTo({
center: [lng, lat],
duration: 500
});
Более продвинутый вариант включает управление наклоном и масштабом:
map.easeTo({
center: [lng, lat],
zoom: 15,
bearing: heading,
pitch: 45,
duration: 700
});
Направление вычисляется на основе разницы между предыдущей и текущей точками:
const dx = lng2 - lng1;
const dy = lat2 - lat1;
const heading = Math.atan2(dx, dy) * (180 / Math.PI);
Полученное значение используется для поворота карты или иконки маркера.
Встроенный компонент Mapbox GL JS предоставляет готовую реализацию трекинга:
const geolocate = new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
});
map.addControl(geolocate);
Контрол автоматически управляет обновлением координат и отображением позиции пользователя, включая направление движения.
При отслеживании нескольких объектов используется структура
FeatureCollection, где каждый объект имеет уникальный
идентификатор:
const collection = {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: { id: 1 },
geometry: { type: "Point", coordinates: [lng1, lat1] }
},
{
type: "Feature",
properties: { id: 2 },
geometry: { type: "Point", coordinates: [lng2, lat2] }
}
]
};
Обновление выполняется целиком через setData, что
гарантирует консистентность отображения.
При высокой частоте входящих координат используется буферизация:
setDatarequestAnimationFrame вместо прямых
обновленийТакой подход снижает нагрузку на WebGL-рендерер карты.
В 3D-режиме движение объекта дополняется управлением перспективой:
map.setPitch(60);
map.setBearing(heading);
Комбинация наклона и поворота позволяет визуально согласовать движение объекта с направлением камеры, создавая эффект навигации в пространстве.
При подключении внешних источников координат (WebSocket, SSE) обновление источников карты синхронизируется с входящим потоком:
socket.onmess age = (event) => {
const data = JSON.parse(event.data);
map.getSource("tracked-point").setData(data);
};
Это позволяет отображать движение объектов в реальном времени без промежуточных задержек на стороне клиента.
При построении системы трекинга важно разделять:
Такая модель обеспечивает контроль над визуальной непрерывностью даже при потере пакетов данных или задержках сети.