各キャリアごとに携帯のGPSを取得するPHP

お仕事で使うということもあって、携帯でGPSを取得して処理するためのPHPクラスを作りました。
PHPならPEARでもあるくらいのものですが、自分用に作りたかったので一から作ることにしました。


参考にしたのはこちら

http://www.phppro.jp/phptips/archives/vol40/2
http://www.yaskey.cside.tv/mapserver/note/gps.html
http://www.plusmb.jp/2008/12/26/1934.html


まずはキャリアごとに違うGPS機能の使い方を全部同じにする。
今回は<a>での取得のみですが<input>でもできるようです。

function GPS_output_link($url,$link_title){
//携帯GPSリンク取得(キャリアごとのGPS取得リンクを返します。)
//引数1 $url --- GPSを処理するスクリプトのURL(指定しない "" or 0 の場合は現在表示しているページに設定)
//引数2 $link_title --- リンクのタイトル
	if(!$url){$url = $_SERVER['PHP_SELF'];}
	$agent = $_SERVER["HTTP_USER_AGENT"];
	if(preg_match("/^DoCoMo\/[12]\.0/i", $agent)){//DoCoMo
		echo "<a href=\"".$url."\" lcs>".$link_title."</a>";
	} elseif(preg_match("/^(J\-PHONE|Vodafone|MOT\-[CV]980|SoftBank)\//i", $agent)){//SoftBank
		echo "<a href=\"location:auto?url=".$url."\">".$link_title."</a>";
	} elseif(preg_match("/^KDDI\-/i", $agent) || preg_match("/UP\.Browser/i", $agent)){//au
		echo "<a href=\"device:gpsone?url=".$url."&ver=1&datum=0&unit=0\">".$link_title."</a>";
	} elseif(preg_match("/^DDIPOCKET/i", $agent) || preg_match("/^WILLCOM/i", $agent)){//WILLCOM
		echo "<a href=\"http://location.request/dummy.cgi?my=".$url."&pos=$location\">".$link_title."</a>";
	} else {
		echo $link_title ;
	}
}

functionでリンク先のURLとリンクのタイトルを渡せば、それぞれのキャリアごとに判別してGPS取得<a>を出力してくれます。
例えば、HTMLに「<?php GPS_output_link(SITE_URL,"GPS位置取得"); ?>」なんて書けば出力してくれます。
auはパラメーターを渡して、いろいろなカタチでパラメーターを受け取ることができますが、詳しくはリンク先を見てください。


class GPS_param_get{
	
	//緯度 latitude(dd.mm.ss.sss)
	var $lat;
	
	//経度 longitude(dd.mm.ss.sss)
	var $lon;
	
	//緯度(世界測地系に変換:00.000000)
	var $lat_world;
	
