みなさんこんにちわ!
みなさんは突然「あーーーー地表面の形状を可視化してぇなーーーーー」と思うことはありますか?
僕はあります。
(4年ぶり2度目)
以前こんな記事を公開しました!
これはQGISで国土地理院のDEM(数値標高モデル)XMLファイルを読み込むQGISプラグインを作った記事なんですが、おかげさまでとてもたくさんの方に利用してもらっています。
(現在、僕は関わっていないんですが…)
この中で利用している内部モジュールでconvert_fgd_dem
というライブラリも自作しています。
なんですが!結構処理が非効率だったり、そもそもPythonで書かれていて遅かったりします。
もう4年も経ったし、最近はRustも書いてるしAIも発展しているしで色々状況は変わったので「ちょっとリファクタするかー」と思ったのでガッと作り直してしまいました!
今回はQGISプラグイン化していないんですが、PyO3とmaturinでPythonバインディングも作ってるので、いつかQGISプラグインにも移植しようと思います!
使い方
インストール
今回作ったのはこちらのライブラリです。
crates.ioに公開しているので、Cargoでサクッとインストールできます。
Rustがインストールされていない場合は以下を参考にしてコマンドを1つ実行するだけでインストールできるようになります。
基本的な使い方
利用方法はとても簡単です。
# 単一XMLファイルの変換
japan-dem input.xml -o output_dir
# ディレクトリ一括変換(複数DEM結合しない)
japan-dem input_dir/ -o output_dir
# ZIPファイルを処理(複数DEM結合)
japan-dem input.zip -o output_dir --merge
# Terrain-RGB形式で出力
japan-dem input.xml -o output_dir --terrain-rgb
# 並列処理のスレッド数を明示的に指定
japan-dem input_dir/ -o output_dir --threads 8
QGISなどで読み込ませるとこんな感じでよく見るDEMが表示されます。
QuickDEM4JPプラグインと比較すると20倍超の速度が出ていたので、大規模に変換したい場合はこちらのツールで変換されると良いのではないでしょうか!
ちなみにTerrain-RGBも綺麗に変換できていそうです!
Pythonバインディングの実装
せっかくRustで高速なパーサーを作ったので、Pythonからも使えるようにしたくなりました。
現代ではPyO3を利用してこんな感じで簡単にバインディングを作れます。
(作成したRustの関数などをPythonで呼び出すための特殊な記法で修飾してあげるだけ)
(ちなみに、こんな感じで公開していますが、CIが微妙に上手くいってなくて最新版がアップロードされていないかもしれません。)
Pythonでの使い方
import japan_dem
# XMLファイルを解析
dem_tile = japan_dem.parse_dem_xml("input.xml")
print(f"Mesh code: {dem_tile.metadata.mesh_code}")
print(f"Size: {dem_tile.rows}x{dem_tile.cols}")
# Terrain-RGB GeoTIFFとして出力
japan_dem.dem_to_terrain_rgb(dem_tile, "output.tif")
終わりに
今回はRustで高速なDEM(XML)パーサーを作ってみました!
また、Pythonバインディングも提供することで、既存のGISワークフローにも簡単に組み込めるようになりそうです!
オープンソースで公開しているので、ぜひ皆さんも使ってみてください!
バグ報告や機能要望もお待ちしています。
Views: 0