(PHP)携帯電話でGPS位置情報取得したいの続きです。
最終的にしたいことは、携帯から取得したGPS座標から任意の距離内にある施設(DBに登録)を探したいということです。
DBに置いておく施設情報には、位置情報が入っていないといけないため、緯度、経度を入れておくフィールドを用意してやります。
今回は MySQL で、"latitude" , "longitude" という DOUBLE 型のフィールドを用意。また、"id","name" 列もあるとします。
で、携帯電話で計測した位置から半径5km以内のデータを探すという処理してます。
(なお、このソースはここの続きなので、"$lat" や "$lon" は携帯から取得した座標が入っているとします。)
//$lat,$lon は時小数点形式の緯度経度が入っているものとする
//DB接続は省略
//クエリ生成
$query = "SELECT * FROM store WHERE latitude IS NOT NULL AND longitude IS NOT NULL ";
//クエリ実行
$result = mysql_query($query);
//条件にあうデータを格納する配列
$findAry = array();
while ($row = mysql_fetch_assoc($result)) {
if (isset($lat) && isset($lon)){
//GPSからのクエリの場合距離計算(m)
$dist = distance( $lat , $lon , $row["latitude"] ,$row["longitude"] ,true);
//debug
//echo "dist:" . $dist . " lat:" . $row["latitude"] . " lot:" . $row["longitude"] . "
";//指定距離内なら配列追加 (今回は5km)
if ($dist < 5000){
array_push($findAry ,array( "id" => $row["id"] ,
"name" => mb_convert_encoding(htmlspecialchars($row["name"]),"sjis-win" , "UTF-8") , //DB,PHPがUFT8のため携帯向けのshift-jisに変換
"lat" => $row["latitude"] ,
"lon" => $row["longitude"] , ));
}
}
}
//$findAryに結果が入ってるので、これをSmartyに渡すなり、そのまま出力したりする。
/**
* 2地点間の直線距離を求める(Hubenyの簡易式による)携帯電話GPSの測地系はwgs84なので世界測地系使用
* @param string $a_lati A地点の緯度(時小数点形式 33.000000)
* @param string $a_long A地点の経度(時小数点形式 132.000000)
* @param string $b_lati B地点の緯度(時小数点形式 33.000000)
* @param string $b_long B地点の経度(時小数点形式 132.000000)
* @return double 直線距離(メートル)
*/
function calc_distance($a_lati , $a_long , $b_lati , $b_long ) {
//ラジアンに変換
$a_long = deg2rad($a_long);
$a_lati = deg2rad($a_lati);
$b_long = deg2rad($b_long);
$b_lati = deg2rad($b_lati);
$latave = ($a_lati + $b_lati) / 2;
$latidiff = $a_lati - $b_lati;
$longdiff = $a_long - $b_long;
//子午線曲率半径
//$meridian = 6334834 / sqrt(pow(1 - 0.006674 * sin($latave) * sin($latave), 3)); //日本測地系
$meridian = 6335439 / sqrt(pow(1 - 0.006694 * sin($latave) * sin($latave), 3)); //世界測地系
//卯酉線曲率半径
//$primevertical = 6377397 / sqrt(1 - 0.006674 * sin($latave) * sin($latave)); //日本測地系
$primevertical = 6378137 / sqrt(1 - 0.006694 * sin($latave) * sin($latave)); //世界測地系
//Hubenyの簡易式
$x = $meridian * $latidiff;
$y = $primevertical * cos($latave) * $longdiff;
return sqrt($x * $x + $y * $y);
}
いろいろ試した結果、Google MAP API で計測した時の距離とどうも誤差があるようです。(Google Maps:地図から距離、方角方位、面積を得るっていうサイトで簡単に半径とか求められれます。)
それが少しではなく、結構あるんですよね。。。
まぁ時間あればこの誤差についても調べて見ようかと思います。
参考:
ぱふぅ家のホームページ:PHPで2地点間の直線距離を求める 位置計算はほぼこちらで作られた関数使わしてもらってます。
katyos開発室:PHPで2点間の距離を計算する(ヒュベニの公式)
緯度経度、距離計測WEBサービス:
Plus-α.net:緯度経度検索 地図上でクリックした位置の緯度経度を表示。
【R1web】地図上の直線距離計測ページv3-1 地図上の2点間の直線距離を計測。
2点間の直線距離がわかる距離計算サイト 2点間の距離計測。