コンテンツにスキップ

FAQ/ 地形・粗度・盛土データをNetCDF形式でインポートしたい

テクニカルリファレンス 入出力機能/ 地形・粗度・盛土のインポート機能/ NetCDF形式 について、netCDFファイルを作成するツールや方法を教えてください。

回答

netCDFを作成する方法には、いくつかの方法があります。

  • テキストファイルから ncgen.exe というツールを使って netCDF形式に変換する方法
  • QGISなどのGISソフトを使って、メッシュデータをASC形式でエクスポートし、PowerShellなどのプログラミング言語を使って netCDF形式を作成する方法

ここでは、1番目の方法について説明します。 2番目の方法については、こちらをご参照ください。

  1. netCDFライブラリをインストールします。
    NetCDF の公式サイトの Installing and Using netCDF-C Libraries in Windows から netCDF4 64-bit版を取得します。
    2021年10月現在の最新バージョンは、netCDF4.8.0-NC4-64.exe です。
    以降の説明では、このバージョン4.8.0をインストールしたものとして説明します。
    既定では C:\Program Files\netCDF 4.8.0\ に netCDFライブラリがインストールされます。

  2. データを作成します。
    サンプルデータを示します。これは、CDL形式と呼ばれる形式です。なお、CDLの文法は、NetCDF User's Guide - CDL Syntax に定められています。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    netcdf test {
    dimensions:
        lon = 9;
        lat = 15;
    variables:
        short lon(lon);
            lon:add_offset = 140.00015625;
            lon:scale_factor = 0.0003125;
            lon:units = "degrees_east";
        short lat(lat);
            lat:add_offset = 36.000104166666666666666666666667;
            lat:scale_factor = 0.000208333333333333333333333333;
            lat:units = "degrees_north";
        int glev(lat, lon);
            glev:valid_min = -100000;
            glev:valid_max = 1000000;
            glev:scale_factor = 0.01;
            glev:units = "m";
        short roughness(lat, lon);
            roughness:scale_factor = 0.001;
            roughness:units = "m\^(-1/3).s";
        int leveeHeight(lat, lon);
            leveeHeight:valid_min = -100000;
            leveeHeight:valid_max = 1000000;
            leveeHeight:scale_factor = 0.01;
            leveeHeight:units = "m";
        byte leveeFlag(lat, lon);
            leveeFlag:flag_meanings = "east north";
            leveeFlag:flag_masks = 1b, 2b;
    data:
        lon = 0, 1, 2, 3, 4, 5, 6, 7, 8;
        lat = 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
        glev = 100, 100, 100, 100, 100, 100, 100, 100, 100,
            100, 109, 116, 121, 122, 121, 116, 109, 100,
            100, 117, 131, 140, 143, 140, 131, 117, 100,
            100, 124, 144, 158, 162, 158, 144, 124, 100,
            100, 130, 155, 172, 178, 172, 155, 130, 100,
            100, 135, 164, 183, 190, 183, 164, 135, 100,
            100, 137, 169, 190, 198, 190, 169, 137, 100,
            100, 138, 171, 192, 200, 192, 171, 138, 100,
            100, 137, 169, 190, 198, 190, 169, 137, 100,
            100, 135, 164, 183, 190, 183, 164, 135, 100,
            100, 130, 155, 172, 178, 172, 155, 130, 100,
            100, 124, 144, 158, 162, 158, 144, 124, 100,
            100, 117, 131, 140, 143, 140, 131, 117, 100,
            100, 109, 116, 121, 122, 121, 116, 109, 100,
            100, 100, 100, 100, 100, 100, 100, 100, 100;
       roughness = 30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30;
        leveeHeight = 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            300, 300, 300, 300, 300, 0, 0, 0, 0,
            0, 0, 0, 0, 300, 0, 0, 0, 0,
            0, 0, 0, 0, 300, 0, 0, 0, 0,
            0, 0, 0, 0, 300, 0, 0, 0, 0,
            0, 0, 0, 0, 300, 0, 0, 0, 0;
        leveeFlag = 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0,
            2, 2, 2, 2, 3, 0, 0, 0, 0,
            0, 0, 0, 0, 1, 0, 0, 0, 0,
            0, 0, 0, 0, 1, 0, 0, 0, 0,
            0, 0, 0, 0, 1, 0, 0, 0, 0,
            0, 0, 0, 0, 1, 0, 0, 0, 0;
    }
    
    • ここでは、左下の緯度経度が (36.0 deg, 140.0 deg) で、横が 9セル、縦が15セル、緯度経度座標でメッシュサイズが 25 m のデータを作る例を示します。
    • データは横が 9セル、縦が15セルです。これらの値を lon および lat に与えます(3~4行目)。
    • 緯度経度座標のメッシュサイズ25 mは、経度方向の解像度が 1/3200 = 0.0003125 deg、緯度方向の解像度が 1/4800 = 0.000208333333333333333333333333 deg に相当します。これらの値を それぞれ lon:scale_factor および lat:scale_factor に与えます(8行目および12行目)。(参考: メッシュサイズと緯度経度方向の解像度の関係
    • 左下経度 140.0 に、経度の解像度に 1/2 かけた値を加え、lon:add_offset に与えます(7行目)。また、左下緯度 36.0 に、緯度の解像度に 1/2 かけた値を加え、lat:add_offset に与えます(11行目)。なお、このように1/2セルだけ右上にずらす処理をするのは、netCDFではセルの中心の値を与えるためです。
    • 31行目は、0から始まり、横のセル数 - 1 で終わる、1ずつ増える数列を与えます。
    • 32行目は、縦のセル数 - 1 から始まり、0で終わる、1ずつ減る数列を与えます。
    • 33行目~は、標高データ(m)を100倍した値を glev に格納します。左上、右上、左下、右下の順で、カンマ(,)区切りで与えます。横9セル、縦15セルありますので、ここに135セル分の値が並びます。カンマのあとの改行はなくてもかまいません。最後の値の後にセミコロン(;)を書きます。なお、標高データを100倍する理由は、ここに格納する値は glev:scale_factor の逆数倍にする必要があるためです。
    • 48行目~は、粗度データを1000倍した値を roughness に格納します。
    • 63行目~は、堤防天端(m)を100倍した値を leveeHeight に格納します。
    • 78行目~は、堤防フラグを leveeFlag に格納します。盛土を作らない場合は 0、セルの東側に盛土を作る場合は1、北側に作る場合は2、東および北側に作る場合は3を与えます。なお、leveeFlag:flag_masks には、数字の最後に b があります。これは byte (符号付き8ビット整数)を意味します。

      図: leveeFlag と盛土の位置関係
    • 作成したデータを ファイル名 sample.cdl.txt でデスクトップに保存します。
  3. netCDFライブラリに付属のツール ncgen.exe を使って変換します。
    既定では、C:\Program Files\netCDF 4.8.0\bin\ncgen.exe に格納されています。
    コマンドプロンプト cmd.exe から、次のコマンドを呼び出します。

    1
    2
    cd %USERPROFILE%\Desktop
    "C:\Program Files\netCDF 4.8.0\bin\ncgen.exe" -b -k 4 sample.cdl.txt
    

    デスクトップに sample.cdl.nc が作成されます。

  4. 作成した netCDF をDioVISTA に取り込みます。

    1. DioVISTAを立ち上げます。
    2. メニュー > [ファイル] > [テンプレートから新規作成] > [緯度経度座標] を選択します。

    3. プロジェクト > [計算領域] > [NetCDFからインポート] を選択します。

    4. 出現したダイアログのファイル名に、 sample.cdl.nc を指定します。
      メッシュサイズに 25 m を指定します。

    5. DioVISTAにデータが取り込まれました。

最終更新日: 2024-03-29