WPF で Google Map & GeoTag を扱うシリーズその 4。
開発環境で住所情報の IPTC 書き込み ( 撮影場所、撮影国・都市・町 ) に成功し、サンプルプログラムと XnView では正しく読み込めるようになった。
しかし ViewNX で読み込むと、文字化けして読めない。
流石にこれは解決したいので、もう少し調査を行う。
代りに今回のテーマは「BitmapMetadata を使用した、緯度・経度の正しい読み書き」とする。
GPSLatitudeRef、GPSLongitudeRef
今日気が付いたのだが、前回までのサンプルプログラムでは、緯度・経度の保存が不完全であった。
具体的には、緯度・経度の座標は書き込まれるが、GPSLatitudeRef と GPSLongitudeRef の書き込みに失敗していた為、他のプログラムでこれらが埋め込まれていない場合、座標としては中途半端な状態になっていた。
このデータは「北緯・南緯」と「東経・西経」を表しており、緯度・経度の符号を決める為に必須となる。
これまでは、これらのデータを表す BitmapMetadata 用のクエリ文字列を以下のように定義していた。
/// <summary>
/// EXIF の GPS 情報における「緯度の進行方向 ( "N" または "S" )」を示すパス文字列。
/// </summary>
private const string ExifPathGpsLatitudeDirection = "/app1/ifd/gps/subifd:{char=1}";
/// <summary>
/// EXIF の GPS 情報における「経度の進行方向 ( "E" または "W" )」を示すパス文字列。
/// </summary>
private const string ExifPathGpsLongitudeDirection = "/app1/ifd/gps/subifd:{char=3}";
このクエリ文字列の場合、BitmapMetadata.GetQuery では問題なくデータを読み込めるが、SetQuery に失敗する。
SetQuery は不正なクエリ文字列が指定された場合に例外を送出するはずなのだが、この指定の場合は何も起きないので、問題が無いように見えてしまう。
正しいクエリ文字列
以下の資料を見ると、GPSLatitudeRef、GPSLongitudeRef の型は ASCII が 2 つ分のサイズとして定義されている事がわかる。
Exif 2.1 GPS IFD tags
TIFF Tag Reference, GPS Tags
GPS TIFF Tag GPSLatitudeRef, code 1 (0×0001)
GPS TIFF Tag GPSLongitudeRef, code 3 (0×0003)
これまでのクエリ文字列ではデータ型を char で指定していたが、これでは ASCII が 1 つ分となり、書き込まれるデータ量が半分になってしまう。
その為、クエリ文字列は以下のように修正する必要がある。
/// <summary>
/// EXIF の GPS 情報における「緯度の進行方向 ( "N" または "S" )」を示すパス文字列。
/// </summary>
private const string ExifPathGpsLatitudeDirection = "/app1/ifd/gps/subifd:{short=1}";
/// <summary>
/// EXIF の GPS 情報における「経度の進行方向 ( "E" または "W" )」を示すパス文字列。
/// </summary>
private const string ExifPathGpsLongitudeDirection = "/app1/ifd/gps/subifd:{short=3}";
データ型の指定を、char から short に変更している。
このようにする事で、例えば北緯を表す “N” を書き込んだ場合、”N” の文字コードと終端となる NULL 文字が埋め込まれ、正しいデータとして保存されるようになる。
データ型が char でも BitmapMetadata.GetQuery に成功するのは、読み込み量が半分でも、文字コード部分が取得できる為だと思われる。
最後に、今回の調査を行う上で役に立ったプログラムを紹介しておく。
ピンバック: [Mr.Harn] ライフストリーム、ガジェット、街を行く俺のライフログ » Google Maps with Twitter GeoLogging and OAuth