Panoramica
Scopri come creare una legenda su una mappa Google in questo tutorial. Le legende descrivono in genere i simboli e gli indicatori su una mappa. Puoi crearli utilizzando la funzionalità di posizionamento dei controlli personalizzati.
La mappa riportata di seguito contiene una legenda che fornisce informazioni su tre diversi indicatori personalizzati sulla mappa.
Le sezioni seguenti spiegano i passaggi principali per creare una legenda.
Consulta la sezione Esempio di codice completo per visualizzare il codice completo.
Crea il contenitore della legenda
Crea il contenitore della legenda aggiungendo un div all'elemento gmp-map.
Utilizza l'inserimento dei controlli per impostare la posizione della legenda. Scopri di più sulle opzioni di posizione dei controlli.
<gmp-map center="-33.91722,151.23064" zoom="16.5" map-id="DEMO_MAP_ID">
<div id="legend" slot="control-inline-start-block-start"></div>
</gmp-map>
Applica gli stili per impostare l'aspetto visivo della legenda. Questo esempio applica lo stile al contenitore, al titolo e all'elemento della legenda.
#legend {
background-color: #fff;
width: 15em;
margin: 1em;
border-radius: 8px;
font-family: Roboto, Arial, sans-serif;
overflow: hidden;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
.legend-item {
margin: 0.5em 1em;
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 0.5em;
}
.legend-icon {
margin-right: 1em;
font-size: 24px;
}
.legend-text {
font-size: 1.5em;
}
Aggiungere i contenuti della legenda
La funzione makeLegend() crea in modo programmatico una legenda della mappa visiva e
la inserisce nel DOM della pagina. Ecco come funziona:
- Importa la libreria:importa dinamicamente la classe
PinElementda Maps SDK (await google.maps.importLibrary('marker')).
const { PinElement } = await google.maps.importLibrary('marker');
- Prepara il contenitore:recupera il
<div id="legend">vuoto esistente dall'HTML e aggiunge un elemento titolo "Legenda".
const legend = document.getElementById('legend')!;
const title = document.createElement('div');
title.innerText = 'Legend';
title.classList.add('title');
legend.appendChild(title);
- Itera le configurazioni:esegue un ciclo sull'oggetto di configurazione
iconsper generare una riga per ogni elemento (Parcheggio, Biblioteca, Informazioni). La funzione helper ha il seguente aspetto:
async function makeLegend() { const { PinElement } = await google.maps.importLibrary('marker'); const legend = document.getElementById('legend'); const title = document.createElement('div'); title.innerText = 'Legend'; title.classList.add('title'); legend.appendChild(title); for (const type of Object.values(icons)) { const wrapper = document.createElement('div'); wrapper.classList.add('legend-item'); const pin = new PinElement({ background: type.color, borderColor: type.color, glyphSrc: new URL( `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(type.icon)}` ), scale: 1.0, }); // PinElement extends HTMLElement directly, so we can append it directly! const pinContainer = document.createElement('div'); pinContainer.classList.add('legend-icon'); pinContainer.appendChild(pin); const txt = document.createElement('div'); txt.classList.add('legend-text'); txt.innerText = type.name; wrapper.appendChild(pinContainer); wrapper.appendChild(txt); legend.appendChild(wrapper); } }
Per un altro esempio di legenda generata in modo programmatico, consulta Funzionalità dei dati dei punti di stile.
Esempio di codice completo
La sezione seguente mostra l'intero codice necessario per creare la mappa e la legenda in questo tutorial.
TypeScript
const parkingSvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M13 3H6v18h4v-6h3c3.31 0 6-2.69 6-6s-2.69-6-6-6zm.2 8H10V7h3.2c1.1 0 2 .9 2 2s-.9 2-2 2z"/></svg>`; const librarySvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 11.55C9.64 9.35 6.48 8 3 8v11c3.48 0 6.64 1.35 9 3.55 2.36-2.19 5.52-3.55 9-3.55V8c-3.48 0-6.64 1.35-9 3.55zM12 8c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3z"/></svg>`; const infoSvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>`; const icons: Record<string, { name: string; icon: string; color: string }> = { parking: { name: 'Parking', icon: parkingSvg, color: '#1E88E5', // Blue }, library: { name: 'Library', icon: librarySvg, color: '#43A047', // Green }, info: { name: 'Info', icon: infoSvg, color: '#E53935', // Red }, }; async function init(): Promise<void> { const [{ AdvancedMarkerElement, PinElement }, { event }] = await Promise.all([ google.maps.importLibrary('marker'), google.maps.importLibrary('core'), google.maps.importLibrary('maps'), ]); const mapElement = document.querySelector('gmp-map')!; const innerMap = mapElement.innerMap; // Wait for the map to load before building the legend. event.addListenerOnce(innerMap, 'idle', () => { void makeLegend(); }); const features = [ { position: { lat: -33.91721, lng: 151.2263 }, type: 'info', }, { position: { lat: -33.91539, lng: 151.2282 }, type: 'info', }, { position: { lat: -33.91747, lng: 151.22912 }, type: 'info', }, { position: { lat: -33.9191, lng: 151.22907 }, type: 'info', }, { position: { lat: -33.91725, lng: 151.23011 }, type: 'info', }, { position: { lat: -33.91872, lng: 151.23089 }, type: 'info', }, { position: { lat: -33.91784, lng: 151.23094 }, type: 'info', }, { position: { lat: -33.91682, lng: 151.23149 }, type: 'info', }, { position: { lat: -33.9179, lng: 151.23463 }, type: 'info', }, { position: { lat: -33.91666, lng: 151.23468 }, type: 'info', }, { position: { lat: -33.916988, lng: 151.23364 }, type: 'info', }, { position: { lat: -33.91662347903106, lng: 151.22879464019775 }, type: 'parking', }, { position: { lat: -33.916365282092855, lng: 151.22937399734496 }, type: 'parking', }, { position: { lat: -33.91665018901448, lng: 151.2282474695587 }, type: 'parking', }, { position: { lat: -33.919543720969806, lng: 151.23112279762267 }, type: 'parking', }, { position: { lat: -33.91608037421864, lng: 151.23288232673644 }, type: 'parking', }, { position: { lat: -33.91851096391805, lng: 151.2344058214569 }, type: 'parking', }, { position: { lat: -33.91818154739766, lng: 151.2346203981781 }, type: 'parking', }, { position: { lat: -33.91727341958453, lng: 151.23348314155578 }, type: 'library', }, ]; for (const feature of features) { const iconData = icons[feature.type]; const pin = new PinElement({ background: iconData.color, borderColor: iconData.color, glyphSrc: new URL( `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(iconData.icon)}` ), scale: 1.5, }); const marker = new AdvancedMarkerElement({ position: feature.position, title: iconData.name, }); marker.append(pin); mapElement.append(marker); } } async function makeLegend() { const { PinElement } = await google.maps.importLibrary('marker'); const legend = document.getElementById('legend')!; const title = document.createElement('div'); title.innerText = 'Legend'; title.classList.add('title'); legend.appendChild(title); for (const type of Object.values(icons)) { const wrapper = document.createElement('div'); wrapper.classList.add('legend-item'); const pin = new PinElement({ background: type.color, borderColor: type.color, glyphSrc: new URL( `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(type.icon)}` ), scale: 1.0, }); // PinElement extends HTMLElement directly, so we can append it directly! const pinContainer = document.createElement('div'); pinContainer.classList.add('legend-icon'); pinContainer.appendChild(pin); const txt = document.createElement('div'); txt.classList.add('legend-text'); txt.innerText = type.name; wrapper.appendChild(pinContainer); wrapper.appendChild(txt); legend.appendChild(wrapper); } } void init();
JavaScript
const parkingSvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M13 3H6v18h4v-6h3c3.31 0 6-2.69 6-6s-2.69-6-6-6zm.2 8H10V7h3.2c1.1 0 2 .9 2 2s-.9 2-2 2z"/></svg>`; const librarySvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 11.55C9.64 9.35 6.48 8 3 8v11c3.48 0 6.64 1.35 9 3.55 2.36-2.19 5.52-3.55 9-3.55V8c-3.48 0-6.64 1.35-9 3.55zM12 8c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3z"/></svg>`; const infoSvg = `<svg fill="white" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>`; const icons = { parking: { name: 'Parking', icon: parkingSvg, color: '#1E88E5', // Blue }, library: { name: 'Library', icon: librarySvg, color: '#43A047', // Green }, info: { name: 'Info', icon: infoSvg, color: '#E53935', // Red }, }; async function init() { const [{ AdvancedMarkerElement, PinElement }, { event }] = await Promise.all([ google.maps.importLibrary('marker'), google.maps.importLibrary('core'), google.maps.importLibrary('maps'), ]); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; // Wait for the map to load before building the legend. event.addListenerOnce(innerMap, 'idle', () => { void makeLegend(); }); const features = [ { position: { lat: -33.91721, lng: 151.2263 }, type: 'info', }, { position: { lat: -33.91539, lng: 151.2282 }, type: 'info', }, { position: { lat: -33.91747, lng: 151.22912 }, type: 'info', }, { position: { lat: -33.9191, lng: 151.22907 }, type: 'info', }, { position: { lat: -33.91725, lng: 151.23011 }, type: 'info', }, { position: { lat: -33.91872, lng: 151.23089 }, type: 'info', }, { position: { lat: -33.91784, lng: 151.23094 }, type: 'info', }, { position: { lat: -33.91682, lng: 151.23149 }, type: 'info', }, { position: { lat: -33.9179, lng: 151.23463 }, type: 'info', }, { position: { lat: -33.91666, lng: 151.23468 }, type: 'info', }, { position: { lat: -33.916988, lng: 151.23364 }, type: 'info', }, { position: { lat: -33.91662347903106, lng: 151.22879464019775 }, type: 'parking', }, { position: { lat: -33.916365282092855, lng: 151.22937399734496 }, type: 'parking', }, { position: { lat: -33.91665018901448, lng: 151.2282474695587 }, type: 'parking', }, { position: { lat: -33.919543720969806, lng: 151.23112279762267 }, type: 'parking', }, { position: { lat: -33.91608037421864, lng: 151.23288232673644 }, type: 'parking', }, { position: { lat: -33.91851096391805, lng: 151.2344058214569 }, type: 'parking', }, { position: { lat: -33.91818154739766, lng: 151.2346203981781 }, type: 'parking', }, { position: { lat: -33.91727341958453, lng: 151.23348314155578 }, type: 'library', }, ]; for (const feature of features) { const iconData = icons[feature.type]; const pin = new PinElement({ background: iconData.color, borderColor: iconData.color, glyphSrc: new URL( `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(iconData.icon)}` ), scale: 1.5, }); const marker = new AdvancedMarkerElement({ position: feature.position, title: iconData.name, }); marker.append(pin); mapElement.append(marker); } } async function makeLegend() { const { PinElement } = await google.maps.importLibrary('marker'); const legend = document.getElementById('legend'); const title = document.createElement('div'); title.innerText = 'Legend'; title.classList.add('title'); legend.appendChild(title); for (const type of Object.values(icons)) { const wrapper = document.createElement('div'); wrapper.classList.add('legend-item'); const pin = new PinElement({ background: type.color, borderColor: type.color, glyphSrc: new URL( `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(type.icon)}` ), scale: 1.0, }); // PinElement extends HTMLElement directly, so we can append it directly! const pinContainer = document.createElement('div'); pinContainer.classList.add('legend-icon'); pinContainer.appendChild(pin); const txt = document.createElement('div'); txt.classList.add('legend-text'); txt.innerText = type.name; wrapper.appendChild(pinContainer); wrapper.appendChild(txt); legend.appendChild(wrapper); } } void init();
CSS
html, body { height: 100%; margin: 0; padding: 0; } #legend { background-color: #fff; width: 15em; margin: 1em; border-radius: 8px; font-family: Roboto, Arial, sans-serif; overflow: hidden; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); } .title { padding: 0.5em 1em; font-weight: bold; font-size: 1.5em; margin-bottom: 0.5em; background-color: rgb(66, 133, 244); color: white; box-sizing: border-box; } .legend-item { margin: 0.5em 1em; display: flex; flex-direction: row; align-items: center; padding-bottom: 0.5em; } .legend-icon { margin-right: 1em; font-size: 24px; } .legend-text { font-size: 1.5em; }
HTML
<html>
<head>
<title>Custom Legend</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<gmp-map center="-33.91722,151.23064" zoom="16.5" map-id="DEMO_MAP_ID">
<div id="legend" slot="control-inline-start-block-start"></div>
</gmp-map>
</body>
</html>