Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

📍 Come aggiungere più marcatori personalizzati con una legenda a Google Maps

📍 Come aggiungere più marcatori personalizzati con una legenda a Google Maps

Markers are il modo principale per indicare un punto su una mappa. Il classico "pin" rosso di Google Maps è riconoscibile, ma quando hai cinque punti di tipo diverso l'utente si perde: qual è un indirizzo esatto e quale un punto di riferimento approssimativo?

Succede di continuo: un catalogo di negozi diviso in sedi "di proprietà" e "partner", una mappa di consegne con zone, un pannello logistico con tipi di carico. Ovunque tu abbia più di tre punti con significati diversi, senza icone personalizzate e una legenda regna il caos.

La soluzione sono icone personalizzate per i marker e una legenda che spieghi ogni simbolo. In 20 minuti costruirai una mappa con più tipi di marker e gli utenti capiranno al primo sguardo cosa rappresenta ciascuno. Nella pratica, abbiamo visto più e più volte che un paio di pin diversi e un blocco legenda nell'angolo fanno risparmiare minuti di interpretazione agli utenti e decine di domande del tipo «cosa significa il cerchio blu?» ai team di supporto.

Ecco una guida passo passo con semplice JavaScript, senza framework. Useremo coordinate intorno alla Torre Eiffel, un punto di riferimento comodo dalla geometria riconoscibile. Il codice è volutamente minimale, con ogni metodo spiegato riga per riga così puoi adattarlo al tuo compito senza leggere l'intera documentazione.

Il materiale procede dal semplice al complesso: prima otterrai una chiave API e visualizzerai una mappa base, poi aggiungerai marker con icone diverse, costruirai una legenda e infine avrai un file HTML funzionante e subito eseguibile. Tutti gli esempi sono stati testati su Google Chrome 120+, Firefox 121+ e Safari 17+.

💡 Panoramica rapida:

  • Ottieni una chiave API di Google Maps e includi la libreria
  • Prepara un array di punti in JSON: nome, coordinate, tipo (esatto/approssimativo)
  • Assegna a ogni tipo la sua icona tramite la proprietà icon
  • Costruisci la legenda come elemento HTML e agganciala alla mappa con map.controls
  • Risultato: una mappa, due tipi visivi di marker, legenda nell'angolo in alto a destra

Ottenere una chiave API di Google Maps

Lavorare con l'API JavaScript Maps richiede una chiave. Se non ne hai una, creala nella Google Cloud Console.

Passaggi rapidi: vai alla Console, crea un progetto (o selezionane uno esistente), abilita Maps JavaScript API, genera una chiave. Per lo sviluppo in locale, limitare la chiave tramite referrer HTTP è sufficiente; per la produzione, aggiungi il tuo dominio alla allowlist. Nei progetti reali creiamo sempre una chiave separata per ogni applicazione: è più facile tracciare le quote nella Cloud Console e revocare l'accesso in modo mirato se una chiave viene compromessa.

Includere la libreria richiede una riga in <script>:

1<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=drawMap"></script>

L'attributo callback specifica quale funzione eseguire dopo il caricamento dell'API. La scriveremo tra poco.

Marcatori su mappa: icone personalizzate per Google Maps

Importante: da febbraio 2024, la classe google.maps.Marker è ufficialmente deprecata. È stata sostituita da google.maps.marker.AdvancedMarkerElement, che offre prestazioni migliori e supporta HTML personalizzato. Il codice qui sotto usa il classico Marker (funziona ancora ed è più semplice per iniziare), e la sezione FAQ include un link alla guida alla migrazione per passare ad AdvancedMarkerElement.

Inizializzare la mappa e preparare i dati

Per prima cosa, un contenitore per la mappa e un array di coordinate. Usa le coordinate che preferisci; qui abbiamo cinque punti intorno alla Torre Eiffel a Parigi, tre esatti e due approssimativi.

1<div id="mapCanvas"></div>

