DEVELOPERS BLOGデベロッパーズブログ

  1. HOME > 
  2. 加藤 正人のデベロッパーズブログ > 
  3. 緯度経度で与えられる2地点間の距離を計算する PHP ライブラリ

加藤 正人のデベロッパーズブログ

加藤 正人

氏名
加藤 正人
役職
多分SE
血液型
秘密
出没
美味しいもののあるところ
特色
タヒチ大好き。ちょいメタボ。

PhpSpreadsheet でExcel ファイルを読み込む (CakePHP3)

2014/08/23

PhpSpreadsheet でExcel ファイルを読み込む (CakePHP3)

 

緯度・経度で与えられる2つの地点間の距離を計算する PHP ライブラリを考えてみた。

緯度経度による2地点間の距離は、Hubeny の公式が良く用いられているので、これを利用する。 (以下 http://yamadarake.jp/trdi/report000001.html より)

Hubeny の公式

地点1の経度 (ラジアン)を 、緯度を (ラジアン) とする。同様に地点2の経度および緯度をそれぞれ とすると、この2地点間の距離 (m) は次の式で計算できる。

ここで各変数は以下のようになる。

(2地点の経度の差)
(2地点の緯度の差)
2点間の緯度の平均値
子午線曲率半径
卯酉線曲率半径
 

なお、上記で使用される各定数は以下の通り。

第一離心率
長半径 (赤道半径)
短半径 (極半径)

ここで (赤道半径)、 (極半径) は使用する楕円体モデルにより規定されているので、その値 (m) を使用する。Google Maps や GPS であれば WGS84 楕円体であり、a = 6,378,137.000、b = 6,356,752.314 245 となる。

PHP での実装

コアになる機能は以下のように実装できる。

class HubenyDistance
{
	// ヒュベニの公式に基づき緯度経度で与えられた2点間の距離を計算する。
	const a = 6378137.000000;	// WGS84 楕円体モデルの地球赤道半径 (長半径) (m)
	const b = 6356752.314245; // WGS84 楕円体モデルの地球極半径 (短半径) (m)

	// $point1: array('lon' => float, 'lat' => float)
	// $point2: array('lon' => float, 'lat' => float)
	public static function calculate($point1, $point2)
	{
		$lat1 = $point1['lat'];
		$lon1 = $point1['lon'];
		$lat2 = $point2['lat'];
		$lon2 = $point2['lon'];

		$e2 = (pow(self::a, 2) - pow(self::b, 2))/pow(self::a, 2);	// 第一離心率の二乗値

		$x1 = deg2rad($lon1);	// 経度 ⇒ ラジアン変換
		$y1 = deg2rad($lat1);	// 緯度 ⇒ ラジアン変換
		$x2 = deg2rad($lon2);	// 経度 ⇒ ラジアン変換
		$y2 = deg2rad($lat2);	// 緯度 ⇒ ラジアン変換

		$dy = $y1 - $y2;	// 緯度の差
		$dx = $x1 - $x2;	// 経度の差

		$mu_y = ($y1 + $y2) / 2.0; 	// 緯度の平均値

		$W = sqrt(1.0 - ($e2 * pow(sin($mu_y), 2)));

		$N = self::a / $W;	// 卯酉線曲率半径

		$M = (self::a * (1 - $e2)) / pow($W, 3);	// 子午線曲率半径

		return sqrt(pow($dy * $M, 2) + pow($dx*$N*cos($mu_y), 2));	// 2点間の距離 (m);
	}
}

これを元に CakePHP のヘルパーやコンポーネントを作れば、距離計算の必要なサイトの構築が楽になるかもしれない。

関連タグ: