風場視覺化:風場資料

XXHolic發表於2022-02-21

引子

瞭解 WebGL 基礎之後,接著去看獲取解析風場資料的邏輯,又遇到問題。

安裝 ecCodes

在文章示例源庫的說明中,首先要安裝 ecCodes ,嘗試使用 HomeBrew 但不行。於是就按照 ecCodes 源庫的介紹本地進行編譯安裝。

在進行第 4 步的時候,碰到了問題:

No CMAKE_Fortran_COMPILER could be found.

查詢資料說是缺少 gfortran ,可以使用命令檢視是否已安裝:

which gfortran

有好幾種安裝方式,我選擇下載安裝包

解決這個問題後按照指導繼續,編譯安裝成功,版本是 2.23.0 。

執行指令碼

執行指令碼的時候,出現了錯誤提示:

grib_set: command not found grib_dump: command not found

但在前面安裝的資料夾的 bin 目錄下是找到了 grib_set 的執行檔案。推斷是沒有註冊到全域性路徑中。

檢視 ecCodes 安裝路徑是否註冊到全域性路徑中:

echo $PATH

這裡碰到的問題是沒有註冊到全域性路徑中,設定方式可參考這裡

修改示例:

vim ./.bash_profile

進入到編輯模式後,新增下面的內容:

export ECCODE_HOME=/xx/xx/xx/xx/eccodesbuild/bin
export PATH=$PATH:$ECCODE_HOME

儲存後,使其生效

source ./.bash_profile

想知道是否生效了,試試指令 grib_set -h ,如果發現沒有效果,有可能跟使用的 shell 端有關,可參看這裡

資料生成

指令碼可以正常執行了,但生成的資料不對:

undefined:1

{"u":,"v":}

檢視源庫的 issues ,裡面也有人提這個問題,試了裡面的一些方法,發現這個 pull 的修改可以正常的執行。於是就 fork 了一下把這個修改的內容弄過來了,改了些資料,見 XXHolic/webgl-wind

資料含義

download.sh 指令碼中,獲取資料解析後,生成可讀檔案 tmp.json ,來看看這個檔案中主要結構和部分資料:

{
  "u":{
    "messages" : [
      [
        {
          "key" : "name",
          "value" : "U component of wind"
        },
        {
          "key" : "Ni",
          "value" : 360
        },
        {
          "key" : "Nj",
          "value" : 181
        },
        {
          "key" : "values",
          "value" : [5.51964, 5.71964, ...]
        },
        {
          "key" : "maximum",
          "value" : 103.02
        },
        {
          "key" : "minimum",
          "value" : -36.0804
        }
      ]
    ]
  },
  "v":{
    "messages" : [
      [
        {
          "key" : "name",
          "value" : "V component of wind"
        },
        {
          "key" : "getNumberOfValues",
          "value" : 65160
        },
        {
          "key" : "values",
          "value" : [14.9446, 14.8446, ...]
        },
        {
          "key" : "maximum",
          "value" : 80.3446
        },
        {
          "key" : "minimum",
          "value" : -66.4554
        }
      ]
    ]
  }
}

看到這些可能會有些疑惑,大氣中的氣流既有速度也有方向,在數學上可以用一個向量表示。在氣象學中,如果知道風的方向和大小,就可以得到表示風的向量,u 分量和 v 分量:

// ws 風力大小 θ 風在數學上的方向描述
u = ws * cos(θ)
v = ws * sin(θ)

97-1

更加詳細的介紹見 Wind: u and v Components

接著在 prepare.js 中使用到風資料中的 key 有:

  • Ni 表示在一條緯線上有多少個點,簡單的說就是有多少列。
  • Nj 表示在一條經線上有多少個點,簡單的說就是有多少行。
  • values 存放分量所有的值。
  • minimum 表示分量的最小值。
  • maximum 表示分量的最大值。

其中 NiNj 決定了生成圖片的寬和高,風速大小對映對應顏色主要邏輯如下:

for (let y = 0; y < height; y++) {
  for (let x = 0; x < width; x++) {
    const i = (y * width + x) * 4;
    const k = y * width + ((x + width / 2) % width);
    png.data[i + 0] = Math.floor(
      (255 * (u.values[k] - u.minimum)) / (u.maximum - u.minimum)
    );
    png.data[i + 1] = Math.floor(
      (255 * (v.values[k] - v.minimum)) / (v.maximum - v.minimum)
    );
    png.data[i + 2] = 0;
    png.data[i + 3] = 255;
  }
}
  • i : 使用了 pngjs 外掛,顏色使用 RGBA 模式,陣列中每連續的 4 個位置儲存的是一個點的顏色值,所以 i 變數要是 4 的倍數。
  • k : 用於獲取風速大小的索引,先看看 y=0 時,k 的取值變化先從 180 -> 359 遞增,然後從 0 -> 179 遞增,這樣從中間開始取值,猜測是由於這個展示地圖是二維的世界地圖,返回的資料就是這樣的對應規則。
  • 對映方式: 以 maximum - minimum 作為基準,然後計算風速大小相對值 values[k] - minimum ,兩個值的比例乘以顏色分量最大值 255 。

參考資料

相關文章