2
3

More than 3 years have passed since last update.

2019年警察庁交通事故統計データをdeck.glで可視化してみました(その2)

Last updated at Posted at 2020-12-31

はじめに

アウトプットイメージ

image.png
ezgif.com-gif-maker (2).gif

※「交通事故統計情報のオープンデータ」(警察庁)
(https://www.npa.go.jp/publications/statistics/koutsuu/opendata/2019/opendata_2019.html) を加工して作成

前提条件

  • 交通事故統計データは以下のデータ形式(csvファイル)とします。
    image.png

  • 高速道路のラインデータは国土数値情報からダウンロードし、QGISでgeojsonファイルに変換したデータになります。

  • なお、交通事故統計データや高速道路のラインデータはWebサーバ上に保存されていることが前提です。

html

2019jiko.html
<html>
  <head>
    <title>2019年警察庁事故データ(全事故)</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>cellSize</label>
        <input id="cellSize" type="range" min="0" max="10000" step="50" value="2000"></input>
        <span id="cellSize-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>
    <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;
  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には、取得したアクセストークンを入力してください。
  • honhyo_2019_all_utf-8.csvが交通事故統計データになります。
  • N06-19_HighwaySection.geojsonが高速道路のラインデータになります。
script.js
const deckgl = new deck.DeckGL({
  mapboxApiAccessToken: 'アクセストークンを入力してください',
  mapStyle: 'mapbox://styles/mapbox/dark-v9',
  initialViewState: {
    latitude: 35.1801494,
    longitude: 136.9034925,
    zoom: 7,
    maxZoom: 16,
    pitch: 45,
    bearing: 15
  },
  controller: true,
  });

const OPTIONS = ['cellSize', 'elevationScale', 'coverage', 'opacity'];

const colorRange  = [
  [0, 255, 255, 127],
  [63, 255, 0, 127],
  [255, 255, 0, 127],
  [255, 127, 60, 170],
  [255, 0, 0, 212],
  [152, 0, 38, 255]
];

const getValue=(d) =>{
        return Number(d.jiko);
};

const data = d3.csv('data/honhyo_2019_all_utf-8.csv');
const highway = d3.json('data/N06-19_HighwaySection.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 gridLayer = new GridLayer({
      id: 'grid',
      data,
      getPosition: d => [Number(d.lng), Number(d.lat)],
      colorRange,
      getColorWeight: getValue,
      getElevationWeight: getValue,
      elevationScale: 200,
      extruded: true,
      pickable: true,
      cellSize: 2000,
      opacity: 1,
      coverage: 1,
      ...options
    });

  const geoJsonLayer = new deck.GeoJsonLayer({
    id: 'geojson',
    data: highway,
    stroked: false,
    filled: false,
    lineWidthMinPixels: 2,
    parameters: {
      depthTest: false
    },
    opacity: 0.5,
    getLineColor: [240,240,240],
    getLineWidth: 2,

    pickable: false,
  });

 deckgl.setProps({
  layers:[gridLayer, geoJsonLayer],
  getTooltip: ({object}) => object && `全事故件数: ${object.count}`
});

}

renderLayer();

OPTIONS.forEach(key => {
  document.getElementById(key).oninput = renderLayer;
});

参考文献

https://deck.gl/docs/api-reference/aggregation-layers/grid-layer
https://deck.gl/gallery/
https://github.com/visgl/deck.gl
https://deckgl.readthedocs.io/en/latest/index.html

2
3
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
2
3