Leafletでラスターデータに色調をつけて表示する方法

1. はじめに

今まで記事ではラスターデータの白黒表示しか取り扱ってきませんでしたが、この記事ではラスターデータに色調を付与して表示する方法を解説していきたいと思います。使用するデータは前回の記事と同じく気象庁速報版解析雨量GPVをGeoTIFFフォーマットに変換したものです。

 

2. ラスターデータに色調を付与する方法

ラスターデータに色調を付与する方法は色々あると思いますが、ここではLeafletのウェブサイトで示されているサンプルコードにならいChroma.jsというJavascriptのライブラリーを使用することにします。Chroma.jsというライブラリーを用いて、ラスターデータの個々のピクセルごとの値に対して色調を与える関数を定義してやります。

 

3. ソースコードの解説

この記事で取り上げたサンプルでもJavascritpライブラリーのLeafletを使っています。Leafletの基本的な導入方法については過去の記事で解説しています。

4行目から7行目までがLeafletを導入するためのリファレンスリンクです。

20行目は、Leafletで設定した背景地図や今回のラスターデータを表示するためのdiv要素です。

24行目から27行目でLeafletで表示する地図の領域の設定をしています。

29行目から32行目で背景地図のデータを指定しています。

ここまでは前回までの記事とほぼ同じです。

34行目から69行目までがGeoTIFFファイルのカラー表示する部分となります。

34行目で表示するGeoTIFFファイルを指定しています。

39行目から41行目でGeoTIFFファイルの各ピクセルの値の最大値、最小値、そして値の幅を取得しています。これらは、50行目で指定する値を色調に変換するときの定義関数(pixelValueToColorFn)で利用しています。この関数はユーザーが独自に指定できるものなので、pixelValueToColorFnの中で利用しないのであれば、この部分は不要になります。

44行目でログ出力を設定しています。このコードはアプリを実行する際には必要ありませんが、他の色見本を参照するときに必要となります。

45行目で用いる色調スキーマを指定しています。他にどのようなスキーマがあるかは、ログを参照することにより調べることができます。ここでは、降雨データを表示するのに適していると思われた「viridis」という色調スキーマを用いました。

ログを参照するには、

  1. アプリを起動させ、メニューバーのViewメニューのToggle Developer Toolsを選択する、またはショートカットキー(Control+Shift+I)を押して、Developer Toolsを起動します。
  2. Developer ToolsのConsoleタブをクリックしてConsole画面に切り替えます。
  3. Objectの三角印 「▶e」をクリックすると、下図のように色調スキーマの一覧とその定義を表示がされます。
Chroma.jsの色調スキーマの表示

 

47行目から63行目までが色調を付与するGeoTIFFファイルの表示レイヤーの定義です。

49行目でレイヤーの透明度を指定しています。

50行目から61行目までが色調に変換するときの定義関数(pixelValueToColorFn)の設定です。コメントを読めばおおよそ意味はわかると思いますが、一応簡単に解説しておきます。

54行目はピクセルの値がゼロのときは、そのピクセルは表示させない。

57行目で関数の戻り値が0から1の値になるように正規化しています。

58行目で戻り値を16進数化しています。

 

Leafletのサンプルコード「simple_geotiff_color.html」

<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJLQ==" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
    <script src="https://unpkg.com/georaster"></script>
    <script src="https://unpkg.com/georaster-layer-for-leaflet"></script>
    
    <!-- color display(chroma)-->
    <script src="https://unpkg.com/chroma-js"></script>

    <style>
      #mapid {
        width:  100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="mapid"></div>

        <script type="text/javascript">

            let map = L.map('mapid', {
                center: [37.0, 137.0],
                zoom: 5.5,
            });        

            let tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
            });
            tileLayer.addTo(map);

            let geotiff_file_path = "./sample_geotiff.tif";
            fetch(geotiff_file_path)
              .then(response => response.arrayBuffer())
              .then(arrayBuffer => {
                parseGeoraster(arrayBuffer).then(georaster => {
                  const min = georaster.mins[0];
                  const max = georaster.maxs[0];
                  const range = georaster.ranges[0];

                  // available color scales can be found by running console.log(chroma.brewer);
                  console.log(chroma.brewer);
                  let scale = chroma.scale("viridis");

                  let layer = new GeoRasterLayer({
                      georaster: georaster,
                      opacity: 0.7,
                      pixelValuesToColorFn: function(pixelValues) {
                        let pixelValue = pixelValues[0]; // there's just one band in this raster

                        // if there's zero wind, don't return a color
                        if (pixelValue === 0) return null;

                        // scale to 0 - 1 used by chroma
                        let scaledPixelValue = (pixelValue - min) / range;
                        let color = scale(scaledPixelValue).hex();

                        return color;
                      },
                      resolution: 256
                  });
                  console.log("layer:", layer);
                  layer.addTo(map);

                  map.fitBounds(layer.getBounds());
                });
              });
        </script>
    </body>
</html>

 

4. ソースコードの動かし方

この記事で使うソースコードは、下記のリンクからダウンロードすることができます。だだ、その中にあるhtmlのソースコード「simple_geotiff_color.html」をブラウザから開くと背景の日本地図しか表示されません。

 

GeoTIFFファイルを表示しようと思ったら、simple_geotiff_color.htmlとGeoTIFFファイルの両方をウェブサーバー上の同一ディレクトリに配置する必要があります。

ウェブサーバーを用意するのはなかなか大変だと思いますので、ここで配布するサンプルプログラムではnode.jsというサーバサイドJavascriptのプラットフォームを用いています。よって、このサンプルプログラムを動かす前に、node.jsをインストールする必要があります。

ダウンロードしたzipファイルを解凍すると、package.jsonを始めとする4つのファイル格納されたフォルダが現れます。そのフォルダ上でコマンドプロンプトまたはターミナル画面を開き、下記のコマンドを打ち込みます。

npm install
npm start

 

1行目のコマンドを打ち込むと、node.jsの必要なモジュールがインストールされます。これには数分かかると思います。そして、2行目のコマンドを打ち込むと、下図のようにウィンドウに日本地図 を背景としてGeoTIFFデータがカラー表示されたウィンドウが現れます。

ラスターファイル(GeoTIFF)の色調つき表示

 

5. まとめ

この記事では、Javascriptのライブラリ「Leaflet」でラスターデータをカラー表示する方法を解説しました。

ここで解説した方法により、Chroma.jsで提供されている色調スキーマは使えるようになりますが、実際に使う場合は細かなカスタマイズを加えたくなると思います。

降雨データの表示するためのChroma.jsの色調表示のカスタマイズ方法について、次の記事で解説したいと思います。

以上、最後まで読んでいただきありがとうございました。

最新情報をチェックしよう!