Impacchettiamo i dati in un array di oggetti. Il campo is_exact separerà i marker in due tipi: quelli che individuano un indirizzo esatto e quelli che indicano un'area generale.

1const locations = [
2 { name: "Eiffel Tower", lat: 48.85837, lng: 2.294481, is_exact: true },
3 { name: "UNESCO HQ", lat: 48.84956, lng: 2.306326, is_exact: false },
4 { name: "Trocadéro", lat: 48.86278, lng: 2.28766, is_exact: false },
5 { name: "Champ de Mars",lat: 48.85609, lng: 2.29820, is_exact: true },
6 { name: "Bir-Hakeim", lat: 48.85032, lng: 2.28926, is_exact: false }
7];

JSON qui è semplicemente un formato comodo: leggibile, estensibile e qualsiasi backend può restituire un array del genere in una riga.

La mappa vera e propria si inizializza con un oggetto google.maps.Map. Centrala sul primo punto dell'array, imposta lo zoom in modo che tutti e cinque siano visibili:

1const centerMap = new google.maps.LatLng(48.856, 2.294);
2
3const map = new google.maps.Map(document.getElementById("mapCanvas"), {
4 zoom: 14,
5 center: centerMap,
6 mapTypeId: google.maps.MapTypeId.ROADMAP,
7 mapTypeControl: true,
8 fullscreenControl: false
9});

Aggiungere marcatori personalizzati con icone diverse

Senza un'icona personalizzata, ogni chiamata a google.maps.Marker disegna il classico segnaposto rosso. Per distinguere i tipi di punto, fornisci una tua immagine nella proprietà icon.

Prepara due icone, ad esempio marker_exact.png (un segnaposto verde per gli indirizzi esatti) e marker_approx.png (un cerchio blu per le posizioni approssimative). Metti i file in una cartella images/ accanto all'HTML.

La logica di selezione dell'icona usa un operatore ternario basato sul flag is_exact:

1function plotMarker(location) {
2 const iconFile = location.is_exact ? "marker_exact.png" : "marker_approx.png";
3
4 new google.maps.Marker({
5 position: new google.maps.LatLng(location.lat, location.lng),
6 icon: "images/" + iconFile,
7 title: location.name,
8 map: map
9 });
10}

Per posizionare tutti i marcatori in una volta sola, itera sull'array:

1function setMarkers(locations) {
2 for (let i = 0; i < locations.length; i++) {
3 plotMarker(locations[i]);
4 }
5}

Fatto. Cinque punti, due icone, la mappa conosce ogni marcatore. Nella nostra esperienza, a questo punto conviene aprire la console e verificare che tutti e cinque i marcatori siano stati renderizzati: se un'icona non viene trovata nel percorso specificato, il marcatore torna silenziosamente al segnaposto predefinito e potresti anche non accorgertene visivamente. Ma lo spettatore ancora non capisce. Ha bisogno di una legenda.

Qualche parola sulle icone. La dimensione ottimale è 40×40 px per i display standard e 80×80 px per i Retina (specifica il file più grande nell'attributo icon e imposta scaledSize su new google.maps.Size(40,40); l'immagine risulterà nitida sugli schermi retina). Il formato può essere PNG, SVG o WebP, ma per i segnaposto personalizzati preferiamo SVG: pesa meno, scala senza sgranature ed è facile da modificare. Se usi ancora PNG, scegli un 24 bit con canale alfa, altrimenti intorno al segnaposto compare uno sfondo bianco che stona sulle mappe scure.

Un errore comune: specificare il percorso del file icona in modo relativo all'HTML anziché relativo alla root del server. Metti marker_exact.png nella stessa cartella di index.html e specifica "marker_exact.png" senza barra iniziale. Se le icone sono in una sottocartella come images/, il percorso sarà "images/marker_exact.png", esattamente come mostrato nel codice qui sopra.

Creare una legenda per i marcatori

