EXIF(JPEG)から緯度経度を抜きだすDLLを作成した。
ファイル名を引数にして、構造体にdouble値の緯度経度を返却するメソッドgetLatLon(string filename)。
同僚がAUのGPS機能付き携帯で撮影した写真を、GoogleMapに表示させたところ、なかなかの精度でポイントが落ちた。(駅のホームで撮ったとか、高速道路のサービスエリア駐車場とか)
■DLLの作成
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace lib
{
public interface Iexif
{
exif.Point getLatLon(string filename);
}
public class exif : Iexif
{
private double lat;
private double lon;
public double Lat
{
set { this.lat = value; }
get { return lat; }
}
public double Lon
{
set { this.lon = value; }
get { return lon; }
}
public struct Point
{
public double Lat;
public double Lon;
}
public Point getLatLon(string filename)
{
Point p = new Point();
//画像ファイル名
if (filename.Length == 0)
{
//お好きな座標値を初期値としてセットしてね(これは富士山)
p.lat=35.36285567162891;
p.lon=138.73091250658035;
}
//読み込む
double i = 0;
double j = 0;
double k = 0;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(filename);
foreach (System.Drawing.Imaging.PropertyItem item in bmp.PropertyItems)
{
//緯度を取得する(DMS形式のみ) 20090206コメント追記
if*1 //item.Type=5はRational
{
i = (double)*2;
j = (double)*3;
p.lat = (double)(i+(j+k)/3600);
}
//経度
if *4 //item.Type=5はRational
{
i = (double)*5;
j = (double)*6;
p.lon = (double)(i + (j+k)/3600);
}
}
bmp.Dispose();
return p;
}
}
}
■呼び出し
//緯度経度を格納する構造体
lib.exif.Point p = new lib.exif.Point();
//ファイル名を渡す
//exif抜き出しオブジェクトのインスタンス化
lib.exif obj=new lib.exif();
p =obj.getLatLon(filename);
Console.WriteLine(filename+"→["+p.Lat.ToString()+","+p.Lon.ToString()+"]");
この後、DBに格納するもよし、テキストファイルに書くも良し
*1:item.Id==0x0002)&&(item.Type==5
*2:short)BitConverter.ToUInt16(item.Value, 0)/(short)BitConverter.ToUInt16(item.Value, 4
*3:short)BitConverter.ToUInt16(item.Value, 8)/(short)BitConverter.ToUInt16(item.Value, 12)*60); k = (double)((short)BitConverter.ToUInt16(item.Value, 16)/(short)BitConverter.ToUInt16(item.Value,20
*4:item.Id == 0x0004)&&(item.Type==5
*5:short)BitConverter.ToUInt16(item.Value, 0) / (short)BitConverter.ToUInt16(item.Value, 4
*6:short)BitConverter.ToUInt16(item.Value, 8) / (short)BitConverter.ToUInt16(item.Value, 12)*60); k = (double)((short)BitConverter.ToUInt16(item.Value, 16) / (short)BitConverter.ToUInt16(item.Value, 20