多次元ラスターデータモデル

このドキュメントは,GDAL 3.1 で追加された GDAL の多次元データモデルについて説明します. GDAL の多次元データセットが含むことができる情報の種類とその意味についてです.

多次元ラスター API は,3D、4D またはそれ以上の次元のデータセットを扱うための従来の ラスターデータモデル の一般化です. 現在, 基本的な読み書き API に限定されており,他の高レベルのユーティリティにはあまり接続されていません.

これは、netCDF および HDF5 API およびデータモデルから強くインスパイアされています. HDF5 フォーマットとデータモデル を参照してください.

多次元コンテンツを持つ GDALDataset には,ルート GDALGroup が含まれています.

グループ

GDALGroup ( HDF5 Group をモデル化) は,GDALAttribute, GDALMDArray または他の GDALGroup の名前付きコンテナです. そのため、GDALGroup はオブジェクトの階層を記述できます.

属性

GDALAttribute ( HDF5 Attribute をモデル化) は,名前と値を持ち、通常はメタデータ項目を記述するために使用されます. 値は (HDF5 フォーマットの場合) 一般的な場合には "any" 型の多次元配列であることがあります(ほとんどの場合,これは文字列または数値型の単一の値になります)

多次元配列

GDALMDArray ( HDF5 Dataset をモデル化) は,名前,多次元配列,GDALDimension の参照,GDALAttribute のリストを持ちます.

ほとんどのドライバは、次元に対して行優先の規則を使用します: つまり,配列要素が連続してメモリに格納されていると考えると,最初の次元は最も変化が遅いものであり(2D 画像の場合,行), 最後の次元は最も変化が速いものである(2D 画像の場合,列)です. その規則は、NumPy 配列、MEM ドライバ,HDF5 および netCDF API でデフォルトの規則として使用されます. GDAL API は,その規則についてはほとんど無関心ですが, GDALAbstractMDArray::Read() および GDALAbstractMDArray::Write() メソッドの stride パラメータに NULL 配列を渡す場合を除いてです. NumPy の多次元配列のインデックス順序の問題に関するドキュメント を参照してください.

GDALMDArray にはオプションのプロパティもあります:

  • 空間参照系: OGRSpatialReference

  • データ無しの値:

  • 単位

  • オフセット, unscaled_value = offset + scale * raw_value

  • 縮尺, unscaled_value = offset + scale * raw_value

配列に対して多くの操作を適用して,それを変更されたビューにすることができます: GDALMDArray::Transpose(), GDALMDArray::GetView(), など

GDALMDArray::Cache() メソッドを使用して,ビュー配列の値をサイドカーファイルにキャッシュすることができます.

次元

GDALDimension は,多次元配列をインデックスするために使用される次元/軸を記述します. 以下のプロパティを持ちます:

  • 名前

  • サイズ, つまり次元に沿ってインデックスできる値の数

  • タイプ, 次元の性質を示す文字列です. 事前定義された値は: HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC 他の値も使用できます. 空の値は不明を意味します.

  • 方向. 事前定義された値は: EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST 他の値も使用できます. 空の値は不明を意味します.

  • GDALMDArray 変数への参照, 通常は次元が取る値を記述する 1 次元のものです. ジオリファレンス付きの GDALMDArray とその X 次元の場合,これは通常,各グリッドポイントの東経/経度の値になります.

データタイプ

GDALExtendedDataType ( HDF5 datatype をモデル化) は,GDALAttribute または GDALMDArray の個々の値が取るタイプを記述します. そのクラスは NUMERIC, STRING, COMPOUND です. NUMERIC の場合,既存の GDALDataType 列挙値がサポートされます. COMPOUND の場合,データタイプはメンバーのリストであり,各メンバーは名前,複合構造内のバイトオフセット,および GDALExtendedDataType で記述されます.

注釈

HDF5 モデリングでは,より複雑なデータタイプが可能です.

