Источник (source) в MapLibre GL JS представляет собой объект, поставляющий географические данные для отображения на карте. Все визуальные слои (layers) получают данные именно из источников. Если источник настроен неправильно, отсутствует, недоступен или содержит ошибки в данных, это приводит к сбоям отображения, пустым слоям, ошибкам консоли и проблемам производительности.
Большинство трудностей при работе с картографическими приложениями связано не с настройкой слоёв, а именно с источниками данных.
Основные типы источников:
Каждый тип имеет собственные особенности и набор типичных проблем.
Одна из самых распространённых ошибок возникает, когда слой ссылается на несуществующий источник.
Некорректный пример:
map.addLayer({
id: 'cities',
type: 'circle',
source: 'city-data'
});
Если источник не был зарегистрирован:
map.addSource('cities-data', {
type: 'geojson',
data: 'cities.geojson'
});
в консоли появится сообщение наподобие:
Source "city-data" not found
Причина заключается в несовпадении идентификаторов.
Правильный вариант:
map.addSource('city-data', {
type: 'geojson',
data: 'cities.geojson'
});
map.addLayer({
id: 'cities',
type: 'circle',
source: 'city-data'
});
Полезно придерживаться единого соглашения об именовании источников и слоёв.
MapLibre обрабатывает слои и источники последовательно. Если слой создаётся раньше соответствующего источника, возникает ошибка.
Некорректно:
map.addLayer({
id: 'roads',
type: 'line',
source: 'roads-source'
});
map.addSource('roads-source', {
type: 'geojson',
data: roadsData
});
Корректно:
map.addSource('roads-source', {
type: 'geojson',
data: roadsData
});
map.addLayer({
id: 'roads',
type: 'line',
source: 'roads-source'
});
Особенно часто такая проблема появляется при асинхронной загрузке данных.
Многие методы становятся доступными только после полной инициализации карты.
Ошибка:
const map = new maplibregl.Map({...});
map.addSource('buildings', {
type: 'geojson',
data: 'buildings.geojson'
});
В некоторых ситуациях карта ещё не готова принимать изменения.
Рекомендуемый подход:
map.on('load', () => {
map.addSource('buildings', {
type: 'geojson',
data: 'buildings.geojson'
});
});
Событие load гарантирует готовность стиля и внутренних
компонентов карты.
GeoJSON является самым популярным типом источников, однако именно с ним связано большинство ошибок.
Пример подключения:
map.addSource('parks', {
type: 'geojson',
data: '/data/parks.geojson'
});
Возможные причины неудачной загрузки:
Проверка обычно начинается с вкладки Network в инструментах разработчика браузера.
MapLibre ожидает корректную структуру GeoJSON согласно спецификации.
Ошибка:
{
"name": "Park"
}
Такой объект не является GeoJSON-документом.
Корректный пример:
{
"type": "FeatureCollection",
"features": []
}
При сомнениях полезно использовать специализированные валидаторы GeoJSON.
Часто данные присутствуют, но объекты не отображаются на карте.
Причина может заключаться в неверном порядке координат.
Правильный порядок:
[longitude, latitude]
Пример:
[37.6176, 55.7558]
Ошибка:
[55.7558, 37.6176]
MapLibre интерпретирует координаты строго как:
[долгота, широта]
Перестановка значений может перенести объект в другую часть мира или сделать его невидимым.
Допустимые диапазоны:
Широта
от -90 до 90
Долгота
от -180 до 180
Некорректные значения:
[250, 120]
могут вызывать ошибки отображения или приводить к игнорированию объектов.
Перед загрузкой данных полезно выполнять предварительную проверку координат.
Подключение векторных тайлов выглядит следующим образом:
map.addSource('osm', {
type: 'vector',
tiles: [
'https://server.com/tiles/{z}/{x}/{y}.pbf'
]
});
Типичные проблемы:
Для векторных тайлов требуется дополнительный параметр:
source-layer
Пример:
map.addLayer({
id: 'roads',
type: 'line',
source: 'osm',
'source-layer': 'transportation'
});
Если внутри тайла отсутствует слой с таким именем, данные отображаться не будут.
Проблема особенно распространена при переходе между различными поставщиками тайлов.
Браузер может блокировать загрузку данных с другого домена.
Пример запроса:
https://api.example.com/data.geojson
При отсутствии необходимых заголовков серверного ответа появится ошибка:
Access-Control-Allow-Origin
Результат:
Решение находится на стороне сервера и заключается в корректной настройке CORS-заголовков.
Иногда источник присутствует:
map.getSource('cities')
возвращает объект, однако слой пустой.
Следует проверить:
Например:
minzoom: 10
скроет слой при масштабе меньше 10.
Источник может обновляться динамически.
Пример:
map.getSource('vehicles').setData(newData);
Ошибка возникает, если источник ещё не существует:
Cannot read properties of undefined
Безопасный вариант:
const source = map.getSource('vehicles');
if (source) {
source.setData(newData);
}
Некоторые приложения обновляют данные каждую секунду:
setInterval(() => {
source.setData(data);
}, 1000);
Для небольших наборов данных это допустимо.
Для десятков тысяч объектов возникают проблемы:
В таких случаях следует:
GeoJSON хранится полностью в памяти браузера.
Например:
{
"type": "FeatureCollection",
"features": [...]
}
Если коллекция содержит сотни тысяч объектов, возможны:
Для крупных наборов данных предпочтительнее использовать векторные тайлы.
GeoJSON поддерживает встроенную кластеризацию.
Источник:
map.addSource('earthquakes', {
type: 'geojson',
data: data,
cluster: true
});
Типичные проблемы:
clusterRadius.Пример слишком большого радиуса:
clusterRadius: 500
В результате почти все точки объединяются в один кластер.
Источник изображения:
map.addSource('overlay', {
type: 'image',
url: '/images/map.png',
coordinates: [...]
});
Проблемы:
Если угловые координаты указаны неверно, изображение может оказаться за пределами видимой области карты.
Видеоисточник:
map.addSource('video', {
type: 'video',
urls: [
'video.mp4'
],
coordinates: [...]
});
Распространённые причины проблем:
Некоторые браузеры блокируют автоматическое воспроизведение мультимедиа без пользовательского взаимодействия.
Пример растрового источника:
map.addSource('satellite', {
type: 'raster',
tiles: [
'https://tiles.example.com/{z}/{x}/{y}.png'
]
});
Возможные ошибки:
Особенно часто возникают проблемы при смешивании HTTP и HTTPS ресурсов.
Если карта открыта через HTTPS:
https://site.com
а источник использует HTTP:
http://tiles.com
браузер может заблокировать загрузку.
В консоли появляется сообщение:
Mixed Content
Все внешние ресурсы рекомендуется загружать через HTTPS.
Источник нельзя удалить, пока существуют связанные слои.
Ошибка:
map.removeSource('roads');
при наличии слоя:
source: 'roads'
приведёт к исключению.
Правильный порядок:
map.removeLayer('roads-layer');
map.removeSource('roads');
Сначала удаляются все зависимые слои, затем источник.
Перед созданием нового источника полезно выполнять проверку.
Пример:
if (!map.getSource('cities')) {
map.addSource('cities', {
type: 'geojson',
data: data
});
}
Это предотвращает ошибки вида:
Source already exists
при повторной инициализации компонентов.
Наиболее полезные инструменты диагностики:
Проверка наличия источника:
console.log(
map.getSource('cities')
);
Прослушивание ошибок карты:
map.on('error', (e) => {
console.error(e);
});
Контроль сетевых запросов:
Developer Tools → Network
Просмотр данных GeoJSON:
fetch('/data.geojson')
.then(r => r.json())
.then(console.log);
Проверка состояния загрузки:
map.isSourceLoaded('cities');
Систематическая проверка идентификаторов, структуры данных, сетевых запросов, координат и параметров отображения позволяет обнаружить подавляющее большинство проблем с источниками в MapLibre GL JS ещё на этапе разработки и избежать появления пустых слоёв, ошибок рендеринга и деградации производительности в рабочем приложении.