BODIK APIの使い方(Google編)
「BODIK APIの使い方(Javascript編)」では、アプリに近い形として、JavascriptからBODIK APIの呼び出し方を学びました。
このときは、「どのようにしてJavascriptからBODIK APIを呼び出すのか?」を理解するために、Javascriptを記述したHTMLファイルを直接ブラウザに呼び出すことで、ローカルで機能を確認しました。実際にアプリケーションとして使う場合は、何らかのサーバーが欲しくなります。しかし、専用のサーバーを構築することを考えると、難易度が上がってしまいます。どうにかならないか?
Googleの「Apps Script」を使えばこれを実現できます。
Google Apps Scriptを使ったWebアプリの作成
「BODIK APIの使い方(Javascript編)」の「課題2.地図に表示する」に追加機能を組み込んだHTMLを例にして、Webアプリを作ってみましょう。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>BODIK API</title> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> <script type="text/javascript"> let map = null; let marker_list = null; let marker_layer = null; let areaCircle = null; function init() { map = L.map('map', { zoomControl: false }); // 指定された緯度経度を中心とした地図 let lat = 33.59334325082392; let lon = 130.35598920962553; let center = [lat, lon]; map.setView(center, 14); //地理院地図の標準地図タイル let gsi = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>" }); gsi.addTo(map); //showMarker(lat, lon); map.on('click', onMapClick); } function onMapClick(e) { let latlng = e.latlng; let lat = latlng.lat; let lon = latlng.lng; showMarker(lat, lon); } function showMarker(lat, lon) { let api_server = 'https://wapi.bodik.jp'; let api = 'aed'; let distance = 2000; let maxResults = 100; let api_url = `${api_server}/${api}?select_type=geometry&lat=${lat}&lon=${lon}&distance=${distance}&maxResults=${maxResults}`; fetch(api_url) .then(response => response.json()) .then(data => { if (marker_layer) { map.removeLayer(marker_layer); marker_layer = null; } if (areaCircle) { map.removeLayer(areaCircle); areaCircle = null; } // クリックされた地点を中心に円を描く areaCircle = L.circle([lat, lon], { radius: distance, color: '#5555ff', weight: 1, fill: true, opacity: 0.5 } ); areaCircle.addTo(map); let features = data['resultsets']['features']; marker_list = []; let center = [lat, lon]; let bounds = L.latLngBounds(center, center); // 中心点で境界を初期設定する for (let feature of features) { let properties = feature['properties']; let popup = L.popup().setContent(properties['name']); let geometry = feature['geometry']; let location = geometry['coordinates']; let pos = [location[1], location[0]]; let marker = L.marker(pos); marker.bindPopup(popup); marker_list.push(marker); bounds.extend(pos); // 境界を拡張する } if (marker_list.length > 0) { marker_layer = L.layerGroup(marker_list); map.addLayer(marker_layer); } map.fitBounds(bounds); // 地図表示を境界に合わせる }); } </script> </head> <body onload="init()"> <h2>BODIK API program #2</h2> <div class="map" id="map" style="width:800px;height:600px"></div> </body> </html>
Googleスプレッドシートを用意する
- ご自分のGoogleドライブの任意のフォルダにGoogleスプレッドシートを作成してください。
- メニューの「拡張機能」から「Apps Script」を実行すると、「Apps Script」の画面が表示されます。
アプリの入口を作成する
- 初期表示されている「function myFunction()」を全部消して、次のコードに書き換える。
function doGet(e) { let template = HtmlService.createTemplateFromFile("index"); return template.evaluate(); }
HTMLファイルを作成する
- 左側の「ファイル」の右にある「+記号(ファイルの追加)」をクリックし、「HTML」を選択する。
- 追加されたhtmlファイルの名前を「index」に変更する。
- 「BODIK APIの使い方」のHTMLファイルから、「body」の部分をクリップボードにコピーする。
- index.htmlの「body」部分をクリップボードからペーストする。
- 地図を表示するためのLeafletライブラリの宣言部分をコピペする。
<!DOCTYPE html> <html> <head> <base target="_top"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> </head> <body onload="init()"> <h2>BODIK API program #2</h2> <div class="map" id="map" style="width:800px;height:600px"></div> </body> </html>
Javascript部分を組み込む
- 左側の「ファイル」の右にある「+記号(ファイルの追加)」をクリックし、「HTML」を選択する。
- 追加されたhtmlファイルの名前を「js」に変更する。
- 「BODIK APIの使い方」のHTMLファイルからBODIK APIを呼び出しているjavascript部分(<script>から</script>まで)をクリップボードにコピーする。
- js.htmlファイルの内容をクリップボードからペーストして置き換える。
<script type="text/javascript"> let map = null; let marker_list = null; let marker_layer = null; let areaCircle = null; function init() { map = L.map('map', { zoomControl: false }); // 指定された緯度経度を中心とした地図 let lat = 33.59334325082392; let lon = 130.35598920962553; let center = [lat, lon]; map.setView(center, 14); //地理院地図の標準地図タイル let gsi = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>" }); gsi.addTo(map); //showMarker(lat, lon); map.on('click', onMapClick); } function onMapClick(e) { let latlng = e.latlng; let lat = latlng.lat; let lon = latlng.lng; showMarker(lat, lon); } function showMarker(lat, lon) { let api_server = 'https://wapi.bodik.jp'; let api = 'aed'; let distance = 2000; let maxResults = 100; let api_url = `${api_server}/${api}?select_type=geometry&lat=${lat}&lon=${lon}&distance=${distance}&maxResults=${maxResults}`; fetch(api_url) .then(response => response.json()) .then(data => { if (marker_layer) { map.removeLayer(marker_layer); marker_layer = null; } if (areaCircle) { map.removeLayer(areaCircle); areaCircle = null; } // クリックされた地点を中心に円を描く areaCircle = L.circle([lat, lon], { radius: distance, color: '#5555ff', weight: 1, fill: true, opacity: 0.5 } ); areaCircle.addTo(map); let features = data['resultsets']['features']; marker_list = []; let center = [lat, lon]; let bounds = L.latLngBounds(center, center); // 中心点で境界を初期設定する for (let feature of features) { let properties = feature['properties']; let popup = L.popup().setContent(properties['name']); let geometry = feature['geometry']; let location = geometry['coordinates']; let pos = [location[1], location[0]]; let marker = L.marker(pos); marker.bindPopup(popup); marker_list.push(marker); bounds.extend(pos); // 境界を拡張する } if (marker_list.length > 0) { marker_layer = L.layerGroup(marker_list); map.addLayer(marker_layer); } map.fitBounds(bounds); // 地図表示を境界に合わせる }); } </script>
HTMLにJavascriptを追加する
- index.htmlにJavascriptファイルを読み込むために次の行を追加する。
<!DOCTYPE html> <html> <head> <base target="_top"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> <?!= HtmlService.createHtmlOutputFromFile('js').getContent(); ?> </head> <body onload="init()"> <h2>BODIK API program #2</h2> <div class="map" id="map" style="width:800px;height:600px"></div> </body> </html>
プロジェクトをデプロイする
以上で、HTMLファイルで記述したBODIK API呼び出しのサンプルプログラムを、コピペでApps Scriptに組み込むことができました。これをWebアプリとして発行しましょう。
- Apps Scriptの画面で、「デプロイ」ボタンを押し、「新しいデプロイ」を選択する。
- 初めてのデプロイの場合、「種類の選択」の「歯車アイコン」をクリックし、「ウェブアプリ」を選択する。
- 自分だけが使う場合は、「自分のみ」になっていることを確認し、「デプロイ」ボタンを押す。
- 「ウェブアプリ」のURLを「コピー」し、「完了」ボタンを押す。
- ブラウザを表示し、URL部分にコピーした「ウェブアプリのURL」を貼り付けて、表示する。
- ウェブアプリのURLは非常に長い文字列となっている。
まとめ
HTMLファイルで確認したコードを、Webアプリとして構築することができました。デプロイ時に「自分のみ」の利用としているので、「ウェブアプリのURL」を呼び出したとき、Googleがユーザー認証してくれます。
今回は「Googleスプレッドシート」のApps Scriptに組み込みました。Googleスプレッドシートの機能は使っていませんので、単純に「Apps Script」として作成することも可能です。
「Googleスプレッドシート」に組み込むことで、今後の機能拡張としてGoogleスプレッドシートをデータベースのように利用することも可能です。
「GAS HTML」などのキーワードで検索すると、いろいろな事例が見つかります。ぜひ、いろいろ試してください。
ひらの