DEV Community

Cover image for Building a Route Search Function with Amazon Location SDK and API Key Function
Yasunori Kirimoto for AWS Heroes

Posted on

Building a Route Search Function with Amazon Location SDK and API Key Function

In the past, to use the Amazon Location Service, you had the option of configuring it manually or using Amplify Geo (although the route search functionality is not yet supported). However, with the release of the Amazon Location SDK and API Key feature last year, more options are now available, and the Amazon Location SDK makes manual configuration easier. I would like to explain the route search feature using this new functionality in this article.

The created environment is available on GitHub. Please use it.

maplibregljs-amazon-location-service-route-calculators-starter

img

Advance Preparation

Create an API key for Amazon Location Service

Amazon Location Service #004 - API Key Creation (Maps)
Amazon Location Service #005 - API Key Creation (routing)

Execution environment

  • node v20.0.0
  • npm v9.6.4

MapLibre GL JS and Amazon Location Service Starter

First, build an environment with the existing starter. Fork or download the package to your local environment and verify that it works.

maplibregljs-amazon-location-service-starter

maplibregljs-amazon-location-service-starter

Overall Configuration
img

.env

Set the region, map API key, and map name created in the preliminaries to the env file.

VITE_REGION = xxxxx
VITE_MAP_API_KEY = v1.public.xxxxx
VITE_MAP_NAME = xxxxx
Enter fullscreen mode Exit fullscreen mode

Install the package

npm install
Enter fullscreen mode Exit fullscreen mode

Start the local server

npm run dev
Enter fullscreen mode Exit fullscreen mode

img

Install Amazon Location SDK

Next, install the necessary libraries for the Amazon Location SDK. The installation will make it easier to authenticate the API and combine it with MapLibre GL JS.

client-location

Install the AWS SDK. "client-location" is an SDK that allows you to manipulate the Amazon Location Service.

npm install @aws-sdk/client-location
Enter fullscreen mode Exit fullscreen mode

amazon-location-utilities-auth-helper

Install "amazon-location-utilities-auth-helper," a library that facilitates authentication with Amazon Location Service API keys and Cognito.

npm install @aws/amazon-location-utilities-auth-helper
Enter fullscreen mode Exit fullscreen mode

amazon-location-utilities-datatypes

Install "amazon-location-utilities-datatypes," a library that converts Amazon Location Service responses to GeoJSON format.

npm install @aws/amazon-location-utilities-datatypes
Enter fullscreen mode Exit fullscreen mode

I contributed to "amazon-location-utilities-datatypes" to add an optional feature because it was sometimes difficult to use in combination with MapLibre GL JS!

https://github.com/aws-geospatial

Building a Route Search Function

Finally, we will build the route search function. Some files are changed from the starter.

package.json

{
  "name": "maplibregljs-amazon-location-service-route-calculators-starter",
  "version": "4.0.2",
  "description": "",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "keywords": [],
  "author": "MapLibre User Group Japan",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^5.3.3",
    "vite": "^5.1.4"
  },
  "dependencies": {
    "@aws-sdk/client-location": "^3.521.0",
    "@aws/amazon-location-utilities-auth-helper": "^1.0.4",
    "@aws/amazon-location-utilities-datatypes": "^1.0.5",
    "maplibre-gl": "^4.0.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

.env

Set the region, map API key, map name, routing API key, and routing name created in the preliminaries to the env file.

VITE_REGION = xxxxx
VITE_MAP_API_KEY = v1.public.xxxxx
VITE_MAP_NAME = xxxxx
VITE_ROUTE_API_KEY = v1.public.xxxxx
VITE_ROUTE_NAME = xxxxx
Enter fullscreen mode Exit fullscreen mode

main.ts

import './style.css'
import 'maplibre-gl/dist/maplibre-gl.css';
import maplibregl from 'maplibre-gl';
import { LocationClient, CalculateRouteCommand } from "@aws-sdk/client-location";
import { routeToFeatureCollection } from '@aws/amazon-location-utilities-datatypes';
import { withAPIKey } from '@aws/amazon-location-utilities-auth-helper';

const region = import.meta.env.VITE_REGION;
const mapApiKey = import.meta.env.VITE_MAP_API_KEY;
const mapName = import.meta.env.VITE_MAP_NAME;
const routeApiKey = import.meta.env.VITE_ROUTE_API_KEY;
const routeName = import.meta.env.VITE_ROUTE_NAME;

async function initialize() {
    const authHelper = await withAPIKey(routeApiKey);
    const client = new LocationClient({
        region: region,
        ...authHelper.getLocationClientConfig()
    });

    const input = {
        CalculatorName: routeName,
        DeparturePosition: [139.7558, 35.6767],
        DestinationPosition: [139.8160, 35.6830],
        IncludeLegGeometry: true,
    };
    const command = new CalculateRouteCommand(input);

    const response = await client.send(command);
    const featureCollection = routeToFeatureCollection(response, {
        flattenProperties: true
    });

    const map = new maplibregl.Map({
        container: 'map',
        style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${mapApiKey}`,
        center: [139.767, 35.681],
        zoom: 11,
    });
    map.addControl(
        new maplibregl.NavigationControl({
            visualizePitch: true,
        })
    );

    map.on('load', function () {
        map.addSource("route-result", {
            type: "geojson",
            data: featureCollection
        });
        map.addLayer({
            'id': "route-result",
            'type': 'line',
            'source': 'route-result',
            'layout': {
                'line-join': 'round',
                'line-cap': 'round'
            },
            'paint': {
                'line-color': '#FF0000',
                'line-width': 10,
                'line-opacity': 0.5
            }
        });
        map.on('click', 'route-result', (e) => {
            const coordinates = e.lngLat;
            const description = `${e.features?.[0]?.properties['Distance'] ?? ''}km`;
            new maplibregl.Popup()
                .setLngLat(coordinates)
                .setHTML(description)
                .addTo(map);
        });
        map.on('mouseenter', 'route-result', () => {
            map.getCanvas().style.cursor = 'pointer';
        });
        map.on('mouseleave', 'route-result', () => {
            map.getCanvas().style.cursor = '';
        });
    });
}
initialize();
Enter fullscreen mode Exit fullscreen mode

Define the Amazon Location SDK.

import { LocationClient, CalculateRouteCommand } from "@aws-sdk/client-location";
import { routeToFeatureCollection } from '@aws/amazon-location-utilities-datatypes';
import { withAPIKey } from '@aws/amazon-location-utilities-auth-helper';
Enter fullscreen mode Exit fullscreen mode

Set up authentication for the API key.

const authHelper = await withAPIKey(routeApiKey);
const client = new LocationClient({
    region: region,
    ...authHelper.getLocationClientConfig()
});
Enter fullscreen mode Exit fullscreen mode

Search for a route at the specified location.

const input = {
    CalculatorName: routeName,
    DeparturePosition: [139.7558, 35.6767],
    DestinationPosition: [139.8160, 35.6830],
    IncludeLegGeometry: true,
};
const command = new CalculateRouteCommand(input);
const response = await client.send(command);
Enter fullscreen mode Exit fullscreen mode

Convert the routing response to GeoJSON.

const featureCollection = routeToFeatureCollection(response, {
    flattenProperties: true
});
Enter fullscreen mode Exit fullscreen mode

Let's check with a simple local server.

npm run dev
Enter fullscreen mode Exit fullscreen mode

img

Related Articles

References
Amazon Location Service
MapLibre GL JS

Top comments (0)