はじめに
.NET Frameworkの NuGet パッケージでは、EXIF を扱うものがいくつかありますが、このうち評判が高そうな(ダウンロード数が多い) ExifLib を使用して写真(jpegファイル)へ埋め込まれたジオタグ(GPS情報)を得てみます。
※System.Linq を使用しています。
- EXIFタグ一覧 - INAGAKI さんのページ
サンプルコード
「NuGet パッケージの管理」で、プロジェクトへ ExitLib を取り込みます。
namespace SampleProject
{
public class Sample1
{
/// <summary>
/// 指定されたファイルのジオタグを読み込み、GoogleMapでその位置を示します。
/// </summary>
/// <param name="jpegFilePath">写真ファイルのパス。</param>
public void BrowseMap(string jpegFilePath)
{
var rd = new ExifLib.ExifReader(jpegFilePath);
double[] lat, lng;
string rLat, rLng;
rd.GetTagValue<double[]>(ExifLib.ExifTags.GPSLatitude, out lat);
rd.GetTagValue<double[]>(ExifLib.ExifTags.GPSLongitude, out lng);
rd.GetTagValue<string>(ExifLib.ExifTags.GPSLatitudeRef, out rLat);
rd.GetTagValue<string>(ExifLib.ExifTags.GPSLongitudeRef, out rLng);
if((lat != null) && (lng != null))
{
var latitude = lat.Reverse().Aggregate<double>((s, v) => { return s / 60 + v; }) * (rLat.Equals("S") ? -1 : 1);
//var latitude = (lat[0] + lat[1] / 60 + lat[2] / 3600) * (rLat.Equals("S") ? -1 : 1); でもよいでしょう。
var longitude = lng.Reverse().Aggregate<double>((s, v) => { return s / 60 + v; }) * (rLng.Equals("W") ? -1 : 1);
var url = "https://www.google.com/maps/?q=" + latitude.ToString() + "," + longitude.ToString();
System.Diagnostics.Process.Start(url);
}
}
}
GPSLatitude と GPSLongitude の値は double[] 型で取得でき、度、分、秒の順に入っています。また、GPSLatitudeRefには文字列(string型)で北緯:Nか南緯:Sか、GPSLongitudeRefには東経:Eか西経:Wが入っています。
(例)
この「度、分、秒」の緯度・経度の値を10進数の値に変換して、さらに南緯や西経の場合は符号を反転させて、GoogleMap サーバへ渡すURLに埋め込んでいます。
大抵が世界測地系で記録されているようなので、測地系の変換をせずとも GoogleMapでそのまま表示できます。
備考
photo.exif パッケージも使用してみました。こちらは次のようなコードで、EXIF情報を丸ごと得られるのが利点です。
ただ他の情報はうまく取れるようですが、ジオタグ(GPS情報)は整数部分だけしか取得できませんでした。
var exifInfo = (new photo.exif.Parser()).Parse(jpegFilePath).ToArray();
