Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

AWS Location ServiceをCDKで構築して地図をカスタマイズしてみた

こんにちは、igaです。
8月ももう終わりですが、まだまだ暑い日が続きますね。私は数年前から日傘を使うようになりましたが、晴れた日に外を歩く際、日傘があると少しだけ体感温度がましになるので、夏は日傘が手放せなくなりました。

今回は、AWS Location ServiceをCDKで構築して、地図のスタイルをカスタマイズしてみました。

AWS Location Service

AWS Location Serviceとは

AWS Location Service(以降、Location Serviceと表記します)はAWSが提供する、地図や位置情報、移動経路などが利用できるサービスです。
aws.amazon.com

今回の内容

今回は、次の2つを実施します。

  1. Location ServiceをCDKで構築して、クライアントで地図を表示する
  2. 地図のスタイルをカスタマイズする

地図のスタイルのカスタマイズとして、標準で表示される地図の色を変更します。

注意事項

Location Serviceを利用するには、地図などのリソースやAPIに対してアクセス権をユーザーに付与する必要があります。
Location Serviceでは、IAMユーザーかCognitoにより認証されたユーザーに対してアクセス権を付与することが可能です。

今回は、地図の表示を簡易に行うため、APIキーを使用します。
以下のAWSのドキュメントにあるように、APIキーは「認証されていないユーザーに対して読み取り専用の権限を付与する」ことが可能になります。
読み取り専用のため、例えば地図上に移動経路を保存するといった操作を行うことはできません。
Amazon Location Service へのアクセスを許可する - Amazon Location Service

Location Serviceの構築とクライアントでの地図表示

今回は、Location Serviceの作成と地図を表示するためのクライアントを構築する手順は、AWSのドキュメントにあるクイックスタートを参考にします。
docs.aws.amazon.com

Location Serviceの構築はCDKによって実施します。

CDK(Python)による構築

Location Serviceを作成するCDKのスタックは以下の通りです。

from aws_cdk import Stack
from aws_cdk.aws_location import CfnAPIKey, CfnMap, CfnPlaceIndex


class LocationStack(Stack):
    """Location Serviceのリソース作成Stack

    Args:
        cdk (Stack): スタック
    """

    def __init__(self, scope, id, **kwargs):
        super().__init__(scope, id, **kwargs)
        stage = self.node.try_get_context("stage")
        stage_context = self.node.try_get_context(stage)

        self.__create_location(stage, stage_context)

    def __create_location(self, stage, stage_context):
        """Locationを作成する

        Args:
            stage (str): 環境識別子
            stage_context (dict): 環境別の設定
        """
        # マップの作成
        my_map = CfnMap(
            self,
            "MyMap",
            map_name="test-map",
            configuration=CfnMap.MapConfigurationProperty(
                style="VectorHereExplore"
            )
        )

        # プレイスインデックスの作成
        my_place_index = CfnPlaceIndex(
            self,
            "MyPlaceIndex",
            index_name="test-place-index",
            data_source="Here",
            data_source_configuration=CfnPlaceIndex.DataSourceConfigurationProperty(
                intended_use="SingleUse"
            ),
            pricing_plan="RequestBasedUsage"
        )

        # APIキーの作成
        my_api_key = CfnAPIKey(
            self,
            "MyApiKey",
            key_name="test-api-key",
            restrictions=CfnAPIKey.ApiKeyRestrictionsProperty(
                allow_actions=[
                    "geo:GetMap*",
                    "geo:GetPlace",
                    "geo:SearchPlaceIndexForPosition",
                    "geo:SearchPlaceIndexForSuggestions",
                    "geo:SearchPlaceIndexForText"
                ],
                allow_resources=[
                    my_map.attr_map_arn,
                    my_place_index.attr_index_arn
                ],
                allow_referers=[
                    "http://localhost:3000/*",
                    "http://localhost:8000/*"
                ]

            ),
            no_expiry=True
        )

こちらのソースコードを利用して、デプロイするとLocation Serviceの地図、プレースインデックス、APIキーが作成されます。
今回、APIキーは簡易版として「有効期限なし」で作成しています。

クライアントの構築

AWSで公開されている、クイックスタートのソースコードをダウンロードします。
github.com

ドキュメントにある通り、main.jsの以下の部分を修正します。

const apiKey = "<API Key>";
const mapName = "<Map Resource Name>";
const placesName = "<Places Resource Name>";
const region = "<Region>";

今回構築したリソースでは、次のようになります。

const apiKey = "v1.public.eyJ*****";  // AWSコンソールのAPIキーから、「API キー値」の内容にします
const mapName = "test-map";
const placesName = "test-place-index";
const region = "us-west-2";

こちらのクライアントのコードを、以下のコマンドで実行します。

> npx serve

ブラウザで「http://localhost:3000/quickstart.html」を開くと、今回構築したLocation Serviceの地図が表示されます。

地図スタイルのカスタマイズ

