3
4

More than 1 year has passed since last update.

H27国勢調査の500mメッシュ人口データをdeck.glで表示してみました

Last updated at Posted at 2021-09-26

はじめに

  • H27国勢調査の500mメッシュ人口データをdeck.glで表示してみました。
  • H27国勢調査の500mメッシュ人口データは、e-statより統計データ及び境界データをダウンロードして用いています。
  • deck.glでの表示には、HexagonLayerを用いています。

アウトプットイメージ

Animation14.gif

事前準備

  • H27国勢調査の500mメッシュ人口データをHexagonLayerで表示するには、500mメッシュのポリゴンデータをポイントデータ(メッシュの重心)に変換する必要があります。
  • 500mメッシュのポリゴンデータからポイントデータ(メッシュの重心)の変換にはQGISを用いています。
  • QGISでの作業の流れは以下のとおりです(本記事では詳細は割愛します)。
  • H27国勢調査の500mメッシュ人口データの境界データと統計データをQGIS上で結合します。
  • 結合したデータ(ポリゴンデータ)の重心座標を求め、ポイントデータをcsv形式で保存します。
  • 保存した、csv形式のポイントデータは以下のとおりです。

image.png

前提条件

  • 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;
});

参考文献

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4