さて、本日も ArcGIS API for JavaScript について書いてみようと思います。標高 API は以下のエントリーで紹介しているのですが、Python と C# での呼び出しについてでした。今回は JavaScript を使って処理を書いてみようと思います。
今回やろうとしていること
ArcGIS API for JavaScript を使用して、マップをクリックしたら標高を表示する、というような処理を書いてみようと思います。
今回使用するソース
前回のエントリーをベースに今回使用する処理を書き足そうと思います。
前回の完成イメージです。
今回は以下のように「レイヤー一覧」ボタンの隣に「標高」ボタンを追加しようと思います。
環境
ArcGIS API for JavaScript 4.12
Chrome
マップクリック時に何か処理を走らせたい場合
View クラスの on() メソッドを使用します。
view.on("click", function(event){ console.log(event.mapPoint); });
標高API を使用してみる
以下のように実装してみました。リクエストを投げて受け取ったJSONをパースするだけなので、すごく簡単にできますね。
view.on("click", function (event) { if(elevation==1){ var data = { 'lon': event.mapPoint.longitude , 'lat': event.mapPoint.latitude }; var querystring = encodeQueryData(data); var url = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?" + querystring + "&outtype=JSON" // リクエストなげる var request = new XMLHttpRequest(); request.open('GET', url); request.onreadystatechange = function () { var result = JSON.parse(request.responseText); view.popup.open({ title: result.elevation, content : result.elevation, location: event.mapPoint }); }; request.send(null); } }); function encodeQueryData(data) { let ret = []; for (let d in data) ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d])); return ret.join('&'); }
if(elevation==1)
の部分ですが、これは「標高」ボタンを押したら標高 API を使用するモードを切り替える処理を以下のように入れているためです。
// 標高ボタンを押して標高を取得できるモードを切り替える var elevation = 0; function getElevation(){ if(elevation==1){ elevation = 0; }else{ elevation = 1; } }
HTMLの部分を除いてですが、今回追加した処理はこれだけです。
サンプルコード
全コードを以下に記載します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> <title>レイヤ一覧表示</title> <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css"> <script src="https://js.arcgis.com/4.12/"></script> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } #layerToggle { display: none; top: 80px; right: 20px; position: absolute; z-index: 99; background-color: white; border-radius: 8px; padding: 10px; opacity: 0.75; } #menu{ padding: 0; margin: 0; height:42px; background-color:#eeeeee; font-weight:bold; } #menu li { height:42px; margin-right: 2px; display: inline-block; } #button,#buttonElevation { left:0px; width:164px; height:42px; } </style> <script> require([ "esri/Map", "esri/views/MapView", "esri/layers/VectorTileLayer", "esri/layers/FeatureLayer", "esri/layers/MapImageLayer", "dojo/on", "dojo/domReady!" ], function( Map, MapView, VectorTileLayer, FeatureLayer, MapImageLayer, on ) { var map = new Map({ basemap: "gray-vector" }); var vectorTileLayer = new VectorTileLayer({ url: "https://www.arcgis.com/sharing/rest/content/items/92c551c9f07b4147846aae273e822714/resources/styles/root.json", id:"vectorTile" }); var mapImageLayer = new MapImageLayer({ url: "https://content.esrij.com/arcgis/rest/services/Dosyasaigai/Dosyasaigai_Tile/MapServer", id:"mapImage" }); var boundary = new FeatureLayer({ url:"https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/JPN_Boundaries_ECM/FeatureServer", id:"boundary", opacity:0.5, minScale:1500000, maxScale:50000 }); map.add(vectorTileLayer); map.add(mapImageLayer); map.add(boundary); var view = new MapView({ container: "viewDiv", map: map, center: [139.740286, 35.678601], zoom: 15 }); var vectorTileToggle = document.getElementById("vectorTileLayer"); var mapImageToggle = document.getElementById("mapImageLayer"); var boundaryToggle = document.getElementById("boundary"); on(vectorTileToggle, "change", function() { vectorTileLayer.visible = vectorTileToggle.checked; }); on(mapImageToggle, "change", function() { mapImageLayer.visible = mapImageToggle.checked; }); on(boundaryToggle, "change", function() { boundary.visible = boundaryToggle.checked; }); view.on("click", function (event) { if(elevation==1){ var data = { 'lon': event.mapPoint.longitude , 'lat': event.mapPoint.latitude }; var querystring = encodeQueryData(data); var url = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?" + querystring + "&outtype=JSON" // リクエストなげる var request = new XMLHttpRequest(); request.open('GET', url); request.onreadystatechange = function () { var result = JSON.parse(request.responseText); view.popup.open({ title: result.elevation, content : result.elevation, location: event.mapPoint }); }; request.send(null); } }); function encodeQueryData(data) { let ret = []; for (let d in data) ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d])); return ret.join('&'); } }); function displayLayerList(){ var toggle = document.getElementById("layerToggle"); if(toggle.style.display=="block"){ // 非表示 toggle.style.display ="none"; }else{ // 表示 toggle.style.display ="block"; } } // 標高ボタンを押して標高を取得できるモードを切り替える var elevation = 0; function getElevation(){ if(elevation==1){ elevation = 0; }else{ elevation = 1; } } </script> </head> <body> <ul id="menu"> <li id="menu"> <button id="button" type="button" onClick="displayLayerList()">レイヤー一覧</button> </li> <li> <button id="buttonElevation" type="button" onClick="getElevation()">標高</button> </li> </ul> <div id="viewDiv"></div> <div id="layerToggle"> <input type="checkbox" id="vectorTileLayer" checked/>背景<br> <input type="checkbox" id="mapImageLayer" checked/>国土数値情報 災害情報<br> <input type="checkbox" id="boundary" checked />平成 27 年国勢調査 都道府県界<br> </div> </body> </html>
このようにマップをクリックすると標高を取得することができました。皇居周辺は大体標高が20数メートルということがわかりました!
今回は簡単にポップアップで標高を表示してみましたが、グラフィックか何かで標高を表示しても面白そうですね。その辺の実装も機会があれば紹介できればと思います。今回は以上です。