Amazon Location ServiceのMapとplace Index+CoginitoでWebAppに地図を埋め込む。
はじめに
前回記事からの流れで、
Amazon Location Serviceを触りはじめます。
開発者ガイドを見ながら進めていきます。
※少し簡略化はしていますが、オリジナルな部分はほぼないです。
※あくまでもハンズオンではなく「やってみた。」ですので、暖かい目でお願いします。
※↑の手順通りやった方が理解できます。
※リソースの削除については記載していません。
開始。
Amazon Location Serviceを開きます。
左端のハンバーガーメニューを押下し、左ペインを表示させます。
以下ブロックごとにアコーディオンに纏めています。↓↓↓
Maps
Maps
左ペインからMapsを選択。
create mapボタンを押下。
↓↓
※分かり易いように「日本語に翻訳」して入力していきます。
マップの1つを選択します。
今回は立体のこれ(HERE Berlin)を選んでみます。
Tagはつけず、チェックボックスにチェックを入れボタンを押下。
次は Place indexesを触ります↓↓↓
Place indexes
Place indexes
次は手順通りアプリの認証部分を作ります↓↓↓
Cognitoでアプリケーションの認証を設定
Cognito
※以下こちらのページの中段の手順です。
AmazonCognitoコンソールに移動し、「IDプールの管理」ボタンを押下。
[新しいIDプールの作成]を選択してから、IDプールの名前を入力。
※作成するプールは、前セクションで作成したALSリソースと同じアカウントおよびリージョンである必要有。
[認証されていないIDの折りたたみ可能]セクションから、[認証されていないIDへのアクセスを有効にする]にチェックを入れます。
認証フロー・認証プロバイダはスルーし、「プールの作成」ボタンを押下。
ボタンを押したらIamRoleを作成するページに遷移します。
[詳細の表示]で展開します
[ポリシードキュメントの表示]で展開。
[編集]クリック。
中身を全消しして以下に挿げ替え。
※<日本語の指示>の部分は書いてある通りに変更。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LocationReadOnly",
"Effect": "Allow",
"Action": [
"geo:GetMapStyleDescriptor",
"geo:GetMapGlyphs",
"geo:GetMapSprites",
"geo:GetMapTile",
"geo:SearchPlaceIndex*"
],
"Resource": [
"<ここにさっき作ったMapのARNをコピーして貼る>",
"<ここにさっき作ったPlace IndexのARNをコピーして貼る>"
]
}
]
}
許可を押して完了。
↓プラットフォームから”Javascript”を選択。
※ここで表示される「AWS 認証情報の取得」から情報をコピーしてローカルに保存しておきます。
ここまで来たら、”次のステップ”ですが、
今回は自分の中では「Webアプリの作成」一択です。
Webアプリの作成
Webアプリの作成
※以下私はVSCODEで作業します。
※これから3つのファイルを作りますが全部同じディレクトリ(わからなければ同じフォルダ内)に保存します。
※これで動作問題ないと思いますが、万一以下を踏襲いただいて「うまく動作しない」場合本来の手順通りされるのをお勧めします。
テキストエディタで
①”quickstart.html”を作成します。
中身↓↓(本来の手順纏めてます。)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quick start tutorial</title>
<!-- Styles -->
<link href="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.css" rel="stylesheet" />
<link href="main.css" rel="stylesheet" />
</head>
<body>
<header>
<h1>Quick start tutorial</h1>
</header>
<main>
<div id="map"></div>
<aside>
<h2>JSON Response</h2>
<pre id="response"></pre>
</aside>
</main>
<footer>This is a simple Amazon Location Service app. Pan and zoom. Click to see details about entities close to a point.</footer>
<!-- JavaScript dependencies -->
<script src="https://unpkg.com/maplibre-gl@1.14.0/dist/maplibre-gl.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1030.0.min.js"></script>
<script src="https://unpkg.com/@aws-amplify/core@3.7.0/dist/aws-amplify-core.min.js"></script>
<!-- JavaScript for the app -->
<script src="main.js"></script>
</body>
</html>
②続いて”main.css”を作成します。
中身↓↓
* {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
body {
margin: 0;
}
header {
background: #000000;
padding: 0.5rem;
}
h1 {
margin: 0;
text-align: center;
font-size: 1.5rem;
color: #ffffff;
}
main {
display: flex;
min-height: calc(100vh - 94px);
}
#map {
flex: 1;
}
aside {
overflow-y: auto;
flex: 0 0 30%;
max-height: calc(100vh - 94px);
box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;
background: #f9f9f9;
padding: 1rem;
}
h2 {
margin: 0;
}
pre {
white-space: pre-wrap;
font-family: monospace;
color: #16191f;
}
footer {
background: #000000;
padding: 1rem;
color: #ffffff;
}
③最後に”main.js”を作ります。
中身↓↓
※ここも本来の手順纏めてます。
※<日本語の指示>の部分は書いてある通りに変更します。
// Use Signer from @aws-amplify/core
const { Signer } = window.aws_amplify_core;
// AWS Resources
// Cognito:
const identityPoolId = "<※ここにさっきのAWS 認証情報の取得をコピーした時のIdentityPoolIdをコピーして貼る>";
// Amazon Location Service resource names:
const mapName = "<ここにさっき作ったMapの名前をコピーして貼る>";
const placesName = "<ここにさっき作ったPlace Indexの名前をコピーして貼る>";
// Extract the region from the Identity Pool ID
AWS.config.region = identityPoolId.split(":")[0];
// Instantiate a Cognito-backed credential provider
const credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: identityPoolId,
});
// Sign requests made by MapLibre GL JS using AWS SigV4:
function transformRequest(url, resourceType) {
if (resourceType === "Style" && !url.includes("://")) {
// Resolve to an AWS URL
url = `https://maps.geo.${AWS.config.region}.amazonaws.com/maps/v0/maps/${url}/style-descriptor`;
}
if (url.includes("amazonaws.com")) {
// Sign AWS requests (with the signature as part of the query string)
return {
url: Signer.signUrl(url, {
access_key: credentials.accessKeyId,
secret_key: credentials.secretAccessKey,
session_token: credentials.sessionToken,
}),
};
}
// If not amazonaws.com, falls to here without signing
return { url };
}
// Initialize a map
async function initializeMap() {
// Load credentials and set them up to refresh
await credentials.getPromise();
// Initialize the map
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: mapName,
transformRequest,
});
// Add navigation control to the top left of the map
mlglMap.addControl(new maplibregl.NavigationControl(), "top-left");
return mlglMap;
}
async function main() {
// Initialize map and AWS SDK for Location Service:
const map = await initializeMap();
const location = new AWS.Location({credentials, region: AWS.config.region});
// Variable to hold marker that will be rendered on click
let marker;
// On mouse click, get results:
map.on("click", function(e) {
// Remove any existing marker
if(marker) {
marker.remove();
}
// Render a marker on clicked point
marker = new maplibregl.Marker()
.setLngLat([e.lngLat.lng, e.lngLat.lat])
.addTo(map);
// Set up parameters for search call
let params = {
IndexName: placesName,
Position: [e.lngLat.lng, e.lngLat.lat],
Language: "en",
MaxResults: "5"
};
// Search for results around clicked point
location.searchPlaceIndexForPosition(params, function(err, data) {
if (err) {
// Alert user about an error
alert("There was an error searching.");
// Write JSON response error to HTML
document.querySelector("#response").textContent = JSON.stringify(err, undefined, 2);
} else {
// Write JSON response data to HTML
document.querySelector("#response").textContent = JSON.stringify(data, undefined, 2);
// Display place label in an alert box
alert(data.Results[0].Place.Label); }
});
});
}
main();
ここでは端折ってますが、
・MapLibreGLJS
・AWSSDKバージョン2
・AWSAmplify
なんかの依存関係を記述している事でパンやズーム・データ取得・認証がうまくいっているんだそうです。(振り返りで個人的に勉強し直そうと思います。)
④全部保存出来たら”quickstart.html”ファイルをブラウザにドロップします。
⑤無事表示されました。
※ちなみにJSのこの部分↓↓を変更すれば初期の位置・画面のズーム度合いは変えられます。
center: [-77.03674, 38.891602], // Initial map centerpoint
zoom: 16, // Initial map zoom
[139.70628210300083, 35.66161975232981]に変更して東京のこの辺りを表示してみました。
⑥クリックするとこんなふうに表示されるようになりました。凄いです。
最後に
楽しいです。
まだ途中ですので、明日以降時間を見つけて続きをやっていきます。
読んでくださった方お時間くださって有難う御座いました。
Discussion