bobo

2024-12-12

GISファイル軽量化の備忘録

ペイントマップ」では、国土数値情報の行政区域データを使用して地図を描画しています。定期的に市町村合併・政令区の再編等で同様の作業が必要になるので、GISファイルの容量削減手順を備忘録として残しておきます。

※以下、「全国:2024年(令和6年)」の「N03-20240101.geojson」を使用した場合のファイル容量を記載しています。

1. 行政区域データを準備

国土交通省の国土数値情報ダウンロードサイトより、行政区域データをダウンロード。ポリゴンの簡素化時に都道府県境界がずれることがあるので、一部の都道府県のみのアップデートでも全国版のデータを使用する。同様に、都道府県の区域データ (市区町村をひとまとめにしたデータ) は使用せず、市区町村別のデータから都道府県の区域データを生成する。

代替テキスト https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-2024.html

2. ポリゴンを簡素化

mapshaperを使用して、ポリゴンの簡素化およびTopoJSONへの変換を行う。簡素化前のデータは重すぎてQGISでは読み込めないのと、TopoJSONに変換することで簡素化しても市町村の間に隙間ができないようにする。

ファイル容量と精度の兼ね合いで、0.50%まで簡素化し、geoJSON形式でエクスポートする。 (475 MB → 22.5 MB)

代替テキスト

3. ジオメトリのエラー修正

QGISでgeoJSONファイルを読み込み、メニューバーの「プロセシング」→「ツールボックス」→「ベクタジオメトリ」→「ジオメトリの修復」を実施。エラーが残っていると次のステップが落ちるのでこのタイミングで実行。

代替テキスト

4. ジオメトリの融合

一つの市町村が複数のFeatureから構成されており、propertiesの記載が重複して容量を食っているので、1つの市区町村ごとに1つのFeatureにまとめて容量を削減する。

圧縮前のデータ構造

{"type":"FeatureCollection", "features": [ ..., {"type":"Feature","geometry":null,"properties":{"N03_001":"北海道","N03_002":"渡島総合振興局","N03_003":null,"N03_004":"函館市","N03_005":null,"N03_007":"01202"}}, {"type":"Feature","geometry":null,"properties":{"N03_001":"北海道","N03_002":"渡島総合振興局","N03_003":null,"N03_004":"函館市","N03_005":null,"N03_007":"01202"}}, {"type":"Feature","geometry":null,"properties":{"N03_001":"北海道","N03_002":"渡島総合振興局","N03_003":null,"N03_004":"函館市","N03_005":null,"N03_007":"01202"}}, {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[140.84480981,43.2003834],...]]}, ... }

QGISのメニューバーの「ベクタ」→「空間演算ツール」→「融合 (dissolve)…」を実施。

代替テキスト

| 作成する地図 | 「基準とする属性」設定 | | ---- | ---- | | 市区町村境界データ | すべて | | 政令市の区をまとめたデータ | N03_001, N03_002, N03_003, N03_004 | | 都道府県境界 | N03_001 のみ |

市区町村境界データについては、22.5 MB → 4.5 MBまで圧縮できる。

5. 改行・スペースの削除

QGISがエクスポートするJSONは改行・スペースを含むので、これらを削除。JSON.parse()JSON.stringify() を連続で実行するのが早い。(4.5 MB → 3.7 MB)

6. gzip圧縮

.htaccessにてgzip圧縮の設定を行う。(3.7 MB → 1.0 MB)

SetOutputFilter DEFLATE BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary Header append Vary User-Agent env=!dont-vary

7. 微調整

市区町村ペイントマップでは、properties.N03_004が"所属未定地"であるようなFeatureは不要なので削除する。合わせて、必要に応じてpropertiesの形式を変更したり、Featuresの並び順を市町村コード順にしておく。

市区町村境界データのFeaturesは1898件になればよい。(市町村1718 + 北方領土6 + 東京特別区23 - 政令市20 + 政令市の区171)

delete data.name; delete data.crs; data.features = data.features.filter(feature=>feature.properties.N03_004 !== "所属未定地").map(({geometry, properties, type}) => ({ geometry, properties: { code: properties.N03_007, name: properties.N03_005 ?? properties.N03_004, fullname: properties.N03_005 ? properties.N03_004 + properties.N03_005 : properties.N03_003 ? properties.N03_001 + properties.N03_003 + properties.N03_004 : properties.N03_001 + properties.N03_004 }, type })).sort((a,b) => a.properties.code - b.properties.code);

7.1. 政令市の区をまとめたデータ

Featuresは1747件になればよい。(市町村1718 + 北方領土6 + 東京特別区23)

融合 (dissolve) の仕様上、政令市のpropertiesはいずれかの行政区のものが引き継がれているので、政令市自体の自治体コード (下一桁が0) に修正が必要。

delete data.name; delete data.crs; data.features = data.features.filter(feature=>feature.properties.N03_004 !== "所属未定地").map(feature => { if (feature.properties.N03_005) { feature.properties.N03_005 = null; feature.properties.N03_007 = feature.properties.N03_007.slice(0, 4) + "0"; } return feature; }).map(({geometry, properties, type}) => ({ geometry, properties: { code: properties.N03_007, name: properties.N03_005 ?? properties.N03_004, fullname: properties.N03_005 ? properties.N03_004 + properties.N03_005 : properties.N03_003 ? properties.N03_001 + properties.N03_003 + properties.N03_004 : properties.N03_001 + properties.N03_004 }, type })).sort((a,b) => a.properties.code - b.properties.code);

7.2. 都道府県境界のデータ

当然、Featuresは47件になればよい。市区町村の所属が未定のFeatureも、いずれかの都道府県に属するので、filterは不要。

delete data.name; delete data.crs; data.features = data.features.sort((a,b) => a.properties.N03_007 - b.properties.N03_007).map(({geometry, properties, type}) => ({ geometry, properties: { name: properties.N03_001 }, type }));

8. まとめ

GISファイルの容量削減手順をまとめた。

ただし、現状でも画面表示までに4〜5秒程度かかる場合があるので、サーバの速度等も含めて改善を検討したい。