dayjournal memo

Total 973 articles!!

Try #104 – Amazon Location SDKとAPIキーで住所検索機能を構築してみた

Yasunori Kirimoto's avatar

img

img




Amazon Location SDKとAPIキー機能で住所検索を構築してみました!


これまでAmazon Location Serviceを利用するには、手動で設定をおこなうか、Amplify Geoで設定という選択肢がありました。そして、Amazon Location SDKとAPIキー機能が今年発表され、選択肢がさらに広がりました。Amazon Location SDKを利用することで手動での設定も手軽になりました。今回は、この新機能を利用した住所検索機能について紹介したいと思います!


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

maplibregljs-amazon-location-service-place-indexes-starter



事前準備

実行環境

  • node v20.6.1
  • npm v9.8.1


MapLibre GL JS & Amazon Location Service スターターの利用方法

既存のスターターを利用し、住所検索機能を構築します。ローカル環境にforkまたはダウンロードし動作確認をします。


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

npm install

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

npm run dev

マップが表示されます。

img



Amazon Location SDKのインストール

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


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

npm install @aws-sdk/client-location

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

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

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

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

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

AWS Geospatial



住所検索機能の構築

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


全体構成 img


package.json

{
  "name": "maplibregljs-amazon-location-service-place-indexes-starter",
  "version": "3.3.1",
  "description": "",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "keywords": [],
  "author": "MapLibre User Group Japan",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^5.2.2",
    "vite": "^4.4.9"
  },
  "dependencies": {
    "@aws-sdk/client-location": "^3.433.0",
    "@aws/amazon-location-utilities-auth-helper": "^1.0.2",
    "@aws/amazon-location-utilities-datatypes": "^1.0.3",
    "maplibre-gl": "^3.3.1"
  }
}


.env

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

VITE_REGION = xxxxx
VITE_MAP_API_KEY = v1.public.xxxxx
VITE_MAP_NAME = xxxxx
VITE_PLACE_API_KEY = v1.public.xxxxx
VITE_PLACE_NAME = xxxxx


/src

main.ts

import './style.css'
import 'maplibre-gl/dist/maplibre-gl.css';
import maplibregl from 'maplibre-gl';
import { LocationClient, SearchPlaceIndexForTextCommand } from "@aws-sdk/client-location";
import { placeToFeatureCollection } 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 placeApiKey = import.meta.env.VITE_PLACE_API_KEY;
const placeName = import.meta.env.VITE_PLACE_NAME;

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

    const input = {
        IndexName: placeName,
        Text: "サッポロファクトリー",
    };
    const command = new SearchPlaceIndexForTextCommand(input);
    const response = await client.send(command);
    const featureCollection = placeToFeatureCollection(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("search-result", {
            type: "geojson",
            data: featureCollection
        });
        map.addLayer({
            'id': "search-result",
            'type': 'circle',
            'source': 'search-result',
            'layout': {},
            'paint': {
                'circle-color': '#007cbf',
                'circle-radius': 10
            }
        });
        map.on('click', 'search-result', (e) => {
            const coordinates = e.lngLat;
            const description = e.features![0].properties['Place.Label'];
            new maplibregl.Popup()
                .setLngLat(coordinates)
                .setHTML(description)
                .addTo(map);
        });
        map.on('mouseenter', 'search-result', () => {
            map.getCanvas().style.cursor = 'pointer';
        });
        map.on('mouseleave', 'search-result', () => {
            map.getCanvas().style.cursor = '';
        });
    });
}
initialize();

Amazon Location SDKを定義します。

import { LocationClient, SearchPlaceIndexForTextCommand } from "@aws-sdk/client-location";
import { placeToFeatureCollection } from '@aws/amazon-location-utilities-datatypes';
import { withAPIKey } from '@aws/amazon-location-utilities-auth-helper';

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

const authHelper = await withAPIKey(placeApiKey);
const client = new LocationClient({
    region: region,
    ...authHelper.getLocationClientConfig()
});

テキストからジオコーディングをします。

const input = {
    IndexName: placeName,
    Text: "サッポロファクトリー",
};
const command = new SearchPlaceIndexForTextCommand(input);
const response = await client.send(command);

ジオコーディングのレスポンスをGeoJSONに変換します。

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


ローカルサーバーで確認

npm run dev


Amazon Location SDKとAPIキー機能を組み合わせて住所検索結果を表示することができました!

img



他の例も紹介します!


IDからジオコーディングをします。

import { LocationClient, GetPlaceCommand } from "@aws-sdk/client-location";

...

    const input = {
        IndexName: placeName,
        PlaceId: "AQABAFkA9d5eLnjB7XKy9_p0QX3oXD4nrLodHDtIvvzOwEyHbBx9m7LhmUP9WoNILhCrNzsL_DzOmUqagzNOgEabayDDLe6Oxh0rXolepvlZamPS5Q4KX41udsz856yYG6UdXqO6JmoLazImn-Isq2p20k5q_0902-uClFkGTw"
    };
    const command = new GetPlaceCommand(input);

...

img



指定位置からリバースジオコーディングをします。

import { LocationClient, SearchPlaceIndexForPositionCommand } from "@aws-sdk/client-location";

...

    const input = {
        IndexName: placeName,
        Position: [139.767, 35.681],
    };
    const command = new SearchPlaceIndexForPositionCommand(input);

...

img




MapLibre GL JS・Amazon Location Serviceについて、他にも記事を書いています。よろしければぜひ。
tags - MapLibre GL JS
tags - Amazon Location Service



book

Q&A