В архитектуре Mapbox GL JS источники (sources) являются фундаментальным слоем данных, на котором строится визуализация карты. Каждый слой (layer) опирается на источник, а обновление данных в реальном времени часто происходит через методы, связанные с источниками.
Два ключевых метода для динамической работы с данными —
setData и getSource — используются для
управления GeoJSON-источниками и получения доступа к их состоянию.
Наиболее гибкий тип источника в Mapbox GL JS — geojson.
Он позволяет обновлять данные без перезагрузки карты, что критично
для:
Пример базового источника:
map.addSource('points', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
});
setData используется для полной замены данных внутри
GeoJSON-источника. Он не изменяет существующий объект частично, а
перезаписывает весь набор данных.
source.setData(data);
data — объект GeoJSON (Feature,
FeatureCollection или URL к GeoJSON)Каждый вызов setData заменяет текущие данные
источника:
// FeatureCollection
{
type: 'FeatureCollection',
features: [...]
}
// Feature
{
type: 'Feature',
geometry: {...},
properties: {...}
}
// URL
'https://example.com/data.geojson'
const source = map.getSource('points');
source.setData({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [71.4304, 51.1284]
},
properties: {
title: 'Объект A'
}
}
]
});
setData является ресурсоёмкой операцией, так как:
Рекомендуется:
function updatePoints(points) {
const features = points.map(p => ({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: p.coords
},
properties: p.props
}));
map.getSource('points').setData({
type: 'FeatureCollection',
features
});
}
При частичных изменениях часто эффективнее:
getSource используется для получения объекта источника
по его идентификатору. Это основной способ доступа к источнику после его
регистрации через addSource.
map.getSource(id);
id — строковый идентификатор источникаМетод возвращает объект источника, соответствующий типу:
GeoJSONSourceVectorSourceRasterSourceImageSourceVideoSourceДля динамического изменения данных применяется только
GeoJSONSource.
const source = map.getSource('points');
Дальнейшая работа зависит от типа источника:
if (source && source.setData) {
source.setData(newData);
}
При работе с динамическими интерфейсами важно учитывать асинхронность загрузки карты:
if (map.getSource('points')) {
map.getSource('points').setData(data);
}
Поддерживает:
setDataloadedserializeНе поддерживает:
map.getSource('points').setData(data); // ошибка, если карта не готова
Решение — использовать событие:
map.on('load', () => {
map.getSource('points').setData(data);
});
const source = map.getSource('vector-data');
source.setData(data); // ошибка, если источник не GeoJSON
Оба метода часто используются вместе для управления состоянием данных:
map.on('load', () => {
const source = map.getSource('points');
source.setData({
type: 'FeatureCollection',
features: []
});
});
В более сложных сценариях структура выглядит так:
getSourcesetDataПри потоковой передаче данных (например, GPS-трекинг) используется циклическое обновление:
setInterval(() => {
const source = map.getSource('track');
source.setData({
type: 'FeatureCollection',
features: getLatestTrack()
});
}, 1000);
При использовании setData важно соблюдать корректность
GeoJSON:
typeНекорректные данные приводят к:
Так как setData полностью заменяет источник, для
сохранения состояния применяется паттерн merge:
const source = map.getSource('points');
const current = source._data;
source.setData({
type: 'FeatureCollection',
features: [
...current.features,
newFeature
]
});
Любой слой, связанный с GeoJSON-источником:
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points'
});
автоматически реагирует на:
setDataбез необходимости ручного перерисовывания.
При работе с тысячами объектов:
setData становится узким местомРекомендуемые подходы:
getSource — точка доступа к объекту источникаsetData — механизм полной замены данных GeoJSON