この記事は株式会社 MIERUNE の代表取締役 CEO である Yasunori Kirimoto に寄稿頂いた「 New features and developer experience with enhanced Amazon Location Service 」をソリューションアーキテクトの稲田が翻訳したものです。 地理空間アプリケーションを構築するには、地理空間データを扱うための専門知識と、システムの設計および開発のスキルが必要です。また、大量の地理空間データを収集および管理し、アプリケーションで効果的に利用するスキルも必要とされます。このプロセスは非常に手間がかかる可能性がありますが、その複雑さは Amazon Location Service を活用することで大幅に軽減できます。 Amazon Location Service では、API から高精度の地理空間データをすばやく取得できるため、開発者はアプリケーションの構築に集中できます。さらに、Amazon Location Service が従来の機能に加えて新機能が追加されました。Amazon Location Service の新機能を紹介し、アプリケーションでその機能を活用する方法をご紹介します。 Amazon Location Service の新機能のリリース 最大の変更点は、個別のリソース作成が不要になったことです。つまり、ユーザーは個々のリソース (Place Index、Map、Route Calculator など) を作成する必要がなくなり、API キーを設定するだけで、すぐに Amazon Location Service を使い始められます。 さらに、Maps、Places、Routes API に大幅な機能強化と新機能が追加されました。Maps API は、追加のスタイルと新しい静的マップ機能で更新されました。Places API は、新しい検索と地理コーディング機能で強化されました。最後に、Routes API は、Snap to Road、Waypoint Optimization、および追加の移動モードなどの新機能で更新されました。 API キーの作成 API キー を作成するには、 AWS マネジメントコンソール または AWS Cloud Control API を利用できます。この例では、コンソールを使用します。Amazon Location Service コンソールに移動し、 Manage resources の下にある API keys を選択します。 Create API key を選択してください。 図 1 – Amazon Location Service コンソール – API キーコンソール デモのために、API キーを LasVegasMaps と名付け、以下のアクションを選択します。 GetStaticMap GetTile Geocode GetPlace SearchNearby SearchText CalculateIsolines SnapToRoads 図 2 – API キーアクションの選択 スクロールダウンすると、有効期限の設定や参照元の設定など、追加オプションがあります。これらはオプションですが、本番環境のアプリケーションには強くお勧めします。今回はこのデモのためこれらはデフォルトのままにしています。 図 3 – 追加の API キーオプション Create API Key を選択してください。 API キーを作成したので、次はアプリケーションで使用するための値を取得する必要があります。 Show API key value を選択し、値を安全な場所にコピーしてください。 図 4 – API キーコンソールで、API キーの値を表示する 新しい Maps API まず、GetStyleDescriptor と GetStaticMap について詳しく説明して紹介します。 地図アプリケーションの基盤となる GetStyleDescriptor の構築 GetStyleDescriptor を使用すると、マップスタイル情報を取得し、マップアプリケーションの基盤を迅速に構築できます。この機能は、様々な地理空間ソリューションやアプリケーション基盤に使用できます。新バージョンでは、異なるアプリケーション向けに目的に合わせて設計された拡張マップスタイルを提供しており、様々なレベルの地図詳細を持つダークモードとライトモードを提供しています。 MapLibre GL JS を使用してこれらのマップスタイルを活用する方法を紹介します。MapLibre GL JS と Amazon Location Service API キーを使用して、非常にシンプルな HTML ページを作成します。 simpleMap.html という名前の新しい HTML ファイルを作成し、以下のコードをファイルに貼り付けてください。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon Location Service Map</title> <!-- MapLibre GL CSS --> <link href="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.css" rel="stylesheet" /> <style> body { margin: 0; } #map { height: 100vh; /* Full viewport height */ } </style> </head> <body> <!-- Map container --> <div id="map"></div> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script> <script> // Configuration const region = "<AWS Region>"; // Replace with your AWS region const mapApiKey = "<Your API Key>"; // Replace with your Amazon Location Service API key async function initializeMap() { // Initialize the map const map = new maplibregl.Map({ container: "map", // HTML element ID where the map will be rendered center: [-115.1473824627421, 36.17071351509272], // Initial map center coordinates (Las Vegas) zoom: 12, // Initial zoom level style: `https://maps.geo.${region}.amazonaws.com/v2/styles/Standard/descriptor?&color-scheme=Light&variant=Default&key=${mapApiKey}`, // Map style URL }); // Add navigation controls to the map map.addControl(new maplibregl.NavigationControl(), "top-left"); } // Call the function to initialize the map initializeMap(); </script> </body> </html> この HTML ページをブラウザで開いてください。ラスベガスの地図が表示されるはずです。この地図の鍵は、前のコードで設定したスタイル URL です。この URL では、明るい色のスタンダードスタイルマップを要求しています。政治的な見解など、追加のパラメータも指定できます。 図 5 – ラスベガス(ネバダ州)を中心とした地図 GetStaticMap を使用して静的地図画像を作成する GetStaticMap を使用すると、指定した座標、ズームレベル、イメージサイズに基づいて静的な地図画像を作成できます。この機能は、印刷物やメディアの投稿に地図画像を含めるのに役立ちます。この機能にはさまざまなパラメータがあり、他のデータ (ポイント、ライン、ポリゴンなど) を重ね合わせることもできます。基本的な例を示します。使用する AWS リージョンと新しく作成した API キーに合わせて URL を編集してください。指定した場所の静的な地図画像を表示するには、以下の URL を Web ブラウザのアドレスバーに貼り付けてください。 https://maps.geo.<Your AWS Region>.amazonaws.com/v2/static/map?center=-115.170,36.122&zoom=15&width=1024&height=1024&key=<Your API Key> 図 6 – ラスベガスストリップを表示する静的地図画像 新しい Places API 次に、SearchText と SearchNearby を紹介します。 SearchText による特定の POI データの検索 SearchText を使用すると、ユーザーは特定の目的地(POI)データを検索して表示することができます。この機能は、ユーザーが特定の場所や施設をすばやく検索できるように設計されています。ユーザーは指定されたパラメータで POST リクエストを送信し、候補地点データを含むレスポンスを受け取ることができます。そのデータを地図上に視覚化する例を紹介します。 searchText.html という名前の新しい HTML ファイルを作成し、以下のコードをファイルに貼り付けてください。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon Location Service – Search Text</title> <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> <!-- map container --> <div id="map"></div> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script> <!-- Import the Amazon Location Client --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1"></script> <!-- Import the utility library --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-datatypes@1"></script> <script> // Configuration // Set the AWS region for Amazon Location Service const region = "<AWS Region>"; // API key for authenticating requests const mapApiKey = "<Amazon Location Service API Key>"; async function initializeMap() { // Create an authentication helper using the API key const authHelper = await amazonLocationClient.withAPIKey(mapApiKey, region); // Initialize the Amazon Location Service Places client const client = new amazonLocationClient.places.GeoPlacesClient( authHelper.getClientConfig() ); // Define search parameters for coffee shops const SearchTextInput = { BiasPosition: [-115.170, 36.122], // Las Vegas coordinates MaxResults: 25, QueryText: "Coffee Shops" } // Perform the search using Amazon Location Service const searchResults = await client.send( new amazonLocationClient.places.SearchTextCommand(SearchTextInput) ) // Initialize the map const map = new maplibregl.Map({ container: "map", center: [-115.170, 36.122], // Las Vegas coordinates zoom: 14, style: `https://maps.geo.${region}.amazonaws.com/v2/styles/Standard/descriptor?&color-scheme=Light&variant=Default&key=${mapApiKey}`, }); // Add navigation controls to the map map.addControl(new maplibregl.NavigationControl(), "top-left"); // When the map is loaded, add search results as a layer map.on("load", () => { // Convert search results into a GeoJSON FeatureCollection const featureCollection = amazonLocationDataConverter.searchTextResponseToFeatureCollection(searchResults); // Add a data source containing GeoJSON from the search results 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", }, }); // Add click event listener for the search result points map.on('click', 'place-index-results', (e) => { if (e.features.length > 0) { const feature = e.features[0]; const coordinates = feature.geometry.coordinates.slice(); // Create a formatted HTML string with the feature's properties const properties = feature.properties; let description = '<h3>' + (properties['Title'] || 'Unnamed Location') + '</h3>'; description += '<p>Address: ' + (properties['Address.Label'] || 'N/A') + '</p>'; // Create and display a popup with the location information new maplibregl.Popup() .setLngLat(coordinates) .setHTML(description) .addTo(map); } }); map.on('mouseenter', 'place-index-results', () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', 'place-index-results', () => { map.getCanvas().style.cursor = ''; }); }); } // Call the function to initialize the map initializeMap(); </script> </body> </html> HTML ファイルをブラウザで開くと、ラスベガス(ネバダ州)のベネチアン・リゾートを中心としたコーヒーショップのマップが表示されます(図7)。 図 7 – SearchText API の結果を表示した地図 SearchNearby を使用して指定された場所の周辺の POI データを検索する SearchNearby を使用すると、指定された場所の近くにある POI データを取得できます。この機能は、ユーザーが周辺の店舗や観光スポットを検索するのに便利です。ユーザーは指定されたパラメータを含む POST リクエストを送信し、候補地点データを含むレスポンスを受け取ることができます。そのデータを地図上に可視化する例を示します。 searchNearby.html という名前の新しい HTML ファイルを作成し、以下のコードをファイルに貼り付けてください。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon Location Service – Search Nearby</title> <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> <!-- map container --> <div id="map"></div> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script> <!-- Import the Amazon Location Client --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1"></script> <!-- Import the utility library --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-datatypes@1"></script> <script> // Configuration // Set the AWS region for Amazon Location Service const region = "<AWS Region>"; // API key for authenticating map requests const mapApiKey = "<Amazon Location Service API Key>"; async function initializeMap() { // Create an authentication helper using the API key const authHelper = await amazonLocationClient.withAPIKey(mapApiKey, region); // Initialize the Amazon Location Service Places client const client = new amazonLocationClient.places.GeoPlacesClient( authHelper.getClientConfig() ); // Define search parameters for nearby casinos and hotels const SearchNearbyInput = { QueryPosition: [-115.170, 36.122], // Las Vegas coordinates MaxResults: 25, Filter: { IncludeCategories: [ "casino", "hotel" ] } } // Perform the nearby search using Amazon Location Service const searchResults = await client.send( new amazonLocationClient.places.SearchNearbyCommand(SearchNearbyInput) ) // Initialize the map const map = new maplibregl.Map({ container: "map", center: [-115.170, 36.122], // Las Vegas coordinates zoom: 15, style: `https://maps.geo.${region}.amazonaws.com/v2/styles/Standard/descriptor?&color-scheme=Light&variant=Default&key=${mapApiKey}`, }); // Add navigation controls to the map map.addControl(new maplibregl.NavigationControl(), "top-left"); // When the map is loaded, add search results as a layer map.on("load", () => { // Convert search results into a GeoJSON FeatureCollection const featureCollection = amazonLocationDataConverter.searchNearbyResponseToFeatureCollection(searchResults); // Add a data source containing GeoJSON from the search results 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", }, }); // Add click event listener for the search result points map.on('click', 'place-index-results', (e) => { if (e.features.length > 0) { const feature = e.features[0]; const coordinates = feature.geometry.coordinates.slice(); // Create a formatted HTML string with the feature's properties const properties = feature.properties; let description = '<h3>' + (properties['Title'] || 'Unnamed Location') + '</h3>'; description += '<p>Address: ' + (properties['Address.Label'] || 'N/A') + '</p>'; // Create and display a popup with the location information new maplibregl.Popup() .setLngLat(coordinates) .setHTML(description) .addTo(map); } }); map.on('mouseenter', 'place-index-results', () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', 'place-index-results', () => { map.getCanvas().style.cursor = ''; }); }); } // Call the function to initialize the map initializeMap(); </script> </body> </html> 図 8 – SearchNearby API の結果を表示した地図 新しい Routes API 最後に、新しい CalculateIsolines と SnapToRoads について説明します。 CalculateIsolines で指定した場所から到達可能な範囲を見つける CalculateIsolines は、指定したポイントから到達可能な範囲を取得できます。Isolines のユースケースには、配達可能エリアの特定や不動産の立地評価などがあります。ユーザーは指定したパラメータで POST リクエストを送信し、到達可能なエリアを示すポリゴンデータを含むレスポンスを受け取ることができます。そのデータを地図上に可視化する例を紹介します。 calculateIsolines.html という名前の新しい HTML ファイルを作成し、以下のコードをファイルに貼り付けてください <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon Location Service - Isolines</title> <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> <!-- map container --> <div id="map"></div> <!-- JavaScript dependencies --> <script src="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.js"></script> <!-- Import the Amazon Location Client --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1"></script> <!-- Import the utility library --> <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-datatypes@1"></script> <script> // Configuration // Set the AWS region for the Amazon Location Service const region = "<AWS Region>"; // API key for authenticating map requests const mapApiKey = "<Amazon Location Service API Key"; async function initializeMap() { // Create an authentication helper using the API key const authHelper = await amazonLocationClient.withAPIKey(mapApiKey, region); // Initialize the Amazon Location Service Routes client const client = new amazonLocationClient.routes.GeoRoutesClient( authHelper.getClientConfig() ); // Define parameters for calculating isolines const IsolinesInput = { Origin: [-115.17015436843275, 36.12122662193694], // Starting point coordinates Thresholds: { Time: [ 300, 600, 900 // Time thresholds in seconds ] }, TravelMode: "Pedestrian" // Travel mode for isoline calculation } // Calculate isolines using Amazon Location Service const routeResults = await client.send( new amazonLocationClient.routes.CalculateIsolinesCommand(IsolinesInput) ) // Initialize the map const map = new maplibregl.Map({ container: "map", center: [-115.16766776735061, 36.12177195550658], // Map center coordinates zoom: 15, style: `https://maps.geo.${region}.amazonaws.com/v2/styles/Standard/descriptor?&color-scheme=Light&variant=Default&key=${mapApiKey}`, }); // Add navigation controls to the map map.addControl(new maplibregl.NavigationControl(), "top-left"); // Add a marker at the origin point const marker = new maplibregl.Marker() .setLngLat([-115.17015436843275, 36.12122662193694]) .addTo(map) // When the map is loaded, add isolines as layers map.on("load", () => { // Convert isoline results into a GeoJSON FeatureCollection const featureCollection = amazonLocationDataConverter.calculateIsolinesResponseToFeatureCollection(routeResults); // Add a data source containing GeoJSON from the isoline results map.addSource("isolines", { type: "geojson", data: featureCollection }); // Add a fill layer to visualize the isoline areas map.addLayer({ 'id': 'isolines-fill-900', 'type': 'fill', 'source': 'isolines', 'filter': ['==', ['get', 'TimeThreshold'], 900], 'paint': { 'fill-color': '#0000ff', 'fill-opacity': 0.5 } }); // Add a layer for 600m (10) map.addLayer({ 'id': 'isolines-fill-600', 'type': 'fill', 'source': 'isolines', 'filter': ['==', ['get', 'TimeThreshold'], 600], 'paint': { 'fill-color': '#00ff00', 'fill-opacity': .5 } }); // Add a layer for 300m (5) map.addLayer({ 'id': 'isolines-fill-300', 'type': 'fill', 'source': 'isolines', 'filter': ['==', ['get', 'TimeThreshold'], 300], 'paint': { 'fill-color': '#f10000', 'fill-opacity': 0.5 } }); // Add an outline layer to highlight the isoline boundaries map.addLayer({ 'id': 'isolines-outline', 'type': 'line', 'source': 'isolines', 'paint': { 'line-color': '#000000', 'line-width': 2 } }); }); } // Call the function to initialize the map initializeMap(); </script> </body> </html> HTMLファイルをブラウザで開くと、次の地図(図9)が表示されます。この地図は、ベネチアン・リゾートからの徒歩圏内の距離を 5 分、15 分、30 分の時間枠で示しています。 HTMLファイルをブラウザで開くと、次の地図(図9)が表示されます。この地図は、ベネチアン・リゾートからの徒歩圏内の距離を 5 分、15 分、30 分の時間枠で示しています。 図 9 – ベネチアンリゾートからの徒歩距離を表示した地図 SnapToRoads による位置補正されたルートデータの取得 SnapToRoads を使用すると、GPS データやその他の位置データを最寄りの道路にスナップし、位置補正後の線データを取得することができます。この機能は、車両追跡や交通分析の精度を向上させるのに非常に役立ちます。ユーザーは指定されたパラメータを含む POST リクエストを送信し、位置補正された線データを含むレスポンスを受け取ることができます。処理前と処理後のデータを地図上で視覚化する例を示します。 snapToRoad.html という名前の新しい HTML ファイルを作成し、以下のコードをファイルに貼り付けてください。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Amazon Location Service - Snap to Roads</title> <!-- MapLibre GL CSS --> <link href="https://unpkg.com/maplibre-gl@3.x/dist/maplibre-gl.css" rel="stylesheet" /> <style> body { margin: 0; } #map { height: 100vh; /* Full viewport height */ } </style> </head> HTML ファイルをブラウザで開くと、以下の地図(図10)が表示されます。青い線は GPS トレースを表し、赤い線は道路にスナップされたバージョンを表しています。 図 10 – GPS トレースに基づいて修正されたルートを表示した地図 クリーンアップ このデモで作成された Amazon Location Service リソースは API キーのみでした。API キーを削除するには、Amazon Location Service コンソールに移動し、作成した API キーを選択して、 Deactivate を選択します。キーの無効化を確認し、 Delete を選択します。標準の 90 日間の無効化期間を無視してキーを強制的を選択してください まとめ Amazon Location Service は新しい機能によりさらに柔軟性が向上しました。このアップデートにより、以前は必要だったリソース作成が不要になり、API キーを設定するだけで様々な API を使用できるようになりました。これにより、ユーザーは地理空間アプリケーションを迅速かつスムーズに構築できます。 注目すべき新機能には、Maps API の GetStyleDescriptor と GetStaticMap、Places API の SearchText と SearchNearby、Routes API の CalculateIsolines と SnapToRoads があります。 Maps API では、GetStyleDescriptor を使用して様々なマップスタイルを取得し、アプリケーションに適用できます。また、GetStaticMap は指定した座標とズームレベルに基づいて静的な地図画像を生成できます。Places API では SearchText を使用して POI データを検索でき、SearchNearby は特定の場所の周辺にある POI を見つけることができます。Routes API では、CalculateIsolines を使用して指定したポイントからの到達可能性を計算し、SnapToRoads は GPS データを修正して正確な経路データを取得できます。 これらの新機能により、アプリケーション開発者は地理空間データをより効果的に活用し、ユーザーエクスペリエンスを大幅に向上させることができます。ビジネスの加速化に役立つ方法の詳細については、 AWS の担当者 にお問い合わせください。 参考資料 Amazon Location Service Routes, Places, Maps の新しい API を発表 Amazon Location Service API ドキュメント AWS Geospatial – GitHub Yasunori Kirimoto Yasunori Kirimoto は、AWS DevTools Hero であり、株式会社 MIERUNE の共同創業者兼 CEO です。GIS(地理情報システム)とFOSS4G(Free and Open Source Software for Geospatial)を専門としています。20 年以上の経験と地理空間データおよびアプリケーションに関する幅広い知識を持っています。