はじめに
- H27国勢調査の500mメッシュ人口データをdeck.glで表示してみました。
- H27国勢調査の500mメッシュ人口データは、e-statより統計データ及び境界データをダウンロードして用いています。
- deck.glでの表示には、HexagonLayerを用いています。
アウトプットイメージ
https://t.co/j5x1odcLvT のサンプルコードを参考(https://t.co/lLUAmWQ2mR)に、H27国勢調査(500mメッシュ人口)を可視化してみた😇
— shi_works🌥️ (@syanseto) October 11, 2020
グリグリ動かせて、いい感じです🗾https://t.co/j5x1odcLvT ごいすー🍵😄 pic.twitter.com/rSpML7NfHH
事前準備
- H27国勢調査の500mメッシュ人口データをHexagonLayerで表示するには、500mメッシュのポリゴンデータをポイントデータ(メッシュの重心)に変換する必要があります。
- 500mメッシュのポリゴンデータからポイントデータ(メッシュの重心)の変換にはQGISを用いています。
- QGISでの作業の流れは以下のとおりです(本記事では詳細は割愛します)。
- H27国勢調査の500mメッシュ人口データの境界データと統計データをQGIS上で結合します。
- 結合したデータ(ポリゴンデータ)の重心座標を求め、ポイントデータをcsv形式で保存します。
- 保存した、csv形式のポイントデータは以下のとおりです。
前提条件
- Mapboxのアクセストークンが必要になります。
- Mapboxのアクセストークンを入力してください。
- 27国勢調査の500mメッシュ総人口(ポイントデータ:H27kokusei_4jimesh_point.csv)を読み込んでいます。
- また、国土数値情報の鉄道データ(ラインデータ:N02-19_RailroadSection.geojson)を読み込んでいます。
html
H27kokusei_4jimeshjinko.html
<html>
<head>
<title>平成27年国勢調査 500mメッシュ総人口</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>Radius</label>
<input id="radius" type="range" min="500" max="20000" step="100" value="2000"></input>
<span id="radius-value"></span>
</div>
<div>
<label>ElevationScale</label>
<input id="elevationScale" type="range" min="0" max="500" step="50" value="200"></input>
<span id="elevationScale-value"></span>
</div>
<div>
<label>Coverage</label>
<input id="coverage" type="range" min="0" max="1" step="0.1" value="1"></input>
<span id="coverage-value"></span>
</div>
<div>
<label>opacity</label>
<input id="opacity" type="range" min="0" max="1" step="0.01" value="1"></input>
<span id="opacity-value"></span>
</div>
</div>
<div id="tooltip"></div>
<script src="script.js"></script>
</body>
</html>
CSS
style.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;
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
script.js
const deckgl = new deck.DeckGL({
mapboxApiAccessToken: 'Mapboxのアクセストークンを入力してください',
mapStyle: 'mapbox://styles/mapbox/streets-v9',
initialViewState: {
latitude: 35.1801494,
longitude: 136.9034925,
zoom: 7,
maxZoom: 16,
pitch: 45,
bearing: 15
},
controller: true,
});
const OPTIONS = ['radius', 'elevationScale', 'coverage', 'opacity'];
const colorRange = [
[1, 152, 189],
[73, 227, 206],
[216, 254, 181],
[216, 254, 181],
[254, 237, 177],
[254, 237, 177],
[254, 237, 177],
[254, 237, 177],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[254, 173, 84],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
[209, 55, 78],
];
const getValue=(d) =>{
// console.log(d.jinko)
return Number(d.jinko);
};
const data = d3.csv('data/H27kokusei_4jimesh_point.csv');
const railway = d3.json('data/N02-19_RailroadSection.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 hexagonLayer = new deck.HexagonLayer({
id: 'hex',
data,
getPosition: d => [Number(d.lng), Number(d.lat)],
colorRange,
getColorWeight: getValue,
getElevationWeight: getValue,
elevationScale: 200,
extruded: true,
pickable: true,
radius: 1000,
opacity: 1,
coverage: 1,
upperPercentile: 100,
...options
});
const geoJsonLayer = new deck.GeoJsonLayer({
id: 'geojson',
data: railway,
stroked: false,
filled: false,
lineWidthMinPixels: 2,
parameters: {
depthTest: false
},
opacity: 0.5,
getLineColor: [240,240,240],
getLineWidth: 2,
pickable: false,
});
deckgl.setProps({
layers:[hexagonLayer, geoJsonLayer],
getTooltip: ({object}) => object && `総人口: ${object.elevationValue}`
});
}
renderLayer();
OPTIONS.forEach(key => {
document.getElementById(key).oninput = renderLayer;
});
参考文献