AWS Location ServiceのMaps機能について触りながら理解していく ～AWS100本ノック～32/100

# はじめに
こんにちは。[株式会社アベリオシステムズ](https://www.avelio.co.jp/)でエンジニアをやっている、なかざとです:smile:

[前回の記事](https://qiita.com/namasa/items/6ba4365e2b75dd1bce26)では、**AWS Location Service**についてザックリ紹介しました。
今回は、その中の1機能である**Maps**について紹介いたします。

# Mapsとは？
Mapsはその名の通り、WebアプリケーションやアプリなどにMapを組み込むための機能を提供しています。

## GoogleMapじゃダメなの？
Mapといえばみなさん普段GoogleMapを使っていると思います。

AWS上でアプリケーションを構築するとしても、GoogleMapを使えばいいじゃん？という声も聞こえてくるような気もしますね :thinking: 
おそらく、Mapだけ使いたいのであればGoogleMapで良いとは思います :thinking: 

しかし、AWS Location Seriviceを利用することで**ジオフェンスやトラッキング**機能を使ったアプリケーションをAWSで構築できます。
これらについては、次回以降の記事で紹介します :smile: 

# 実際にMapを使ってみる
使ってみないとわからないので、とりあえずMapを作成してみます。
※作成といいつつ、Mapの設定をするだけなので実際にオリジナルのマップを作るわけではありません

:::note info
とりあえず、AWS Location Serviceの機能を試したいという方は、**APIエクスプローラー**から各機能を試すことが出来ます
:::

## マップを選択
`マップを作成`をクリックしてマップ作成画面を表示します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/908e2cd5-d946-4f34-aa6f-48feb5382e2b.png)


マップ名を入力し、

- **データプロバイダー**
- **属性**
- **タイプ**
を選択すると、該当するマップスタイルがリスト化されますので、1つ選択します。
2025年6月現在、東京リージョンだと15個のマップスタイルが利用できるようです。
※シンガポールリージョンだと、17個のマップスタイルが使えます

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/16dbed6a-efa0-4719-ac45-d30e44d12dd9.png)

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/e07c1092-59da-45e2-9706-73e43acc8aa7.png)



### データプロバイダーとは？
**データプロバイダー**とは、地図の背景となる画像データや地図情報を取得・提供する事業者になります。

例えば、Google Mapsのデータプロバイダーは、Googleやサードパーティープロバイダになります。
AWS Locations Serviceでは、
- **Esri**
- **HERE**
- **Grab** ※シンガポールリージョンのみ
- **OpenData**　※オープンソースの地理空間データに基づき構築されたコミュニティ主導のマップ

から選択できます。

### 属性とは？
どういったマップの種類にするか以下の6つから選択します。

- **衛星画像**
- **Light**
- **Dark**
- **3D**
- **トラック** ※輸送と物流のユースケースに特化したマップ
- **ポリティカルビュー**

#### ポリティカルビューとは？
日本語だと、**政治的な見解**という意味になります！

今年放送されたドラマ、御上先生でも`personal is political(個人的なことは政治的なこと`というセリフがありましたね～(脱線しました... :bow: )

日本をマップ表示する際には関係ないのですが、インドなどの一部の国では、領土問題により国間での国境認識があいまいになります。
そこで、ポリティカルビューが反映されたマップを使用すると、その国の政治的見解を反映したマップが表示されます。

![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/9184d845-ae26-4a43-8932-8d9a22e56647.png)

👆がポリティカルビューあり、👇がポリティカルビューなし、になります。
ポリティカルビューなしだと線が表示されていないことがわかります。

![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/bd86d76b-317e-44bf-9c5f-5e0db73ec309.png)


:::note info
2025年6月現在、ポリティカルビューで選択できるのはインドのみになります
:::


### タイプとは？
マップのスタイルを選択します。**ラスタ**と**ベクタ**のいずれかを選択できます。
※ラスタとベクタのハイブリッドマップもあります。

