0
0

More than 1 year has passed since last update.

D3.jsとJSDOMを活用してかんたんな震度分布図を作ってみよう

Posted at

tl;dr

震度分布図作ります。

かなりのスパゲッティーコードです
あとかなり読みにくい日本語となっています、すいません。

しくみ

P2PQuake JSONAPI
↓
パーズ
↓
描画部分で最大震度の色に変換
↓
完成!

コード

出来るだけ短く済むように一部を変更したりしてます。
フルで汚いコードはgithubにあげておりますのでよければどうぞ
https://github.com/akikaki-bot/Earthquake_mapmaker

(async() => {

const d3 = require('d3');
const fs = require('fs');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const Path = require('path');
const Util = require('./util/changesindo.js')
const request = require('request');
const createtime = new Date();

//新しいドキュメントの宣言

const document = new JSDOM().window.document

//ここから保存関係

    const dir = process.cwd();
    const datadir = Path.join(dir, "data");
    const fullPath = Path.join(datadir, "eq_map.csv");
    const targetPath = Path.format({
                dir: Path.join(dir, "svg"),
                name: Path.basename(fullPath, Path.extname(fullPath)),
                ext: ".svg"
            });

//サイズ指定
    const width = 1234; 
    const height = 694; 
    const scale = 2000; 

//一時的
  let pref = "";
  let maxscale = 00;

//ゲット
       request.get('https://api.p2pquake.net/v2/history?codes=551&limit=1',async(res,req,body) => {
        p2p = JSON.parse(body);

  //おまじない
    const projection = d3.geoMercator().center([137.0, 38.2]).translate([width / 2, height / 2]).scale(scale);
    const path = d3.geoPath().projection(projection);

//あたらしい地図のベース作成
    const svg = d3.select(document.body)
              .append('svg')
              .attr("xmlns",'http://www.w3.org/2000/svg')
              .attr('width', width)
              .attr('height', height)
              .style(`background-color`,"#001639")

              const data = await d3.json(`geojsonのファイルだかURLを。なんか私の環境だとURLじゃないとダメだった。`);
              svg
              .selectAll('path')
              .data(data.features)
              .enter()
              .append(`path`)
              .attr(`d`, path)
              .attr(`stroke`, `#666`)
              .attr(`stroke-width`, 0.25)
              .attr(`fill`, (item) => {
                function check() {
                  for(var point of p2p[0].points){
                      if(!pref){
                         maxscale = 0;
                         pref = point.pref;
                         maxscale = point.scale;
                      }
                      if((pref === item.properties.nam_ja)){
                        return new Util().changesindo(maxscale)
                      } else {
                        pref = "";
                      }
                   }
                }
                return check();
              })
              //タイトル
                //(省略)
              fs.writeFileSync(targetPath, document.body.innerHTML ,(e) =>  {
                if(err){
                    console.error('[地図描画] エラー : '+err.message ? err.message : err)
                } else {
                    console.log(`[地図描画] 成功しました。 処理時間 : ${new Date() - createtime}`)
                }
        })
    })
    })()

震度から色に変換するUtilクラス

私がそれっぽい色を選択しています。

class Util {
    changesindo(sindo){
        switch(sindo){
            case 10: return "#778899"
            case 20: return "#4682b4"
            case 30: return "#008000"
            case 40: return "#ffd700"
            case 45: return "#ffa500"
            case 50: return "#d2691e"
            case 55: return "#800000"
            case 60: return "#b22222"
            case 70: return "#4b0082"
            default: return "#FFFFFF"
        }
    }
}

module.exports = Util;

苦戦したところ

・情報パーズして色分けの所がなかなか仕組みを考えるのに苦戦しちゃいました。

かんそう

たのしかったです!

※ここ間違ってるよ!とかがありましたらお気兼ねなくコメントをしていただけるとありがたいです💛

0
0
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
0
0