📚

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

に公開

前回までのあらすじ

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

gdal raster pipeline / gdal vector pipeline

pipeline サブコマンドは、その名の通り複数の処理をパイプライン化できる機能です。つまり、ひとつのサブコマンドでは完結しないような複雑な処理を、一時ファイルに書き出すことなく一気に実行することができます。

使用例

まず、migration guide に載っていた pipeline の例を見てみましょう。

以下は、bbox に一部でも含まれている地物に絞り込んで、さらに EPSG:32631 に再投影する、という処理を ogr2ogr でやるときのコマンドラインです。

ogr2ogr -t_srs EPSG:32631 -spat 2 49 3 50 out.gpkg in.shp

つまり、これは本来、地物の絞り込み(filter)と投影変換(reproject)という二つの処理が関わっています。これを pipeline で書くと、こうなります。

gdal vector pipeline \
  read in.gpkg ! \
  filter --bbox=2,49,3,50 ! \
  reproject --dst-crs=EPSG:32631 ! \
  write out.gpkg

pipeline は、! で処理をつないでいくという書き方で、最初はデータの読み込み(read)、最後はデータの書き出し(write)になります。

読み込み ! 処理1 ! 処理2 ! ... ! 書き出し

文法

読み込み

最初のステップはかならずデータセットの読み込みです。読み込みのコマンドは2種類あります。

  • read
  • concat(ベクタデータのみ)

違いは、単純に、入力が1つか複数か、というだけです。引数は、入力データと、その読み取りのオプションを指定します。

* read [OPTIONS] <INPUT>
------------------------

Read a vector dataset.

Positional arguments:
  -i, --input <INPUT>                       Input vector datasets [required]

Options:
  -l, --layer, --input-layer <INPUT-LAYER>  Input layer name(s) [may be repeated]

Advanced Options:
  --if, --input-format <INPUT-FORMAT>       Input formats [may be repeated]
  --oo, --open-option <KEY=VALUE>           Open options [may be repeated]
* concat [OPTIONS] <INPUT>...
-----------------------------

Concatenate vector datasets.

Positional arguments:
  -i, --input <INPUT>                                        Input vector datasets [1.. values] [required]

Options:
  -l, --layer, --input-layer <INPUT-LAYER>                   Input layer name(s) [may be repeated]
  --mode <MODE>                                              Determine the strategy to create output layers from source layers . MODE=merge-per-layer-name|stack|single (default: merge-per-layer-name)
  --output-layer <OUTPUT-LAYER>                              Name of the output vector layer (single mode), or template to name the output vector layers (stack mode)
  --source-layer-field-name <SOURCE-LAYER-FIELD-NAME>        Name of the new field to add to contain identificoncation of the source layer, with value determined from 'source-layer-field-content'
  --source-layer-field-content <SOURCE-LAYER-FIELD-CONTENT>  A string, possibly using {AUTO_NAME}, {DS_NAME}, {DS_BASENAME}, {DS_INDEX}, {LAYER_NAME}, {LAYER_INDEX}
  --field-strategy <FIELD-STRATEGY>                          How to determine target fields from source fields. FIELD-STRATEGY=union|intersection (default: union)
  -s, --src-crs <SRC-CRS>                                    Source CRS
  -d, --dst-crs <DST-CRS>                                    Destination CRS

Advanced Options:
  --if, --input-format <INPUT-FORMAT>                        Input formats [may be repeated]
  --oo, --open-option <KEY=VALUE>                            Open options [may be repeated]

ちょっと気になるのは、gdal raster pipeline には concat がないという点です。前回 見たように、複数のラスタファイルを1つにまとめるには gdal raster mosaic を使っていましたが、それは pipeline では使えないみたいです。これが意図してこうなっているのか、なんらかの技術的制約があるからなのかはよくわかりませんでした。

書き出し

最後のステップはかならず write になります。出力先と、その書き込みオプションを指定します。

* write [OPTIONS] <OUTPUT>
--------------------------

Write a vector dataset.

Positional arguments:
  -o, --output <OUTPUT>                                Output vector dataset [required]

Options:
  -f, --of, --format, --output-format <OUTPUT-FORMAT>  Output format ("GDALG" allowed)
  --co, --creation-option <KEY>=<VALUE>                Creation option [may be repeated]
  --lco, --layer-creation-option <KEY>=<VALUE>         Layer creation option [may be repeated]
  --overwrite                                          Whether overwriting existing output is allowed
  --update                                             Whether to open existing dataset in update mode
  --overwrite-layer                                    Whether overwriting existing layer is allowed
  --append                                             Whether appending to existing layer is allowed
  -l, --output-layer <OUTPUT-LAYER>                    Output layer name

