Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menggunakan Tangram dengan Amazon Location Service
Tangram
Tangram dibangun di atas Leaflet
Gaya Tangram yang dibuat untuk bekerja dengan skema Tilezen sebagian
-
Bubble Wrap
- Gaya wayfinding berfitur lengkap dengan ikon bermanfaat untuk tempat menarik -
Cinnabar
— Tampilan klasik dan pilihan untuk aplikasi pemetaan umum -
Isi Ulang
— Gaya peta minimalis yang dirancang untuk hamparan visualisasi data, terinspirasi oleh gaya Toner mani oleh Stamen Design -
Tron
— Eksplorasi transformasi skala dalam bahasa visual TRON -
Walkabout
— Gaya yang berfokus pada luar ruangan yang sempurna untuk hiking atau keluar dan berkeliling
Panduan ini menjelaskan cara mengintegrasikan Tangram dengan Lokasi Amazon dalam JavaScript HTML/aplikasi dasar menggunakan Gaya Tangram yang disebut Bubble Wrap.
Sementara gaya Tangram lainnya paling baik disertai dengan ubin raster, yang menyandikan informasi medan, fitur ini belum didukung oleh Amazon Location.
penting
Gaya Tangram dalam tutorial berikut hanya kompatibel dengan sumber daya peta Lokasi Amazon yang dikonfigurasi dengan VectorHereContrast
gaya.
Membangun aplikasi: Scaffolding
Aplikasi ini adalah halaman HTML dengan JavaScript untuk membangun peta pada aplikasi web Anda. Buat halaman HTML (index.html
) dan buat wadah peta:
-
Masukkan
div
elemenid
dengan peta untuk menerapkan dimensi peta ke tampilan peta. -
Dimensi diwarisi dari viewport.
<html> <head> <style> body { margin: 0; } #map { height: 100vh; /* 100% of viewport height */ } </style> </head> <body> <!-- map container --> <div id="map" /> </body> </html>
Membangun aplikasi: Menambahkan dependensi
Tambahkan dependensi berikut:
-
Leaflet dan CSS yang terkait.
-
Tangram.
-
AWS SDK untuk 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>
Ini membuat halaman kosong dengan prasyarat yang diperlukan. Langkah selanjutnya memandu Anda melalui penulisan JavaScript kode untuk aplikasi Anda.
Membangun aplikasi: Konfigurasi
Untuk mengonfigurasi aplikasi Anda dengan sumber daya dan kredensyal Anda:
-
Masukkan nama dan pengidentifikasi sumber daya Anda.
// 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
"; -
Buat instance penyedia kredensi menggunakan kumpulan identitas tidak diautentikasi yang Anda buat di Menggunakan peta - Langkah 2, Siapkan otentikasi. Karena ini menggunakan kredensyal di luar alur kerja AWS SDK normal, sesi kedaluwarsa setelah satu jam.
// 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
, }); -
Meskipun Tangram memungkinkan Anda untuk mengganti URL yang digunakan untuk mengambil ubin, itu tidak termasuk kemampuan untuk mencegat permintaan sehingga mereka dapat ditandatangani.
Untuk mengatasinya, ganti
sources.mapzen.url
untuk menunjuk ke Lokasi Amazon menggunakan nama host sintetisamazon.location
, yang akan ditangani oleh pekerja layanan. Berikut ini adalah contoh konfigurasi adegan menggunakan 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, }, }, };
Membangun aplikasi: Minta transformasi
Untuk mendaftarkan dan menginisialisasi service worker, buat registerServiceWorker
fungsi yang akan dipanggil sebelum peta diinisialisasi. Ini mendaftarkan JavaScript kode yang disediakan dalam file terpisah yang disebut sw.js
sebagai pengendali index.html
pekerja layanan.
Kredensyal dimuat dari Amazon Cognito dan diteruskan ke service worker di samping Wilayah untuk memberikan informasi guna menandatangani permintaan ubin dengan 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"); } }
Implementasi Service Worker dalam sw.js
mendengarkan message
peristiwa untuk mengambil kredensi dan perubahan konfigurasi Wilayah. Ini juga bertindak sebagai server proxy dengan mendengarkan fetch
acara. fetch
peristiwa yang menargetkan nama host amazon.location
sintetis akan ditulis ulang untuk menargetkan API Lokasi Amazon yang sesuai dan ditandatangani menggunakan 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)); });
Untuk memperbarui kredensyal secara otomatis dan mengirimkannya ke service worker sebelum kedaluwarsa, gunakan fungsi berikut di dalam: 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()); }
Membangun aplikasi: Inisialisasi peta
Agar peta ditampilkan setelah halaman dimuat, Anda harus menginisialisasi peta. Anda memiliki opsi untuk menyesuaikan lokasi peta awal, menambahkan kontrol tambahan, dan data hamparan.
catatan
Anda harus memberikan tanda kata atau atribusi teks untuk setiap penyedia data yang Anda gunakan, baik pada aplikasi atau dokumentasi Anda. String atribusi disertakan dalam respons deskriptor gaya di bawahsources.esri.attribution
,sources.here.attribution
, dan kunci. source.grabmaptiles.attribution
Karena Tangram tidak meminta sumber daya ini, dan hanya kompatibel dengan peta dari SINI, gunakan “© 2020 DI SINI”. Saat menggunakan sumber daya Lokasi Amazon dengan penyedia data, pastikan untuk membaca syarat dan ketentuan layanan
/** * 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();
Menjalankan aplikasi
Untuk menjalankan sampel ini, Anda dapat:
-
Gunakan host yang mendukung HTTPS,
-
Gunakan server web lokal untuk mematuhi batasan keamanan pekerja layanan.
Untuk menggunakan server web lokal, Anda dapat menggunakan npx, karena itu diinstal sebagai bagian dari Node.js. Anda dapat menggunakan npx serve
dari dalam direktori yang sama dengan index.html
dansw.js
. Ini melayani aplikasi di localhost
Berikut ini adalah index.html
filenya:
<!-- 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>
Berikut ini adalah sw.js
filenya:
// 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)); });
Sampel ini tersedia sebagai bagian dari repositori sampel Amazon Location Service di. GitHub