Utilisation de Tangram avec Amazon Location Service - Amazon Location Service

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation de Tangram avec Amazon Location Service

Tangram est un moteur de cartographie flexible, conçu pour le rendu en temps réel de cartes 2D et 3D à partir de tuiles vectorielles. Il peut être utilisé avec les styles conçus par Mapzen et les vignettes HERE fournies par l'API Maps d'Amazon Location Service. Ce guide explique comment intégrer Tangram à Amazon Location dans une JavaScript application HTML/ de base, bien que les mêmes bibliothèques et techniques s'appliquent également lors de l'utilisation de frameworks tels que React et Angular.

Tangram est construit sur Leaflet, une JavaScript bibliothèque open source de cartes interactives adaptées aux mobiles. Cela signifie que de nombreux plugins et contrôles compatibles avec Leaflet fonctionnent également avec Tangram.

Les styles Tangram conçus pour fonctionner avec le schéma Tilezen sont largement compatibles avec Amazon Location lorsque vous utilisez des cartes provenant de HERE. Il s'agit des licences suivantes :

  • Bubble Wrap — Un style d'orientation complet avec des icônes utiles pour les points d'intérêt

  • Cinnabar — Un look classique et incontournable pour les applications cartographiques générales

  • Refill — Un style de carte minimaliste conçu pour les superpositions de visualisation de données, inspiré du style Toner emblématique de Stamen Design

  • Tron — Une exploration des transformations d'échelle dans le langage visuel de TRON

  • Walkabout — Un style axé sur le plein air, parfait pour la randonnée ou les sorties

Ce guide explique comment intégrer Tangram à Amazon Location dans une JavaScript application HTML/ de base utilisant le style Tangram appelé Bubble Wrap. Cet exemple est disponible dans le référentiel d'exemples Amazon Location Service sur GitHub.

Bien que les autres styles Tangram soient mieux accompagnés de tuiles matricielles, qui encodent les informations de terrain, cette fonctionnalité n'est pas encore prise en charge par Amazon Location.

Important

Les styles Tangram présentés dans le didacticiel suivant sont uniquement compatibles avec les ressources cartographiques Amazon Location configurées avec ce VectorHereContrast style.

Création de l'application : échafaudage

L'application est une page HTML permettant JavaScript de créer la carte sur votre application Web. Créez une page HTML (index.html) et créez le conteneur de la carte :

  • Entrez un div élément avec une carte id ou pour appliquer les dimensions de la carte à la vue cartographique.

  • Les dimensions sont héritées de la fenêtre d'affichage.

<html> <head> <style> body { margin: 0; } #map { height: 100vh; /* 100% of viewport height */ } </style> </head> <body> <!-- map container --> <div id="map" /> </body> </html>

Création de l'application : ajout de dépendances

Ajoutez les dépendances suivantes :

  • Brochure et son code CSS associé.

  • Tangram.

  • SDK AWS pour. 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>

Cela crée une page vide avec les prérequis nécessaires. L'étape suivante vous guide dans l'écriture du JavaScript code de votre application.

Création de l'application : Configuration

Pour configurer votre application avec vos ressources et vos informations d'identification :

  1. Entrez les noms et les identifiants de vos ressources.

    // 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";
  2. Instanciez un fournisseur d'informations d'identification à l'aide du pool d'identités non authentifié que vous avez créé dans Utilisation de cartes - Étape 2, Configuration de l'authentification. Comme cela utilise des informations d'identification en dehors du flux de travail normal du SDK AWS, les sessions expirent au bout d'une heure.

    // 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, });
  3. Bien que Tangram vous permette de remplacer les URL utilisées pour récupérer les tuiles, il n'inclut pas la possibilité d'intercepter les demandes afin qu'elles puissent être signées.

    Pour contourner ce problème, remplacez sources.mapzen.url pour pointer vers Amazon Location à l'aide d'un nom d'hôte synthétiqueamazon.location, qui sera géré par un technicien de maintenance. Voici un exemple de configuration de scène à l'aide de 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, }, }, };

Création de l'application : transformation des demandes

Pour enregistrer et initialiser le service worker, créez une registerServiceWorker fonction à appeler avant l'initialisation de la carte. Cela enregistre le JavaScript code fourni dans un fichier séparé sw.js appelé service worker controllingindex.html.

Les informations d'identification sont chargées depuis Amazon Cognito et sont transmises au technicien de service aux côtés de la région pour fournir les informations nécessaires à la signature des demandes de vignettes avec Signature Version 4.

/** * 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"); } }

L'implémentation de Service Worker sw.js écoute les message événements pour détecter les modifications des informations d'identification et de configuration de la région. Il agit également comme un serveur proxy en écoutant les fetch événements. fetchles événements ciblant le nom d'hôte amazon.location synthétique seront réécrits pour cibler l'API Amazon Location appropriée et signés à l'aide d'Amplify Core. 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)); });

Pour renouveler automatiquement les informations d'identification et les envoyer au service worker avant leur expiration, utilisez la fonction suivante dans 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()); }

Création de l'application : initialisation de la carte

Pour que la carte s'affiche une fois la page chargée, vous devez l'initialiser. Vous avez la possibilité d'ajuster l'emplacement initial de la carte, d'ajouter des contrôles supplémentaires et de superposer des données.

Note

Vous devez indiquer l'attribution d'un mot ou d'un texte pour chaque fournisseur de données que vous utilisez, que ce soit sur votre application ou dans votre documentation. Les chaînes d'attribution sont incluses dans la réponse du descripteur de style sous les source.grabmaptiles.attribution touches sources.esri.attributionsources.here.attribution, et.

Étant donné que Tangram ne demande pas ces ressources et n'est compatible qu'avec les cartes d'HERE, utilisez « © 2020 HERE ». Lorsque vous utilisez les ressources Amazon Location avec des fournisseurs de données, assurez-vous de lire les conditions générales du service.

/** * 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();

Exécution de l'application

Pour exécuter cet exemple, vous pouvez :

  • Utilisez un hôte qui supporte le protocole HTTPS,

  • Utilisez un serveur Web local pour respecter les restrictions de sécurité du personnel de maintenance.

Pour utiliser un serveur Web local, vous pouvez utiliser npx, car il est installé dans le cadre de Node.js. Vous pouvez utiliser npx serve depuis le même répertoire que index.html etsw.js. Cela sert l'application sur localhost:5000.

Voici le index.html fichier :

<!-- 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>

Voici le sw.js fichier :

// 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)); });

Cet exemple est disponible dans le référentiel d'exemples Amazon Location Service sur GitHub.