はじめに
-
国土数値情報の2018年度駅別乗降客数データを、deck.glのScatterplotLayerを用いて可視化してみました。
-
2018年度駅別乗降客数データは以下の国土数値情報の提供サイトよりシェープファイル(ライン)がダウンロードできます。
※本記事では、シェープファイル(ライン)をQGISで重心(ポイント)に変換したデータを用いています。
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-S12-v2_6.html -
背景地図にはMapboxを使用しているため、Mapboxにてアクセストークンの取得が必要になります。
アウトプットイメージ
※「駅別乗降客数データ」(国土交通省)
(https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-S12-v2_6.html) を加工して作成
前提条件
-
駅別乗降客数データは以下のデータ形式(csvファイル)とします。
-
最後列の「S12_037」が2018年度の駅別乗降客数になります。
-
鉄道路線や鉄道駅のラインデータは国土数値情報からダウンロードし、geojsonファイルを用いています。
-
なお、駅別乗降客数データや鉄道路線や鉄道駅のラインデータはWebサーバ上に保存されていることが前提です。
html
<html>
<head>
<title>2018年駅別乗降客数データ(国土数値情報)</title>
<meta charset="UTF-8">
<script src="https://unpkg.com/deck.gl@^7.0.0/dist.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js"></script>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<div id="control-panel">
<div>
<label>opacity</label>
<input id="opacity" type="range" min="0" max="1" step="0.01" value="0.5"></input>
<span id="opacity-value"></span>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS
html,body {
font-family: Helvetica, Arial, sans-serif;
width: 100vw;
height: 100vh;
margin: 0;
}
.deck-tooltip {
font-family: Helvetica, Arial, sans-serif;
padding: 6px !important;
margin: 8px;
color: #ffffff;
background-color: #4682b4;
max-width: 300px;
font-size: 20px;
}
#control-panel {
position: absolute;
top: 0;
left: 0;
margin: 12px;
padding: 20px;
font-size: 12px;
line-height: 1.5;
z-index: 1;
background: #fff;
font-family: Helvetica, Arial, sans-serif;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
}
label {
display: inline-block;
width: 140px;
}
#JavaScript
- mapboxApiAccessTokenには、取得したアクセストークンを入力してください。
- S12-19_NumberOfPassengers_point_2018.csvが駅別乗降客数データになります。
- N02-19_RailroadSection.geojsonが鉄道路線のラインデータになります。
- N02-19_Station.geojsonが鉄道駅のラインデータになります。
const deckgl = new deck.DeckGL({
mapboxApiAccessToken: 'アクセストークンを入力してください',
mapStyle: 'mapbox://styles/mapbox/dark-v9',
initialViewState: {
latitude: 35.685175,
longitude: 139.7527995,
zoom: 10,
maxZoom: 20,
pitch: 45,
bearing: 15
},
controller: true,
});
const OPTIONS = ['opacity'];
const data = d3.csv('data/S12-19_NumberOfPassengers_point_2018.csv');
const railway = d3.json('data/N02-19_RailroadSection.geojson');
const station = d3.json('data/N02-19_Station.geojson');
const renderLayer = () => {
const options = {};
OPTIONS.forEach(key => {
const value = document.getElementById(key).value;
document.getElementById(key + '-value').innerHTML = value;
options[key] = Number(value);
});
const geoJsonLayer1 = new deck.GeoJsonLayer({
id: 'railway',
data: railway,
stroked: false,
filled: false,
lineWidthMinPixels: 2,
parameters: {
depthTest: false
},
opacity: 0.7,
getLineColor: [240,240,240],
getLineWidth: 2,
pickable: false,
});
const geoJsonLayer2 = new deck.GeoJsonLayer({
id: 'station',
data: station,
stroked: false,
filled: false,
lineWidthMinPixels: 2,
parameters: {
depthTest: false
},
opacity: 1,
getLineColor: [229,229,229],
getLineWidth: 10,
pickable: false,
});
const scatterplotLayer = new ScatterplotLayer({
id: 'scatter-plot',
data: data,
radiusUnits: 'meters',
radiusScale: 1,
lineWidthUnits: 'meters',
lineWidthScale: 1,
stroked: false,
filled: true,
pickable: true,
opacity: 0.5,
radiusMinPixels: 4,
radiusMaxPixels: 100,
lineWidthMinPixels: 1,
getPosition: d => [Number(d.lng), Number(d.lat)],
getRadius: d => Math.sqrt(d.S12_037),
getColor: d => [101, 101, 255],
getLineColor: d => [0, 0, 0],
...options
});
deckgl.setProps({
layers:[geoJsonLayer1, geoJsonLayer2, scatterplotLayer],
getTooltip: ({object}) => object && `${object.S12_002}\n${object.S12_003}\n${object.S12_001}駅\n駅別乗降客数: ${object.S12_037}`
});
}
renderLayer();
OPTIONS.forEach(key => {
document.getElementById(key).oninput = renderLayer;
});
参考文献
https://deck.gl/docs/api-reference/layers/scatterplot-layer
https://deck.gl/gallery/
https://github.com/visgl/deck.gl
https://deckgl.readthedocs.io/en/latest/index.html