Ikony SVG MapLibre: sprawdź piksele i rozmiar symbolu
Dekoduj własne SVG dla warstwy symboli MapLibre, kontroluj gęstość obrazu i rozmiar ikony oraz zachowaj edytowalny wzorzec. Sprawdź wyświetlany kształt i otwór.
Na tej stronie
Aby użyć obrazu ikony SVG w MapLibre GL JS, zdekoduj SVG przeglądarkowym Image, przekaż obraz do addImage i odwołaj się do jego identyfikatora w icon-image warstwy symboli. Zachowaj źródłowy SVG oddzielnie: zarejestrowany obraz stylu dostarcza piksele do renderowania, a nie edytowalne obiekty ścieżek SVG.
Aktualny oficjalny przykład symbolu SVG pokazuje tę drogę dekodowania. Ogólne stwierdzenie, że MapLibre nie może wyświetlać grafiki SVG, pomijałoby ten przykład. Nasz przykład przypina 6.12.0 i testuje oryginalny pusty znak na pustej mapie bez tokena.
Oddziel źródło od zarejestrowanego obrazu
Zachowane źródło zawiera jedną złożoną ścieżkę rombu z wewnętrznym otworem. Jej viewBox pozostaje 0 0 64 64. Tworzymy dwie kopie z jawną szerokością i wysokością 64 lub 128; dane ścieżki pozostają identyczne.
Dekodowanie przeglądarki zmienia każdą kopię w obraz o zadeklarowanych wymiarach. API addImage MapLibre akceptuje obiekty obrazów, takie jak HTMLImageElement i ImageData. Nie przyjmuje ścieżki SVG jako instrukcji geometrii symbolu.
Różnica ma znaczenie przy zmianie koloru lub konturu. Edytuj wzorzec SVG, zdekoduj zmieniony obraz i zaktualizuj obraz mapy właściwym API. Sprawdzanie zarejestrowanych pikseli nie odzyska pierwotnej konstrukcji ścieżki. Nasz poradnik SVG z osadzonym rastrem wyjaśnia szerszą różnicę między kontenerem SVG a edytowalną geometrią.

Wybierz wspólnie gęstość obrazu i rozmiar ikony
Dwa ustawienia wpływają na nominalny prostokąt obrazu symbolu. pixelRatio obrazu opisuje jego gęstość; icon-size warstwy skaluje wynikową ikonę. Zobacz aktualne metadane obrazu stylu i specyfikację układu symboli.
Dla naszego wyśrodkowanego, nieobróconego symbolu bez dopasowania do tekstu nominalny prostokąt wynosi:
logical width = decoded width / image pixelRatio * icon-size
logical height = decoded height / image pixelRatio * icon-sizeObraz 128×128 zarejestrowany przy współczynniku 2 daje ten sam nominalny prostokąt 64×64 co obraz 64×64 przy współczynniku 1, gdy icon-size wynosi 1. Zmiana pierwszego współczynnika na 1 podwaja prostokąt. Zwiększenie icon-size do 1.5 daje logicznemu prostokątowi 64×64 rozmiar 96×96.
Prostokąt obejmuje puste miejsce źródła. Jeśli znak wygląda na zbyt mały w jego wnętrzu, sprawdź granice SVG przed zwiększeniem wszystkich symboli. Większy zdekodowany obraz przy tym samym współczynniku także powiększa symbol; same wymiary wejściowe nie są strategią gęstości.
Canvas mapy ma własny współczynnik pikseli. Jest oddzielny od współczynnika przekazanego do addImage. Nasz przykład pomiarowy jawnie ustawia współczynnik Canvas na 1 przez udokumentowane opcje Map; współczynnik pikseli urządzenia w przeglądarce wynosił 2. Izoluje to poniższe porównania zamiast traktowania pikseli urządzenia ze zrzutu jako wymiarów CSS.
Porównaj faktycznie pomalowany obszar
Wyrenderowaliśmy pięć przypadków symboli w Chrome z WebGL 2. Każda mapa miała jeden punkt, takie samo jasne tło, brak kafelków i tokena. Oba źródła SVG miały jedną identyczną ścieżkę i brak osadzonego obrazu.
Aby zmierzyć terakotową grafikę, odczyt skanował faktyczne piksele WebGL pod kątem koloru z przewagą czerwieni: czerwony większy niż 1.35 razy zielony i 1.6 razy niebieski. Podzieliliśmy wymiary wykrytej obwiedni przez stosunek bufora Canvas do CSS. Mierzy to progowany pomalowany obszar, a nie cały prostokąt obrazu.
| Zdekodowany obraz | Współczynnik obrazu | icon-size | Nominalny prostokąt | Zaobserwowane granice malowania |
|---|---|---|---|---|
| 64×64 | 1 | 1 | 64×64 | 62×62 px CSS |
| 128×128 | 1 | 1 | 128×128 | 126×126 px CSS |
| 128×128 | 2 | 1 | 64×64 | 62×62 px CSS |
| 64×64 | 1 | 1.5 | 96×96 | 94×94 px CSS |
| 128×128 | 2 | 1.5 | 96×96 | 94×94 px CSS |
Nie wszystkie piksele krawędzi przechodzą próg koloru, co wyjaśnia, dlaczego zmierzone granice malowania są mniejsze od nominalnych prostokątów. Pary pokazują zamierzoną zależność rozmiaru w tym przykładzie; nie dowodzą identycznej jakości pikseli przy każdej gęstości lub powiększeniu.
Alfa środka zarejestrowanego obrazu wynosiła zero w każdym przypadku. Na renderowanej mapie ta pozycja pokazywała kolor tła (244, 242, 232) z alfa 255, ponieważ sama warstwa tła była nieprzezroczysta. Widok nieprzezroczystych pikseli mapy przez otwór nie oznacza utraty przezroczystości ikony.
To ograniczone obserwacje naszego źródła, przeglądarki, ustawień Canvas i progu. Testuj przekazywaną grafikę w docelowych rozmiarach, zwłaszcza jeśli ma cienkie kontury lub małe otwory.
Skopiuj przykład startowy symbolu bez tokena
Zapisz kompletny HTML i udostępnij z lokalnego serwera internetowego. Internet jest potrzebny do przypiętej biblioteki i CSS; mapa nie używa usługi kafelków ani klucza API. SVG jest osadzony jako tekst i zakodowany w adresie danych.
Przykład czeka na image.decode(), więc rejestracja następuje po udanym dekodowaniu. Rejestruje znany obraz po wczytaniu stylu; dla tego jednego stałego znaku nie potrzebuje mechanizmu obsługi brakującego obrazu z oficjalnego przykładu.
<!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>Stan powinien pokazać zdekodowane i zarejestrowane wymiary [128, 128], współczynnik obrazu 2 i logiczny prostokąt [64, 64]. Raportuje nominalny prostokąt, a nie zmierzoną pomalowaną obwiednię. Zmień iconSize na 1.5, aby otrzymać 96×96. Aby porównać wejście o niskiej gęstości, zmień szerokość i wysokość SVG na 64, a ratio na 1, zachowując ścieżkę i viewBox.
Zachowaj icon-image równy zarejestrowanemu identyfikatorowi. Jeśli ikona się nie pojawia, potwierdź udane dekodowanie i rejestrację, a potem sprawdź źródło, warstwę, widoczność i ustawienia położenia. Nasz jednopunktowy przykład używa icon-overlap: 'always', aby porównanie było niezależne od kolizji z innymi symbolami. Styl produkcyjny może wymagać innego zachowania kolizji.
Użyj znacznika DOM, gdy odpowiada modelowi przekazania
MapLibre opisuje także własne ikony ze znacznikami DOM. Ta droga opakowuje element HTML zamiast rejestrować obraz stylu. Wybierz ją, gdy proces znacznika opartego na elemencie pasuje do aplikacji, a następnie osobno sprawdź style i położenie w przeglądarce.
Nie przenoś twierdzeń o funkcjach ikon wektorowych Mapbox Studio lub przykładzie MapTiler SDK na ten potok obrazów stylu MapLibre. Zwykły pełnokolorowy obraz SVG nie staje się też polem odległości ze znakiem przez samą zmianę flagi sdf. Ustawienia gęstości kontrolują interpretowanie i wyświetlanie obrazu; nie zmieniają pikseli w edytowalne kontury.
Jeśli miejsce docelowe wymaga PNG, nasz poradnik renderowania SVG przez Sharp opisuje przygotowanie rastrowej kopii do przekazania. Zachowaj zwykły wzorzec SVG do edycji; SVG inline i przekazanie przez obraz także mają różne modele interakcji.
Jeśli ikona istnieje tylko jako PNG lub JPG i potrzebujesz edytowalnej grafiki, odzyskaj kontury SVG przez PerfectVector, sprawdź kształt zewnętrzny i otwór oraz zachowaj wzorzec przed dekodowaniem obrazu mapy. Kod mapy nadal kontroluje gęstość, rozmiar symbolu i pozycję geograficzną. Czysty istniejący SVG może przejść bezpośrednio przez dekodowanie; poradnik wektoryzacji wyjaśnia, kiedy konwersja rastra jest użyteczna.
Najczęstsze pytania
Czy MapLibre GL JS może wyświetlać grafikę SVG jako symbol? Tak. Jego obecny oficjalny przykład dekoduje tekst SVG przeglądarkowym Image i rejestruje obraz dla warstwy symboli. Zachowaj oryginalny SVG oddzielnie od zarejestrowanego obrazu.
Dlaczego większe wejście powiększyło ikonę? Zwiększenie zdekodowanych wymiarów przy zachowaniu współczynnika pikseli obrazu i icon-size zwiększa nominalny prostokąt. Świadomie dobieraj razem gęstość obrazu i skalowanie wyświetlania.
Czy pixelRatio zachowuje edytowalne ścieżki SVG w symbolu? Nie. Opisuje gęstość obrazu. Zachowaj i edytuj źródłowy SVG, a następnie zdekoduj poprawioną grafikę dla mapy.
Dlaczego piksel mapy wewnątrz otworu ikony jest nieprzezroczysty? Nieprzezroczysta warstwa tła może być widoczna przez przezroczysty otwór ikony. Sprawdzaj alfa zarejestrowanego obrazu oddzielnie od w pełni skomponowanego Canvas mapy.
Źródła
- MapLibre — Wyświetlanie zdalnego symbolu SVG — Obecna droga tekstu SVG, obrazu przeglądarkowego i addImage.
- MapLibre — API Map — Akceptowane obiekty obrazów i rejestracja obrazów w czasie działania.
- MapLibre — StyleImageMetadata — Metadane gęstości obrazu i interpretacji SDF.
- MapLibre — Specyfikacja układu symboli — Skalowanie ikon i zachowanie kolizji.
- MapLibre — MapOptions — Opcje Canvas użyte do kontrolowania przykładu pomiarowego.
- MDN — HTMLImageElement.decode — Oczekiwanie na dekodowanie obrazu w przeglądarce i obsługa niepowodzeń.
- MapLibre — Dodawanie własnych ikon przez Markers — Oddzielny proces znacznika opartego na elemencie HTML.
Więcej z bloga

Logo SVG w Satori: zachowaj grafikę na karcie marki
Osadź logo SVG w karcie Satori z jawnymi wymiarami i samowystarczalnymi danymi obrazu. Sprawdź zagnieżdżoną grafikę i wyrenderuj osobny PNG do przekazania.

SVG na Canvas: wczytaj grafikę przed eksportem PNG
Wczytaj całe SVG przez Image.decode, narysuj w wybranym rozmiarze bitmapy, sprawdź CORS i odczyt PNG oraz oddziel edytowalne źródło od eksportowanych pikseli.