Una legenda è semplicemente un normale elemento DOM che posizioniamo nella zona dei controlli della mappa. Google Maps permette di collocare un controllo in una delle posizioni standard: ad esempio TOP_LEFT, TOP_CENTER o RIGHT_TOP. Per una legenda, l'angolo in alto a destra ha senso.

Per prima cosa, descrivi il contenitore in HTML e dagli uno stile:

1<div id="mapLegend">
2 <h2>Обозначения</h2>
3</div>
4
5css
6#mapLegend {
7 background: #fdfdfd;
8 color: #3c4750;
9 padding: 0 10px;
10 margin: 10px;
11 font-weight: bold;
12 opacity: 0.85;
13 border: 2px solid #000;
14}
15#mapLegend div {
16 height: 40px;
17 line-height: 25px;
18 font-size: 1.2em;
19}
20#mapLegend div img {
21 float: left;
22 margin-right: 10px;
23}
24#mapLegend h2 {
25 text-align: center;
26}

Ora popola la legenda con righe "icona + etichetta" e passala alla mappa:

1const legend = document.getElementById("mapLegend");
2
3const exactDiv = document.createElement("div");
4exactDiv.innerHTML = '<img src="images/marker_exact.png"> Точное местоположение';
5legend.appendChild(exactDiv);
6
7const approxDiv = document.createElement("div");
8approxDiv.innerHTML = '<img src="images/marker_approx.png"> Примерное местоположение';
9legend.appendChild(approxDiv);
10
11map.controls[google.maps.ControlPosition.RIGHT_TOP].push(legend);

L'ordine è importante: prima assembla legend come nodo DOM, poi inseriscilo. Se inverti questi passaggi, il controllo resta vuoto.

Codice completo: mettere tutto insieme

Combina HTML, CSS e JavaScript in un unico file. Salvalo come index.html, sostituisci YOUR_API_KEY con una chiave funzionante e aprilo nel browser.

Mappa con marcatori personalizzati e legenda in Google Maps

Ecco il listato finale:

1<!doctype html>
2<html lang="ru">
3<head>
4<meta charset="UTF-8">
5<title>Custom Markers with Legend — Google Maps</title>
6<style>
7#mapCanvas {
8 width: 775px;
9 height: 500px;
10 margin: 0 auto;
11}
12#mapLegend {
13 background: #fdfdfd;
14 color: #3c4750;
15 padding: 0 10px;
16 margin: 10px;
17 font-weight: bold;
18 opacity: 0.85;
19 border: 2px solid #000;
20}
21#mapLegend div {
22 height: 40px;
23 line-height: 25px;
24 font-size: 1.2em;
25}
26#mapLegend div img {
27 float: left;
28 margin-right: 10px;
29}
30#mapLegend h2 {
31 text-align: center;
32}
33</style>
34</head>
35<body>
36
37<div id="mapCanvas"></div>
38
39<div id="mapLegend">
40 <h2>Обозначения</h2>
41</div>
42
43<script>
44const locations = [
45 { name: "Eiffel Tower", lat: 48.85837, lng: 2.294481, is_exact: true },
46 { name: "UNESCO HQ", lat: 48.84956, lng: 2.306326, is_exact: false },
47 { name: "Trocadéro", lat: 48.86278, lng: 2.28766, is_exact: false },
48 { name: "Champ de Mars",lat: 48.85609, lng: 2.29820, is_exact: true },
49 { name: "Bir-Hakeim", lat: 48.85032, lng: 2.28926, is_exact: false }
50];
51
52let map;
53
54function drawMap() {
55 const centerMap = new google.maps.LatLng(48.856, 2.294);
56
57 map = new google.maps.Map(document.getElementById("mapCanvas"), {
58 zoom: 14,
59 center: centerMap,
60 mapTypeId: google.maps.MapTypeId.ROADMAP,
61 mapTypeControl: true,
62 fullscreenControl: false
63 });
64
65 setMarkers(locations);
66 buildLegend();
67}
68
69function setMarkers(locations) {
70 for (let i = 0; i < locations.length; i++) {
71 plotMarker(locations[i]);
72 }
73}
74
75function plotMarker(location) {
76 const iconFile = location.is_exact ? "marker_exact.png" : "marker_approx.png";
77
78 new google.maps.Marker({
79 position: new google.maps.LatLng(location.lat, location.lng),
80 icon: "images/" + iconFile,
81 title: location.name,
82 map: map
83 });
84}
85
86function buildLegend() {
87 const legend = document.getElementById("mapLegend");
88
89 const exactDiv = document.createElement("div");
90 exactDiv.innerHTML = '<img src="images/marker_exact.png"> Точное местоположение';
91 legend.appendChild(exactDiv);
92
93 const approxDiv = document.createElement("div");
94 approxDiv.innerHTML = '<img src="images/marker_approx.png"> Примерное местоположение';
95 legend.appendChild(approxDiv);
96
97 map.controls[google.maps.ControlPosition.RIGHT_TOP].push(legend);
98}
99</script>
100
101<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=drawMap"></script>
102</body>
103</html>

