Warstwa danych Map Google udostępnia kontener na dowolne dane geoprzestrzenne. Warstwy danych możesz używać do przechowywania danych niestandardowych lub wyświetlania danych GeoJSON na mapie Google.
Przegląd
Obejrzyj ten film z serii DevBytes, aby dowiedzieć się więcej o warstwie danych.
Za pomocą interfejsu Maps JavaScript API możesz oznaczać mapę różnymi nakładkami, takimi jak znaczniki, linie łamane, wielokąty itp. Każda z tych adnotacji łączy informacje o stylu z danymi o lokalizacji. Klasa google.maps.Data to kontener na dowolne dane geoprzestrzenne. Zamiast dodawać te nakładki, możesz użyć warstwy danych, aby dodać do mapy dowolne dane geograficzne. Jeśli dane zawierają elementy geometryczne, takie jak punkty, linie lub wielokąty, interfejs API domyślnie renderuje je jako znaczniki, linie łamane i wielokąty. Możesz określić styl tych obiektów tak samo jak w przypadku zwykłej nakładki lub zastosować reguły stylu na podstawie innych właściwości zawartych w zbiorze danych.
Klasa google.maps.Data umożliwia:
- Rysowanie wielokątów na mapie
- Dodaj dane GeoJSON do mapy.
GeoJSON to standard danych geoprzestrzennych w internecie. KlasaDataodzwierciedla strukturę GeoJSON w reprezentacji danych i ułatwia wyświetlanie danych GeoJSON. Użyj metodyloadGeoJson(), aby łatwo importować dane GeoJSON i wyświetlać punkty, ciągi linii i wielokąty. - Użyj
google.maps.Data, aby modelować dowolne dane.
Większość encji w świecie rzeczywistym ma powiązane z nimi inne właściwości. Na przykład sklepy mają godziny otwarcia, drogi mają prędkość ruchu, a każda drużyna harcerska ma swój teren, na którym sprzedaje ciasteczka. Dziękigoogle.maps.Datamożesz modelować te właściwości i odpowiednio stylizować dane. - Wybierz sposób prezentacji danych i zmieniaj go na bieżąco.
Warstwa danych pozwala podejmować decyzje dotyczące wizualizacji danych i interakcji z nimi. Na przykład na mapie sklepów osiedlowych możesz wyświetlić tylko te, które sprzedają bilety na transport publiczny.
Rysowanie wielokąta
Klasa Data.Polygon obsługuje nawijanie wielokątów. Możesz przekazać tablicę zawierającą co najmniej 1 pierścień liniowy zdefiniowany jako współrzędne szerokości i długości geograficznej. Pierwszy pierścień liniowy definiuje zewnętrzną granicę wielokątu. Jeśli przekażesz więcej niż 1 pierścień liniowy, drugi i kolejne pierścienie liniowe zostaną użyte do zdefiniowania ścieżek wewnętrznych (otworów) w wielokącie.
W tym przykładzie tworzony jest prostokątny wielokąt z 2 otworami:
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;
Wczytywanie GeoJSON
GeoJSON to popularny standard udostępniania danych geoprzestrzennych w internecie. Jest lekki i łatwo zrozumiałe dla człowieka, dzięki czemu idealnie nadaje się do udostępniania i współpracy. Dzięki warstwie danych możesz dodać dane GeoJSON do mapy Google za pomocą tylko jednej linii kodu.
map.data.loadGeoJson('google.json');
Każda mapa ma obiekt map.data, który działa jako warstwa danych dla dowolnych danych geoprzestrzennych, w tym GeoJSON. Plik GeoJSON możesz wczytać i wyświetlić, wywołując metodę loadGeoJSON() obiektu data. Poniższy przykład pokazuje, jak dodać mapę i wczytać zewnętrzne dane GeoJSON.
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();
Obliczanie powierzchni działki i zawierania punktu w wielokącie na podstawie obiektów GeoJSON
Aby wczytać dane GeoJSON FeatureCollection w pamięci (np. działki GIS, strefy katastralne lub granice terytorialne) bez pobierania zewnętrznego adresu URL, wywołaj map.data.addGeoJson(geojsonObject).
Uwaga dotycząca granic (Data.Polygon i google.maps.geometry): funkcje w bibliotece geometry, takie jak google.maps.geometry.spherical.computeArea() i google.maps.geometry.poly.containsLocation(), nie akceptują bezpośrednio obiektów google.maps.Data.Feature ani google.maps.Data.Polygon. Aby obliczyć obszar w metrach kwadratowych lub sprawdzić, czy współrzędna znajduje się wewnątrz wielokąta GeoJSON, najpierw wyodrębnij tablicę LatLng zewnętrznego pierścienia za pomocą 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 })); } });
Przykładowy plik GeoJSON
Większość przykładów na tej stronie korzysta z popularnego pliku GeoJSON. Ten plik definiuje 6 znaków w słowie „Google” jako wielokąty nad Australią. Możesz skopiować lub zmodyfikować ten plik podczas testowania warstwy danych.
Uwaga: aby można było wczytać plik JSON z innej domeny, musi ona mieć włączone współdzielenie zasobów między domenami.
Pełny tekst pliku można zobaczyć poniżej, rozwijając małą strzałkę obok słów 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] ] ] } } ] }
Stylizowanie danych GeoJSON
Użyj metody Data.setStyle(), aby określić, jak mają wyglądać dane. Metoda setStyle() przyjmuje literał obiektu StyleOptions lub funkcję, która oblicza styl dla każdej cechy.
Proste reguły stylu
Najprostszym sposobem na określenie stylu obiektów jest przekazanie literału obiektu StyleOptions do setStyle(). Spowoduje to ustawienie jednego stylu dla każdej cechy w kolekcji. Pamiętaj, że każdy typ funkcji może renderować tylko podzbiór dostępnych opcji. Oznacza to, że w jednym literale obiektu można łączyć style różnych typów obiektów. Na przykład poniższy fragment kodu ustawia zarówno niestandardowy parametr icon, który wpływa tylko na geometrie punktów, jak i parametr fillColor, który wpływa tylko na wielokąty.
map.data.setStyle({ icon: '//example.com/path/to/image.png', fillColor: 'green' });
Więcej informacji o prawidłowych kombinacjach stylów i funkcji znajdziesz w artykule Opcje stylu.
Poniżej znajdziesz przykład ustawiania koloru obrysu i koloru wypełnienia dla kilku obiektów za pomocą literału obiektu StyleOptions. Zwróć uwagę, że każdy wielokąt ma taki sam styl.
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>Reguły stylu deklaratywnego
Jeśli chcesz zaktualizować styl dużej liczby nakładek, takich jak znaczniki lub linie łamane, zwykle musisz przejść przez każdą nakładkę na mapie i ustawić jej styl osobno. Dzięki warstwie danych możesz deklaratywnie ustawiać reguły, które będą stosowane do całego zbioru danych. Gdy dane lub reguły zostaną zaktualizowane, styl zostanie automatycznie zastosowany do każdego elementu. Możesz użyć właściwości elementu, aby dostosować jego styl.
Na przykład poniższy kod ustawia kolor każdego znaku w google.json, sprawdzając jego pozycję w zestawie znaków ASCII. W tym przypadku zakodowaliśmy pozycję znaku wraz z danymi.
// 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 }; });
Usuwanie stylów
Jeśli chcesz usunąć zastosowane style, przekaż do metody setStyles() pusty literał obiektu.
// Remove custom styles. map.data.setStyle({});
Spowoduje to usunięcie wszystkich określonych przez Ciebie stylów niestandardowych, a funkcje będą renderowane przy użyciu stylów domyślnych. Jeśli nie chcesz już renderować funkcji, ustaw właściwość visible elementu StyleOptions na false.
// Hide the Data layer. map.data.setStyle({visible: false});
Zastępowanie stylów domyślnych
Reguły stylów są zwykle stosowane do wszystkich obiektów w warstwie danych. Czasami jednak możesz chcieć zastosować specjalne reguły stylów do konkretnych obiektów. Możesz na przykład wyróżnić funkcję po kliknięciu.
Aby zastosować specjalne reguły stylów, użyj metody overrideStyle(). Wszystkie właściwości, które zmienisz za pomocą metody overrideStyle(), zostaną zastosowane oprócz stylów globalnych określonych już w pliku setStyle(). Na przykład poniższy kod zmieni kolor wypełnienia wielokąta po kliknięciu, ale nie ustawi żadnych innych stylów.
// 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'}); });
Aby usunąć wszystkie zastąpienia stylów, wywołaj metodę revertStyle().
Opcje stylu
Dostępne opcje stylizacji poszczególnych obiektów zależą od typu obiektu.
Na przykład fillColor będzie renderowany tylko na geometriach wielokątnych, a icon będzie się pojawiać tylko na geometrii punktowej. Więcej informacji znajdziesz w dokumentacji referencyjnej StyleOptions.
Dostępne we wszystkich geometriach
clickable: jeślitrue, funkcja otrzymuje zdarzenia myszy i dotknięciavisible: jeślitrue, funkcja jest widoczna.zIndex: wszystkie obiekty są wyświetlane na mapie w kolejności ichzIndex, przy czym wyższe wartości są wyświetlane przed obiektami o niższych wartościach. Znaczniki są zawsze wyświetlane przed ciągami linii i wielokątami.
Dostępne w przypadku geometrii punktów
cursor: kursor myszy, który ma być wyświetlany po najechaniu.icon: ikona wyświetlana dla geometrii punktu.shape: definiuje mapę obrazu używaną do wykrywania kliknięć.title: tekst po najechaniu kursorem.
Dostępne w przypadku geometrii linii
strokeColor: kolor obrysu. Obsługiwane są wszystkie kolory CSS3 z wyjątkiem rozszerzonych nazwanych kolorów.strokeOpacity: nieprzezroczystość linii od 0,0 do 1,0.strokeWeight: szerokość obrysu w pikselach.
Dostępne w przypadku geometrii wielokątów
fillColor: kolor wypełnienia. Obsługiwane są wszystkie kolory CSS3 z wyjątkiem rozszerzonych nazwanych kolorów.fillOpacity: nieprzezroczystość wypełnienia od0.0do1.0.strokeColor: kolor obrysu. Obsługiwane są wszystkie kolory CSS3 z wyjątkiem rozszerzonych nazwanych kolorów.strokeOpacity: nieprzezroczystość linii od 0,0 do 1,0.strokeWeight: szerokość obrysu w pikselach.
Dodawanie modułów obsługi zdarzeń
Funkcje reagują na zdarzenia, takie jak mouseup lub mousedown. Możesz dodać detektory zdarzeń, aby umożliwić użytkownikom interakcję z danymi na mapie. W poniższym przykładzie dodajemy zdarzenie najechania kursorem, które wyświetla informacje o obiekcie pod kursorem myszy.
// Set mouseover event for each feature. innerMap.data.addListener('mouseover', (event) => { document.getElementById('info-box').textContent = event.feature.getProperty('letter'); });
Zdarzenia warstwy danych
Te zdarzenia są wspólne dla wszystkich obiektów, niezależnie od ich typu geometrii:
addfeatureclickdblclickmousedownmouseoutmouseovermouseupremovefeatureremovepropertyrightclicksetgeometrysetproperty
Więcej informacji o tych zdarzeniach znajdziesz w dokumentacji referencyjnej klasy google.maps.data.
Dynamiczna zmiana wyglądu
Możesz ustawić styl warstwy danych, przekazując do metody google.maps.data.setStyle() funkcję, która oblicza styl każdego elementu. Ta funkcja będzie wywoływana za każdym razem, gdy właściwości obiektu zostaną zaktualizowane.
W przykładzie poniżej dodajemy detektor zdarzeń dla zdarzenia click, które aktualizuje właściwość isColorful elementu. Styl elementu zostanie zaktualizowany, aby odzwierciedlić zmianę, gdy tylko właściwość zostanie ustawiona.
// 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(); });