BODIK APIの使い方(Javascript編)機能追加2
「BODIK APIの使い方(Javascript編)」で、Javascriptを使ったWebアプリケーションで、BODIK APIをどのように使うのかをご説明しています。課題2では、BODIK APIを呼び出した結果を地図に表示するプログラムを記述しました。
課題2のプログラムに機能を追加することを考えてみましょう。
検索領域を円で表示する
課題2のプログラムでは、地図をクリックすると、そのクリックされた地点を中心に一定の半径内にある「AED」をBODIK APIで検索し、その結果を地図上にマーカーとして表示しました。この中心点と半径の関係が地図に表示できていません。
イメージとしては、クリックされた地点を中心に円を表示したいところです。
対策
基本的な考え方として、次のようになります。
- 古い円があったら削除する。
- クリックされた地点を中心に指定された半径の円を描く。
「円を描く」は、Leafletの「circle」が使えます。
let circle = L.circle([lat, lon] , options); circle.addTo(map);
「円を削除する」は、Leafletの「removeLayer」メソッドを使えます。
map.removeLayer(circle);
プログラムは次のようになります。
半径(distance=20000)が大きすぎたので、2000mに変更しました。
<!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 = [];
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 marker = L.marker([location[1], location[0]]);
marker.bindPopup(popup);
marker_list.push(marker); // 配列に記録する
}
if (marker_list.length > 0) {
marker_layer = L.layerGroup(marker_list); // レイヤーを作成
map.addLayer(marker_layer); // 地図に表示する
}
});
}
</script>
</head>
<body onload="init()">
<h2>BODIK API program #2</h2>
<div class="map" id="map" style="width:800px;height:600px"></div>
</body>
</html>
どの範囲を検索した結果を表示しているのか?がわかるようになりましたね。
ひらの


