Using MapLibre GL JS with Amazon Location Service
Use MapLibre GL
JS
MapLibre GL JS is an open-source JavaScript library that's compatible with the styles and tiles provided by the Amazon Location Service Maps API. You can integrate MapLibre GL JS within a basic HTML or JavaScript application to embed customizable and responsive client-side maps.
This tutorial describes how to integrate MapLibre GL JS with Amazon Location within
a basic HTML and JavaScript application. The same libraries and techniques
presented in this tutorial also apply to frameworks, such as React
The sample application for this tutorial is available as part of the Amazon Location Service
samples repository on GitHub
Building the application: Scaffolding
This tutorial creates a web application that uses JavaScript to build a map on an HTML page.
Begin by creating an HTML page (index.html
) that includes the
map's container:
-
Enter a
div
element with anid
ofmap
to apply the map's dimensions to the map view. The dimensions are inherited from the viewport.
<html> <head> <style> body { margin: 0; } #map { height: 100vh; /* 100% of viewport height */ } </style> </head> <body> <!-- map container --> <div id="map" /> </body> </html>
Building the application: Adding dependencies
Add the following dependencies to your application:
-
MapLibre GL JS (v1.14.0 or later), and its associated CSS.
-
AWS SDK for JavaScript.
-
AWS Amplify core library.
<!-- CSS dependencies --> <link href="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.css" rel="stylesheet" /> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.js"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.784.0.min.js"></script> <script src="https://unpkg.com/@aws-amplify/core@3.7.0/dist/aws-amplify-core.min.js"></script> <script> // application-specific code </script>
This creates an empty page with the map's container.
Building the application: Configuration
To configure your application using JavaScript:
-
Enter the names and identifiers of your resources.
// Cognito Identity Pool ID const identityPoolId = "
us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd
"; // Amazon Location Service Map name const mapName = "ExampleMap
"; -
Instantiate a credential provider using the unauthenticated identity pool you created in Using maps - Step 2, Set up authentication.
// extract the Region from the Identity Pool ID; this will be used for both Amazon Cognito and Amazon Location AWS.config.region = identityPoolId.split(":")[0]; // instantiate an Amazon Cognito-backed credential provider const credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId:
identityPoolId
, }); -
Because this uses credentials outside the normal AWS SDK work flow sessions expire after one hour.
The following is an example of a function that will automatically renew credentials before they expire:
async function refreshCredentials() { await credentials.refreshPromise(); // schedule the next credential refresh when they're about to expire setTimeout(refreshCredentials, credentials.expireTime - new Date()); }
Building the application: Request transformation
MapLibre GL JS map instances include a transformRequest
option, which you use to intercept and modify requests before they're made.
To sign AWS requests using Signature Version 4 with credentials obtained from Amazon Cognito, enter the following function.
// use Signer from @aws-amplify/core const { Signer } = window.aws_amplify_core; /** * Sign requests made by MapLibre GL JS using AWS SigV4. */ function transformRequest(url, resourceType) { if (resourceType === "Style" && !url.includes("://")) { // resolve to an AWS URL url = `https://maps.geo.${AWS.config.region}.amazonaws.com/maps/v0/maps/${url}/style-descriptor`; } if (url.includes("amazonaws.com")) { // only sign AWS requests (with the signature as part of the query string) return { url: Signer.signUrl(url, { access_key: credentials.accessKeyId, secret_key: credentials.secretAccessKey, session_token: credentials.sessionToken, }), }; } // don't sign return { url }; }
Building the application: Map initialization
For the map to display after the page is loaded, you must initialize the map. You can adjust the initial map location, add additional controls, and overlay data.
async function initializeMap() { // load credentials and set them up to refresh await credentials.getPromise(); // Initialize the map const map = new maplibregl.Map({ container: "map", center: [-123.1187, 49.2819], // initial map centerpoint zoom: 10, // initial map zoom style: mapName, transformRequest, }); map.addControl(new maplibregl.NavigationControl(), "top-left"); } initializeMap();
You must provide word mark or text attribution for each data provider
that you use, either on your application or your documentation.
Attribution strings are included in the style descriptor response under
the sources.esri.attribution
, sources.here.attribution
,
and sources.grabmaptiles.attribution
keys. MapLibre GL JS will
automatically provide attribution. When using Amazon Location resources with
data
providers, make sure to read the service terms and
conditions
Running the application
You can run this sample application by using it in a local web server, or opening it in a browser.
To use a local web server, you can use npx, because it's installed as part
of Node.js. You can use npx serve
from within the same
directory as index.html
. This serves the application on
localhost:5000
.
If the policy you created for your unauthenticated Amazon Cognito role includes
a referer
condition, you might be blocked from testing with
localhost:
URLs. In this case. you can test with a web
server that provides a URL that is in your policy.
After completing the tutorial, the final application looks like the following example.
<!-- index.html --> <html> <head> <link href="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.css" rel="stylesheet" /> <style> body { margin: 0; } #map { height: 100vh; } </style> </head> <body> <!-- map container --> <div id="map" /> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.js"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.784.0.min.js"></script> <script src="https://unpkg.com/@aws-amplify/core@3.7.0/dist/aws-amplify-core.min.js"></script> <script> // use Signer from @aws-amplify/core const { Signer } = window.aws_amplify_core; // configuration const identityPoolId = "us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd"; // Cognito Identity Pool ID const mapName = "ExampleMap"; // Amazon Location Service Map Name // extract the region from the Identity Pool ID AWS.config.region = identityPoolId.split(":")[0]; // instantiate a Cognito-backed credential provider const credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: identityPoolId, }); /** * Sign requests made by MapLibre GL JS using AWS SigV4. */ function transformRequest(url, resourceType) { if (resourceType === "Style" && !url.includes("://")) { // resolve to an AWS URL url = `https://maps.geo.${AWS.config.region}.amazonaws.com/maps/v0/maps/${url}/style-descriptor`; } if (url.includes("amazonaws.com")) { // only sign AWS requests (with the signature as part of the query string) return { url: Signer.signUrl(url, { access_key: credentials.accessKeyId, secret_key: credentials.secretAccessKey, session_token: credentials.sessionToken, }), }; } // don't sign return { url }; } /** * Initialize a map. */ async function initializeMap() { // load credentials and set them up to refresh await credentials.getPromise(); // Initialize the map const map = new maplibregl.Map({ container: "map", center: [-123.1187, 49.2819], // initial map centerpoint zoom: 10, // initial map zoom style: mapName, transformRequest, }); map.addControl(new maplibregl.NavigationControl(), "top-left"); } initializeMap(); </script> </body> </html>
Running this application displays a full-screen map using your chosen map
style. This sample is available in the Amazon Location Service samples repository on GitHub