はじめに
誰もがテレビで「東京ドーム〇〇個分の大きさ」という表現を耳にしたことがあると思います。
しかしこれは、東京ドームを見たことがない人にはあまりピンと来ない表現です。
そこで、東京ドームの大きさを身近に感じられる地図コンテンツを作りました。
何を作ったか
現在地を東京ドームと(大体)同じ大きさのポリゴンで覆う地図コンテンツを作りました。
デモページ
差分(航空写真 var.)
このコンテンツでは、ボタンを押すだけで、現在地を中心としたポリゴンが載ったWeb地図を生成することができます。
(※閲覧はスマホ推奨、PCでも可)
東京ドーム型のポリゴンについて
東京ドーム型のポリゴンの大きさは、東京ドームを円形と仮定して、公式HPの情報をもとに計算しました。
大きさの設定に用いたパラメータは、以下のとおりです。
- 半径: 122m(※建築面積から算出)
- 最高部の高さ: 56.190m
どう作ったか
地図描画ライブラリMapbox GL JSと、地理空間データ分析ライブラリTurf.jsを用いて実装しました。
ただし、現在地の取得にはMapbox GL JSのメソッドを使わず、Geolocation APIを利用しています。
ソースコード
この記事では要点を絞って、下記の2つの機能のスクリプトを紹介します。
- 現在地の緯度経度を受け渡す機能
- 渡された緯度経度を中心とした東京ドームポリゴン付きの地図を生成する機能
ちなみに、コンテンツ全体のソースコードは次のページに掲載しています。
https://bl.ocks.org/Hirosaji/ed4443946608237eaddcf1207b3776cb
https://gist.github.com/Hirosaji/ed4443946608237eaddcf1207b3776cb
1. 現在地の緯度経度を受け渡す機能
ボタンのクリックイベントを受け取ってGeolocation APIの呼び出し、呼び出し成功時に緯度経度を 2. の関数に渡すスクリプトです。
var successCallBackFunction, errorCallBackFunction;
// API option
var option = {
enableHighAccuracy: true, // Whether to use GPS to improve accuracy
maximumAge: 0, // To hold cache ms
timeout: 30000 // Timeout ms
};
/**
* Processing at the end of HTML loading
*/
window.addEventListener('load', function () {
// Check whether API is enabled/disabled
if (!navigator.geolocation) {
alert('Geolocation API is disabled');
return;
}
// Set button to get position info from API
document.getElementById('button_id').addEventListener('click', function () {
// API call
navigator.geolocation.getCurrentPosition(successCallBackFunction, errorCallBackFunction, option);
}, false);
}, false);
/**
* Callback func at successful getting position info
*/
successCallBackFunction = function (position) {
var lng = position.coords.longitude;
var lat = position.coords.latitude;
// Pass lng & lat to creating polygon function (for 2.)
latlng2polygon(lng, lat);
};
/**
* Callback func at faild getting position info
*/
errorCallBackFunction = function (positionError) {
alert(positionError.code + ': ' + positionError.message);
};
参考リンク
- Geolocatoion APIで現在地を取得しGoogleマップに表示する方法 - ゆとり世代プログラマの備忘録
2. 取得した緯度経度を中心とした東京ドームポリゴン付きの地図を生成する機能
取得した緯度経度を中心とした東京ドーム型のポリゴンをTruf.jsで生成し、Mapboxの地図上に載せるスクリプトです。
function latlng2polygon(lng, lat) {
mapboxgl.accessToken = 'Your token';
var center = [lng, lat];
var radius = 0.122;
var precision = 0.001525;
var epsilon = 0.0001;
// Create new Mapbox object
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: center,
zoom: 16,
pitch: 60
});
/**
* Create Tokyo Dome Polygon using Turf.js
*/
var grid = turf.hexGrid(turf.bbox(turf.circle(center, radius)), precision);
// Calculate parameters of each element in turf circular bbox
var dome = turf.featureCollection(grid.features.map(function (feature) {
var point = turf.centroid(feature);
var distance = turf.distance(center, point);
if (distance > radius) { return; }
// sphere r^2 = x^2 + y^2 + z^2
// therefore z = Math.sqrt(r^2 - x^2 - y^2)
// = Math.sqrt(r^2 - (x^2 + y^2))
// but distance^2 = x^2 + y^2
// so z = Math.sqrt(r^2 - distance^2)
var z = Math.sqrt(Math.pow(radius, 2) - Math.pow(distance, 2));
var normHeight = 56.190 / 122; // to normalize height
z = isNaN(z) ? 0 : z * normHeight;
// Adapt parameters to Tokyo dome polygon data
return turf.feature(feature.geometry, {
base_height: z * 1000, // adopt z / m from z / km
height: (z * 1000) + (distance * 1000 + epsilon) * 0.1
});
}).filter(function (feature) { return feature; }));
// add Tokyo Dome polygon Layer on Mapbox
map.on('load', function () {
map.addSource('dome', {
type: 'geojson',
data: dome
});
map.addLayer({
id: 'dome',
type: 'fill-extrusion',
source: 'dome',
paint: {
'fill-extrusion-color': 'red',
'fill-extrusion-base': {
type: 'identity',
property: 'base_height'
},
'fill-extrusion-height': {
type: 'identity',
property: 'height'
},
'fill-extrusion-opacity': 0.5
}
});
});
};
参考リンク
- Add dome in Mapbox GL JS using a hex grid and polygon extrusions - Andrew Harvey’s Block
おわりに
この記事では、東京ドームの大きさを可視化した地図コンテンツを紹介し、その要点となるスクリプトをコメントアウト付きで掲載しました。
地図系のライブラリは、組み合わせ次第で様々な表現ができるので、使っていてとても楽しいです。
特にMapbox GL JSは、3D表現が可能なWebGLを用いたライブラリの中でも、とにかく多様な表現ができることで有名です。
Mapbox GL JSをご存知ない方は、ぜひ公式のExamplesを覗いてみてください。
その表現の幅広さに、エンジニアなら誰もが気持ちを高ぶらせてしまうと思います。
またTurf.jsは、地理空間上で数値計算やデータ分析をする際には欠かせないライブラリです。
まだ参考サイトは少ないですが、今後リッチなWeb地図を作りたい方は、覚えておいて損はないと思います。
以上、ぜひ皆さんも自分だけの新たな地図を作ってみてください。