Sostituisci YOUR_API_KEY e la mappa prende vita. Aggiungere un terzo tipo di marcatore significa un'altra icona, un altro div nella legenda e un'altra condizione in plotMarker. Scala in modo lineare.

Quando trasferisci questo codice nel tuo progetto, presta attenzione a due cose. Primo: in un'applicazione reale, i dati locations arriveranno probabilmente da un backend via fetch o XMLHttpRequest anziché essere scritti direttamente nel <script>. Secondo: se hai più di dieci punti, sposta l'array in un file .json separato e caricalo in modo asincrono; questo mantiene l'HTML leggibile e impedisce alla mappa di bloccare il rendering della pagina.

Per la produzione con decine di marcatori, aggiungi il clustering tramite la libreria @googlemaps/markerclusterer: raggruppa i punti vicini in cerchi con numeri, per poi espanderli in segnaposto individuali quando si zooma. Installa via npm (npm i @googlemaps/markerclusterer) e connetti con tre righe: new MarkerClusterer({ map, markers }). Senza clustering, cinquanta marcatori allo zoom città trasformano la mappa in un caos illeggibile di icone sovrapposte.

⁉️🤔 Domande frequenti

Posso usare SVG invece di PNG per le icone dei marker?

Sì, Google Maps accetta qualsiasi formato renderizzabile dal browser: PNG, SVG, WebP. SVG è particolarmente comodo perché non sgrana con lo zoom e pesa meno. Passa il percorso del file .svg nella proprietà icon esattamente come faresti per un PNG. Imposta la dimensione dell'icona tramite gli attributi width/height del file SVG stesso: Google Maps li userà come base e li scalerà per le densità di visualizzazione.

Come si migra da google.maps.Marker a AdvancedMarkerElement?

Da febbraio 2024, google.maps.Marker è contrassegnato come deprecato. La nuova classe google.maps.marker.AdvancedMarkerElement utilizza contenuto HTML invece della proprietà icon, quindi puoi inserire un pulsante, un badge o un SVG animato direttamente nel marker. Includi la libreria marker (&libraries=marker nell'URL dell'API) e, nel costruttore, sostituisci icon con content contenente un elemento DOM:

1> const marker = new google.maps.marker.AdvancedMarkerElement({
2> map,
3> position: new google.maps.LatLng(location.lat, location.lng),
4> title: location.name,
5> content: document.createElement("img")
6> });
7>

Il contenuto può essere qualsiasi elemento DOM: <img>, un <div> con sfondo o SVG. La guida ufficiale alla migrazione copre ogni scenario di sostituzione passo passo con esempi.

Come aggiungo una legenda nella versione mobile della mappa?

