2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

はじめに

こんにちは。株式会社アベリオシステムズでエンジニアをやっている、なかざとです:smile:

前回の記事では、AWS Location Service(以降ALS)のTrackers機能について紹介しました。
今回は、Geofencing機能について紹介いたします。

Geofencingとは?

マップ上に表示するポリゴンor円形のジオフェンス(仮想的な地理的境界)を保存・管理する機能になります。
ジオフェンスは、ジオフェンスコレクションと呼ばれる、1つ以上のジオフェンスを管理する箱に作成します。

5.png

主な機能としては、以下になります。

  • ジオフェンスコレクションの作成
  • ジオフェンスの作成
  • ジオフェンスコレクションに対するデバイスの位置の評価・ジオフェンスイベントの発行

実際にGeofencingの各機能を試してみる

では実際に、ジオフェンスを作成し、各機能を試してみようと思います。

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

ジオフェンスコレクションの作成

ジオフェンスを作るためにはまず、ジオフェンスコレクションを作成する必要があります。
ジオフェンスコレクションを作成をクリックします。

1.png

以下の情報を入力して、ジオフェンスコレクションを作成します。

  • コレクション名:用途や目的などがわかる名前
  • CloudWatchをターゲットとするEventBridgeルール:ジオフェンスのEntry/Exitイベントが発生した場合に、CloudWatchへログを発行するかの設定
  • データの暗号化設定

ジオフェンスコレクションをどの粒度で作るか悩むのですが、以下のような分け方で作っていくのが良さそうです:thinking:
※初期段階だとなかなか決めづらかったりするので、最初は大きい単位(1つだけとか)で作るのがいいかもしれません
※その上で、トラッカーをどの粒度で作るのかと併せて検討する必要がありそうです

  • 1つのみ
  • 国毎
  • 組織・会社など何かしらのグループ単位
  • 用途毎:マーケティング、配送など

※トラッカーとジオフェンスコレクションを紐づけて評価する場合、トラッカーに紐づけたジオフェンスコレクションの数によって請求されるので、ジオフェンスコレクションは可能な限り少なくすることをAWSは推奨しています

ジオフェンスの作成

ジオフェンスコレクションを作成したので、次にジオフェンスを作成します。

ジオフェンスは

  • ポリゴン:デバイスが特定のエリアにいつ出入りしたかを検出することが出来る
  • :デバイスがポイントから特定の距離(半径)以内に出入りしたことを検出することが出来る

のいずれかで作成します。

GeoJSONファイルをアップロードすると、ジオオフェンスを追加することが出来ます。
3.png

いきなりGeoJsonをアップロードしてくれって言われても困ったりする人もいると思いますが、サンプルをダウンロードできますので、まずはこちらで作成してみても良いかと思います。
4.png

円形のジオフェンスは、マネジメントコンソールからだと作成できないようなので、今回はAWS CLIでジオフェンスを登録してみます。

ジオフェンスの登録/更新にはPutGeofenceを利用します。
※複数のジオフェンスを一括で登録/更新したい場合はBatchPutGeofenceを利用します

各パラメータは以下になります。

  • CollectionName:作成したジオフェンスコレクション名
  • GeofenceId:一意なジオフェンス名
  • Geometry.Polygon[]:ポリゴンを形成する3点以上の位置座標
  • GeofenceProperties:任意のデータ(1個~3個まで指定可能)
    • 住所、都道府県、建物名など任意のキー/値を設定できる

実行してみると、無事に保存できました:smile:

ポリゴンのジオフェンスを登録
cat polygon-geofence.json

{
    "CollectionName": "test-collection",
    "GeofenceId": "test-polygon-geofence",
    "Geometry": {
      "Polygon": [
        [
          [
            139.6531736226557,
            35.698441130044216
          ],
          [
            139.6555920713164,
            35.681834498866706
          ],
          [
            139.67636874390718,
            35.68094157129863
          ],
          [
            139.70297167918216,
            35.69522721320111
          ],
          [
            139.67559923751446,
            35.71370546605378
          ],
          [
            139.6531736226557,
            35.698441130044216
          ]
        ]
      ]
    },
    "GeofenceProperties": {
      "Prefecture": "Tokyo",
      "Name": "GotandaOffice"
    }
}

aws location put-geofence \
  --cli-input-json file://polygon-geofence.json

{
    "GeofenceId": "test-polygon-geofence",
    "CreateTime": "2025-07-01T07:22:55.137000+00:00",
    "UpdateTime": "2025-07-01T07:22:55.137000+00:00"
}

