PNG標高タイル
PNG Elevation Tile

ver 0.6.3
2016-04-20
産業技術総合研究所 シームレス地質情報研究グループ

 PNG標高タイルは,Webブラウザで使用するためのPNGを利用した標高タイルフォーマットで,シームレス地質情報研究グループが提案するものです.

仕様

・タイルファイルフォーマット

 PNG(Portable Network Graphics) 24ビットRGB,32ビットRGBまたは8bitインデックスカラー

・各セルの値が示す内容

 各セルの値はセル北西端の値を表します.
 ※セルの代表値(平均値や中央値など)ではありません.

・タイル東端・南端の扱いとタイプ

 タイル東端・南端の扱いによって通常タイプと拡大タイプの2種類を規定します.各セルの値がセル北西端の値を表すため,通常はタイル画像東端および南端の標高値を表現できません.これを通常タイプと呼びます.画素数を縦,横1ピクセルずつ増やして東端および南端の標高値を表現するものを拡大タイプとします.

・標高データの取得方法

 セルの画素から標高値を取得するには,そのRGB値(r,g,b)をこの順に並べて24bit符号付き整数として解釈し整数値を得え,この値にデータセット毎に定めらえた標高分解能u(単位m)をかけて標高値h(単位m)を値取得します.
 ただし,負の最大値を示す標高値(h = -223/u, x = -223 ) は無効値(NA)を示すものとします.
 具体的な式は以下のようになります.

x = 216r + 28 g + b

( x < 223 ) h = xu
( x = 223 ) h = NA
( x > 223 ) h = (x-224)u

 無効値は ( R=128, G=0, B=0 )となります.

解説

 標高タイル (Elevation tile) とは,標高データを保持するタイル状に分割された画像またはテキストなどのファイルを指します.標高データを画像のピクセル情報として保持する方法自体は新しいものではなく,GeoTiff画像などとしてよく用いられます.また,多量の標高データを扱う場合,それを同じサイズの「タイル」に分割することは自然な方法であり,これもしばしば用いられます.一方,標高タイルにおける画像フォーマットやセルへの情報の保存方法は,その目的によって様々なものが用いられます.ここでは,特に,多量の標高データをWebブラウザで高速に扱うために適したフォーマットを規定しています.

・応用範囲

 国土地理院の標高データを扱うために考案されましたが,極地域を含む日本以外や,様々な精度に対応できるように設計されています.
 このため,本仕様の中では以下の内容は規定されていません.

・地図投影法,タイル分割法,タイル命名規則

 仕様上は規定していませんが,Googleマップ互換の真球メルカトルや命名規則,OpenLayers.XYZなどが汎用性があり,扱いやすいでしょう. 
 一方,真球メルカトルでは極が表現できませんので,用途によっては正距円筒図法などの投影法を採用することになります.

・セルサイズ

 一般に縦横それぞれ256が用いられますが,この仕様上は規定していません.

・標高精度(有効桁数)

 地理院地図の標高タイルでは標高分解能0.01m(1cm)でデータが保存されています.この標高分解能の場合,本フォーマットでは-83,886.07m~+83,886.07mが表現可能で,界最高標高のエベレスト(8,844m)や世界最深のマリアナ海溝チャレンジャー海淵(10,911m)まで表現可能です.標高分解能0.001m(1mm)で表現する場合は-8,388.607m~+8,388.607mが表現可能で,日本最高標高の富士山(3,776m)を表現することができます.逆に精度を落とした場合は,PNGの圧縮効率が上がり,ファイルサイズが小さくなることが期待できます.

・Webブラウザでの情報の取得方法

 Webブラウザでは,HTML5のCanvasおよびJavaScriptを使って標高データを取り出すことができます.ただし,クロスオリジンによる制約を回避するため,imageオブジェクトのcrossOriginプロパティに'anonymous'を設定する等の対応が必要になります.
 以下に,タイル内座標(i, j)の位置の標高データを取得するJavaScriptのサンプルコードを示します(標高分解能は1mとします).

var
    image = new Image(),
    i = 0, j = 0;    // ピクセル位置を指定する

image.crossOrigin = 'anonymous';
image.onload = function() {
    var
        r, g, b, x, h,
        canvas = document.createElement('canvas'),
        context = canvas.getContext( '2d' );

    canvas.width = this.width;
    canvas.height = this.height;  
    context.drawImage( this, 0, 0 );
    data = context.getImageData( i, j, 1, 1 ).data;
    r = data[ 0 ]
    g = data[ 1 ]
    b = data[ 2 ]
    x = r * 256 * 256 + g * 256 + b;
    h = ( x < Math.pow( 2, 23 )  ) ? x : x - Math.pow( 2, 24 );
    if ( h !== -Math.pow( 2, 23) ) {
        console.log( h );
    } else {
        console.log( '無効値' );
    }
}
image.src = 'http://gsj-seamless.jp/labs/elev/m/9/201/454.png';

サンプル

 国土地理院の提供する標高タイルデータをもとにサンプルファイルを作成しました.
 Googleマップ互換のタイル分割方法で東京付近(z=9, y=201, x=454)のPNG標高タイルです.

http://gsj-seamless.jp/labs/elev/m/9/201/454.png