マップ表示の高速化には、マップタイルという仕組みがあるのですが、そちらについては[こちら](https://blog.esrij.com/2016/12/13/post-18171/)のサイトをご確認ください。

#### ラスタとは？
**格子状に並んだピクセル**で構成されたデータの形式です。
ファイル形式としては、pngやjpgなど一般的な画像ファイル形式になります。

地図を拡大すると、ぼやけて格子の状態が確認できるかと思いますが、これがラスタデータの特徴です。

1つ1つのピクセルの大きさをピクセルサイズもしくは解像度と言います。
ピクセルサイズは小さいほど細かな情報を表現できる反面、データ量が大きくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/326cc9b3-aa41-41ad-8924-4204df3feb4b.png)



以下のような衛星写真を使ったマップなどがラスタ形式になります。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/6252b82f-e0a9-4030-bfce-f18956faeff5.png)


ラスタデータには、各ピクセルに以下のような属性(値)が格納されています。
- RGB値
- 標高値
- 気温値
- 土地利用データ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/44871f7f-ca34-4d80-8891-706fb54bebe1.png)


#### ベクタとは？
**点（ポイント）、線（ライン）、面（ポリゴン）** の組み合わせで地図情報を表現する形式です。
ファイル形式としては、shpやdbfやshxなど耳慣れないファイル形式になるのですが、これはデータプロバイダの1つであるEsriが提唱したGIS（Geographic Information System：地理情報システム）を代表するデータフォーマットで、**シェープファイル**と呼びます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/faf52699-06bb-46e6-a4de-6f6974ca0566.png)


ちなみに、ジオ(geo)は地球や土地を意味するらしいです :thinking: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/47180829-4db7-433a-8570-4ef0295425c5.png)


- **点(ポイント)**
  - 地理空間における特定の位置を、2次元(x,y)または3次元(x,y,z)の座標で示す形状の**ジオメトリ**
  - 空間的な広がりや距離を持たずに特定の１地点を示します
  - 例：交差点、店舗の場所など
- **線(ライン)**
  - 2つ以上の点を結んだ形状のジオメトリ
  - 複数の頂点を連結することで構成する
  - 始点と終点が存在し長さを持ちます
  - 例：線路や道路、河川、電線など
- **面(ポリゴン)**
  - 頂点を結ぶラインが閉じた形状のジオメトリ
  - 最低でも３点の頂点を持ち、始点と終点は同じ点で閉じている
  - ポリゴンは特定の領域を表現するので面積を持つ
  - 例：土地の区画、建物、湖、市町村の範囲など

同じ情報でも点、線、面のどれを使うかは目的に応じて変わります。
例えば以下のように、ある建物をピンで刺すなら点でしょうし、形状を地図へ表示したいなら面になります。

![スクリーンショット 2025-06-20 171848.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/24beb565-ad56-4a6a-bb68-4ebff5a98293.png)


ベクタデータには、それぞれの地物対して以下のような属性(値)が格納されています。
- 建物名
- 住所
- 面積


## カスタムレイヤー
一部のマップでは、カスタムレイヤーと呼ばれる機能が利用できます。
現状は、**POI（Point Of Interest：興味のあるポイント）** という店舗や名所などのポイントをマップに表示できるレイヤーが利用できます。

![5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/3b872be8-1812-4274-99a1-808456226d9e.png)

👆がPOIあり、👇がPOIなしになります。
POIありだといろんなお店とかが表示されていますね。

![5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/b7e90047-a487-400b-8739-112f1c5676f6.png)


## 認証
Mapをアプリケーションに組み込む際の認証を選択します。
現在以下の2つから選ぶことになりますが、今回はAPIキーを選択します。
APIキーは事前に作っておいて選択するか、Map作成時に作ります。

- **APIキー**
- **Cognito**

### APIキーの作成