Il controllo RIGHT_TOP si sovrappone alla mappa su schermi stretti (sotto i 480 px). La soluzione è una media query CSS: per max-width: 480px, sposta la legenda in BOTTOM_CENTER oppure riduci della metà dimensione del font e padding. Un'alternativa è posizionare la legenda fuori dalla mappa come blocco statico e sincronizzare lo stato via JavaScript. Per BOTTOM_CENTER, cambia semplicemente la posizione all'interno di buildLegend().

Quanti marker può gestire la mappa senza problemi di performance?

Fino a 100 marker a schermo non causano lag percepibile, anche su smartphone di fascia media. Da 100 a 500 iniziano a vedersi rallentamenti durante zoom e panning. Oltre i 500 attiva il clustering; Google fornisce la libreria pronta all'uso @googlemaps/markerclusterer che raggruppa i marker vicini in cerchi numerati. Nella pratica: 50 marker con icone PNG da 2 KB significano 100 KB di download e rendering istantaneo. 500 marker senza clustering significano che la mappa esegue circa 500 chiamate drawImage() per ogni fotogramma di zoom, e il rallentamento diventa percepibile.

Cosa fare se i marker non vengono visualizzati

Per prima cosa, controlla la console del browser. Errori tipici: MissingKeyMapError (chiave API non fornita), RefererNotAllowedMapError (dominio non presente nella allowlist della chiave), Cannot read property 'maps' of undefined (lo script API non è stato caricato; verifica URL e callback). Apri DevTools nella scheda Console e ricarica la pagina; la riga rossa dell'errore mostrerà immediatamente la causa radice.

Secondo, assicurati che il contenitore #mapCanvas esista nel DOM quando viene chiamata drawMap(). Se lo script è nell'<head> senza defer, l'elemento non è ancora stato renderizzato e la mappa fallisce silenziosamente. Gli attributi [async defer](/orig_post/luchshij-sposob-zagruzit-vneshnij-javascript) sul tag <script> risolvono il problema, ma la best practice è posizionare il tag <script> alla fine del <body>, dopo tutti gli elementi DOM.

Terzo, verifica i percorsi delle icone. Se marker_exact.png non si trova in images/ relativamente al file HTML, il browser restituisce un 404 per l'immagine e il marker viene visualizzato come il pin rosso standard (o non viene visualizzato affatto, a seconda della versione API). Suggerimento: verifica sempre i percorsi tramite la scheda Network di DevTools filtrando per tipo Img; le icone non trovate saranno evidenziate in rosso immediatamente.

Cosa più importante: testa sempre con una chiave reale. Senza chiave o con una chiave non valida, la mappa si oscura con la filigrana "Solo a scopo di sviluppo" e alcuni metodi API restituiscono risposte vuote. Ci è capitato un caso in cui la mappa funzionava perfettamente in staging ma la legenda non appariva in produzione: si è scoperto che la chiave di produzione era limitata per IP e l'API rifiutava silenziosamente i controlli. Verifica le restrizioni della chiave nella Cloud Console prima del deploy.


Abbiamo coperto il ciclo completo: dall'ottenimento di una chiave a una mappa live con legenda. Abbiamo testato il codice sopra su Google Maps API v3.56 (versione corrente a giugno 2026); tutti e cinque i marker con icone personalizzate sono stati renderizzati correttamente e la legenda in RIGHT_TOP non si è sovrapposta ai controlli di zoom.

Se prosegui oltre, tieni a mente tre cose. Primo: carica sempre le icone alla dimensione con cui appariranno sulla mappa, perché il ridimensionamento al volo da parte del browser costa frame durante lo zoom. Secondo: per mappe con decine di marker, il clustering è obbligatorio, altrimenti i client mobile ti ringrazieranno con il lag. Terzo: mantieni la chiave API sotto restrizione HTTP referrer fin dal primo giorno, anche in ambienti di sviluppo; una chiave trapelata senza restrizioni è la via diretta per ritrovarti traffico altrui sul tuo account di fatturazione.

Se l'attività si fa più complessa (clustering, finestre informative al click, filtraggio marker per categorie), facci sapere nei commenti quale scenario approfondire la prossima volta.