注釈

HDF5 には複素値のためのネイティブデータ型がない一方, GDALDataType にはあります.そのため,ドライバは,複素値を表す HDF5 複合データ型から GDT_Cxxxx データ型を公開することを決定するかもしれません.

オブジェクトライフタイム

多次元 API のドライバ実装は, GDALGroup, GDALMDArray, GDALAttribute, GDALDimension のインスタンスが,それらが取得されたオブジェクトとは独立して使用できるようになっています. つまり:

  • GDALDataset::GetRootGroup() で返された GDALGroup インスタンスは,データセットが閉じられた後でも使用できます.

  • GDALGroup::OpenGroup() から取得したサブグループや, GDALGroup::OpenMDArray() から取得した配列は,所有しているグループが解放された後でも使用できます.

  • 同様に,グループや配列から取得した属性や次元についても同様です.

したがって,次のようなことは完全に合法です:

#include "gdal_priv.h"

std::shared_ptr<GDALMDArray> GetArray()
{
    auto poDataset = std::unique_ptr<GDALDataset>(
        GDALDataset::Open( "in.nc", GDAL_OF_MULTIDIM_RASTER ));
    if( !poDataset )
    {
        return nullptr:
    }
    auto poRootGroup = poDataset->GetRootGroup();
    if( !poRootGroup )
    {
        return nullptr:
    }
    auto poVar = poRootGroup->OpenMDArray("temperature");
    if( !poVar )
    {
        return nullptr:
    }
    return poVar;
}

int main()
{
    GDALAllRegister();
    auto poVar = GetArray();
    if( !poVar )
    {
        exit(1);
    }

    // Do something with poVar

    return 0;
}

注意すべきポイントは,データセットを作成/編集する際に,これらのオブジェクトがすべて基になるファイルディスクリプタを保持しているため,データセットに関連するすべてのオブジェクトが解放されたときにのみ,変更がシリアライズされることが保証されるということです.

C++言語での例

int main()
{
    GDALAllRegister();

    auto poDataset = std::unique_ptr<GDALDataset>(
        GetGDALDriverManager()->GetDriverByName("netCDF")->
            CreateMultiDimensional( "new.nc", nullptr, nullptr ));
    auto poRootGroup = poDataset->GetRootGroup();

    // Could be closed a bit later too
    poDataset.reset();

    auto poDim = poRootGroup->CreateDimension(
        "my_dim", std::string(), std::string(), 10);
    auto poArray = poRootGroup->CreateMDArray(
        "my_var", {poDim}, GDALExtendedDataType::Create(GDT_Byte), nullptr);

    // Can be closed in any order
    poArray.reset();
    poDim.reset();
    poRootGroup.reset();

    // new.nc is fully valid just now

    return 0;
}

Python言語での例

from osgeo import gdal

with gdal.GetDriverByName("netCDF").CreateMultiDimensional("new.nc") as ds:
    rg = ds.GetRootGroup()
    dim = rg.CreateDimension("my_dim", "", "", 10)
    array = rg.CreateMDArray("my_var", [dim], gdal.ExtendedDataType.Create(gdal.GDT_Byte))

    del array
    del dim
    del rg

# new.nc is fully valid just now

GDAL 2D ラスターデータモデルとの違い

  • GDALRasterBand の概念は,もはや多次元には使用されません. これは異なる GDALMDArray としてモデル化するか,複合データ型を使用することができます.

  • 多次元 API には,まだ標準化された概念の多解像度配列/概要がありません

GDAL 2D クラシックラスターデータモデルと多次元データモデルの間のブリッジ

GDALRasterBand::AsMDArray()GDALMDArray::AsClassicDataset() は,それぞれラスターバンドを MD 配列に変換したり,2D データセットを MD 配列に変換したりするために使用できます.

アプリケーション

次のアプリケーションを使用して,多次元データセットを調査および操作できます: