Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

都道府県のデータを作ってみた話

都道府県」のデータを作りたい。
そんな要望を受けたので、色々と調べてみることにしました。

とはいえ、データがないと何も始まらないので、データを探すことに・・・

取得先候補1: 総務省が出している「全国地方公共団体コードから取得」

www.soumu.go.jp

都道府県・市区町村のデータ、政令指定都市もわかるようになっており、データの形としては○。
しかし、Excelで作られているため、何かしらツールを使って取得しないといけない・・・うーん(= = ;;

取得先候補2: 内閣府が出している「都道府県一覧APIから取得」

opendata.resas-portal.go.jp

APIなので取得は簡単◎。これを使えば楽じゃないかーと思ったが・・・
データが古く、最新のデータが入っていない(= = ;; うーん

取得先候補3: 国土交通省が出している「都道府県コード一覧から取得」

www.land.mlit.go.jp

これもAPI。最新のデータも入っているように見える。
しかし、更新履歴等が無く、APIがいつ更新されるかも不明なので、継続的に使用するのはちょっと怖い・・・うーん(= = ;; うーん

結果: データ取得先候補1を選定

Excelで作られてはいるが、データとしては揃っているので、これを使うことにしました。
Excelから抽出できるツールは、なんちゃってTypeScriptで作ります。
出力結果は、jsonのようでjsonじゃないファイルで作ります。

import * as XLSX from "xlsx";
import { createWriteStream } from 'fs'

// 読み込み用Excel
let workBook = XLSX.readFile('./assets/000618153.xls')

const sheetList = workBook.SheetNames
const sheet1    = workBook.Sheets[sheetList[0]]
const sheet2    = workBook.Sheets[sheetList[1]]

interface JsonSheet {
  '団体コード': string,
  '都道府県名\n(漢字)': string,
  '市区町村名\n(漢字)': string,
  '都道府県名\n(カナ)': string,
  '市区町村名\n(カナ)': string
}

const jsonSheet1: JsonSheet[] = XLSX.utils.sheet_to_json(sheet1)
// 政令指定都市Sheetは、ヘッダーが無いため配列で格納する
const arraySheet2: string[] = XLSX.utils.sheet_to_json(sheet2, {header: 1})

// 政令指定都市Sheetの団体コードは、StringとNumber型が混在しているため、Stringに統一させる
const arrayStringUnifySheet2 = arraySheet2.map(x => typeof x[0] === 'number' ? [String(x[0]), x[1], x[2]] : x)

const prefectures = jsonSheet1.filter(cel => !cel['市区町村名\n(漢字)'] && !cel['市区町村名\n(カナ)'])
const cities = jsonSheet1.filter(cel => cel['市区町村名\n(漢字)'] && cel['市区町村名\n(カナ)'])

// 書き込み用Jsonファイル
const src = createWriteStream('./assets/prefMaster.json')

prefectures.forEach( cel => {
  let prefCode = cel['団体コード'].slice(0, 2)

  let city = cities.filter(cel => prefCode === cel['団体コード'].slice(0, 2))
  let ordinanceDesignatedCity = arrayStringUnifySheet2.filter(cel => cel[0].slice(3, 5) !== '00' ? prefCode === cel[0].slice(0, 2) : false)

  city.forEach(x => {
    src.write(`{ "prefCode": "${prefCode}", "prefName": "${cel['都道府県名\n(漢字)']}", \
"cityCode": "${x['団体コード'].slice(0, 5)}", "cityName": "${x['市区町村名\n(漢字)']}" }`)
    src.write('\n')
  })
  if (ordinanceDesignatedCity) {
    ordinanceDesignatedCity.forEach(x => {
      src.write(`{ "prefCode": "${prefCode}", "prefName": "${cel['都道府県名\n(漢字)']}", \
"cityCode": "${x[0].slice(0, 5)}", "cityName": "${x[1]}" }`)
      src.write('\n')
    })
  }
})

よし!では、出力結果を見てみよう!

{ "prefCode": "01", "prefName": "北海道", "cityCode": "01100", "cityName": "札幌市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01202", "cityName": "函館市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01203", "cityName": "小樽市" }
{ "prefCode": "01", "prefName": "北海道", "cityCode": "01204", "cityName": "旭川市" }
// ・・・省略・・・
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47362", "cityName": "八重瀬町" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47375", "cityName": "多良間村" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47381", "cityName": "竹富町" }
{ "prefCode": "47", "prefName": "沖縄県", "cityCode": "47382", "cityName": "与那国町" }

できたー。

まとめ

都道府県のデータを取得するのって、簡単だろう」と思ったら、意外とちゃんとしたデータって落ちていないものですね。
皆さんどうやって作っているのだろうか・・・