3D画像ファイルのGeoTIFFとは?
地理情報システムにおけるGeoTIFFを解きほぐす
はじめに
前回ので、3D画像ファイルにおける点群はどういうものなのかを調べました。
その前回記事では、「シェープファイルは、地理情報システム(GIS)の分野で広く活用されている地理データ格納ファイルです。例えば、井戸、川、湖などの空間要素が
であるポイント、ライン、ポリゴンで示され、各要素に固有名称や温度などの任意の属性を付与できる。」と紹介して、シェープファイルの構造や具体例を説明しました。地理情報システム(GIS)でよく利用されるデータには
「ベクタデータの代表的なファイル形式として、ESRIのシェープファイル(Shapefile)がある。」
「ラスタデータの位置情報を保持した代表的なファイル形式として、GeoTIFFがある。」
引用:地理情報データ
と記載されています。
前回記事で
のファイルを取り上げなかったのは片手落ちと思いましたので、今回はラスター形式の代表的なファイルであるGeoTIFFを取り上げることにします。GeoTIFFはウィキペディアには、
引用:GeoTIFF
と記されています。
前回のシェープファイルの記事で、「地理情報システム(GIS)で奥行きの距離情報に相当する値に標高値があります。」と書き、シェープファイルが標高値データを扱う仕組みを説明しました。
そういう標高値データをGeoTIFFではどのように扱っているのでしょうか?
例によってGeoTIFFについての解説記事は沢山見つかりますが、具体例が少なくて混乱してしまいます。
ここでは、GeoTIFFで標高値データをどのように扱っているかという仕組みに焦点を当てて、GeoTIFFを分かり易く具体的に解きほぐしたいと考えています。
GeoTIFFファイルフォーマットの仕様
GeoTIFFファイルフォーマットの仕様については、GeoTIFF Format Specificationに書かれていて、
GeoTIFFのベースとなるTIFFファイルフォーマットRev.6.0の仕様については、GeoTIFF Format Specificationに書かれています。
TIFF(Tagged Image File Format)ファイルは、タグ(Tag)と呼ばれる識別子を用いて画像の構造を記述しており広く用いられている画像ファイルです。
TagIDは2Byteで表されるので65536種類を定義できるのですが、0x8000(32768)以上はプライベート領域として未定義となっています。
その未定義領域を利用して、GeoTIFFファイルは地理情報を格納するタグを定義しています。
このため、GeoTIFFのタグを認識しないTIFFファイル処理ソフトはGeoTIFFのタグを読み飛ばすので通常のTIFFファイルのようにGeoTIFF画像を表示することができます。
これはJPEGファイルに対して撮影情報を付加するExifファイルフォーマットと同様の仕組みであり、ExifもTIFFの未定義タグを利用しています。
ファイル拡張子もTIFFファイルと同じ.tifあるいは.tiffが使われます。
GeoTIFFのファイルフォーマットについては、解説記事GeoTIFFフォーマットが分かり易く書かれています。
GeoTIFFのファイルフォーマットは、
に地理情報が格納される構造になっています。
詳しいファイル仕様については上記仕様書を参照頂くことにして、以下の具体例でそれらGeoTIFFに格納される情報を説明します。
GeoTIFFは次の3種類のタイプに分類できるのではと考えます。
これらを以下の具体例に示します。
地理情報のみ格納タイプのGeoTIFF
GeoTIFFを調べ始めた頃、GeoTIFFには当然に標高値データが格納されているのだろうと思っていたのですが、データを調べてもそれらしきものがなく考え違いということに気付きました。
「地図に画像を貼り込むためには、画像データそのものと、その画像が地図上のどの位置に貼り込まれるのかという情報が必要です。これらを扱うには複数の方法がありますが、今回は、GeoTIFFという形式の画像ファイルを使います。GeoTIFFは名前の通りTIFF画像に位置情報を埋め込んだものです。」
引用:位置情報埋め込み画像を作るノウハウ
という記事を見つけ納得できました。
具体例1
GDAL のコマンドで GeoTIFF ファイルを扱うという記事に、
「GeoTIFF について練習したい場合には, GeoTIFF サンプルデータファイルを入手する. 例えば,次の Web ページから cea.tif をダウンロード 」
と記載があったので、「練習」のためにそのcea.tifを調べることにしました。
この記事には、gdalinfo コマンドを使用してcea.tifファイルの中身を解読した例も挙げられていますので合わせて参照すると理解が進むと思います。
GDALはウィキペディアには、
引用:GDAL
と記されています。
このcea.tifは514×515のサイズで【図1】に示すモノクロ画像です。
具体例1では、TIFFタグを格納するIFDエントリはIFD0からIFD15まで計16個あり、IFD11からIFD15までの計5個がGeoTIFFのタグになっています。
また、IFD13のGeoKeyDirectoryTagによって呼び出されるGeoKeyデータがKEY0からKEY13までの計14個がGeoTIFFのキーになっています。
具体例1に格納されているそれらGeoTIFFのタグとキーのデータを以下に示します。
GeoTIFFタグは 、GeoTIFFキーは で示しています。
また、GeoTIFFタグではないがこの具体例で特徴的となるTIFFタグを で示しています。
タグ | タグID | タグ名 | 値 |
---|---|---|---|
IFD4 | 262(0x106) | GrayImage | |
IFD11 | 33550(0x830E) | 60.022、60.022、0 | |
IFD12 | 33922(0x8482) | 0、0、0、-28493.167、4255884.544、0 | |
IFD13 | 34735(0x87AF) | 0x421EA | |
IFD14 | 34736(0x87B0) | 0x42262 | |
IFD15 | 34737(0x87B1) | 0x42282 | |
キー | キーID | キー名 | 値 |
KEY0 | 1024(0x400) | ModelTypeProjected | |
KEY1 | 1025(0x401) | RasterPixelIsArea | |
KET2 | 1026(0x402) | unnamed | |
KEY3 | 2048(0x800) | GCS_NAD27 | |
KEY4 | 2049(0x801) | NAD27 | |
KEY5 | 2054(0x806) | Angular_Degree | |
KEY6 | 3072(0xC00) | user-defined | |
KEY7 | 3074(0xC02) | user-defined | |
KEY8 | 3075(0xC03) | 28 | |
KEY9 | 3076(0xC04) | Linear_Meter | |
KEY10 | 3078(0xC06) | 33.75 | |
KEY11 | 3080(0xC08) | -117.3333 | |
KEY12 | 3082(0xC0A) | 0 | |
KEY13 | 3083(0xC0B) | 0 |
具体例1の解説
GeoTIFFキーエントリは、 のGeoTIFFタグから呼び出されます(この例では0x421EA)。
GeoTIFFタグは元となるTIFFタグと同様に、2ByteのタグID、2Byteの型、4Byteのカウント、4Byteのタグデータの計12ByteのIFDエントリの構成になっていて、GeoTIFFキーは、2ByteのキーID、2ByteのTIFFTagLocation,、2Byteのカウント、2Byteのキーデータの計8Byteのキーエントリの構成になっています。
キーデータは2Byteですので、2Byteより大きなデータやオフセットアドレスを指定することができません。
このため、4ByteのDouble型数値データは のGeoTIFFタグで示されるアドレス(この例では0x42262)、文字データは のGeoTIFFタグで示されるアドレス(この例では0x42282)に格納されたデータの内の何番目のデータであるかをその2Byteのキーデータで指定して取り出します。
それら数値データや文字データの区別は、 や のタグIDをTIFFTagLocationに設定することでなされます。
は、地理画像に対応する画素間隔を表していて、ScaleX、ScaleY、ScaleZの3個の値があり、単位は で示され、ここではメートルで(60.022、60.022、0)なので1画素約60mに相当することになります。
は、画像の座標(i、j、k)に対応する地理座標系の座標(x、y、z)を表していて、i、j、k、x、y、zの順に格納されており、(0、0、0、-28493.167、4255884.544、0)であるので画面に左上隅(0、0)がx=-28493.167m、y=4255884.544mに対応していることになります。
4隅のコーナーの位置データは格納されておらず、左上隅1点の位置データだけがあり、他の3隅は の値を画素数に掛け算して求めることになります。
この具体例1は下記具体例2や3と異なり、単位がメートルになっているので、コーナー4隅の点に対応する緯度経度は示されていません。
上述のgdalinfo コマンドを使用した解析結果では、
Corner Coordinates:
Upper Left ( -28493.167, 4255884.544) (117d38'27.05"W, 33d56'37.74"N)
Lower Left ( -28493.167, 4224973.143) (117d38'27.05"W, 33d39'53.81"N)
Upper Right ( 2358.212, 4255884.544) (117d18'28.38"W, 33d56'37.74"N)
Lower Right ( 2358.212, 4224973.143) (117d18'28.38"W, 33d39'53.81"N)
となっていて4隅のxy距離と共に緯度経度が表示されています。
これはgdalinfo コマンドによって、GeoTIFFキーの で示される測地系GCS_NAD27などのデータを用いて座標系変換処理が実行された結果であり、GeoTIFFファイルにはそういう緯度経度の結果は格納されていません。
今回の調査でcea.tifはカリフォルニア州マシューズ湖の画像であることを知りました。
標高値データを輝度データに変換するタイプのGeoTIFF
GeoTIFF画像の輝度を標高データの値に応じて変化させれば標高を表現できます。
こういうやり方を用いているGeoTIFFファイルサンプルを探したのですが見つからなかったので、
「QGIS(キュージーアイエス、旧称:Quantum GIS)は、地理空間情報データの閲覧、編集、分析機能を有するクロスプラットフォームのオープンソースソフトウェア・GISソフト」
引用:QGIS
と記されている著名なQGISを使って作成することにしました。
QGISはこちらからダウンロードできます。
具体例2
前回のの「シェープファイルの点群」で用いた、国土地理院の鳥島の地図にあたるXMLファイルFG-GML-4540-52-dem10b-20161001.xmlをここでも用いて解析し易くしています。
QGISで以下の方法でGeoTIFFファイルを取得します。
入力設定の形式はxml、DEMはFG-GML-4540-52-dem10b-20161001.xmlがあるパス名、
出力設定の形式はGeoTiff、出力先は適当に、CRSはEPSG4326-WGS84を選択して、
「アルゴリズムの終了後、QGIS上で出力ファイルを開く」にチェックしてOKをクリックする。
出力モードは画像を選択し、
形式はGeoTIFFを選択し、
ファイル名は拡張子.tifを含むファイル(ここではgeotiffテスト.tifとしておきます)のパス名を入力してOKをクリックする。
こうして得られたgeotiffテスト.tifは1125×750のサイズで、島の部分だけの画像を【図2】に示します。
具体例2では、TIFFタグを格納するIFDエントリはIFD0からIFD16まで計17個あり、IFD12からIFD16までの計5個がGeoTIFFのタグになっています。
また、IFD14のGeoKeyDirectoryTagによって呼び出されるGeoKeyデータがKEY0からKEY6までの計7個がGeoTIFFのキーになっています。
具体例2に格納されているGeoTIFFのタグとキーのデータを以下に示します。
GeoTIFFタグは 、GeoTIFFキーは で示しています。
また、GeoTIFFタグではないがこの具体例で特徴的となるTIFFタグを で示しています。
タグ | タグID | タグ名 | 値 |
---|---|---|---|
IFD2 | 258(0x102) | 08、08、08、08 | |
IFD4 | 262(0x106) | RGB | |
IFD6 | 277(0x115) | 4 | |
IFD10 | 338(0x152) | Unassociated alpha data | |
IFD11 | 339(0x153) | 1、1、1、1 | |
IFD12 | 33550(0x830E) | 0.000111111、0.000111111、0 | |
IFD13 | 33922(0x8482) | 0、0、0、140.25、30.5、0 | |
IFD14 | 34735(0x87AF) | 0x12C6 | |
IFD15 | 34736(0x87B0) | 0x1306 | |
IFD16 | 34737(0x87B1) | 0x1316 | |
キー | キー名 | 値 | |
KEY0 | 1024(0x400) | ModelTypeGeographic | |
KEY1 | 1025(0x401) | RasterPixelIsArea | |
KEY2 | 2048(0x800) | GCS_WGS_84 | |
KEY3 | 2049(0x801) | WGS 84 | |
KEY4 | 2054(0x806) | Angular_Degree | |
KEY5 | 2057(0x809) | 6378137 | |
KEY6 | 2059(0x80B) | 298.257223563 |
具体例2の解説
TIFFタグである の値がRGBになっていますが、海の部分が透明で、島の部分は、
01 01 01 FF 02 02 02 FF 03 03 03 FF ・・・
のように並んでおり、RGBが同値でアルファチャンネルは不透明あるのでモノクロ(白黒)画像になっています。
それらRGB値はこのGeoTIFFファイルを生成したQGISで設定されたのであり、QGISのレイヤのプロパティとして【図3】のような図が示されています。
この鳥島の最高地点の標高378.1mを白とし、標高0mを黒にして標高値に比例したグレーレベルになっています。
そういう標高値と輝度の対応テーブルなどはファイルに記録されていません。
この具体例2でも、標高データであることを示す情報は格納されていませんが、標高データが1Byte画像データに変換され、同じ値の3Byte色データ(色はグレー)にコピーされて格納されていることになります。
具体例2の は、地理画像に対応する画素間隔を表していて、ScaleX、ScaleY、ScaleZの3個の値があり、具体例1と異なり、ここでは単位は角度(度)で(0.000111111、0.000111111、0)になっています。
は、画像の座標(i、j、k)に対応する地理座標系の座標(x、y、z)を表していて、i、j、k、x、y、zの順に格納されており、(0、0、0、140.25、30.5、0)であるので画面に左上隅(0、0)がx=経度140.25゜、y=緯度30.5゜に対応していることになります。
具体例1と同様に、4隅のコーナーの位置データは格納されておらず、左上隅1点の位置データだけがあり、他の3隅は の値を画素数に掛け算して求めることになります。
この具体例2は鳥島の地図にあたるXMLファイルが元になっているので、の【図11】と同じ図を【図4】に示します。
そのXMLファイルでは画面の左下隅と右上隅の緯度経度が格納されていました。
その2つのコーナーのデータから左上隅の座標が抽出されて の値になっています。
の0.000111111と画像サイズを掛け合わせると、例えば
140.25+0.000111111×1125=140.375
となって右隅の経度が求まります。
標高値データを色データに変換するタイプのGeoTIFF
GeoTIFF画像の色を標高データの値に応じて変化させても標高を表現できます。
このタイプの画像は山の部分を赤褐色にして見やすくしている地図としてよく見かけます。
これの仕組みを具体例3に示します。
具体例3
国土地理院の地球地図日本ダウンロードから地球地図日本第1.1版ラスタTIFF(FG-GML-4540-52-DEM10B.zip)をダウンロードし、GeoTIFFファイルel.tifを取り出して具体例3とします。
このel.tifは日本全体の地図であり4199×3600のサイズで【図5】に示すような画像です。
具体例3では、TIFFタグを格納するIFDエントリはIFD0からIFD17まで計18個あり、IFD15からIFD17までの計3個がGeoTIFFのタグになっています。
また、IFD17のGeoKeyDirectoryTagによって呼び出されるGeoKeyデータKEY0の1個だけがGeoTIFFのキーになっています。
具体例3に格納されているGeoTIFFのタグとキーのデータを以下に示します。
GeoTIFFタグは 、GeoTIFFキーは で示しています。
また、GeoTIFFタグではないがこの具体例で特徴的となるTIFFタグを で示しています。
タグ | タグID | タグ名 | 値 |
---|---|---|---|
IFD5 | 262(0x106) | Palette color | |
IFD7 | 277(0x115) | 1 | |
IFD14 | 320(0x140) | 0x1D3D | |
IFD15 | 33550(0x830E) | 0.0083333、0.0083333、0 | |
IFD16 | 33922(0x8482) | 0、0、0、120.0042、49.9958、0 | |
IFD17 | 34735(0x87AF) | 0x2385 | |
キー | キーID | キー名 | 値 |
KEY0 | 1025(0x401) | RasterPixelIsArea |
具体例3の解説
ファイルの画像データは色データではありません。
の値をPalette colorからGrayImageに変更してみると(ColorMapは無視される)、格納されている各1Byteの画像データがモノクロ(白黒)で示されて【図6】に示す図になります。
【図6】では山の部分が白になっているので、元のファイルデータが標高データを輝度に変換したデータになっていることが推定できます。
この輝度データが によって更に色に変換されて【図5】の図になっているのです。
例えば海の部分はデータが0ですが、 によってRGB=(0、0、100)に変換されて濃い青色に表示されています。
この具体例3でも、標高データであることを示す情報は格納されていませんが、標高データが1Byte画像データに変換されて格納され、表示する際に色データに変換されていることになります。
具体例3の は、地理画像に対応する画素間隔を表していて、ScaleX、ScaleY、ScaleZの3個の値があり、具体例1と異なり、ここでは単位は角度(度)で(0.0083333、0.0083333、0)になっています。
は、画像の座標(i、j、k)に対応する地理座標系の座標(x、y、z)を表していて、i、j、k、x、y、zの順に格納されており、(0、0、0、120.0042、49.9958、0)であるので画面に左上隅(0、0)がx=経度120.0042゜、y=緯度49.9958゜に対応していることになります。
具体例1と同様に、4隅のコーナーの位置データは格納されておらず、左上隅1点の位置データだけがあり、他の3隅は の値を画素数に掛け算して求めることになります。
測地系を明記しないGeoTIFFもあることを知りました。
GeoTIFFデータをご自身で簡単に調べたいなら
おわりに
の2つの値で地理情報を表しているのが特徴的です。
GeoTIFFでは地理情報をいろいろな形態で記述することができるようになっています。
例えば、上記左上隅1点の地理上の座標値は、具体例1では投影座標系での距離で示されていますが、具体例2や3は測地座標系の緯度経度で示されています。
測地座標系も具体例1や2では明記されていますが、具体例3では明記されていません。
を示しました。
具体例2と3はどちらも標高値データを輝度に変換して格納しており、具体例3はその変換された輝度データを更に表示時に色に変換するようになっています。
どの具体例も標高値データ自体を格納しておりません。
具体例3のように色に変換すればRGB各1Byteで1677万色になり、細かく標高データを表現できるような気がしますが、格納されている変換元の輝度データは1Byteなので256段階しか区別できません。
で述べたシェープファイルでは8Byteのdouble(倍精度浮動小数点数)型で標高値を表していたのに比べると、GeoTIFFで標高値データを表現するのは難しそうです。
せめて標高値を色に変換して格納すれば少しは精度を上げることができるでしょう。
具体例2のように、QGISで生成する場合ならQGISのレイヤプロパティで把握できますが、単に入手しただけのGeoTIFFファイルではその画像が何を表しているかが分からなくなると思われます。
GeoTIFFタグやキーにそういう画像の情報が追加されればより便利になるだろうと思います。