LoginSignup
11
6

More than 5 years have passed since last update.

国土数値情報 行政区域データの GeoJSON を作る

Posted at

国土数値情報 行政区域データのダウンロード

http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html
利用規約などはご自身でご確認ください。

shapefile から GeoJSON に変換

ogr2ogr コマンドを使う。 該当コマンドは GDAL に含まれている。

gdalのインストール
$ brew install gdal
変換
$ ogr2ogr -lco "ENCODING=UTF-8" -f geoJSON N03-15_150101.geojson N03-15_150101.shp

GeoJSON ファイルを分割

Node モジュールの geojsplit が使えそうだ。
https://www.npmjs.com/package/geojsplit

geojsplitのインストール
$ npm install geojsplit

--key オプションで指定すれば市区町村コード毎に分割できそう。

geojsplitのコマンド引数
Options:
  -a, --suffix-length     number of characters in the suffix length for split file names  [default: 4]
  -l, --geometry-count    number of geometries per split file                             [default: 10]
  --help, -h              display this message                                            [boolean]  [default: false]
  -v, --verbose           verbose output                                                  [boolean]  [default: false]
  -o, --output-directory  output directory                                                [string]
  -k, --key               split by key [property name properties]                         [string]

が、

実行!
$ ./node_modules/.bin/geojsplit -k N03_007 -o splited_geojson N03-15_150101.geojson 

<--- Last few GCs --->

[5065:0x102004c00]    61374 ms: Mark-sweep 1405.1 (1465.1) -> 1405.1 (1465.1) MB, 1093.7 / 0.0 ms  allocation failure GC in old space requested
[5065:0x102004c00]    62455 ms: Mark-sweep 1405.1 (1465.1) -> 1405.1 (1434.1) MB, 1081.3 / 0.0 ms  last resort gc 
[5065:0x102004c00]    63495 ms: Mark-sweep 1405.1 (1434.1) -> 1405.1 (1434.1) MB, 1040.1 / 0.0 ms  last resort gc 


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x7bba2ec0d31 <JS Object>
    1: _onToken [/Users/k-nakamura/tmp/N03-20150101_GML/node_modules/jsonparse/jsonparse.js:~331] [pc=0x3bac160a6a35](this=0x29e591481d61 <a Parser with map 0xb00d3c2d2e9>,token=3,value=0x7bba2e9c821 <String[1]: [>)
    2: write [/Users/k-nakamura/tmp/N03-20150101_GML/node_modules/jsonparse/jsonparse.js:~87] [pc=0x3bac16061929](this=0x29e591481d61 <a Parser with map 0xb00d3c2d2e9>,buffer=0x1ef4b...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 5: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/usr/local/bin/node]
 6: v8::internal::Runtime_AllocateInTargetSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
 7: 0x3bac15f08506
 8: 0x3bac160a6a35
 9: 0x3bac16061929
Abort trap: 6

heap out of memory で死亡 :innocent:
全国を一気に処理は難しいみたいだ。

自前スクリプトで GeoJSON ファイルを分割

どちらにせよ巨大な JSON 文字列は一気に処理できないので、 geojsplit で分割したものを処理する。

Feature_100件毎に分割
$ mkdir split_by_num
$ ./node_modules/.bin/geojsplit -l 100 -o split_by_num N03-15_150101.geojson
split.js
const fs = require('fs');
const files = fs.readdirSync('split_by_num');

let lastFeature;
files.forEach((file) => {
  let current = JSON.parse(fs.readFileSync(`split_by_num/${file}`, {encoding: 'utf8'}));
  current.features.forEach((feature) => {
    if (!lastFeature) {
      lastFeature = feature;
    } else {
      let city = feature.properties.N03_007;
      let lastCity = lastFeature.properties.N03_007;
      if (lastCity == city) {
        lastFeature.geometry.coordinates.push(feature.geometry.coordinates[0]);
      } else {
        if (lastCity) {
          let filePath = `split_by_city/${lastCity}.geojson`;
          if (fs.existsSync(filePath)) {
            console.log(`>>> ${filePath} already exists !!! <<<`);
            let already = JSON.parse(fs.readFileSync(filePath, {encoding: 'utf8'}));
            lastFeature.geometry.coordinates = lastFeature.geometry.coordinates.concat(already.features[0].geometry.coordinates);
          }
          fs.writeFileSync(filePath, JSON.stringify({
            type: "FeatureCollection",
            features: [lastFeature]
          }, null, "  "));
          console.log(`${filePath} has ${lastFeature.geometry.coordinates.length} polygons`);
        }
        lastFeature = feature;
      }
    }
  });
});
実行!
$ mkdir split_by_city
$ node split.js

GitHub で確認

うp
$ cd split_by_city
$ git init
$ git add -A && git commit -m init
$ git remote add origin https://github.com/kozy4324/gyosei-kuiki-geojson.git
$ git push -u origin master

マルチポリゴンもよい感じである :v: :sun_with_face: :v:
https://github.com/kozy4324/gyosei-kuiki-geojson/blob/master/data/01517.geojson

11
6
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
11
6