PNG標高タイル
PNG Elevation Tile

ver 0.6.0
2014-12-25
産業技術総合研究所 シームレス地質情報研究グループ

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

仕様

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

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

・各セルの値が示す内容

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

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

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

・標高データの保持方法

 標高データ(h)は,小数点以下の桁数mに応じて10mをかけて整数化し,負数は2の補数表現を使って符号なし整数(x)に変換します.

(h >= 0) ... x = h * 10m
(h < 0) ... x = h * 10m + 224n

 ただし,負の最大値(h*10m = -223, x = 223)は無効データであることを示すものとします.
 次に,xを256進数に分解し,下位の桁からR(red), G(Green), B(Blue)に割り当てます.
 すなわち,xは以下の式で表されます.

x = R * 256 * 256 + G * 256 + B

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

解説

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

・応用範囲

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

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

 仕様上は規定していませんが,Googleマップ互換フォーマットやOpenLayers.XYZなどが汎用性があり,扱いやすいでしょう. 
 一方,Webメルカトルでは極が表現できませんので,用途によっては他の投影法を採用することになります.

・セルサイズ

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

・標高精度(有効桁数)

 地理院地図の標高タイルでは小数点以下2桁のメートル単位でデータが保存されています.この標高精度の場合,本フォーマットでは-83,886.07m~+83,886.07mが表現可能で,界最高標高のエベレスト(8844.43m)や世界最深のマリアナ海溝チャレンジャー海淵(10,911m)まで表現可能です.
 精度を落とすことにより,PNGの圧縮効率も上がり,ファイルサイズを小さくできます.

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

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

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/040/m/9/202/453.png';

サンプル

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

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

(この地図の作成に当たっては,国土地理院長の承認を得て,同院発行の基盤地図情報を使用しました(承認番号 平24情使、第284号))