> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# Значки SVG MapLibre: пиксели и размер символа

> Декодируйте собственную SVG-графику для слоя символов MapLibre, управляйте плотностью изображения и размером значка, сохраняйте редактируемый мастер. Проверьте форму и отверстие на экране.

Source: https://perfectvector.com/ru/blog/maplibre-svg-symbol-image

Language: ru
Author: Irene Kim
Published: 2026-10-05T08:00:00+09:00
Updated: 2026-10-05T08:00:00+09:00

Чтобы использовать изображение значка SVG в MapLibre GL JS, декодируйте SVG браузерным `Image`, передайте изображение в `addImage` и укажите его ID в `icon-image` слоя символов. Храните исходный SVG отдельно: зарегистрированное изображение стиля предоставляет пиксели для отрисовки, а не редактируемые объекты контуров SVG.

Текущий [официальный пример символа SVG](https://maplibre.org/maplibre-gl-js/docs/examples/display-a-remote-svg-symbol/) демонстрирует этот способ декодирования. Общее утверждение, что MapLibre не может показывать SVG-графику, упустило бы его. Наш пример закрепляет 6.12.0 и проверяет оригинальную полую эмблему на пустой карте без токена.

## Держите исходник отдельно от зарегистрированного изображения

Сохраняемый исходник содержит один составной ромбический контур с внутренним отверстием. Его `viewBox` остаётся `0 0 64 64`. Мы создаём две копии с явными шириной и высотой 64 или 128; данные контура остаются одинаковыми.

Браузерное декодирование превращает каждую копию в изображение с объявленными размерами. [API `addImage`](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#addimage) MapLibre принимает объекты изображений, такие как `HTMLImageElement` и `ImageData`. Он не принимает контур SVG как инструкцию геометрии символа.

Это различие важно при смене цвета или очертаний. Отредактируйте мастер SVG, декодируйте изменённое изображение и обновите изображение карты через соответствующий API. Проверка зарегистрированных пикселей не восстановит исходное построение контура. Наше [руководство по SVG со встроенным растром](https://perfectvector.com/ru/blog/svg-contains-raster-image) объясняет более широкое различие контейнера SVG и редактируемой геометрии.

**Исходная графика и окрашивание символа**

![Концептуальная иллюстрация полой ромбической эмблемы как редактируемых контуров и пиксельных копий для показа](https://perfectvector.com/blog/maplibre-svg-symbol-image/source-and-symbol.webp)

*Иллюстрация: сохраняйте редактируемый SVG, управляя размером показа декодированного изображения. Измерения WebGL ниже получены на отдельно созданных браузерных образцах.*

## Выбирайте плотность изображения и размер значка вместе

На номинальную рамку изображения нашего символа влияют две настройки. `pixelRatio` изображения описывает его плотность, а `icon-size` слоя масштабирует полученный значок. См. текущие [метаданные изображения стиля](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/StyleImageMetadata/) и [спецификацию компоновки символов](https://maplibre.org/maplibre-style-spec/layers/#icon-size).

Для нашего центрированного символа без поворота и подгонки под текст номинальная рамка такова:

```text
logical width = decoded width / image pixelRatio * icon-size
logical height = decoded height / image pixelRatio * icon-size
```

Изображение 128×128, зарегистрированное с отношением 2, даёт ту же номинальную рамку 64×64, что изображение 64×64 с отношением 1, когда `icon-size` равен 1. Изменение первого отношения на 1 удваивает рамку. Увеличение `icon-size` до 1,5 превращает логическую рамку изображения 64×64 в 96×96.

Эта рамка включает пустое пространство исходника. Если эмблема внутри выглядит слишком маленькой, проверьте границы SVG, прежде чем увеличивать все символы. Большее декодированное изображение при том же отношении также увеличивает символ; одни входные размеры не являются стратегией плотности.

У холста карты есть собственное пиксельное отношение. Оно отдельно от отношения, передаваемого в `addImage`. Наш измерительный пример явно задаёт отношение холста 1 через документированные [параметры Map](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/); отношение пикселей устройства в браузере было 2. Это изолирует следующие сравнения, не принимая аппаратные пиксели снимка за размеры CSS.

## Сравните фактический закрашенный след

Мы отрисовали пять вариантов символов в Chrome с WebGL 2. На каждой карте была одна точка, одинаковый светлый фон, не было тайлов и токена. Оба исходника SVG содержали один одинаковый контур без встроенного изображения.

Чтобы измерить терракотовую графику, наше считывание сканировало реальные пиксели WebGL на преобладание красного: красный больше зелёного в 1,35 раза и синего в 1,6 раза. Размеры найденного ограничивающего прямоугольника мы делили на отношение внутреннего буфера холста к CSS. Это измеряет закрашенную область по порогу, а не полную рамку изображения.

| Декодированное изображение | Отношение изображения | icon-size | Номинальная рамка | Наблюдаемые закрашенные границы |
| -------------------------- | --------------------- | --------- | ----------------- | ------------------------------- |
| 64×64                      | 1                     | 1         | 64×64             | 62×62 CSS px                    |
| 128×128                    | 1                     | 1         | 128×128           | 126×126 CSS px                  |
| 128×128                    | 2                     | 1         | 64×64             | 62×62 CSS px                    |
| 64×64                      | 1                     | 1.5       | 96×96             | 94×94 CSS px                    |
| 128×128                    | 2                     | 1.5       | 96×96             | 94×94 CSS px                    |

Не все краевые пиксели проходят этот цветовой порог, что объясняет меньшие измеренные закрашенные границы по сравнению с номинальными рамками. Пары показывают нужное соотношение размеров в данном примере; они не доказывают одинаковое качество пикселей при любой плотности или масштабе.

Альфа-канал центра зарегистрированного изображения был нулевым во всех случаях. На отрисованной карте это место показывало цвет фона `(244, 242, 232)` с альфа-каналом 255, поскольку сам фоновый слой непрозрачен. Непрозрачные пиксели карты, видимые через отверстие, не означают, что значок потерял прозрачность.

Это ограниченные наблюдения нашего исходника, браузера, настроек холста и порога. Проверяйте передаваемую графику в целевых размерах, особенно если она содержит тонкие обводки или маленькие отверстия.

## Скопируйте стартовый пример символа без токена

Сохраните этот полный HTML и раздавайте локальным веб-сервером. Для закреплённой библиотеки и CSS нужен интернет; карта не использует сервис тайлов или API-ключ. SVG встроен как текст и закодирован в data URL.

Пример ожидает [`image.decode()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decode), поэтому регистрация следует после успешного декодирования. Он регистрирует известное изображение после загрузки стиля; для этой единственной фиксированной эмблемы не нужен обработчик отсутствующих изображений из официального примера.

```html
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>MapLibre decoded SVG symbol</title>
<link rel="stylesheet"
      href="https://unpkg.com/maplibre-gl@6.12.0/dist/maplibre-gl.css">
<style>#map { width: 360px; height: 280px; }</style>
<div id="map"></div>
<pre id="status">Loading…</pre>
<script type="module">
import * as ml from
  'https://unpkg.com/maplibre-gl@6.12.0/dist/maplibre-gl.mjs';
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 64 64"><path fill="#c45b39" fill-rule="evenodd" d="M32 0 L64 32 L32 64 L0 32 Z M32 16 L16 32 L32 48 L48 32 Z"/></svg>`;
const image = new Image();
image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
try {
  await image.decode();
  const ratio = 2;
  const iconSize = 1;
  const map = new ml.Map({
    container: 'map', center: [0, 0], zoom: 2, interactive: false,
    attributionControl: false, fadeDuration: 0,
    style: { version: 8, sources: {}, layers: [{
      id: 'background', type: 'background',
      paint: { 'background-color': '#f4f2e8' }
    }] }
  });
  map.on('error', e => {
    document.querySelector('#status').textContent = e.error.message;
  });
  await map.once('load');
  map.addImage('emblem', image, { pixelRatio: ratio });
  map.addSource('point', { type: 'geojson', data: {
    type: 'Feature', geometry: { type: 'Point', coordinates: [0, 0] },
    properties: {}
  } });
  map.addLayer({ id: 'emblem', type: 'symbol', source: 'point', layout: {
    'icon-image': 'emblem', 'icon-size': iconSize, 'icon-overlap': 'always'
  } });
  await map.once('idle');
  const registered = map.getImage('emblem');
  document.querySelector('#status').textContent = JSON.stringify({
    version: ml.getVersion(),
    decoded: [image.naturalWidth, image.naturalHeight],
    registered: [registered.data.width, registered.data.height],
    imagePixelRatio: registered.pixelRatio,
    logicalFrame: [image.naturalWidth / ratio * iconSize,
                   image.naturalHeight / ratio * iconSize]
  }, null, 2);
} catch (error) {
  document.querySelector('#status').textContent = String(error);
}
</script>
</html>
```

Состояние должно показать декодированные и зарегистрированные размеры `[128, 128]`, отношение изображения 2 и логическую рамку `[64, 64]`. Оно сообщает номинальную рамку, а не измеренный прямоугольник закрашенной области. Измените `iconSize` на 1,5 для рамки 96×96. Для сравнения входа низкой плотности измените ширину и высоту SVG на 64, а `ratio` на 1, сохранив те же контур и viewBox.

Держите `icon-image` равным зарегистрированному ID. Если значок не появляется, подтвердите успешное декодирование и регистрацию, затем проверьте исходник, слой, видимость и настройки размещения. Наш пример с одной точкой использует `icon-overlap: 'always'`, чтобы сравнение не зависело от столкновений с другими символами. Рабочему стилю может понадобиться иное поведение столкновений.

## Используйте DOM-маркер, если такова модель передачи

MapLibre также описывает [собственные значки с DOM Markers](https://maplibre.org/maplibre-gl-js/docs/examples/add-custom-icons-with-markers/). Этот способ оборачивает HTML-элемент вместо регистрации изображения стиля. Выбирайте его, если процесс маркеров на основе элементов подходит приложению, затем отдельно проверяйте браузерное оформление и размещение.

Не переносите утверждения о векторных значках Mapbox Studio или примере MapTiler SDK на этот конвейер изображений стиля MapLibre. Обычное полноцветное изображение SVG также не становится знаковым полем расстояний от одного изменения флага `sdf`. Настройки плотности управляют интерпретацией и показом изображения; они не превращают пиксели в редактируемые контуры.

Если целевой среде нужен файл PNG, наше [руководство по отрисовке SVG в Sharp](https://perfectvector.com/ru/blog/sharp-svg-to-png) описывает подготовку растровой копии для передачи. Сохраняйте обычный мастер SVG для правок; [встроенный SVG и передача изображения](https://perfectvector.com/ru/blog/inline-svg-vs-img) также имеют разные модели взаимодействия.

Если значок существует только в PNG или JPG, а нужна редактируемая графика, [восстановите контуры SVG с PerfectVector](https://perfectvector.com/ru/image-to-vector), проверьте внешнюю форму и отверстие и сохраните мастер до декодирования изображения для карты. Код карты по-прежнему управляет плотностью, размером символа и географической позицией. Чистый существующий SVG может сразу пройти процесс декодирования; [руководство по векторизации](https://perfectvector.com/ru/blog/what-is-image-vectorization) объясняет, когда полезно преобразование растра.

## Частые вопросы

**Может ли MapLibre GL JS показывать SVG-графику как символ?**
Да. Текущий официальный пример декодирует SVG-текст браузерным Image и регистрирует это изображение для слоя символов. Храните оригинальный SVG отдельно от зарегистрированного изображения.

**Почему больший вход увеличил значок?**
Увеличение декодированных размеров при том же пиксельном отношении изображения и icon-size увеличивает номинальную рамку. Осознанно сочетайте плотность изображения и масштаб отображения.

**Сохраняет ли pixelRatio редактируемые контуры SVG в символе?**
Нет. Он описывает плотность изображения. Сохраняйте и редактируйте исходный SVG, затем декодируйте обновлённую графику для карты.

**Почему пиксель карты внутри отверстия значка непрозрачен?**
Непрозрачный фоновый слой может просвечивать через прозрачное отверстие значка. Проверяйте альфа-канал зарегистрированного изображения отдельно от полностью скомпонованного холста карты.

## Источники

1. [MapLibre — Показ удалённого символа SVG](https://maplibre.org/maplibre-gl-js/docs/examples/display-a-remote-svg-symbol/) — Текущий путь SVG-текста, браузерного изображения и addImage.
2. [MapLibre — API Map](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#addimage) — Принимаемые объекты изображений и регистрация изображений во время выполнения.
3. [MapLibre — StyleImageMetadata](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/StyleImageMetadata/) — Метаданные плотности изображения и интерпретации SDF.
4. [MapLibre — Спецификация компоновки символов](https://maplibre.org/maplibre-style-spec/layers/#icon-size) — Масштабирование значка и поведение столкновений.
5. [MapLibre — MapOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/) — Параметры холста для управления измерительным примером.
6. [MDN — HTMLImageElement.decode](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decode) — Ожидание браузерного декодирования изображения и обработка ошибок.
7. [MapLibre — Добавление собственных значков с Markers](https://maplibre.org/maplibre-gl-js/docs/examples/add-custom-icons-with-markers/) — Отдельный процесс маркеров на основе HTML-элементов.

## Explore

- [Read the HTML article](https://perfectvector.com/ru/blog/maplibre-svg-symbol-image)
- [Логотипы SVG в Satori: графика в фирменной карточке](https://perfectvector.com/ru/blog/satori-svg-logo.md)
- [SVG на Canvas: загрузите графику до экспорта PNG](https://perfectvector.com/ru/blog/svg-canvas-image-export.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