円のジオフェンスで設定する各パラメータは以下になります。

  • CollectionName:作成したジオフェンスコレクション名

  • GeofenceId:一意なジオフェンス名

  • Geometry.Circle.Center[]:円の中心座標

  • Geometry.Circle.Radius:円の半径

  • GeofenceProperties:任意のデータ(1個~3個まで指定可能)

    • 住所、都道府県、建物名など任意のキー/値を設定できる

こちらも無事に保存できました:smile:

円のジオフェンスを登録
cat circle-geofence.json
{
    "CollectionName": "test-collection",
    "GeofenceId": "test-circle-geofence",
    "Geometry": {
      "Circle": {
        "Center": [
          139.67460987215418,
          35.70736660243152
        ],
        "Radius": 2575.313519218831
      }
    },
    "GeofenceProperties": {
      "Prefecture": "Tokyo",
      "Name": "GotandaOffice"
    }
}

aws location put-geofence \
  --cli-input-json file://circle-geofence.json

{
    "GeofenceId": "test-circle-geofence",
    "CreateTime": "2025-07-01T07:22:55.137000+00:00",
    "UpdateTime": "2025-07-01T07:23:11.212000+00:00"
}

作成したジオフェンスを取得してみる

ジオフェンスを1つ取得する場合はGetGeofence、対象のジオフェンスコレクションの全てのジオフェンスを取得したいならListGeofencesを利用します。

GetGeofence
aws location get-geofence \
  --collection-name test-collection \
  --geofence-id test-circle-geofence

{
    "GeofenceId": "test-circle-geofence",
    "Geometry": {
        "Circle": {
            "Center": [
                139.67460987215418,
                35.70736660243152
            ],
            "Radius": 2575.313519218831
        }
    },
    "Status": "ACTIVE",
    "CreateTime": "2025-07-01T07:24:32.648000+00:00",
    "UpdateTime": "2025-07-01T07:24:32.699000+00:00",
    "GeofenceProperties": {
        "Name": "GotandaOffice",
        "Prefecture": "Tokyo"
    }
}
ListGeofences
aws location list-geofences \
  --collection-name test-collection
  
{
    "Entries": [
        {
            "GeofenceId": "test-circle-geofence",
            "Geometry": {
                "Circle": {
                    "Center": [
                        139.67460987215418,
                        35.70736660243152
                    ],
                    "Radius": 2575.313519218831
                }
            },
            "Status": "ACTIVE",
            "CreateTime": "2025-07-01T07:24:32.648000+00:00",
            "UpdateTime": "2025-07-01T07:24:32.699000+00:00",
            "GeofenceProperties": {
                "Name": "GotandaOffice",
                "Prefecture": "Tokyo"
            }
        },
        {
            "GeofenceId": "test-polygon-geofence",
            "Geometry": {
                "Circle": {
                    "Center": [
                        139.67460987215418,
                        35.70736660243152
                    ],
                    "Radius": 2575.313519218831
                }
            },
            "Status": "ACTIVE",
            "CreateTime": "2025-07-01T07:22:55.137000+00:00",
            "UpdateTime": "2025-07-01T07:23:11.271000+00:00",
            "GeofenceProperties": {
                "Name": "GotandaOffice",
                "Prefecture": "Tokyo"
            }
        }
    ]
}

問題なく、取得出来ましたね:smile:
マップに表示したい場合はMapLibreなどを使って表示することになるかと思います。

ちなみに、作成したジオフェンスはAWSコンソールでは見ることが出来ません。
ポリゴンと円形のジオフェンスは以下のような感じでマップに表示されます。(今回登録した座標とは違うジオフェンスです)

5.png

ジオフェンスコレクションに対するデバイスの位置の評価・ジオフェンスイベントの発行

ジオフェンスを作りましたが、これだけではただマップにジオフェンスが表示されるだけです。
ジオフェンスに対して位置情報の評価してジオフェンスイベントを発行するのが主機能になります。

ジオフェンスイベントを発行する方法は2つあります。

1.トラッカーとジオフェンスコレクションを関連付け、トラッカーに位置情報を登録して、位置を評価

  • デバイスの位置履歴を追跡したり、地図上に位置を表示したい場合

2.ジオフェンスコレクションに直接位置情報をリクエストして、位置を評価

  • 位置情報の更新を全て評価したくない場合
  • 位置情報をトラッカーへ保存せずに評価したい場合

位置情報の更新がジオフェンスの境界を超えると、ジオフェンスコレクションはEventBridgeにジオフェンスイベントを発行します。イベントとしては以下の2つになります。

  • ENTER:位置情報の更新がジオフェンス内に入った場合
  • EXIT:位置情報の更新がジオフェンス外に出た場合