	//経度(世界測地系に変換:00.000000)
	var $lon_world;
	
	
	//コンストラクタ
	function GPS_param_get(){
		//携帯GPSで取得したパラメーターから緯度経度を取得
		//返り値 $hoge['lat'] -> 緯度 $hoge['lon'] -> 経度
		$agent = $_SERVER["HTTP_USER_AGENT"];
		if(preg_match("/^DoCoMo\/[12]\.0/i", $agent)){//DoCoMo
			if($_GET['lat'] && $_GET['lon']){
				$lat = preg_replace("/\-/","+-",$_GET['lat']);
				$lon = preg_replace("/\-/","+-",$_GET['lon']);
				$lat = preg_split("/\+/",$lat);
				$lon = preg_split("/\+/",$lon);
				$this->lat = $lat[1];
				$this->lon = $lon[1];
				//世界測地系に変換
				$location_converted = $this->location_convert($lat[1],$lon[1]);
				$this->lat_world = $location_converted['lat_converted'];
				$this->lon_world = $location_converted['lon_converted'];
			}else{
				return FALES;
			}
		} elseif(preg_match("/^(J\-PHONE|Vodafone|MOT\-[CV]980|SoftBank)\//i", $agent)){//SoftBank
			if($_GET['pos']){
				$location = preg_replace("/N/","+",$_GET['pos']);
				$location = preg_replace("/E/","+",$location);
				$location = preg_replace("/S/","+-",$location);
				$location = preg_replace("/W/","+-",$location);
				$location = preg_split("/\+/",$location);
				$this->lat = $location[1];
				$this->lon = $location[2];
				//世界測地系に変換
				$location_converted = $this->location_convert($location[1],$location[2]);
				$this->lat_world = $location_converted['lat_converted'];
				$this->lon_world = $location_converted['lon_converted'];
			}else{
				return FALES;
			}
		} elseif(preg_match("/^KDDI\-/i", $agent) || preg_match("/UP\.Browser/i", $agent)){//au
			if($_GET['lat'] && $_GET['lon']){
				$lat = preg_replace("/\-/","+-",$_GET['lat']);
				$lon = preg_replace("/\-/","+-",$_GET['lon']);
				$lat = preg_split("/\+/",$lat);
				$lon = preg_split("/\+/",$lon);
				$this->lat = $lat[1];
				$this->lon = $lon[1];
				//世界測地系に変換
				$location_converted = $this->location_convert($lat[1],$lon[1]);
				$this->lat_world = $location_converted['lat_converted'];
				$this->lon_world = $location_converted['lon_converted'];
			}else{
				return FALES;
			}
		} elseif(preg_match("/DDIPOCKET/i", $agent) || preg_match("/WILLCOM/i", $agent)){//WILLCOM
			if($_GET['pos']){
				$location = preg_replace("/N/","+",$_GET['pos']);
				$location = preg_replace("/E/","+",$location);
				$location = preg_replace("/S/","+-",$location);
				$location = preg_replace("/W/","+-",$location);
				$location = preg_split("/\+/",$location);
				$this->lat = $location[1];
				$this->lon = $location[2];
				//世界測地系に変換
				$location_converted = $this->location_convert($location[1],$location[2]);
				$this->lat_world = $location_converted['lat_converted'];
				$this->lon_world = $location_converted['lon_converted'];
			}else{
				return FALES;
			}
		} else {
			;
		}
	}
	
	function location_convert($lat,$lon){
		//携帯GPSで取得した緯度・経度情報の書式を世界測地系に変換する
		//引数1 $lat 緯度
		//引数2 $lon 軽度
		//返り値 $hoge['lat_converted'] -> 変換された緯度 $hoge['lon_converted'] -> 変換された経度
		$lat_convert = preg_split("/\./",$lat);
		if(preg_match("/^-[[:digit:]]+/",$lat_convert[0])){
			$lat_converted = $lat_convert[0] - (  ($lat_convert[1]/ 60) + (( $lat_convert[2] + ($lat_convert[3] / 1000)) / 3600 )  );
		}else{
			$lat_converted = $lat_convert[0] + (  ($lat_convert[1]/ 60) + (( $lat_convert[2] + ($lat_convert[3] / 1000)) / 3600 )  );
		}
		$lon_convert = preg_split("/\./",$lon);
		if(preg_match("/^-[[:digit:]]+/",$lon_convert[0])){
			$lon_converted = $lon_convert[0] - (  ($lon_convert[1]/ 60) + (( $lon_convert[2] + ($lon_convert[3] / 1000)) / 3600 )  );
		}else{
			$lon_converted = $lon_convert[0] + (  ($lon_convert[1]/ 60) + (( $lon_convert[2] + ($lon_convert[3] / 1000)) / 3600 )  );
		}
		return array("lat_converted"=>$lat_converted,"lon_converted"=>$lon_converted);
	}
	
}//class GPS_param_get END

そして、パラメーターの受け取りクラス。
各キャリアごとにパラメーターの出力がそれぞれ違うのでそれに合わせて文字列を整形しています。


メインはGPS_param_get()で、location_convert($lat,$lon)は測地座標系(dd.mm.ss.sss)を世界測地系(dd.dddddd)に変換する関数です。
値の取り出しは

$location = new GPS_param_get();
echo $location -> lat;
echo $location -> lon_world;

みたいな感じで取り出せます。
ある程度、テストや確認をおこなっているのですが、WILLCOMだけ確認していないので動かないかも…

GoogleMapStaticと組み合わせれば簡単なナビもできるので楽しいーですね。