Метод addImage используется для добавления растрового
изображения в стиль карты, где оно становится доступным как ресурс для
символических слоёв (symbol layer) через свойство
icon-image. Это один из ключевых механизмов кастомизации
маркеров, пиктограмм и любых графических элементов, отображаемых поверх
географических данных.
addImage расширяет текущий стиль карты, регистрируя
изображение под уникальным идентификатором. После добавления изображение
может быть использовано в любых слоях, поддерживающих иконки, без
необходимости обращения к внешним URL или спрайтам.
Основные сценарии использования:
symbolmap.addImage(id, image, options?)
id Тип: string Уникальный
идентификатор изображения в рамках стиля. Используется в
icon-image.
image Тип:
HTMLImageElement | ImageData | ImageBitmap | Object
Допустимые формы:
<img>{ width, height, data } — массив RGBAoptions (необязательный)
{
pixelRatio?: number,
sdf?: boolean
}
pixelRatio — коэффициент
масштабирования изображенияsdf — включает режим Signed Distance
Field для стилизуемых иконокНаиболее распространённый сценарий — загрузка изображения и регистрация его в стиле карты.
map.on('load', () => {
const img = new Image();
img.onl oad = () => {
map.addImage('custom-marker', img);
};
img.src = '/images/marker.png';
});
После регистрации изображение становится доступным:
map.addLayer({
id: 'points',
type: 'symbol',
source: 'points-source',
layout: {
'icon-image': 'custom-marker',
'icon-size': 1
}
});
При генерации изображения динамически (например, через canvas):
const canvas = document.createElement('canvas');
canvas.width = 64;
canvas.height = 64;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 64, 64);
const imageData = ctx.getImageData(0, 0, 64, 64);
map.addImage('generated-square', imageData);
Такой подход применяется для:
ImageBitmap обеспечивает более эффективный рендеринг по сравнению с HTMLImageElement.
const img = new Image();
img.src = '/icons/poi.png';
img.onl oad = async () => {
const bitmap = await createImageBitmap(img);
map.addImage('poi-bitmap', bitmap);
};
Использование ImageBitmap снижает нагрузку на главный поток и ускоряет отрисовку больших наборов иконок.
pixelRatioПозволяет контролировать плотность пикселей для экранов с высоким DPI.
map.addImage('hd-icon', img, {
pixelRatio: 2
});
Практическое значение:
2 — высокоплотные экраны
Неверная настройка приводит к размытию или чрезмерному масштабированию.
SDF превращает изображение в математически масштабируемую форму, позволяющую изменять цвет и прозрачность через стиль слоя.
map.addImage('sdf-icon', img, {
sdf: true
});
Использование в слое:
map.addLayer({
id: 'sdf-layer',
type: 'symbol',
source: 'points',
layout: {
'icon-image': 'sdf-icon',
'icon-size': 1
},
paint: {
'icon-color': '#ff0000',
'icon-halo-color': '#000000',
'icon-halo-width': 2
}
});
Особенности SDF:
Если изображение с таким id уже существует, его
необходимо удалить перед повторным добавлением.
if (map.hasImage('custom-marker')) {
map.removeImage('custom-marker');
}
map.addImage('custom-marker', img);
Это важно при:
map.hasImage('custom-marker');
Возвращает true или false, позволяя
безопасно управлять ресурсами.
addImage не отображает изображение напрямую. Оно
работает только как ресурс для слоёв типа symbol.
layout: {
'icon-image': 'image-id'
}
Дополнительные свойства слоя:
icon-sizeicon-rotateicon-offseticon-anchoricon-opacityMapbox GL JS поддерживает асинхронную загрузку изображений:
map.loadImage('/icons/airport.png', (error, image) => {
if (error) throw error;
map.addImage('airport', image);
});
Такой подход часто используется при интеграции с API или CDN.
При работе с addImage важно учитывать:
Оптимизационные подходы:
idaddImage часто используется вместе с canvas для создания
контекстных маркеров.
Пример: числовой бейдж
function createBadge(number) {
const canvas = document.createElement('canvas');
canvas.width = 64;
canvas.height = 64;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#1978c8';
ctx.beginPath();
ctx.arc(32, 32, 30, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#fff';
ctx.font = 'bold 24px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(number, 32, 32);
return ctx.getImageData(0, 0, 64, 64);
}
map.addImage('badge-5', createBadge(5));
В сложных приложениях изображения, добавленные через
addImage, используются как часть архитектуры слоёв:
При смене стиля (setStyle) изображения, добавленные
через addImage, теряются, поскольку стиль перезагружается.
Для восстановления используется событие:
map.on('styledata', () => {
map.addImage('custom-marker', img);
});
Это критично для: