Icone SVG in MapLibre: controlla pixel e dimensioni
Decodifica un SVG per un livello simboli MapLibre, controlla densità e dimensione dell'icona e conserva un master modificabile. Verifica forma e apertura visualizzate.
In questa pagina
Per usare un'immagine icona SVG in MapLibre GL JS, decodifica l'SVG con un Image del browser, passa quell'immagine ad addImage e richiama il suo ID nell'icon-image di un livello simboli. Conserva separatamente l'SVG sorgente: l'immagine di stile registrata fornisce pixel per il rendering, non oggetti tracciato SVG modificabili.
L'attuale esempio ufficiale di simbolo SVG dimostra questo percorso di decodifica. Affermare in generale che MapLibre non può visualizzare grafica SVG lo ignorerebbe. Il nostro esempio fissa la versione 6.12.0 e prova un emblema originale forato in una mappa vuota, senza token.
Separa la sorgente dall'immagine registrata
La sorgente conservata contiene un tracciato composto a rombo con un'apertura interna. Il suo viewBox rimane 0 0 64 64. Produciamo due copie con larghezza e altezza esplicite di 64 o 128; i dati del tracciato rimangono identici.
La decodifica del browser trasforma ogni copia in un'immagine alle dimensioni dichiarate. L'API addImage di MapLibre accetta oggetti immagine come HTMLImageElement e ImageData. Non accetta un tracciato SVG come istruzione geometrica per il simbolo.
La distinzione conta quando cambi un colore o un contorno. Modifica il master SVG, decodifica l'immagine rivista e aggiorna l'immagine della mappa tramite l'API appropriata. Esaminare i pixel registrati non recupera la costruzione originale del tracciato. La nostra guida agli SVG con raster incorporati spiega la distinzione più ampia tra contenitore SVG e geometria modificabile.

Scegli insieme densità dell'immagine e dimensione dell'icona
Due impostazioni influenzano il riquadro nominale dell'immagine del nostro simbolo. Il pixelRatio dell'immagine descrive la sua densità; l'icon-size del livello scala l'icona risultante. Consulta gli attuali metadati delle immagini di stile e la specifica del layout dei simboli.
Per il nostro simbolo centrato, non ruotato e senza adattamento al testo, il riquadro nominale è:
logical width = decoded width / image pixelRatio * icon-size
logical height = decoded height / image pixelRatio * icon-sizeUn'immagine 128×128 registrata con rapporto 2 dà lo stesso riquadro nominale 64×64 di un'immagine 64×64 con rapporto 1 quando icon-size è 1. Cambiare il primo rapporto in 1 raddoppia il suo riquadro. Aumentare icon-size a 1.5 trasforma un riquadro logico di immagine 64×64 in 96×96.
Questo riquadro include lo spazio vuoto sorgente. Se l'emblema appare troppo piccolo al suo interno, esamina i limiti SVG prima di aumentare le dimensioni di ogni simbolo. Un'immagine decodificata più grande con lo stesso rapporto ingrandisce anche il simbolo; le sole dimensioni di ingresso non sono una strategia di densità.
Il canvas della mappa ha un proprio rapporto di pixel. È separato dal rapporto passato ad addImage. Il nostro campione di misura imposta esplicitamente il rapporto del canvas a 1 usando le opzioni Map documentate; il rapporto dei pixel del dispositivo nel browser era 2. Questo isola i confronti seguenti invece di trattare i pixel del dispositivo di una schermata come dimensioni CSS.
Confronta l'ingombro effettivamente dipinto
Abbiamo renderizzato cinque casi di simbolo in Chrome con WebGL 2. Ogni mappa aveva un punto, lo stesso sfondo chiaro, nessuna tessera e nessun token. Entrambe le sorgenti SVG avevano un tracciato identico e nessuna immagine incorporata.
Per misurare la grafica terracotta, la nostra lettura ha scandito i pixel WebGL effettivi cercando un colore a predominanza rossa: rosso maggiore di 1.35 volte il verde e 1.6 volte il blu. Abbiamo diviso le dimensioni del riquadro rilevato per il rapporto tra dimensioni interne e CSS del canvas. Questo misura un'area dipinta basata su una soglia, non l'intero riquadro dell'immagine.
| Immagine decodificata | Rapporto immagine | icon-size | Riquadro nominale | Limiti dipinti osservati |
|---|---|---|---|---|
| 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 |
Non tutti i pixel dei bordi superano quella soglia cromatica, il che spiega perché i limiti dipinti misurati sono più piccoli dei riquadri nominali. Le coppie mostrano la relazione dimensionale prevista in questo campione; non dimostrano una qualità dei pixel identica a ogni densità o livello di zoom.
L'alfa al centro dell'immagine registrata era zero in ogni caso. Nella mappa renderizzata, quella posizione mostrava il colore di sfondo (244, 242, 232) con alfa 255, perché il livello di sfondo era opaco. Vedere pixel opachi della mappa attraverso l'apertura non significa che l'icona abbia perso la trasparenza.
Sono osservazioni limitate alla nostra sorgente, al browser, alle impostazioni del canvas e alla soglia. Prova la grafica da consegnare alle dimensioni di visualizzazione previste, soprattutto se contiene tratti sottili o piccole aperture.
Copia un esempio di simbolo senza token
Salva questo HTML completo e servilo da un server web locale. Serve accesso a Internet per la libreria e il CSS con versioni fissate; la mappa non usa servizi di tessere o chiavi API. L'SVG è incorporato come testo e codificato in un URL dati.
L'esempio attende image.decode(), quindi la registrazione segue la decodifica riuscita. Registra l'immagine nota dopo il caricamento dello stile; per questo singolo emblema fisso non richiede il risolutore delle immagini mancanti dell'esempio ufficiale.
<!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>Lo stato dovrebbe mostrare dimensioni decodificate e registrate di [128, 128], rapporto immagine 2 e riquadro logico [64, 64]. Questo stato riporta il riquadro nominale, non un riquadro dipinto misurato. Cambia iconSize in 1.5 per un riquadro 96×96. Per confrontare l'ingresso a bassa densità, cambia larghezza e altezza dell'SVG in 64 e ratio in 1 mantenendo lo stesso tracciato e viewBox.
Mantieni icon-image uguale all'ID registrato. Se un'icona non appare, verifica che decodifica e registrazione siano riuscite, poi esamina sorgente, livello, visibilità e impostazioni di posizionamento. Il nostro esempio con un solo punto usa icon-overlap: 'always' per rendere questo confronto indipendente dalle collisioni con altri simboli. Il tuo stile di produzione può richiedere un comportamento di collisione diverso.
Usa un marcatore DOM quando è il modello di consegna adatto
MapLibre documenta anche icone personalizzate con Marker DOM. Quel percorso avvolge un elemento HTML invece di registrare un'immagine di stile. Sceglilo quando il flusso con marcatori basati su elementi si adatta all'applicazione, poi esaminane separatamente stile e posizionamento nel browser.
Non trasferire le affermazioni sulle icone vettoriali di Mapbox Studio o un esempio del MapTiler SDK a questa sequenza di immagini di stile MapLibre. Una normale immagine SVG a colori non diventa neppure un campo di distanza con segno cambiando soltanto il flag sdf. Le impostazioni di densità controllano come questa immagine viene interpretata e visualizzata; non trasformano i suoi pixel in contorni modificabili.
Se una destinazione richiede un file PNG, la nostra guida al rendering SVG con Sharp tratta la preparazione di una copia raster da consegnare. Conserva il normale master SVG per le modifiche; anche SVG inline e consegna come immagine hanno modelli di interazione diversi.
Se l'icona esiste solo come PNG o JPG e ti serve grafica modificabile, recupera i contorni SVG con PerfectVector, esamina la forma esterna e l'apertura e conserva quel master prima di decodificare l'immagine della mappa. Il codice della mappa continua a controllare densità, dimensione del simbolo e posizione geografica. Un SVG pulito esistente può passare direttamente al flusso di decodifica; la guida alla vettorizzazione spiega quando è utile convertire un raster.
Domande frequenti
MapLibre GL JS può visualizzare grafica SVG come simbolo? Sì. Il suo attuale esempio ufficiale decodifica testo SVG con un Image del browser e registra quell'immagine per un livello simboli. Conserva l'SVG originale separato dall'immagine registrata.
Perché un ingresso più grande ha ingrandito l'icona? Aumentare le dimensioni decodificate mantenendo lo stesso rapporto dei pixel dell'immagine e icon-size aumenta il riquadro nominale. Abbina intenzionalmente densità dell'immagine e scala di visualizzazione.
pixelRatio conserva tracciati SVG modificabili nel simbolo? No. Descrive la densità dell'immagine. Conserva e modifica l'SVG sorgente, poi decodifica la grafica rivista per la mappa.
Perché il pixel della mappa dentro il foro dell'icona è opaco? Un livello di sfondo opaco può vedersi attraverso un'apertura trasparente dell'icona. Esamina l'alfa dell'immagine registrata separatamente dal canvas della mappa completamente composto.
Fonti
- MapLibre — Visualizzare un simbolo SVG remoto — L'attuale percorso con testo SVG, immagine del browser e addImage.
- MapLibre — API Map — Oggetti immagine accettati e registrazione delle immagini durante l'esecuzione.
- MapLibre — StyleImageMetadata — Metadati della densità dell'immagine e dell'interpretazione SDF.
- MapLibre — Specifica del layout dei simboli — Scala delle icone e comportamento delle collisioni.
- MapLibre — MapOptions — Opzioni del canvas usate per controllare il campione di misura.
- MDN — HTMLImageElement.decode — Attendere la decodifica delle immagini nel browser e gestire gli errori.
- MapLibre — Aggiungere icone personalizzate con Marker — Il flusso separato con marcatori a elemento HTML.
Altro dal blog

Loghi SVG in Satori: conserva la grafica nella card
Incorpora un logo SVG in una card Satori con dimensioni esplicite e dati immagine autonomi. Esamina la grafica annidata, poi renderizza un PNG di consegna separato.

Da SVG a Canvas: carica la grafica prima di esportare PNG
Carica un SVG completo con Image.decode, disegnalo alle dimensioni bitmap scelte, prova CORS e lettura PNG e separa la sorgente modificabile dai pixel esportati.
