🗺

Amazon Location SDKとAPIキーでルート検索機能を構築

2024/02/26に公開

これまで、Amazon Location Serviceを利用するには、手動で設定をおこなうか、Amplify Geoで設定(ルート検索機能は未対応)という選択肢がありました。昨年、Amazon Location SDKAPIキー機能が発表され、選択肢がさらに広がりました。今回は、この新機能を利用したルート検索機能について紹介します。

GitHubで作成した環境を公開しています。ぜひご利用ください。

https://github.com/mug-jp/maplibregljs-amazon-location-service-route-calculators-starter

img

img

事前準備

Amazon Location ServiceのAPIキー作成

https://memo.dayjournal.dev/memo/amazon-location-service-004

https://memo.dayjournal.dev/memo/amazon-location-service-006

実行環境

  • node v20.0.0
  • npm v9.6.4

MapLibre GL JS & Amazon Location Service スターター

はじめに、既存のスターターで環境構築をします。ローカル環境にforkまたはダウンロードし動作確認をします。

maplibregljs-amazon-location-service-starter

https://github.com/mug-jp/maplibregljs-amazon-location-service-starter

img
全体構成

.env

事前準備で作成したリージョン・マップAPIキー・マップ名をenvファイルに設定します。

.env
VITE_REGION = xxxxx
VITE_MAP_API_KEY = v1.public.xxxxx
VITE_MAP_NAME = xxxxx

パッケージをインストールします。

npm install

ローカルサーバーを起動します。

npm run dev

img

Amazon Location SDKのインストール

次に、Amazon Location SDKの必要なライブラリをインストールします。インストールすることで、APIの認証やMapLibre GL JSとの組み合わせが手軽になります。

client-location

AWS SDKをインストールします。"client-location"はAmazon Location Serviceを操作できるSDKです。

npm install @aws-sdk/client-location

amazon-location-utilities-auth-helper

"amazon-location-utilities-auth-helper"をインストールします。Amazon Location ServiceのAPIキーとCognitoの認証が手軽になるライブラリです。

npm install @aws/amazon-location-utilities-auth-helper

amazon-location-utilities-datatypes

"amazon-location-utilities-datatypes"をインストールします。Amazon Location ServiceのレスポンスをGeoJSON形式に変換してくれるライブラリです。

npm install @aws/amazon-location-utilities-datatypes

"amazon-location-utilities-datatypes"について、MapLibre GL JSと組み合わせると一部利用しにくかったため、先日オプション機能を追加するコントリビュートをしました。

https://github.com/aws-geospatial

ルート検索機能の構築

最後に、実際にルート検索機能を構築します。スターターから一部のファイル変更をします。

package.json

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"
  }
}

.env

事前準備で作成したリージョン・マップAPIキー・マップ名・ルーティングAPIキー・ルーティング名をenvファイルに設定します。

.env
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

main.ts

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

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';

APIキーの認証設定をします。

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

ルーティングのレスポンスをGeoJSONに変換します。

const featureCollection = routeToFeatureCollection(response, {
    flattenProperties: true
});

ローカルサーバーで確認

npm run dev

img


https://aws.amazon.com/jp/builders-flash/202308/use-3d-map-library-location-service

https://aws.amazon.com/jp/builders-flash/202301/use-map-library-location-service

https://memo.dayjournal.dev/tags/try

https://memo.dayjournal.dev/tags/maplibregljs

https://memo.dayjournal.dev/tags/amazon-location-service

MIERUNEのZennブログ

Discussion