- APIキー名
- APIキーにアタッチする権限
- 有効期限
- リファラー ※APIキーを利用できるドメインを限定
を入力して作成します。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/fdaea7dd-f3b7-4bdf-8eff-4c8ca773e9af.png)

## Mapを表示してみる
必要項目を入力し、`マップを作成`をクリックするとマップが作成されるので、実際に表示してみます。
作成したマップ詳細画面を見ると、**マッププレビュー**で作成したマップを見ることが出来ます。
**埋め込みマップ**をクリックすると、マップを表示するためのサンプルHTMLを見れますのでこれをhtmlファイルとして保存して開いてみましょう。

```
<html>
  <head>
    <link href="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.css" rel="stylesheet" />
    <style>
      body { margin: 0; }
      #map { height: 100vh; }
    </style>
  </head>
  <body>
    <div id="map" />
    <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script>
    <script>
      const apiKey = "*****";
      const mapName = "Political_view";
      const region = "ap-northeast-1";

      const map = new maplibregl.Map({
        container: "map",
        style: `https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`,
        center: [-123.115898, 49.295868],
        zoom: 11,
      });
      map.addControl(new maplibregl.NavigationControl(), "top-left");
    </script>
  </body>
</html>

```

無事、マップが表示されました:smile:
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/d0fb43e3-31b2-4aad-b0c1-57ec10c95de5.png)


# おまけ
最後にMaps系で使えるAPIについて紹介します。

## GetTile
マップのタイルを取得します

```bash
aws geo-maps get-tile \
  --tileset vector.basemap \
  --z 17 \
  --x 0 \
  --y 1 \
  --output json Tile.mvt | jq '.Blob'
```

## GetStyleDescriptor
マップに適用できる標準、モノクロ、ハイブリッド、衛星などの使用可能なマップスタイルを取得します

```bash
aws geo-maps get-style-descriptor \
  --style Standard \
  --color-scheme  Light \
  --output json GetStyleDescriptor.json | jq '.Blob'
```


## GetGlyphs
マップレンダラーがアイコンやマークのラベルを表示するために使用するエンコードされたUnicode文字を含むバイナリファイルを取得します

```bash
aws geo-maps get-glyphs \
  --font-stack "Amazon Ember Bold" \
  --font-unicode-range 0-255.pbf \
  --output json Glyphs.pbf | jq '.Blob'
```

## GetSprites
マップ上にレンダリングされたアイコン、マーカー、その他の要素などの小さなラスターイメージを含むポータブルネットワークグラフィック (PNG) イメージファイルを取得します

:::note info
たくさんの小さな画像を1つの画像（スプライト）にまとめることで、すべての画像を取得するのに必要なリクエストの数を減らすことができ、パフォーマンスが向上し、マップの読み込みが早くなります
:::


```bash
aws geo-maps get-sprites \
  --file-name sprites.png \
  --style Standard \
  --color-scheme Light \
  --variant Default \
  --output json Sprites.png | jq '.Blob'

aws geo-maps get-sprites \
  --file-name sprites.json \
  --style Standard \
  --color-scheme Light \
  --variant Default \
  --output json Sprites.json | jq '.Blob'
```


## GetStaticMap：静的マップ
メールなどに添付するための静的マップを取得します


```bash
aws geo-maps get-static-map \
  --height 1024 \
  --width 1024 \
  --file-name map \
  --style Satellite \
  --zoom 18 \
  --scale-bar-unit Kilometers \
  --center "139.72063525874634,35.62287988577291" \
  --compact-overlay "point:139.72063525874634,35.62287988577291" \
  --output json avelio.png | jq '.Blob'
```

# おわりに
今回は、AWS Location Serviceの1機能であるMapsについて紹介しました。
まだまだGoogle Mapが強いとは思いますが、AWSで構築したアプリケーションにマップ機能を組み込む際は、良さそうですね:smile:
さらなる、Maps機能の拡張に期待したいと思います！