途中の処理

途中の処理には、gdal raster / gdal vector のサブコマンドがだいたい使えます。サブコマンド単体ではあまり使わないけど、pipeline のステップとしてはけっこう使いそうかな、というやつをいくつか挙げておきましょう。

edit

これはラスタデータ・ベクタデータともに使えます。指定できるものは違いますが、メタデータを編集したりするのに使うステップです。注意点として、--crs は、CRS を上書きするだけで投影変換は行いません。

ラスタ:

Options:
  --crs <CRS>               Override CRS (without reprojection)
  --bbox <BBOX>             Bounding box as xmin,ymin,xmax,ymax
  --nodata <NODATA>         Assign a specified nodata value to output bands ('none', numeric value, 'nan', 'inf', '-inf')
  --metadata <KEY>=<VALUE>  Add/update dataset metadata item [may be repeated]
  --unset-metadata <KEY>    Remove dataset metadata item [may be repeated]

ベクタ:

Options:
  --active-layer <ACTIVE-LAYER>    Set active layer (if not specified, all)
  --geometry-type <GEOMETRY-TYPE>  Layer geometry type
  --crs <CRS>                      Override CRS (without reprojection)
  --metadata <KEY>=<VALUE>         Add/update dataset metadata item [may be repeated]
  --unset-metadata <KEY>           Remove dataset metadata item [may be repeated]
  --layer-metadata <KEY>=<VALUE>   Add/update layer metadata item [may be repeated]
  --unset-layer-metadata <KEY>     Remove layer metadata item [may be repeated]

geom

ベクタデータのみの操作です。バッファをつくったり、簡素化したり、ジオメトリ関連の操作ができます。

* geom <COMMAND> [OPTIONS]
where <COMMAND> is one of:
  - buffer:              Compute a buffer around geometries of a vector dataset.
  - explode-collections: Explode geometries of type collection of a vector dataset.
  - make-valid:          Fix validity of geometries of a vector dataset.
  - segmentize:          Segmentize geometries of a vector dataset.
  - set-type:            Modify the geometry type of a vector dataset.
  - simplify:            Simplify geometries of a vector dataset.
  - swap-xy:             Swap X and Y coordinates of geometries of a vector dataset.

select

これはラスタデータ・ベクタデータともに使えますが、意味合いはちょっと異なります。ラスタデータの場合は、バンドの絞り込みや並べ替えができます。ベクタデータの場合は、地物の属性の絞り込みができます。地物のカラムは _ogr_geometry_ という名前で入ってくるみたいです。

前段の処理で使ったけどもういらなくなった属性を捨てたりするときとかに便利そうですね。

ラスタ:

* select [OPTIONS] <BAND>
-------------------------

Select a subset of bands from a raster dataset.

Positional arguments:
  -b, --band <BAND>       Band(s) (1-based index, 'mask' or 'mask:<band>') [1.. values] [required]

Options:
  --mask <MASK>           Mask band (1-based index, 'mask', 'mask:<band>' or 'none')

ベクタ:

* select [OPTIONS] <FIELDS>
---------------------------

Select a subset of fields from a vector dataset.

Positional arguments:
  --fields <FIELDS>              Fields to select (or exclude if --exclude) [may be repeated] [required]

Options:
  --active-layer <ACTIVE-LAYER>  Set active layer (if not specified, all)
  --exclude                      Exclude specified fields
                                 Mutually exclusive with --ignore-missing-fields
  --ignore-missing-fields        Ignore missing fields
                                 Mutually exclusive with --exclude

sql

ベクタデータのみの操作です。select は属性を絞る処理でしたが、SQL で属性を追加するのも絞り込むのも自由自在です。たぶん。

https://gdal.org/en/latest/programs/gdal_vector_sql.html

ラスタデータの場合は、サブコマンド的には calc が使えると便利そうですが、今のところそういうのはなさそうです。

最後に

これはちょっと、実際使ってみないと使い心地わからないな...という感じですね。冒頭の例で言うと ogr2ogr の方が短く書けているわけで、「たしかに pipeline の方が汎用性があって読みやすいけど、コマンドラインは短い方がよくない?」という結論になる可能性もあるかなと思います。

続きを書きました:

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

MIERUNEのZennブログ

Discussion