0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowershellとWSL2(Ubuntu)を使って2024年度版地図XMLをGeoJSONにする

Last updated at Posted at 2024-05-25

はじめに

動機

2024年4月15日に公開された令和6年度の地図XMLをベクトルタイルにしたいと考えています。タイル作成にあたってGeoJSON形式からベクトルタイル(PMTiles形式)への変換は前の記事でまとめたのですが、その時はG空間情報センターから出ている変換済みのGeoJSONファイルを使いました。2024年度地図XMLはまだGeoJSONになっていません。一方で、デジタル庁がコンバーターを公開しているので、自分で地図XMLをGeoJSONに変換してみたので、メモしておきます。

環境

  • Windows 11 home
  • WondowsPowerShell version 5.1 (Build 22621, Revision 2506)
  • WSL Ubuntu version 2
    • tippecanoe v2.53.0
    • GDAL 3.4.1, released 2021/12/27
    • Python 3.10.12, pip 22.0.2
    • デジタル庁のコンバータをインストール済み

手順

Step 1: データのダウンロード

2024年度の地図XMLファイルをダウンロードします。WindowsPowerShellのコマンドでダウンロードできます。ダウンロードに少しかかりますが2010ファイルをダウンロードしました。

$jsonData = (curl.exe 'https://www.geospatial.jp/ckan/api/3/action/resource_search?query=name:-2024.zip&limit=2100' | ConvertFrom-JSON)

for ($i=0; $i -lt $jsonData.result.results.name.length ; $i++ ){
  curl.exe -LO $jsonData.result.results.URL[$i]
}

image.png

Step 2: 投影法リストの作成

地図XMLの半分は任意座標系で座標変換ができないので、公共座標系のファイルだけを対象にする必要があります。そのためにはまず各ファイルの座標が何かをリストする必要があります。以前の記事に詳しく書きましたが、以下のような感じで各ファイルの投影法一覧を作成します。こちらもWindowsPowerShellのコマンドで実行します。

# 作業フォルダの準備
#rm unpack
#rm list
mkdir unpack
mkdir list

# 出力ファイル名を定義
$resultTXT = "projection-list.txt"
$fileSize = "xml-file-size.txt"

# 出力ファイルを初期化
if(Test-Path $resultTXT){
  rm $resultTXT
}
if(Test-Path $fileSize){
  rm $fileSize
}


# XMLの市区町村パッケージ(ZIP)リストの取得
$zipList = Get-Childitem -Path . -filter *.zip

