🦁

GDAL 3.11 で追加される gdal コマンドを触ってみる (4) Python API

に公開

前回までのあらすじ

https://zenn.dev/mierune/articles/5aebc5ef7a814e

https://zenn.dev/mierune/articles/61d7d4d05ab58d

https://zenn.dev/mierune/articles/7f9a9dedc03abb

Python API

これは、gdal コマンドと同じ処理を Python から呼び出せる、というものです。C/C++ API もあります。

https://gdal.org/en/latest/programs/gdal_cli_from_python.html#gdal-cli-from-python

使い方

シンプルに、gdal.Run() という関数に、gdal コマンドと同じパラメータを渡していく、という使い方です。例えば、コマンドラインだとこう書くのが、

gdal raster convert --of=COG --overwrite in.tif out.tif

Python API だとこうなります。サブコマンド(raster convert)をまず指定し、それに続けてパラメータを名前付き引数で指定する、という使い方です。

from osgeo import gdal

gdal.Run(
  "raster",
  "convert",
  input="in.tif",
  output="out.tif",
  output_format="COG",
  overwrite=True
)

サブコマンド部分は繋げて1つの文字列にしたり、リストにしたりしてもいいみたいです。

gdal.Run(
  "raster convert",
gdal.Run(
  ["raster", "convert"],

また、パラメータを dict で渡すこともできます。

params = {
  "input":"in.tif",
  "output":"out.tif",
  "output_format":"COG",
  "overwrite": True
}

gdal.Run("raster", "convert", params)

コマンドラインでは positional に指定できていたパラメータ(ここでは inputoutput)も必ず名前付きにする必要がある点に注意してください。たとえば、こんな感じに書くとエラーになってしまいます。

gdal.Run(
  "raster",
  "convert",
  "in.tif",
  "out.tif",
  output_format="COG",
  overwrite=True
)

そのコマンドにどのような引数があるかは、gdal.Algorithm(...).GetArgNames() で調べることができます。

>>> gdal.Algorithm("raster", "convert").GetArgNames()
['help', 'help-doc', 'version', 'json-usage', 'drivers', 'config', 'progress', 'output-format', 'open-option', 'input-format', 'input', 'output', 'creation-option', 'overwrite', 'append']

gdal.Run() の戻り値

Run() の戻り値は、osgeo.gdal.Algorithm というクラスのオブジェクトになっています。使い方がいまいちわからないのですが、とりあえず出力結果が JSON だったら .Output() を呼ぶと勝手にパースして dict に変換してくれるので便利に使えそうです。

>>> alg = gdal.Run("raster", "info", input="/downloads/byte.nc")
>>> pprint.pprint(alg.Output())
{'bands': [{'band': 1,
            'block': [20, 1],
            'colorInterpretation': 'Undefined',
            'metadata': {'': {'NETCDF_VARNAME': 'Band1',
                              '_Unsigned': 'true',
                              'grid_mapping': 'transverse_mercator',
                              'long_name': 'GDAL Band Number 1',
                              'valid_range': '{0,255}'}},
            'type': 'Byte'}],

あとは、出力先を MEM にして、 Numpy の Array として取り出して、みたいなこともできるみたいです。ちなみに、この raster reporject の場合は出力が複数あるので、.Output() じゃなくて .Outputs() にしないとエラーになります。使い分け難しい...。

with gdal.Run("raster", "reproject", input="byte.tif", output_format="MEM", dst_crs="EPSG:4326") as alg:
   print(alg.Outputs()["output"].ReadAsArray())

感想

まあとりあえず gdal コマンドのインターフェースが固まってからなのかなとは思うのですが、これが使えるようになると、シェルスクリプトと Python スクリプトで別々のを覚える必要がなくて楽になるのかなあ、と思ったりします。今後に期待...。

とりあえずこれで気になっていたところは書ききったので、このシリーズはこれで終わりにします。GDAL 3.11 で気になっている点は他にも ADBC とかいくつかあるので、そっちもまた調べてみようと思っています。

MIERUNEのZennブログ

Discussion