HAQM Web Services ブログ
HAQM Location Service API キーを使った地理空間アプリケーションの構築
地理空間アプリケーションは、インタラクティブな地図から位置情報サービスまで、私たちの日常生活に欠かせないものとなっています。このようなアプリケーションの需要が高まる中、開発者は信頼性の高い地理空間ソリューションを構築するための強力で安全なツールを必要としています。HAQM Web Services (AWS) は最先端のサービスを提供すしており、最近では HAQM Location Service の API キーと認証ヘルパーを発表し、地理空間アプリ開発者にエキサイティングな機会をもたらしました。本記事では、API キー、HAQM Location Service Auth Helper Library、HAQM Location Service Data Types Converter Library を活用して、機能豊富な地理空間アプリケーションを構築する方法を紹介します。
HAQM Location Service の新しいリリース
技術的な詳細に入る前に、HAQM Location Service の最新の機能拡張について簡単に説明します。HAQM Location Service は最近、開発者が HAQM Location Service API に安全にアクセスするための追加オプションを提供する API キーを発表しました。API キーを利用することで、地理空間データやサービスへのアクセスを制御しやすくなり、許可されたユーザーのみがアプリケーションとやり取りできるようになり、より幅広いアプリケーションやツールへのアクセスが可能になります。
さらに、HAQM Location Service Auth Helper Library をリリースしました。これは、開発者の認証エクスペリエンスを合理化するための貴重なリソースです。このライブラリは、 HAQM Location Service の認証のユースケースを合理化するように設計されており、データの保護と開発者のスムーズな体験を保証します。
API キーは、API への認証とアクセス制御に使用される一意の識別子です。この機能を使用することで、特定のドメインや特定の HAQM Location Service リソースへのアクセスを制限するなど、きめ細かなレベルでアクセスを管理することができます。
この機能は、セキュリティを強化し、アプリケーションのパフォーマンスを向上させるために設計されています。HAQM Location Service API キーは、アプリケーションのユーザーに対して特定のアクションへの読み取り専用アクセスを可能にします。アプリケーションのフロントエンドにキーを埋め込むことで、他の認証方法に関連する複数の呼び出しを削除し、待ち時間を改善することができます。このアプローチは API の使用状況を監視し、クォータとキーのローテーションを使用して、リソースの消費を管理し、乱用を防ぐことを可能にします。API キー機能は HAQM Location Service Auth Help Library に統合され、プレースやルートの機能へのアクセス管理がより簡単になりました。
本記事では、API キーと新しい Auth Helper Library の機能をデモンストレーションし、地理空間アプリケーションの構築プロセスを紹介します。
APIキーの作成
API キーを作成する前に、HAQM Location リソースを作成します。マップ、プレース、ルートのガイドに従って、本記事で使用するリソースを作成します。HAQM Location リソースの作成中に、各リソースの API キーを設定するようプロンプトが表示されることに注意してください。API キーを作成してからリソースをリンクするので、この設定ステップは省略できます。
HAQM Location リソースを作成したら、API キーを作成します。今回は、マップ、プレース、ルート で使用できる 1 つの API キーを作成します。
HAQM Location コンソールに移動し、API Keys を選択します。
ここで Create API key を選択します。
API キーに名前を付け、前のステップで作成したリソースを選択します。
次に、権限とその他の API キー設定オプションを定義します。
キーがアクセスできる読み取り専用の API アクションを定義することができます。今回のケースでは、HAQM Location Service の主要な機能を利用できるように、マップ、プレース、ルート API 内の特定のリソースへのアクセスを許可します。これらのリソースには関連コストがかかるため、使用量の急増を監視するために課金アラートを設定し、定期的なキーローテーションプロセスの一環としてAPI キーの有効期限を設定することをお勧めします。
最後に、特定のドメインで使用するために API キーをロックダウンしたい場合は、キーが有効な URL を制限する Referer ドメインを設定することができます。
ここで、Create API key を選択して API キーを作成します。
Show API key value を選択すると、API キーが表示されます。
これで API Key が作成できたので、アプリケーションで API キーを使い始めることが出来ます。これらのデモコードでは、API キーを変数としてハードコードしています。本番環境にデプロイする場合は、Referrer などのセキュリティ機能を使用することに加えて、アプリケーションの認証情報を保存・取得するために AWS Secrets Manager を使用することを推奨します。
API キーを使ったマップアプリケーションの構築
本記事では、地図と検索ボックスを含むシンプルなデモを構築します。人気のある MapLibre GL JS レンダリングライブラリを使って地図を表示することから始めます。MapLibre はスタイル URL の提供をサポートしているので、Auth Helper Library を使用する必要はなく、API エンドポイントを直接設定することができます。
まず index.html
ファイルを作成し、region
と apiKey
に利用するリージョンと API キーを、mapName
には前のステップで作成したマップリソースに置き換えて以下の内容を追加します。
<!-- index.html -->
<!-- Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved. -->
<!-- SPDX-License-Identifier: MIT-0 -->
<html>
<head>
<link href="http://unpkg.com/maplibre-gl@3/dist/maplibre-gl.css" rel="stylesheet" />
<style>
body { margin: 0; }
#map { height: 100vh; }
</style>
</head>
<body>
<!-- Map container -->
<div id="map" />
<!-- JavaScript dependencies -->
<script src="http://unpkg.com/maplibre-gl@3"></script>
<script>
const apiKey = "<Your API Key>"; // API key
const region = "<Your Region>"; // Region
const mapName = "<Your Map Resource>"; // Map name
// URL for style descriptor
const style = `http://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${apiKey}`;
// Initialize the map
const map = new maplibregl.Map({
container: "map",
style,
center: [-123.1187, 49.2819],
zoom: 11,
});
map.addControl(new maplibregl.NavigationControl(), "top-left");
</script>
</body>
</html>
これを index.html
として保存し、ブラウザで開いてください。ブリティッシュコロンビア州バンクーバーの地図が表示されるはずです。
地図を表示できたら、次にアプリケーションに位置検索ウィジェットを追加します。
地図に位置情報検索ボックスを追加する
検索ボックスには、HAQM Location Serviceプレースインデックスを使用します。プレースインデックスを使うと、ジオコーディング/リバースジオコーディングができます。この例では、HAQM Location Service と MapLibre ジオコーダーを使用します。
コードスニペットをコピーする代わりにこのアプリケーションをクローンしたい場合は、このコードは amazon-location-sample-map-with-geocoder GitHubリポジトリで利用可能です。
アプリケーションを作成するために、index.html
ファイルに加えて 2 つのファイルを作成します。
まず、index.html
を編集してマップを削除し、依存関係をダウンロードします。
<!DOCTYPE html>
<!-- Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved. -->
<!-- SPDX-License-Identifier: MIT-0 -->
<html>
<head>
<meta charset="utf-8">
<title>Basic Map with Geocoder</title>
<!-- Styles -->
<link href="http://unpkg.com/maplibre-gl@3/dist/maplibre-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
}
#map {
height: 100vh;
}
</style>
</head>
<body>
<main>
<div id="map"></div>
</main>
<!-- JavaScript dependencies -->
<script src="http://unpkg.com/maplibre-gl@3"></script>
<script src="http://unpkg.com/@aws/amazon-location-client@1/dist/amazonLocationClient.js"></script>
<script src="http://unpkg.com/@aws/amazon-location-utilities-auth-helper@1/dist/amazonLocationAuthHelper.js"></script>
<!-- Load the `maplibre-gl-geocoder` plugin. -->
<script src="http://unpkg.com/@maplibre/maplibre-gl-geocoder@1/dist/maplibre-gl-geocoder.min.js"></script>
<link
rel="stylesheet"
href="http://unpkg.com/@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css"
type="text/css"
/>
<!-- JavaScript for the app -->
<script src="main.js"></script>
</body>
</html>
次に、main.js
という新しいファイルを作成し、以下のコードを貼り付けます。region
と apiKey
に利用するリージョンと API キーを、mapName
には前のステップで作成したマップリソースに置き換えて以下の内容を追加します。
const { GetPlaceCommand, LocationClient, SearchPlaceIndexForSuggestionsCommand, SearchPlaceIndexForTextCommand } = amazonLocationClient;
// HAQM Location Service Resources:
const apiKey = "<HAQM Location API key>";
const mapName = "<HAQM Location Map resource name>";
const placeIndex = "<HAQM Location PlaceIndex resource name>";
const region = "<AWS Region, e.g., eu-central-1>";
// Add Geocoder control to the map via callbacks that are called by maplibre-gl-geocoder.
// forwardGeocode: required for geocoding (HAQM Location SearchPlaceIndexForText API)
// getSuggestions + searchByPlaceId: required for autosugget (HAQM Location SearchPlaceIndexForSuggestions + GetPlace APIs)
async function addGeocoder(map, authHelper, client) {
const amazonLocationGeocoderApi = {
forwardGeocode: async (config) => {
try {
// Set up command to call SearchPlaceIndexForText API
const { Results } = await client.send(new SearchPlaceIndexForTextCommand({
IndexName: placeIndex,
Text: config.query
}));
// Convert the results to Carmen GeoJSON (<link>) to be returned to the MapLibre Geocoder
const features = Results.map((result) => ({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: result.Place.Geometry.Point,
},
place_name: result.Place.Label,
properties: {
id: result.Place.PlaceId,
},
text: result.Place.Label,
place_type: ['place'],
center: result.Place.Geometry.Point,
}));
return { features };
} catch (error) {
console.error(`Failed to forwardGeocode with error: ${error}`);
}
},
getSuggestions: async (config) => {
try {
// Set up a command to call SearchPlaceIndexForSuggestions API;
const { Results } = await client.send(new SearchPlaceIndexForSuggestionsCommand({
IndexName: placeIndex,
Text: config.query
}));
// Iterate over data.Results and return all suggestions and their place ids
const suggestions = Results.map((result) => ({
text: result.Text,
placeId: result.PlaceId,
}));
return { suggestions };
} catch (error) {
console.error(`Failed to getSuggestions with error: ${error}`);
}
},
searchByPlaceId: async (config) => {
try {
// Set up command to call GetPlace API with a place Id of a selected suggestion
const { Place } = await client.send(new GetPlaceCommand({
IndexName: placeIndex,
PlaceId: config.query,
}));
const place = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: Place.Geometry.Point,
},
place_name: Place.Label,
text: Place.Label,
center: Place.Geometry.Point,
};
return { place };
} catch (error) {
console.error(`Failed to searchByPlaceId with error: ${error}`);
}
},
};
// Add Geocoder control to the map
map.addControl(new MaplibreGeocoder(amazonLocationGeocoderApi, { maplibregl, showResultsWhileTyping: true }));
}
// Initialize a map
async function initializeMap() {
const map = new maplibregl.Map({
container: 'map', // HTML element ID of map element
center: [-123.1187, 49.2819], // Initial map centerpoint
zoom: 16, // Initial map zoom
style: `http://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
});
// Add navigation control to the top left of the map
map.addControl(new maplibregl.NavigationControl(), 'top-left');
return map;
}
async function main() {
// Create an authentication helper instance using an API key
const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);
const client = new LocationClient({
region,
...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to HAQM Location
});
// Initialize map and add a geocoder to it.
const map = await initializeMap();
addGeocoder(map, authHelper, client);
}
main();
すべてのファイルが作成されたら、index.html
をブラウザで開き、右上にある検索ボックスがある地図を見ることができます。
これでジオコーディングをテスト出来るようになりました。画像は、HAQM Location Service プレースインデックスの自動補完と前方ジオコーディング機能を試してみたものです。
Auth Library を理解する
さて、アプリケーションを作成しました。HAQM Location Service Auth Helper Library がどのように動作するのかを理解するために、コードを詳しく見ていきましょう。
最初に行うことは、認証方法を定義することです。これには HAQM Cognito Identity Pools、もしくは API キーを使用します。
API キーの場合、次のように Auth メソッドを使用します。
const authHelper = await amazonLocationAuthHelper.withAPIKey(apiKey);
HAQM Cognito Identity Pools を使用する場合、次のように使用します。
const authHelper = await withIdentityPoolId(identityPoolId);
次に、HAQM Location Service Client をインスタンス化する際に、Auth Helper を読み込みます。Auth Helper は、前のステップで設定した認証のタイプに基づいて、クライアントに追加のプロパティを含めます。
const client = new amazonLocationClient.LocationClient({
region,
...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to HAQM Location
});
最後に、HAQM Location Service API を呼び出します。プレースインデックスを使って Seattle, WA を検索するとてもシンプルな例では、Auth Helper と Client を使って SearchPlaceIndexForText API を呼び出します。
<!-- index.html -->
<!-- Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved. -->
<!-- SPDX-License-Identifier: MIT-0 -->
<html>
<head>
</head>
<body>
<pre id="place_index_results" ></pre>
<script src="http://unpkg.com/@aws/amazon-location-client@1/dist/amazonLocationClient.js"></script>
<script src="http://unpkg.com/@aws/amazon-location-utilities-auth-helper@1/dist/amazonLocationAuthHelper.js"></script>
<script>
const Key = "<HAQM Location API key>"; // API key
const region = "<HAQM Location PlaceIndex resource name>"; // Region
const IndexName = "<AWS Region, e.g., eu-central-1>";
async function placeIndexSearch(){
const authHelper = await amazonLocationAuthHelper.withAPIKey(Key);
const { LocationClient, SearchPlaceIndexForTextCommand } = amazonLocationClient;
// Instantiate the HAQM Location Service Client using the Auth Helper configuration
const client = new LocationClient({
region,
...authHelper.getLocationClientConfig() // Provides configuration required to make requests to HAQM Location using either API Keys or Cognito
});
// Call the SearchPlaceIndexForText API using the HAQM Location client
const data = await client.send(new SearchPlaceIndexForTextCommand({
IndexName,
Text: "Seattle, WA",
MaxResults: 1,
}));
document.getElementById("place_index_results").innerHTML = JSON.stringify(data['Results'], null, 4);
}
placeIndexSearch(Key)
</script>
</body>
</html>
この例では、結果は JSON としてブラウザに表示されます。
ご覧の通り、新しい Auth Helper は HAQM Location リソースの認可設定をより簡単にします。
Python での利用
JavaScript によるフロントエンドアプリケーションの構築に加えて、API キーは HAQM Location SDK がサポートするすべての言語でサポートされています。バックエンドアプリケーションで API キーを使用することで、アプリケーションをホストするインフラ上で IAM ロールや一時的な認証情報を設定するために必要なオーバーヘッドを削減することができます。例えば、次の例は、コマンドラインで住所を受け取り、API キーを使用してジオコーディングするシンプルな Python スクリプトです。単純な Python アプリケーションを作成するには、新しい Python ファイルを作成し、以下のコードを貼り付けます。
#Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved.
#SPDX-License-Identifier: MIT-0
import boto3from botocore import UNSIGNEDfrom botocore.config import Config
client = boto3.client("location", region_name='<AWS Region, e.g., eu-central-1>', config=Config(signature_version=UNSIGNED))
text = input()
response = client.search_place_index_for_text(
IndexName='<HAQM Location PlaceIndex resource name>',
Key='<HAQM Location API key>',
MaxResults=1,
Text=text)
print(response['Results'])
コードを実行する際、検索語を入力してください。この場合、ニューヨークを検索します。
Enter を押すと、HAQM Location Service プレースインデックスの検索結果が表示されます。
データ型変換ライブラリ
Auth Helper Library に加えて、JavaScript 用の HAQM Location Utilities – データ型ライブラリもリリースしました。これらのライブラリは、HAQM Location Service API からの出力を一般的な GeoJSON データフォーマットに変換し、ジオフェンスの作成、プレースインデックス検索などのためにこれらのフォーマットからの入力を受け取ります。この例では、ユーザーからの入力を受け取り、HAQM Location Service プレイスインデックスを検索し、結果を GeoJSON フォーマットで返す非常にシンプルなアプリを構築します。そして、このサンプルアプリケーションを使ってポイントを表示します。まず、新しいHTMLファイルを開き、リージョン、プレイスインデックス、API キーを先ほど作成した値に置き換えて、以下を貼り付けます。
<!-- Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved. -->
<!-- SPDX-License-Identifier: MIT-0 -->
<html>
<head>
<link
href="http://unpkg.com/maplibre-gl@3/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
}
#map {
height: 100vh;
}
</style>
</head>
<pre id="jsonText" ></pre>
<body>
<div id="map" />
<script src="http://unpkg.com/maplibre-gl@3"></script>
<script src="http://unpkg.com/@aws/amazon-location-utilities-auth-helper@1/dist/amazonLocationAuthHelper.js"></script>
<script src="http://www.unpkg.com/@aws/amazon-location-utilities-datatypes@1/dist/amazonLocationDataConverter.js"></script>
<script src="http://unpkg.com/@aws/amazon-location-client@1/dist/amazonLocationClient.js"></script>
<script>
async function initializeMap() {
const key = "<HAQM Location API key>";
const mapName = "<HAQM Location Map resource name>";
const region = "<AWS Region, e.g., eu-central-1>";
const IndexName = "<HAQM Location PlaceIndex resource name>";
const searchTerm = prompt("Search for a Location");
// Create an authentication helper instance using credentials from Cognito
const authHelper = await amazonLocationAuthHelper.withAPIKey(key);
const client = new amazonLocationClient.LocationClient({
region,
...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to HAQM Location
});
const searchResults = await client.send(
new amazonLocationClient.SearchPlaceIndexForTextCommand({
IndexName,
Text: searchTerm,
MaxResults: 1,
})
);
// Initialize the map
const map = new maplibregl.Map({
container: "map",
// Set the map centerpoint based on the geojson coordinates
center: featureCollection.features[0].geometry.coordinates,
// Initial zoom level
zoom: 14,
style: `http://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${key}`,
});
// Add navigation controls
map.addControl(new maplibregl.NavigationControl(), "top-left");
map.on("load", () => {
// Convert search results into a GeoJSON FeatureCollection
const featureCollection = amazonLocationDataConverter.placeToFeatureCollection(searchResults);
// Add a data source containing GeoJSON produced from the HAQM Location Service プレースインデックス output.
map.addSource("place-index-results", {
type: "geojson",
data: featureCollection,
});
// Add a new layer to visualize the points.
map.addLayer({
id: "place-index-results",
type: "circle",
source: "place-index-results",
paint: {
"circle-radius": 8,
"circle-color": "#0080ff",
},
});
map.on('click', 'place-index-results', (e) => {
const coordinates = e.features[0].geometry.coordinates.slice();
const description = JSON.stringify(featureCollection, null, 4);;
new maplibregl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
});
}
initializeMap();
</script>
</body>
</html>
HTML ページをロードすると、検索を入力するプロンプトが表示されます。お近くの市町村や、よく行かれるお店を検索してみてください。”OK” をクリックすると、地図とアイコンが表示されます。マーカーをクリックすると、データ型変換ライブラリが提供する GeoJSON 出力が表示されます。
また、データ型変換ライブラリをルーティングに使うことで、HAQM Location Service が提供するルートを開発者が簡単に地図上に描くことができる。この例は上記と非常に似ていますが、今回は先に作成したルート計算機を含みます。 まず、新しい HTML ファイルを開き、region
と CaluculatorName
に利用するリージョンと計算機を、Key に先ほど作成した API キーの値に置き換えて、以下を貼り付けます。ルートを描くために DeparturePosition
と DestinationPosition
を設定します。
<!-- Copyright HAQM.com, Inc. or its affiliates. All Rights Reserved. -->
<!-- SPDX-License-Identifier: MIT-0 -->
<html>
<head>
<link
href="http://unpkg.com/maplibre-gl/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
}
#map {
height: 100vh;
}
</style>
</head>
<body>
<div id="map" />
<script src="http://unpkg.com/maplibre-gl@3"></script>
<script src="http://unpkg.com/@aws/amazon-location-utilities-auth-helper@1/dist/amazonLocationAuthHelper.js"></script>
<script src="http://www.unpkg.com/@aws/amazon-location-utilities-datatypes@1/dist/amazonLocationDataConverter.js"></script>
<script src="http://unpkg.com/@aws/amazon-location-client@1/dist/amazonLocationClient.js"></script>
<script>
async function initializeMap() {
const key = "<HAQM Location API key>";
const mapName = "<HAQM Location Map resource name>";
const region = "<AWS Region, e.g., eu-central-1>";
const IndexName = "<HAQM Location PlaceIndex resource name>";
const CalculatorName = "<HAQM Location Route Calculator resource name>";
const DeparturePosition = "[Departure Longitude, Departure Latitude]"
const DestinationPosition = "[Destination Longitude, Destination Latitude]"
// Create an authentication helper instance using credentials from Cognito
const authHelper = await amazonLocationAuthHelper.withAPIKey(key);
const client = new amazonLocationClient.LocationClient({
region,
...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to HAQM Location
});
const route = await client.send(
new amazonLocationClient.CalculateRouteCommand({
CalculatorName,
DeparturePosition,
DestinationPosition,
IncludeLegGeometry: true,
})
);
// Initialize the map
const map = new maplibregl.Map({
container: "map",
// Set the map centerpoint based on the geojson coordinates
center: DeparturePosition,
// Initial zoom level
zoom: 11,
style: `http://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor?key=${key}`,
});
// Add navigation controls
map.addControl(new maplibregl.NavigationControl(), "top-left");
map.on("load", () => {
// Convert HAQM Location Service route to GeoJSON
const featureCollection = amazonLocationDataConverter.routeToFeatureCollection(route);
// Add a data source containing GeoJSON produced from the HAQM Location Service プレースインデックス output.
map.addSource("route", {
type: "geojson",
data: featureCollection,
});
// Add a new layer to visualize the points.
map.addLayer({
id: "route",
type: "line",
source: "route",
layout: {
"line-join": "round",
"line-cap": "round",
},
paint: {
"line-color": "#00b0ff",
"line-width": 8,
},
});
});
}
initializeMap();
</script>
</body>
</html>
その他のデータ型変換については、GitHub の aws-geospatial/amazon-location-utilities-datatypes-js リポジトリで、これらのユーティリティの使い方や提供されているその他の変換の詳細をご覧ください。
クリーンアップ
以下のリンクを使用して、マップ、プレースインデックス、ルート計算リソースを削除します。本記事で作成した API キーを削除するには、こちらの手順に従ってください。
まとめ
新しい HAQM Location Service Auth Helper Library は、HAQM Location Service API キーおよび HAQM Cognito Identity Pools とのシームレスな統合を提供することで、地理空間アプリケーションの構築を簡素化します。Auth Helper Library を使用することで、開発者はアプリケーションで HAQM Location Service マップ、プレース、ルートと簡単に連携することができます。
また、GeoJSON のような HAQM Location Service と互換性のある異なるデータ型間で変換する機能も開発者に提供しました。これらのユーティリティを使うことで、開発者は GeoJSON を受け取ってジオフェンスを作成したり、プレースインデックス、ジオフェンス、ルートから GeoJSON 出力を得たりすることができます。 これにより、地理空間アプリケーション用の MapLibre などの一般的なライブラリの開発が容易になります。
より多くのサンプルアプリケーションについては、GitHub にホストされている aws-geospatial リポジトリを訪問し、HAQM Location Service が提供する機能をインタラクティブに見るためには location.aws.com デモサイトをチェックしてください。
本記事は「Build a Geospatial Application with HAQM Location Service API Keys」を翻訳したものです。