##################
# 各市区町村ごとのループ開始
foreach($zippedPack in $zipList){

  # 市区町村のパッケージfileをunpackフォルダに解凍
  Expand-Archive $zippedPack -DestinationPath unpack
  # unpackフォルダ中のZIPファイルをリスト
  $testList = Get-Childitem -Path unpack -filter *.zip
  # unpackフォルダ内のzipファイルを解凍
  foreach($item in $testList){
    Expand-Archive unpack/$item -DestinationPath unpack 
    Write-host($item)
  }

  # 解凍したlistを移動
  Move-Item unpack/*.csv -Destination list

  # unpackフォルダ内のzipファイルを削除
  rm unpack/*.zip

  # unpack フォルダ内のxmlファイルの座標系を検索。ファイル一覧も記録。
 
  if ($zahyo) {
    remove-variable zahyo
  }
  $zahyo = Select-String "座標系" unpack/*.xml
  Write-Output $zahyo | Add-Content $resultTXT
  #Get-Item unpack/* | Add-Content $fileSize #ファイル名しか記録されない
  Get-Item unpack/* >> $fileSize #ファイルサイズも残る

  # unpackフォルダをクリーン
  rm unpack/*
}

一日くらいかかりますが、以下のファイルができます。
image.png

7行目が投影法法なのですが、それ以外で拾われている行(今回は以下の3つ)は要削除です。
image.png

テキストファイルとして置換などをしながら、csvファイルで処理できるように加工します。
image.png

最終的にエクセルなどで処理して、公共座標系を持つファイル一覧を抜き出して作成します。全部で316,300ファイル中、137,011ファイルが公共座標系でした。
image.png

Step 3: 投影法リストを参照しながら公共座標のものを変換

今、ローカルディスクにはダウンロードしてきた2010のZIPがあるchizu-xml2024というフォルダがありますが、ここにgeojson2024というフォルダを準備します。
image.png

geojson2024に、前のステップで作った公共座標一覧をコピーして、作業用のフォルダunpackを作ります。
image.png

ここからはWSLを使います。chizu-xmlとgeojson2024のフォルダがおいておる場所にいって、以下のコマンドを実行します。デジタル庁の地図XML変換コンバーターも事前にインストールしておきます。

<スクリプトの説明>

  • 市区町村-法務局のパッケージ全部をforループで処理します。
  • 市区町村のものをgeojson2024のunpackに解凍し、個別ファイルのZIP版がそこにできます。
  • とりあえず個別ファイルのZIP版をXMLに解凍します。
  • 解凍した各XML(ZIP)について、すでに作成した公共座標一覧(geojson2024/kokyo-list.txt)の中に名前があるか探します(grep)。もしあれば($?がゼロ)デジタル庁コンバータmojxml2geojsonを使います。
  • unpackの中にgeojsonができますが、作業の過程でできたZIPファイル、XMLファイル、リストCSVは不要なので削除します。
##各市区町村-法務局ファイルに対して行うforループ
for f in chizu-xml2024/*-2024.zip; 
#for f in chizu-xml2024/4738*-2024.zip; #練習用(1つのところで)

  do echo ${f}; unzip ${f} -d geojson2024/unpack; #まずは市区町村のパッケージを解凍(2度圧縮のうち最初)

  #そのあとに、個別ファイルがgeojson2024/unpackにあるので解凍(2度圧縮のうち最初)
  for g in geojson2024/unpack/*zip; do unzip ${g} -d geojson2024/unpack ; done

  #解凍したところに移動
  cd geojson2024/unpack 

  #それぞれのZIPについて公共座標リストにあった場合には変換(grepと$?を利用)
  for g in *zip; do cat ../../geojson2024/kokyo-list.txt| grep `basename ${g} .zip`.xml ;
    #echo $?; 
    if [ $? = 0 ]; then 
      #echo $? 
      mojxml2geojson `basename ${g} .zip`.xml
    fi;
  done
  rm *.zip
  rm *.xml
  rm *.csv
  cd ..
  cd ..
done

ファイル解凍の時にエラーが出て警告がでているのですが、解凍自体はできているのでよしとします。
image.png

作業中のフォルダはこんな感じです。見ているとXMLよりGeoJSONのほうがずいぶん軽いです。
image.png

後日追記:
以下のほうが無駄な解凍がないので早いと思います。

##各市区町村-法務局ファイルに対して行うforループ
for f in chizu-xml2024/*-2024.zip;
#for f in chizu-xml2024/4738*-2024.zip; #練習用(1つのところで)

  do echo ${f}; unzip ${f} -d geojson2024/unpack; #まずは市区町村のパッケージを解凍(2度圧縮のうち最初)

  #それぞれのZIPについて公共座標リストにあった場合には解凍して変換(grepと$?を利用)
  for g in geojson2024/unpack/*zip; do cat geojson2024/kokyo-list2.txt| grep `basename ${g} .zip`.xml ;
    if [ $? = 0 ]; then 
      unzip ${g} -d geojson2024/unpack
      mojxml2geojson geojson2024/unpack/`basename ${g} .zip`.xml
    fi;
  done
  rm geojson2024/unpack/*.zip
  rm geojson2024/unpack/*.xml
  rm geojson2024/unpack/*.csv

done

追記(変換終了と市区町村ごとのマージ)

Windowsが再起動してしまったりいろいろと途中で止まってしまったことがあったのですが、12日くらいかけてファイルの変換が終了しました。ファイル数は以下の内訳ですが、公共座標のXMLと同じ137,011ファイルでした。

  • 0で始まるファイル: 29,147
  • 1で始まるファイル: 21,144
  • 2で始まるファイル: 26,651
  • 3で始まるファイル: 32,886
  • 4で始まるファイル: 27,183

ファイル数が多いので、0で始まるファイル、1で始まるファイル、2で始まるファイル、3で始まるファイル、4で始まるファイルに分けました。
image.png

マージについてはnpmモジュールのgeojson-mergeを当初試みた(以下図のコマンド)のですが、途中で止まってしまってうまくできませんでした。
image.png

最終的にgdalを使ってGeoJSONseqにしてしまい、それを市町村ごとにファイルに書き込んでいくという方策をとることにしました。GeoJSONseqをそのままtippecanoeに入れたかったのですが、tippecanoe属性調整のためのfileterを作る時間がなかったのでGeoJSONseqを中間ファイルとして準備しておきます。

for f in */*.geojson; do ogr2ogr -f GeoJSONseq -lco RS=YES /vsistdout/ ${f} >>
merge/`basename ${f:3:5}`-2024.geojsons; done #basenameの次の3:5は各自のフォルダ構成により適宜修正

→こんな感じでできてきます。1,925ファイルできました。
image.png

途中、地図番号のところで変換がうまくいかない可能性があるという警告が出ているファイルがいくつかありました。地図番号は気にしませんが、入っているデータの文字コードなどの関係でしょうか。
image.png

追伸:ベクトルタイル化

GeoJSONseqファイルができたので、あとはベクトルタイルにします。まずは市区町村それぞれのGeoJSONseqをmbtiles形式にします。WSLで行います。

for f in merge/*.geojsons; do tippecanoe -o pmtiles/`basename ${f} .geojsons`.mbtiles --no-feature-limit --no-tile-size-limit -Z14 -z16 -L fude:${f}; done

20時間くらいで市区町村ごとにまとめられました。次は、都道府県ごとにpmtilesにします。当該フォルダに移動して、以下のコマンドを実行しました。

for i in $(seq -w 1 47); do fileList=$(ls ${i}*-2024.mbtiles); echo $i;tile-join -f --
no-tile-size-limit -o c-${i}.pmtiles $fileList; done

最後に、都道府県ごとのpmtilesをまとめます。

fileList=$(ls *.pmtiles)
tile-join -f --no-tile-size-limit -o c.pmtiles $fileList

できましたが、サイズが少し大きすぎました。
image.png

以下のコマンドで不要な属性を削ると少しサイズが小さくなりました。

 tile-join -x version -x 測地系判別 -x 地図名 -x 代表点緯度 -x 代表点経度 --no-tile-size-limit -f -o c2.pmtiles c.pmtiles

まとめ

やり方をいろいろと考えたのですが、地図XMLのうち公共座標のファイルだけをGeoJSONに変換する方法を考えました。Windows環境だけでできるので私のパソコンだけでも大丈夫です。

GeoJSONを市区町村ごとにまとめて、そのあとにPMtilesに変換し、全国マージして2024年度版のベクトルタイル(PMTiles)になりました。

感謝

デジタル庁のコンバータ、ありがとうございます。法務省、G空間情報センターの登記所備付データ公開に感謝します。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?