Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Tangram mit Amazon Location Service verwenden
Tangram
Tangram basiert auf Leaflet
Tangram-Stile, die für das Tilezen-Schema
-
Bubble Wrap
— Ein Orientierungsstil mit vollem Funktionsumfang und hilfreichen Symbolen für Sehenswürdigkeiten -
Zinnober
— Ein klassisches Design und ein Muss für allgemeine Kartenanwendungen -
Refill
— Ein minimalistischer Kartenstil für Datenvisualisierungs-Overlays, inspiriert vom wegweisenden Toner-Stil von Stamen Design -
Tron
— Eine Untersuchung von Maßstabstransformationen in der Bildsprache von TRON -
Walkabout
— Ein Outdoor-Style, der sich perfekt zum Wandern oder für unterwegs eignet
In diesem Handbuch wird beschrieben, wie Sie Tangram mit Amazon Location in eine einfache HTML JavaScript /-Anwendung integrieren, die den Tangram-Stil namens Bubble
Während andere Tangram-Styles am besten von Raster-Kacheln begleitet werden, die Geländeinformationen kodieren, wird diese Funktion von Amazon Location noch nicht unterstützt.
Wichtig
Die Tangram-Stile in der folgenden Anleitung sind nur mit Amazon Location Map-Ressourcen kompatibel, die mit dem VectorHereContrast
Stil konfiguriert wurden.
Erstellung der Anwendung: Scaffolding
Die Anwendung ist eine HTML Seite JavaScript zum Erstellen der Karte in Ihrer Webanwendung. Erstellen Sie eine HTML Seite (index.html
) und erstellen Sie den Container der Karte:
-
Geben Sie ein
div
Element mitid
einer OF-Karte ein, um die Abmessungen der Karte auf die Kartenansicht anzuwenden. -
Die Abmessungen werden aus dem Viewport übernommen.
<html> <head> <style> body { margin: 0; } #map { height: 100vh; /* 100% of viewport height */ } </style> </head> <body> <!-- map container --> <div id="map" /> </body> </html>
Die Anwendung erstellen: Abhängigkeiten hinzufügen
Fügen Sie die folgenden Abhängigkeiten hinzu:
-
Flugblatt und dazugehörige CSS Informationen.
-
Tangram.
-
AWSSDKfür JavaScript.
<!-- CSS dependencies --> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" /> <!-- JavaScript dependencies --> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> <script src="https://unpkg.com/tangram"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.784.0.min.js"></script> <script> // application-specific code </script>
Dadurch wird eine leere Seite mit den erforderlichen Voraussetzungen erstellt. Der nächste Schritt führt Sie durch das Schreiben des JavaScript Codes für Ihre Anwendung.
Die Anwendung erstellen: Konfiguration
So konfigurieren Sie Ihre Anwendung mit Ihren Ressourcen und Anmeldeinformationen:
-
Geben Sie die Namen und Kennungen Ihrer Ressourcen ein.
// Cognito Identity Pool ID const identityPoolId = "
us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd
"; // Amazon Location Service map name; must be HERE-backed const mapName = "TangramExampleMap
"; -
Instanziieren Sie einen Anmeldeinformationsanbieter mithilfe des nicht authentifizierten Identitätspools, den Sie unter Karten verwenden — Schritt 2, Authentifizierung einrichten erstellt haben. Da dabei Anmeldeinformationen außerhalb des normalen Workflows verwendet werden, AWS SDK laufen Sitzungen nach einer Stunde ab.
// extract the region from the Identity Pool ID; this will be used for both Amazon Cognito and Amazon Location AWS.config.region = identityPoolId.split(":", 1)[0]; // instantiate a Cognito-backed credential provider const credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId:
identityPoolId
, }); -
Tangram ermöglicht es Ihnen zwar, die zum Abrufen von Kacheln verwendeten URL (n) zu überschreiben, bietet jedoch nicht die Möglichkeit, Anfragen abzufangen, sodass sie signiert werden können.
Um dies zu umgehen, können
sources.mapzen.url
Sie überschreiben, indem Sie mithilfe eines synthetischen Hostnamens auf Amazon Location verweisenamazon.location
, der von einem Servicemitarbeiterverwaltet wird. Im Folgenden finden Sie ein Beispiel für die Szenenkonfiguration mit Bubble Wrap : const scene = { import: [ // Bubble Wrap style "https://www.nextzen.org/carto/bubble-wrap-style/10/bubble-wrap-style.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/label-7.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/bubble-wrap-road-shields-usa.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/bubble-wrap-road-shields-international.zip", ], // override values beneath the `sources` key in the style above sources: { mapzen: { // point at Amazon Location using a synthetic URL, which will be handled by the service // worker url: `https://amazon.location/${mapName}/{z}/{x}/{y}`, }, // effectively disable raster tiles containing encoded normals normals: { max_zoom: 0, }, "normals-elevation": { max_zoom: 0, }, }, };
Die Anwendung erstellen: Transformation anfordern
Um den Service Worker zu registrieren und zu initialisieren, erstellen Sie eine registerServiceWorker
Funktion, die aufgerufen werden soll, bevor die Map initialisiert wird. Dadurch wird der JavaScript Code registriert, der in einer separaten Datei namens Service Worker sw.js
Controlling bereitgestellt wird. index.html
Anmeldeinformationen werden von Amazon Cognito geladen und zusammen mit der Region an den Servicemitarbeiter weitergegeben, um Informationen zum Signieren von Kachelanfragen mit Signature Version 4 bereitzustellen.
/** * Register a service worker that will rewrite and sign requests using Signature Version 4. */ async function registerServiceWorker() { if ("serviceWorker" in navigator) { try { const reg = await navigator.serviceWorker.register("./sw.js"); // refresh credentials from Amazon Cognito await credentials.refreshPromise(); await reg.active.ready; if (navigator.serviceWorker.controller == null) { // trigger a navigate event to active the controller for this page window.location.reload(); } // pass credentials to the service worker reg.active.postMessage({ credentials: { accessKeyId:
credentials.accessKeyId
, secretAccessKey:credentials.secretAccessKey
, sessionToken:credentials.sessionToken
, }, region: AWS.config.region, }); } catch (error) { console.error("Service worker registration failed:", error); } } else { console.warn("Service worker support is required for this example"); } }
Die Service Worker-Implementierung in sw.js
wartet auf message
Ereignisse, um Änderungen an den Anmeldeinformationen und der Regionskonfiguration zu erfassen. Sie fungiert auch als Proxyserver, indem sie auf Ereignisse wartetfetch
. fetch
Ereignisse, die auf den amazon.location
synthetischen Hostnamen abzielen, werden so umgeschrieben, dass sie auf den entsprechenden Amazon-Standort abzielen, API und mit Amplify Cores signiert. Signer
// sw.js self.importScripts( "https://unpkg.com/@aws-amplify/core@3.7.0/dist/aws-amplify-core.min.js" ); const { Signer } = aws_amplify_core; let credentials; let region; self.addEventListener("install", (event) => { // install immediately event.waitUntil(self.skipWaiting()); }); self.addEventListener("activate", (event) => { // control clients ASAP event.waitUntil(self.clients.claim()); }); self.addEventListener("message", (event) => { const { data: { credentials: newCredentials, region: newRegion }, } = event; if (newCredentials != null) { credentials = newCredentials; } if (newRegion != null) { region = newRegion; } }); async function signedFetch(request) { const url = new URL(request.url); const path = url.pathname.slice(1).split("/"); // update URL to point to Amazon Location url.pathname = `/maps/v0/maps/${path[0]}/tiles/${path.slice(1).join("/")}`; url.host = `maps.geo.${region}.amazonaws.com`; // strip params (Tangram generates an empty api_key param) url.search = ""; const signed = Signer.signUrl(url.toString(), { access_key: credentials.accessKeyId, secret_key: credentials.secretAccessKey, session_token: credentials.sessionToken, }); return fetch(signed); } self.addEventListener("fetch", (event) => { const { request } = event; // match the synthetic hostname we're telling Tangram to use if (request.url.includes("amazon.location")) { return event.respondWith(signedFetch(request)); } // fetch normally return event.respondWith(fetch(request)); });
Um Anmeldeinformationen automatisch zu erneuern und sie vor Ablauf an den Servicemitarbeiter zu senden, verwenden Sie die folgende Funktion innerhalb: index.html
async function refreshCredentials() { await credentials.refreshPromise(); if ("serviceWorker" in navigator) { const controller = navigator.serviceWorker.controller; controller.postMessage({ credentials: { accessKeyId: credentials.accessKeyId, secretAccessKey: credentials.secretAccessKey, sessionToken: credentials.sessionToken, }, }); } else { console.warn("Service worker support is required for this example."); } // schedule the next credential refresh when they're about to expire setTimeout(refreshCredentials, credentials.expireTime - new Date()); }
Die Anwendung erstellen: Initialisierung der Map
Damit die Map nach dem Laden der Seite angezeigt wird, müssen Sie die Map initialisieren. Sie haben die Möglichkeit, die ursprüngliche Kartenposition anzupassen, zusätzliche Steuerelemente hinzuzufügen und Daten zu überlagern.
Anmerkung
Sie müssen für jeden Datenanbieter, den Sie verwenden, entweder in Ihrer Anwendung oder in Ihrer Dokumentation eine Wortmarke oder eine Textzuweisung angeben. Zuordnungszeichenfolgen sind in der Antwort auf den Stildeskriptor unter den Tasten sources.esri.attribution
sources.here.attribution
, und enthalten. source.grabmaptiles.attribution
Da Tangram diese Ressourcen nicht anfordert und nur mit Karten von kompatibel istHERE, verwende „© 2020“. HERE Wenn Sie Amazon-Standortressourcen mit Datenanbietern verwenden, lesen Sie unbedingt die Servicebedingungen
/** * Initialize a map. */ async function initializeMap() { // register the service worker to handle requests to https://amazon.location await registerServiceWorker(); // Initialize the map const map = L.map("map").setView([49.2819, -123.1187], 10); Tangram.leafletLayer({ scene, }).addTo(map); map.attributionControl.setPrefix(""); map.attributionControl.addAttribution("© 2020 HERE"); } initializeMap();
Die Anwendung wird ausgeführt
Um dieses Beispiel auszuführen, können Sie:
-
Verwenden Sie einen Host, der unterstütztHTTPS,
-
Verwenden Sie einen lokalen Webserver, um die Sicherheitseinschränkungen für Servicemitarbeiter einzuhalten.
Um einen lokalen Webserver zu verwenden, können Sie npx verwenden, da er als Teil von Node.js installiert ist. Sie können es npx serve
aus demselben Verzeichnis wie index.html
und sw.js
verwenden. Dies dient der Anwendung auf localhost:5000
Das Folgende ist die Datei: index.html
<!-- index.html --> <html> <head> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" /> <style> body { margin: 0; } #map { height: 100vh; } </style> </head> <body> <div id="map" /> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> <script src="https://unpkg.com/tangram"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.784.0.min.js"></script> <script> // configuration // Cognito Identity Pool ID const identityPoolId = "<Identity Pool ID>"; // Amazon Location Service Map name; must be HERE-backed const mapName = "<Map name>"; AWS.config.region = identityPoolId.split(":")[0]; // instantiate a credential provider credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: identityPoolId, }); const scene = { import: [ // Bubble Wrap style "https://www.nextzen.org/carto/bubble-wrap-style/10/bubble-wrap-style.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/label-7.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/bubble-wrap-road-shields-usa.zip", "https://www.nextzen.org/carto/bubble-wrap-style/10/themes/bubble-wrap-road-shields-international.zip", ], // override values beneath the `sources` key in the style above sources: { mapzen: { // point at Amazon Location using a synthetic URL, which will be handled by the service // worker url: `https://amazon.location/${mapName}/{z}/{x}/{y}`, }, // effectively disable raster tiles containing encoded normals normals: { max_zoom: 0, }, "normals-elevation": { max_zoom: 0, }, }, }; /** * Register a service worker that will rewrite and sign requests using Signature Version 4. */ async function registerServiceWorker() { if ("serviceWorker" in navigator) { try { const reg = await navigator.serviceWorker.register("./sw.js"); // refresh credentials from Amazon Cognito await credentials.refreshPromise(); await reg.active.ready; if (navigator.serviceWorker.controller == null) { // trigger a navigate event to active the controller for this page window.location.reload(); } // pass credentials to the service worker reg.active.postMessage({ credentials: { accessKeyId: credentials.accessKeyId, secretAccessKey: credentials.secretAccessKey, sessionToken: credentials.sessionToken, }, region: AWS.config.region, }); } catch (error) { console.error("Service worker registration failed:", error); } } else { console.warn("Service Worker support is required for this example"); } } /** * Initialize a map. */ async function initializeMap() { // register the service worker to handle requests to https://amazon.location await registerServiceWorker(); // Initialize the map const map = L.map("map").setView([49.2819, -123.1187], 10); Tangram.leafletLayer({ scene, }).addTo(map); map.attributionControl.setPrefix(""); map.attributionControl.addAttribution("© 2020 HERE"); } initializeMap(); </script> </body> </html>
Das Folgende ist die sw.js
Datei:
// sw.js self.importScripts( "https://unpkg.com/@aws-amplify/core@3.7.0/dist/aws-amplify-core.min.js" ); const { Signer } = aws_amplify_core; let credentials; let region; self.addEventListener("install", (event) => { // install immediately event.waitUntil(self.skipWaiting()); }); self.addEventListener("activate", (event) => { // control clients ASAP event.waitUntil(self.clients.claim()); }); self.addEventListener("message", (event) => { const { data: { credentials: newCredentials, region: newRegion }, } = event; if (newCredentials != null) { credentials = newCredentials; } if (newRegion != null) { region = newRegion; } }); async function signedFetch(request) { const url = new URL(request.url); const path = url.pathname.slice(1).split("/"); // update URL to point to Amazon Location url.pathname = `/maps/v0/maps/${path[0]}/tiles/${path.slice(1).join("/")}`; url.host = `maps.geo.${region}.amazonaws.com`; // strip params (Tangram generates an empty api_key param) url.search = ""; const signed = Signer.signUrl(url.toString(), { access_key: credentials.accessKeyId, secret_key: credentials.secretAccessKey, session_token: credentials.sessionToken, }); return fetch(signed); } self.addEventListener("fetch", (event) => { const { request } = event; // match the synthetic hostname we're telling Tangram to use if (request.url.includes("amazon.location")) { return event.respondWith(signedFetch(request)); } // fetch normally return event.respondWith(fetch(request)); });
Dieses Beispiel ist als Teil des Amazon Location Service Samples Repository unter verfügbar GitHub