では最後に、ジオフェンスへ出入りした際にイベントが発行されるか試してみます。
試すのはざっくり以下のようなイメージです。

image.png

EventBridgeルールとSNSトピックの準備

まず、EventBridgeとSNSトピックを作成して、イベントを受信してSNSでメールが送れるようにしましょう。

指定したメールアドレスにメールを送信するSNSトピックを作成します。
6-3.png

6-4.png

ジオフェンスイベントを取得し、SNSトピックにイベントを送信するEvent Bridgeルールを作成します。
6-1.png

6-2.png

6-5.png

1.トラッカーとジオフェンスコレクションを関連付け、トラッカーに位置情報を登録して、位置を評価

トラッカーとジオフェンスコレクションの関連付けを行います。
トラッカーの作成については以前書いたこちらの記事をご確認下さい。

aws location associate-tracker-consumer \
  --tracker-name test-tracker \
  --consumer-arn arn:aws:geo:ap-northeast-1:*****:geofence-collection/test-collection

準備が出来ましたので、位置情報を送ってみます。
※ジオフェンスは以下のように新宿・中野あたりで張っているとします
7.png

cat circle-geofence.json
{
  "CollectionName": "test-collection",
  "GeofenceId": "test-circle-geofence",
  "Geometry": {
    "Circle": {
      "Center": [
        139.67922691050796,
        35.70281402500463
      ],
      "Radius": 3168.194806598202
    }
  }
}

aws location put-geofence \
  --cli-input-json file://circle-geofence.json

①ジオフェンス外の位置情報(明大前駅の緯度経度)を送ってみます。
想定通り、メールは届きませんでした。

cat position.json                                                              
{
    "TrackerName": "test-tracker",
    "Updates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.6505229836962,
                35.668562698596126
            ],
            "SampleTime": "2025-06-30T00:00:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

aws location batch-update-device-position \
  --cli-input-json file://position.json

②ジオフェンス外からジオフェンス内(中野駅)に入る位置情報を送ってみます。

cat position.json                                                              
{
    "TrackerName": "test-tracker",
    "Updates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.66541716096066,
                35.705852871335246
            ],
            "SampleTime": "2025-06-30T00:01:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

aws location batch-update-device-position \
  --cli-input-json file://position.json

想定通り、以下のようなENTERイベントのjsonが本文に添付されたメールが届きました。

{
	"version": "0",
	"id": "da1f63d6-52bc-57a9-b1fd-cb56146ca7c7",
	"detail-type": "Location Geofence Event",
	"source": "aws.geo",
	"account": "*****",
	"time": "2025-07-04T06:40:12Z",
	"region": "ap-northeast-1",
	"resources": [
		"arn:aws:geo:ap-northeast-1:"*****",:geofence-collection/test-collection",
		"arn:aws:geo:ap-northeast-1:"*****",:tracker/test-tracker"
	],
	"detail": {
		"EventType": "ENTER",
		"GeofenceId": "test-circle-geofence",
		"DeviceId": "device001",
		"SampleTime": "2025-06-30T00:01:00Z",
		"Position": [
			139.66541716096066,
			35.705852871335246
		],
		"Accuracy": {
			"Horizontal": 10.3
		},
		"PositionProperties": {
			"Altitude": "69.70104",
			"Bearing": "11.24892",
			"Speed": "25.5"
		},
		"GeofenceProperties": {
			"Name": "GotandaOffice",
			"Prefecture": "Tokyo"
		}
	}
}

③ジオフェンス内(東中野駅)の位置情報を送ってみます。
想定通り、メールは届きませんでした。

cat position.json                                                              
{
    "TrackerName": "test-tracker",
    "Updates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.68375056835524,
                35.70636974076509
            ],
            "SampleTime": "2025-06-30T00:02:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

aws location batch-update-device-position \
  --cli-input-json file://position.json

④ジオフェンス外からジオフェンス内(荻窪駅)に入る位置情報を送ってみます。

cat position.json                                                              
{
    "TrackerName": "test-tracker",
    "Updates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.62042958286827,
                35.70466705558538
            ],
            "SampleTime": "2025-06-30T00:03:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

aws location batch-update-device-position \
  --cli-input-json file://position.json

想定通り、以下のようなEXITイベントのjsonが本文に添付されたメールが届きました。

