Hatena::ブログ(Diary)

PHP,MySQL,Flex,JSな日々+イラストとか このページをアンテナに追加 RSSフィード Twitter

2009年07月01日

iPhoneのカメラ写真に付加される緯度経度情報を解析して地図に配置する方法

iPhoneのカメラ写真に付加される緯度経度情報を解析して地図に配置する方法です。

こんな感じ

http://moeten.info/maidcafe/?m=iphone&type=gps8

f:id:haru-komugi:20090701213338j:image

iPhone3.0からカメラ写真に緯度経度情報を付加することができるようになりました。

f:id:haru-komugi:20090701170338j:image

こんな感じにAdobe BridgeでEXIF情報を確認すると緯度経度情報が確認できます。

こいつをPHPでごにょごにょしてうまくGoogleMapで読み込めるようにXML出力していきます。

では簡単な説明です。

PHPで画像のEXIFデータを読み取る

まずは写真に含まれるEXIFデータを読み取ります。

<?php
//php.iniで要extension=php_exif.dll
//EXIF情報から写真の撮影時間を取得する
$fname = "photo.jpg";
$cls = exif_read_data( $fname, 'EXIF');
$exif = array();
foreach ($cls as $key=>$sect) {
    if (is_array($sect) == FALSE) {
        $exif[$key] = $sect;
    } else {
        foreach($sect as $name=>$val){
            $exif[$key . '.' . $name] = $val;
        }
    }
}
var_dump( $exif );
?>

EXIFに記載される緯度経度情報は度分表記なので度分秒表記に変換

iPhoneで記録される緯度経度情報は○度○分なので○度○分○秒に変換してあげます。

iPhoneのEXIFでは度分表記
35,41.93N
139,46.66E

計算の方法

数値に注目して、「35」はそのまま、「41」もそのまま、「0.93」には60を掛けてあげる。

あとは数値を組み立てて、「35,41,55.8」な感じに。

読み方は「35度41分55.8秒」になります。たぶん。

計算方法はこちらのページが詳しいです。

プログラムではこんな感じ。汚い!

<?php
//度分取得@緯度
$lat_a0 = explode( "/" , $exif['GPSLatitude.0'] );
$lat_a1 = explode( "/" , $exif['GPSLatitude.1'] );
//度分を度分秒に変換
$lat_0 = $lat_a0[0]/$lat_a0[1];
$lat_1 = $lat_a1[0]/$lat_a1[1];
$tmp = explode( "." , $lat_1 );
$ss =  ( 0 . $tmp[1] ) * 60/100;
$mm = intval( $lat_1 );
$lat = "{$lat_0}.{$mm}.{$ss}";
//緯度と同じように度分取得@経度
$lng_a0 = explode( "/" , $exif['GPSLongitude.0'] );
$lng_a1 = explode( "/" , $exif['GPSLongitude.1'] );
//度分を度分秒に変換
$lng_0 = $lng_a0[0]/$lng_a0[1];
$lng_1 = $lng_a1[0]/$lng_a1[1];
$tmp = explode( "." , $lng_1 );
$ss =  ( 0 . $tmp[1] ) * 60/100;
$mm = intval( $lng_1 );
$lng = "{$lng_0}.{$mm}.{$ss}";
?>

度分秒表記を角度に変換(最近一般的な緯度経度の表示形式)

度分秒から角度に変換します。これでGoogleMapで扱いやすい表記になります。GoogleMapでは一応度分秒でも対応してくれる場合があるのですが、汎用性を考えて角度にしておくと今後便利だと思います。

こんな感じで度分秒を角度に変換できます。

<?
$gps = dms2degree( "35,41,55.8" , "139,46,39.6" );
echo $gps["lat"];//35.6988333333
echo $gps["lng"];//139.777666667
?>

dms2degreeの中身(自前なので保障はないです汗)

<?php
//度分秒表記を角度に変換
function dms2degree( $pos_n , $pos_e ){
    $posN_a = explode( "." , $pos_n );
    $posE_a = explode( "." , $pos_e );
    $posN_a[2] = $posN_a[2] . "." .$posN_a[3];
    $posE_a[2] = $posE_a[2] . "." .$posE_a[3];
    $posN = $posN_a[0] + $posN_a[1]/60 + $posN_a[2]/3600;//北緯
    $posE = $posE_a[0] + $posE_a[1]/60 + $posE_a[2]/3600;//東経
    $gps['lat'] = $posN;
    $gps['lon'] = $posE;
    return $gps;
}
?>

マップ用にXMLを出力

これで写真のEXIFデータから緯度経度情報を角度として抜き出すことができました。

あとは、GoogleMapが扱いやすいXML形式にて出力すればOK。KMLでもいいですね(^−^)

$xml = <<<EOD
<markers>
  <marker lat="{$gps['lat']}" lng="{$gps['lon']}" label="{$date}"/>
</markers>
EOD;
header ("Content-Type: text/xml; charset=UTF-8");
echo mb_convert_encoding( $xml , "UTF-8" , "SJIS" );
exit;

参考リンク

トラックバック - http://d.hatena.ne.jp/haru-komugi/20090701/1246443154