Il livello dati di Google Maps fornisce un contenitore per dati geospaziali arbitrari. Puoi utilizzare il livello dati per archiviare i tuoi dati personalizzati o per visualizzare i dati GeoJSON su una mappa di Google.
Panoramica
Guarda questo video di DevBytes per scoprire di più sul livello dati.
Con l'API Maps JavaScript puoi contrassegnare una mappa con una serie di overlay, come indicatori, polilinee, poligoni e così via. Ognuna di queste annotazioni combina informazioni sullo stile con dati sulla posizione. La classe google.maps.Data è un contenitore per dati geospaziali arbitrari. Anziché aggiungere questi overlay, puoi utilizzare il livello dati per aggiungere dati geografici arbitrari alla mappa. Se questi dati contengono geometrie, come punti, linee o poligoni, l'API le visualizzerà per impostazione predefinita come indicatori, polilinee e poligoni. Puoi applicare uno stile a questi elementi come faresti con un normale overlay o applicare regole di stile basate su altre proprietà contenute nel set di dati.
La classe google.maps.Data ti consente di:
- Disegna poligoni sulla mappa.
- Aggiungi dati GeoJSON alla mappa.
GeoJSON è uno standard per i dati geospaziali su internet. La classeDatasegue la struttura di GeoJSON nella sua rappresentazione dei dati e semplifica la visualizzazione dei dati GeoJSON. Utilizza il metodoloadGeoJson()per importare facilmente i dati GeoJSON e visualizzare punti, stringhe di linee e poligoni. - Utilizza
google.maps.Dataper modellare dati arbitrari.
La maggior parte delle entità reali ha altre proprietà associate. Ad esempio, i negozi hanno orari di apertura, le strade hanno una velocità del traffico e ogni gruppo di Girl Guide ha un territorio di vendita di biscotti. Congoogle.maps.Data, puoi modellare queste proprietà e applicare uno stile ai dati di conseguenza. - Scegli come rappresentare i tuoi dati e cambia idea al volo.
Il livello dati ti consente di prendere decisioni sulla visualizzazione e sull'interazione dei tuoi dati. Ad esempio, quando guardi una mappa dei minimarket, potresti scegliere di visualizzare solo i negozi che vendono biglietti per il trasporto pubblico.
Disegna un poligono
La classe Data.Polygon gestisce l'avvolgimento dei poligoni per te. Puoi passare un array di uno o più anelli lineari, definiti come coordinate di latitudine/longitudine. Il primo anello lineare definisce il confine esterno del poligono. Se passi più di un anello lineare, il secondo e i successivi vengono utilizzati per definire i percorsi interni (fori) nel poligono.
L'esempio seguente crea un poligono rettangolare con due fori:
TypeScript
// This example uses the Google Maps JavaScript API's Data layer // to create a rectangular polygon with 2 holes in it. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 6, center: { lat: -33.872, lng: 151.252 }, } ); // Define the LatLng coordinates for the outer path. const outerCoords = [ { lat: -32.364, lng: 153.207 }, // north west { lat: -35.364, lng: 153.207 }, // south west { lat: -35.364, lng: 158.207 }, // south east { lat: -32.364, lng: 158.207 }, // north east ]; // Define the LatLng coordinates for an inner path. const innerCoords1 = [ { lat: -33.364, lng: 154.207 }, { lat: -34.364, lng: 154.207 }, { lat: -34.364, lng: 155.207 }, { lat: -33.364, lng: 155.207 }, ]; // Define the LatLng coordinates for another inner path. const innerCoords2 = [ { lat: -33.364, lng: 156.207 }, { lat: -34.364, lng: 156.207 }, { lat: -34.364, lng: 157.207 }, { lat: -33.364, lng: 157.207 }, ]; map.data.add({ geometry: new google.maps.Data.Polygon([ outerCoords, innerCoords1, innerCoords2, ]), }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example uses the Google Maps JavaScript API's Data layer // to create a rectangular polygon with 2 holes in it. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: -33.872, lng: 151.252 }, }); // Define the LatLng coordinates for the outer path. const outerCoords = [ { lat: -32.364, lng: 153.207 }, // north west { lat: -35.364, lng: 153.207 }, // south west { lat: -35.364, lng: 158.207 }, // south east { lat: -32.364, lng: 158.207 }, // north east ]; // Define the LatLng coordinates for an inner path. const innerCoords1 = [ { lat: -33.364, lng: 154.207 }, { lat: -34.364, lng: 154.207 }, { lat: -34.364, lng: 155.207 }, { lat: -33.364, lng: 155.207 }, ]; // Define the LatLng coordinates for another inner path. const innerCoords2 = [ { lat: -33.364, lng: 156.207 }, { lat: -34.364, lng: 156.207 }, { lat: -34.364, lng: 157.207 }, { lat: -33.364, lng: 157.207 }, ]; map.data.add({ geometry: new google.maps.Data.Polygon([ outerCoords, innerCoords1, innerCoords2, ]), }); } window.initMap = initMap;
Carica GeoJSON
GeoJSON è uno standard comune per la condivisione di dati geospaziali su internet. È leggero e facilmente leggibile, il che lo rende ideale per la condivisione e la collaborazione. Con il Livello dati, puoi aggiungere dati GeoJSON a una mappa Google con una sola riga di codice.
map.data.loadGeoJson('google.json');
Ogni mappa ha un oggetto map.data, che funge da livello dati per dati geospaziali arbitrari, incluso GeoJSON. Puoi caricare e visualizzare un file GeoJSON chiamando il metodo loadGeoJSON() dell'oggetto data. L'esempio seguente mostra come aggiungere una mappa e caricare dati GeoJSON esterni.
TypeScript
async function init() { await google.maps.importLibrary('maps'); const mapElement = document.querySelector('gmp-map')!; const innerMap = mapElement.innerMap; innerMap.data.loadGeoJson('google.json'); } void init();
JavaScript
async function init() { await google.maps.importLibrary('maps'); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; innerMap.data.loadGeoJson('google.json'); } void init();
Calcola l'area del lotto di terreno e il contenimento punto-in-poligono sulle caratteristiche GeoJSON
Per caricare un GeoJSON FeatureCollection in memoria (ad esempio lotti di terreno GIS, zone catastali o confini territoriali) senza recuperare un URL esterno, chiama map.data.addGeoJson(geojsonObject).
Nota sui limiti (Data.Polygon vs.
google.maps.geometry): le funzioni della
libreria geometry, come
google.maps.geometry.spherical.computeArea()
e google.maps.geometry.poly.containsLocation(),
non accettano
direttamente oggetti
google.maps.Data.Feature
o google.maps.Data.Polygon. Per calcolare l'area in metri quadrati o verificare se una coordinata rientra in un poligono GeoJSON, estrai prima l'array LatLng dell'anello esterno con feature.getGeometry().getAt(0).getArray():
const { spherical, poly } = await google.maps.importLibrary("geometry"); map.data.forEach((feature) => { const geom = feature.getGeometry(); if (geom.getType() === "Polygon") { const outerRingCoords = geom.getAt(0).getArray(); // Array<google.maps.LatLng> const areaSqMeters = spherical.computeArea(outerRingCoords); const isInside = poly.containsLocation(pointLatLng, new google.maps.Polygon({ paths: outerRingCoords })); } });
GeoJSON di esempio
La maggior parte degli esempi in questa pagina utilizza un file GeoJSON comune. Questo file definisce i sei caratteri di "Google" come poligoni sull'Australia. Puoi copiare o modificare questo file mentre testi il livello dati.
Nota: per caricare un file JSON da un altro dominio, quest'ultimo deve avere attivato la condivisione delle risorse multiorigine.
Il testo completo del file può essere visualizzato di seguito espandendo la piccola freccia accanto alle parole google.json.
google.json
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "letter": "G", "color": "blue", "rank": "7", "ascii": "71" }, "geometry": { "type": "Polygon", "coordinates": [ [ [123.61, -22.14], [122.38, -21.73], [121.06, -21.69], [119.66, -22.22], [119.00, -23.40], [118.65, -24.76], [118.43, -26.07], [118.78, -27.56], [119.22, -28.57], [120.23, -29.49], [121.77, -29.87], [123.57, -29.64], [124.45, -29.03], [124.71, -27.95], [124.80, -26.70], [124.80, -25.60], [123.61, -25.64], [122.56, -25.64], [121.72, -25.72], [121.81, -26.62], [121.86, -26.98], [122.60, -26.90], [123.57, -27.05], [123.57, -27.68], [123.35, -28.18], [122.51, -28.38], [121.77, -28.26], [121.02, -27.91], [120.49, -27.21], [120.14, -26.50], [120.10, -25.64], [120.27, -24.52], [120.67, -23.68], [121.72, -23.32], [122.43, -23.48], [123.04, -24.04], [124.54, -24.28], [124.58, -23.20], [123.61, -22.14] ] ] } }, { "type": "Feature", "properties": { "letter": "o", "color": "red", "rank": "15", "ascii": "111" }, "geometry": { "type": "Polygon", "coordinates": [ [ [128.84, -25.76], [128.18, -25.60], [127.96, -25.52], [127.88, -25.52], [127.70, -25.60], [127.26, -25.79], [126.60, -26.11], [126.16, -26.78], [126.12, -27.68], [126.21, -28.42], [126.69, -29.49], [127.74, -29.80], [128.80, -29.72], [129.41, -29.03], [129.72, -27.95], [129.68, -27.21], [129.33, -26.23], [128.84, -25.76] ], [ [128.45, -27.44], [128.32, -26.94], [127.70, -26.82], [127.35, -27.05], [127.17, -27.80], [127.57, -28.22], [128.10, -28.42], [128.49, -27.80], [128.45, -27.44] ] ] } }, { "type": "Feature", "properties": { "letter": "o", "color": "yellow", "rank": "15", "ascii": "111" }, "geometry": { "type": "Polygon", "coordinates": [ [ [131.87, -25.76], [131.35, -26.07], [130.95, -26.78], [130.82, -27.64], [130.86, -28.53], [131.26, -29.22], [131.92, -29.76], [132.45, -29.87], [133.06, -29.76], [133.72, -29.34], [134.07, -28.80], [134.20, -27.91], [134.07, -27.21], [133.81, -26.31], [133.37, -25.83], [132.71, -25.64], [131.87, -25.76] ], [ [133.15, -27.17], [132.71, -26.86], [132.09, -26.90], [131.74, -27.56], [131.79, -28.26], [132.36, -28.45], [132.93, -28.34], [133.15, -27.76], [133.15, -27.17] ] ] } }, { "type": "Feature", "properties": { "letter": "g", "color": "blue", "rank": "7", "ascii": "103" }, "geometry": { "type": "Polygon", "coordinates": [ [ [138.12, -25.04], [136.84, -25.16], [135.96, -25.36], [135.26, -25.99], [135, -26.90], [135.04, -27.91], [135.26, -28.88], [136.05, -29.45], [137.02, -29.49], [137.81, -29.49], [137.94, -29.99], [137.90, -31.20], [137.85, -32.24], [136.88, -32.69], [136.45, -32.36], [136.27, -31.80], [134.95, -31.84], [135.17, -32.99], [135.52, -33.43], [136.14, -33.76], [137.06, -33.83], [138.12, -33.65], [138.86, -33.21], [139.30, -32.28], [139.30, -31.24], [139.30, -30.14], [139.21, -28.96], [139.17, -28.22], [139.08, -27.41], [139.08, -26.47], [138.99, -25.40], [138.73, -25.00 ], [138.12, -25.04] ], [ [137.50, -26.54], [136.97, -26.47], [136.49, -26.58], [136.31, -27.13], [136.31, -27.72], [136.58, -27.99], [137.50, -28.03], [137.68, -27.68], [137.59, -26.78], [137.50, -26.54] ] ] } }, { "type": "Feature", "properties": { "letter": "l", "color": "green", "rank": "12", "ascii": "108" }, "geometry": { "type": "Polygon", "coordinates": [ [ [140.14,-21.04], [140.31,-29.42], [141.67,-29.49], [141.59,-20.92], [140.14,-21.04] ] ] } }, { "type": "Feature", "properties": { "letter": "e", "color": "red", "rank": "5", "ascii": "101" }, "geometry": { "type": "Polygon", "coordinates": [ [ [144.14, -27.41], [145.67, -27.52], [146.86, -27.09], [146.82, -25.64], [146.25, -25.04], [145.45, -24.68], [144.66, -24.60], [144.09, -24.76], [143.43, -25.08], [142.99, -25.40], [142.64, -26.03], [142.64, -27.05], [142.64, -28.26], [143.30, -29.11], [144.18, -29.57], [145.41, -29.64], [146.46, -29.19], [146.64, -28.72], [146.82, -28.14], [144.84, -28.42], [144.31, -28.26], [144.14, -27.41] ], [ [144.18, -26.39], [144.53, -26.58], [145.19, -26.62], [145.72, -26.35], [145.81, -25.91], [145.41, -25.68], [144.97, -25.68], [144.49, -25.64], [144, -25.99], [144.18, -26.39] ] ] } } ] }
Stile dei dati GeoJSON
Utilizza il metodo Data.setStyle() per specificare l'aspetto dei dati. Il metodo setStyle() accetta un oggetto letterale StyleOptions o una funzione che calcola lo stile per ogni elemento.
Regole di stile semplici
Il modo più semplice per applicare uno stile agli elementi è passare un oggetto letterale StyleOptions a setStyle(). In questo modo, verrà impostato un unico stile per ogni elemento della raccolta. Tieni presente che ogni tipo di elemento è in grado di eseguire il rendering solo di un sottoinsieme delle opzioni disponibili. Ciò significa che è possibile combinare gli stili per diversi tipi di elementi in un unico oggetto letterale. Ad esempio, lo snippet seguente imposta sia un icon personalizzato, che influisce solo sulle geometrie dei punti, sia un fillColor, che influisce solo sui poligoni.
map.data.setStyle({ icon: '//example.com/path/to/image.png', fillColor: 'green' });
Per ulteriori informazioni sulle combinazioni di stili/caratteristiche valide, consulta Opzioni di stile.
Di seguito è riportato un esempio di impostazione del colore del tratto e del colore di riempimento per diverse caratteristiche utilizzando un oggetto letterale StyleOptions. Nota che ogni poligono ha lo stesso stile.
TypeScript
async function init() { const [{ event }] = await Promise.all([ google.maps.importLibrary('core'), google.maps.importLibrary('maps'), ]); const mapElement = document.querySelector('gmp-map')!; const innerMap = mapElement.innerMap; // Load GeoJSON. event.addListenerOnce(innerMap, 'idle', () => { innerMap.data.loadGeoJson('google.json'); }); // Set the stroke width, and fill color for each polygon innerMap.data.setStyle({ fillColor: 'green', strokeWeight: 1, }); } void init();
JavaScript
async function init() { const [{ event }] = await Promise.all([ google.maps.importLibrary('core'), google.maps.importLibrary('maps'), ]); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; // Load GeoJSON. event.addListenerOnce(innerMap, 'idle', () => { innerMap.data.loadGeoJson('google.json'); }); // Set the stroke width, and fill color for each polygon innerMap.data.setStyle({ fillColor: 'green', strokeWeight: 1, }); } void init();
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ gmp-map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html>
<head>
<title>Data Layer: Styling</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="-28,137" zoom="4"></gmp-map>
</body>
</html>Regole di stile dichiarative
Se vuoi aggiornare lo stile di un numero elevato di overlay, ad esempio indicatori o polilinee, in genere devi eseguire l'iterazione di ogni overlay sulla mappa e impostarne lo stile singolarmente. Con il livello dati, puoi impostare regole in modo dichiarativo che verranno applicate all'intero set di dati. Quando i dati o le regole vengono aggiornati, lo stile viene applicato automaticamente a ogni elemento. Puoi utilizzare le proprietà di un elemento per personalizzarne lo stile.
Ad esempio, il codice seguente imposta il colore di ogni carattere nel nostro google.json esaminando la sua posizione nel set di caratteri ASCII. In questo caso, abbiamo codificato la posizione del carattere insieme ai nostri dati.
// Color Capital letters blue, and lower case letters red. // Capital letters are represented in ascii by values less than 91 map.data.setStyle(function(feature) { var ascii = feature.getProperty('ascii'); var color = ascii > 91 ? 'red' : 'blue'; return { fillColor: color, strokeWeight: 1 }; });
Rimuovi stili
Se vuoi rimuovere gli stili applicati, passa un oggetto letterale vuoto al metodo setStyles().
// Remove custom styles. map.data.setStyle({});
In questo modo, verranno rimossi tutti gli stili personalizzati che hai specificato e gli elementi verranno visualizzati utilizzando gli stili predefiniti. Se invece non vuoi più eseguire il rendering delle funzionalità, imposta la proprietà visible di StyleOptions su false.
// Hide the Data layer. map.data.setStyle({visible: false});
Sostituisci gli stili predefiniti
Le regole di stile vengono in genere applicate a ogni elemento nel livello dati. Tuttavia, a volte potresti voler applicare regole di stile speciali a elementi specifici. Ad esempio, per evidenziare una funzionalità al clic.
Per applicare regole di stile speciali, utilizza il metodo overrideStyle(). Tutte le proprietà che modifichi con il metodo overrideStyle() vengono applicate in aggiunta agli stili globali già specificati in setStyle(). Ad esempio, il codice seguente
cambia il colore di riempimento di un poligono al clic, ma non imposta altri
stili.
// Set the global styles. map.data.setStyle({ fillColor: 'green', strokeWeight: 3 }); // Set the fill color to red when the feature is clicked. // Stroke weight remains 3. map.data.addListener('click', function(event) { map.data.overrideStyle(event.feature, {fillColor: 'red'}); });
Chiama il metodo revertStyle() per rimuovere tutte le sostituzioni di stile.
Opzioni stile
Le opzioni disponibili per lo stile di ogni elemento dipendono dal tipo di elemento.
Ad esempio, fillColor verrà visualizzato solo su geometrie poligonali, mentre icon verrà visualizzato solo su una geometria punto. Per saperne di più, consulta la documentazione di riferimento per StyleOptions.
Disponibile su tutte le geometrie
clickable: setrue, la funzionalità riceve eventi del mouse e touchvisible: setrue, la funzionalità è visibile.zIndex: tutte le caratteristiche vengono visualizzate sulla mappa in ordine dizIndex, con i valori più alti visualizzati davanti alle caratteristiche con valori più bassi. Gli indicatori vengono sempre visualizzati davanti a stringhe di linee e poligoni.
Disponibile per le geometrie dei punti
cursor: il cursore del mouse da mostrare al passaggio del mouse.icon: icona da mostrare per la geometria del punto.shape: definisce la mappa immagine utilizzata per il rilevamento dei clic.title: testo di rollover.
Disponibile per le geometrie delle linee
strokeColor: il colore del tratto. Sono supportati tutti i colori CSS3, ad eccezione dei colori con nome esteso.strokeOpacity: l'opacità del tratto compresa tra 0,0 e 1,0.strokeWeight: la larghezza del tratto in pixel.
Disponibile per le geometrie poligonali
fillColor: il colore di riempimento. Sono supportati tutti i colori CSS3, ad eccezione dei colori con nome esteso.fillOpacity: l'opacità del riempimento tra0.0e1.0.strokeColor: il colore del tratto. Sono supportati tutti i colori CSS3, ad eccezione dei colori con nome esteso.strokeOpacity: l'opacità del tratto compresa tra 0,0 e 1,0.strokeWeight: la larghezza del tratto in pixel.
Aggiungi gestori di eventi
Le funzionalità rispondono a eventi, come mouseup o mousedown. Puoi aggiungere listener di eventi per consentire agli utenti di interagire con i dati sulla mappa. Nell'esempio seguente, aggiungiamo un evento mouseover che mostra informazioni sulla funzionalità sotto il cursore del mouse.
// Set mouseover event for each feature. innerMap.data.addListener('mouseover', (event) => { document.getElementById('info-box').textContent = event.feature.getProperty('letter'); });
Eventi del livello dati
I seguenti eventi sono comuni a tutte le caratteristiche, indipendentemente dal tipo di geometria:
addfeatureclickdblclickmousedownmouseoutmouseovermouseupremovefeatureremovepropertyrightclicksetgeometrysetproperty
Per saperne di più su questi eventi, consulta la documentazione di riferimento per la classe google.maps.data.
Cambia l'aspetto in modo dinamico
Puoi impostare lo stile del livello dati passando una funzione che calcola lo stile di ogni elemento al metodo google.maps.data.setStyle(). Questa funzione verrà chiamata ogni volta che le proprietà di un elemento vengono aggiornate.
Nell'esempio seguente, aggiungiamo un listener di eventi per l'evento click che aggiorna la proprietà isColorful della funzionalità. Lo stile della caratteristica viene aggiornato per riflettere la modifica non appena viene impostata la proprietà.
// Color each letter gray. Change the color when the isColorful property // is set to true. map.data.setStyle(function(feature) { var color = 'gray'; if (feature.getProperty('isColorful')) { color = feature.getProperty('color'); } return /** @type {!google.maps.Data.StyleOptions} */({ fillColor: color, strokeColor: color, strokeWeight: 2 }); }); // When the user clicks, set 'isColorful', changing the color of the letters. map.data.addListener('click', function(event) { event.feature.setProperty('isColorful', true); }); // When the user hovers, tempt them to click by outlining the letters. // Call revertStyle() to remove all overrides. This will use the style rules // defined in the function passed to setStyle() map.data.addListener('mouseover', function(event) { map.data.revertStyle(); map.data.overrideStyle(event.feature, {strokeWeight: 8}); }); map.data.addListener('mouseout', function(event) { map.data.revertStyle(); });