{
	"version": "0",
	"id": "59fad866-f464-d9bb-19cf-d422c99764f8",
	"detail-type": "Location Geofence Event",
	"source": "aws.geo",
	"account": "*****",
	"time": "2025-07-04T06:51:19Z",
	"region": "ap-northeast-1",
	"resources": [
		"arn:aws:geo:ap-northeast-1:*****:geofence-collection/test-collection",
		"arn:aws:geo:ap-northeast-1:*****:tracker/test-tracker"
	],
	"detail": {
		"EventType": "EXIT",
		"GeofenceId": "test-circle-geofence",
		"DeviceId": "device001",
		"SampleTime": "2025-06-30T00:03:00Z",
		"Position": [
			139.62042958286827,
			35.70466705558538
		],
		"Accuracy": {
			"Horizontal": 10.3
		},
		"PositionProperties": {
			"Altitude": "69.70104",
			"Bearing": "11.24892",
			"Speed": "25.5"
		},
		"GeofenceProperties": {
			"Name": "GotandaOffice",
			"Prefecture": "Tokyo"
		}
	}
}

2.ジオフェンスコレクションに直接位置情報をリクエストして、位置を評価

こちらも同様にやってみると同じ結果が得られます。
直接ジオフェンスコレクションに位置情報をリクエストするには、BatchEvaluateGeofencesを使います

①ジオフェンス外の位置情報(明大前駅の緯度経度)を送信
cat evaluate-position.json                                                              
{
    "CollectionName": "test-collection",
    "DevicePositionUpdates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.6505229836962,
                35.668562698596126
            ],
            "SampleTime": "2025-06-30T00:04:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

aws location batch-evaluate-geofences \
  --cli-input-json file://evaluate-position.json

②ジオフェンス外からジオフェンス内(中野駅)に入る位置情報を送信
cat evaluate-position.json                                                              
{
    "CollectionName": "test-collection",
    "DevicePositionUpdates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.66541716096066,
                35.705852871335246
            ],
            "SampleTime": "2025-06-30T00:05:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

③ジオフェンス内(東中野駅)の位置情報を送信
cat evaluate-position.json                                                              
{
    "CollectionName": "test-collection",
    "DevicePositionUpdates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.68375056835524,
                35.70636974076509
            ],
            "SampleTime": "2025-06-30T00:06:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

④ジオフェンス外からジオフェンス内(荻窪駅)に入る位置情報を送信
cat evaluate-position.json                                                              
{
    "CollectionName": "test-collection",
    "DevicePositionUpdates": [
        {
            "Accuracy": {
                "Horizontal": 10.30
            },
            "DeviceId": "device001",
            "Position": [
                139.62042958286827,
                35.70466705558538
            ],
            "SampleTime": "2025-06-30T00:07:00",
            "PositionProperties": {
                "Bearing": "11.24892",
                "Altitude": "69.70104",
                "Speed": "25.5"
            }
        }
    ]
}

おまけ

最後にGeofencing系で使えるAPIについて紹介します。

  • BatchDeleteGeofence:ジオフェンスの一括削除
  • BatchEvaluateGeofences:指定したジオフェンスコレクションのジオフェンスに対してデバイスの位置情報を評価し、EventBridgeにEnter/Exitのイベントを送信
  • BatchPutGeofence:ジオフェンスの一括保存
  • CreateGeofenceCollection:ジオフェンスコレクションの作成
  • DeleteGeofenceCollection:ジオフェンスコレクションの削除
  • DescribeGeofenceCollection:ジオフェンスコレクションの取得
  • ForecastGeofenceEvents:デバイスの現在の位置と速度から、ジオフェンスイベントの予測を行う
    • ENTER:デバイスの位置は参照されたジオフェンスの外側にあるが、デバイスが現在の速度を維持している場合、予測時間地平線の間にジオフェンスの中に入る可能性がある
    • EXIT:デバイスの位置は参照されたジオフェンスの内側にあるが、デバイスが現在の速度を維持していれば、予測時間地平線の間にジオフェンスから出る可能性がある
    • IDLE:デバイスはジオフェンス内にあり、デバイスが現在の速度を維持していれば、時間地平線の終わりまでジオフェンス内に留まります
  • GetGeofence:ジオフェンスの取得
  • ListGeofenceCollections:ジオフェンスコレクションの一覧取得
  • ListGeofences:ジオフェンスの一覧取得
  • PutGeofence:ジオフェンスの保存
  • UpdateGeofenceCollection:ジオフェンスコレクションの更新

おわりに

今回は、ALSの1機能であるGeofencingについて紹介しました。
ジオフェンスを使って位置情報を評価することで、配送サービスの通知やクーポン配信などのジオマーケティングに役立ちそうですね:smile:

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?