Location Serviceで提供される地図の形式は複数存在しているのですが、要件によっては地図のスタイルをカスタマイズする必要性が出てくると思います。
今回は地図スタイルをカスタマイズする手順を解説している、AWSのブログを元にして実施します。

aws.amazon.com

環境の準備

Location Serviceの構築は、前のセクションで実施済みとします。

地図スタイルを編集するために、Maputnik というツールを利用するので、ローカル環境にインストールします。

地図スタイル定義の取得

AWS CLIを使って、地図スタイル定義を取得します。
(--profileオプションで指定したdefaultは、AWS CLIの設定で作成したプロファイル名に置き換えてください)

> aws location get-map-style-descriptor --map-name test-map example-style-descriptor.json --profile default

コマンドを実行したフォルダに「example-style-descriptor.json」のファイルがダウンロードされます。
このファイルに対して、APIキーを指定するように修正します。

変更前(変更が必要な個所のみ抜き出しています)

    "sources": {
        "omv": {
            "tiles": [
                "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/tiles/{z}/{x}/{y}"
            ],
        }
    },
    "sprite": "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/sprites/sprites",
    "glyphs": "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/glyphs/{fontstack}/{range}.pbf",

変更後

    "sources": {
        "omv": {
            "tiles": [
                "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/tiles/{z}/{x}/{y}?key=v1.public.eyJ****"
            ],
        }
    },
    "sprite": "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/sprites/sprites?key=v1.public.eyJ****",
    "glyphs": "https://maps.geo.us-west-2.amazonaws.com/maps/v0/maps/test-map/glyphs/{fontstack}/{range}.pbf?key=v1.public.eyJ****",

Maputikによる地図スタイルの編集

インストールしたMaputikを起動します。
起動したらブラウザで「http://localhost:8000」にアクセスすると、Maputikの画面が表示されます。

Location Serviceへのアクセス

Maputikの「Open」メニューを選択すると、地図の選択画面が表示されます。
画面下部の「Empty Style」を選択して空白の地図を選択します(選択しても、地図は表示されません)。


もう一度、Maputikの「Open」メニューを選択して、「Upload Style」のUploadボタンをクリックします。
ファイル選択ダイアログから、前セクションで編集した「example-style-descriptor.json」を選択します。

ファイルを選択したら、地図エリアの「Zoom in」ボタンをクリックすると地図が表示されるようになります。

地図スタイルの編集

Maputikの地図エリアで編集対象のリソースをクリックして、対象のレイヤを特定します。
今回は、道路の色を変更するため、道路をクリックして表示された中から、「landuse-JPN-other_road」を指定します。

レイヤを特定したら、編集領域から要件に合わせて色や線の太さなどを編集します。
色の変更は、レイヤの「Paint properties」で色の値を変更します。

変更前の地図がこちらです。

変更後の地図がこちらです。
色コードを「#DBE6F7」から「#ECFC1E」に変更したので、道路が黄色になりました。
なお、幹線道路は「landuse-JPN-road_major」という別のレイヤなので、このレイヤの色は変更していないので、元の水色のままになります。

地図スタイルのエクスポート

Maputikの「Export」メニューを選択して、「Download」ボタンをクリックします。
ダウンロードしたファイルを、クイックスタートのフォルダにコピーします。
ここでは、ダウンロードしたファイル名を「export_style.json」にしたものとして説明していきます。

地図スタイルの使用

エクスポートした地図スタイルを利用するために、「main.js」を以下のように編集します。

変更前

  const mlglMap = new maplibregl.Map({
    container: "map", // HTML element ID of map element
    center: [-77.03674, 38.891602], // Initial map centerpoint
    zoom: 16, // Initial map zoom
    style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`, // Defines the appearance of the map and authenticates using an API key
  });

変更後

  const mlglMap = new maplibregl.Map({
    container: "map", // HTML element ID of map element
    center: [-77.03674, 38.891602], // Initial map centerpoint
    zoom: 16, // Initial map zoom
    style: `http://localhost:3000/export_style.json`
  });

エクスポートした地図スタイルのURLを、styleで指定します。
今回は、ローカルで実行しているので「http://localhost:3000/」を指定します。

地図の表示確認

main.jsの編集を反映するため、クイックスタートを停止して以下のコマンドで再度起動します。

> npx serve

ブラウザで「http://localhost:3000/quickstart.html」にアクセスして、Maputikで編集したzoomサイズで地図を表示すると、スタイルの変更が反映されて表示されます。

Maputikで変更したように、道路が黄色で表示されました。

まとめ

今回はLocation ServiceをCDKで構築して、地図スタイルのカスタマイズを実施しました。
Location Serviceの構築は、クイックスタートのように地図表示であればCDKの実装も簡単でした。
地図のレイアウト変更については、Maputikで地図を表示するまでに手間取りましたが、今回の手順を行うことでLocation Serviceの地図を表示して、レイアウトの編集ができるようになりました。

Acroquest Technologyでは、キャリア採用を行っています。

  • Azure OpenAI/Amazon Bedrock等を使った生成AIソリューションの開発
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

www.wantedly.com