[解決済み] PHPで2つの座標間の距離を測定する
2022-04-23 15:52:30
質問
こんにちは、私は緯度と経度を持つ2点間の距離を計算する必要があります。
外部APIを一切呼び出さないようにしたい。
PHPでHaversine Formulaを実装してみました。
以下はそのコードです。
class CoordDistance
{
public $lat_a = 0;
public $lon_a = 0;
public $lat_b = 0;
public $lon_b = 0;
public $measure_unit = 'kilometers';
public $measure_state = false;
public $measure = 0;
public $error = '';
public function DistAB()
{
$delta_lat = $this->lat_b - $this->lat_a ;
$delta_lon = $this->lon_b - $this->lon_a ;
$earth_radius = 6372.795477598;
$alpha = $delta_lat/2;
$beta = $delta_lon/2;
$a = sin(deg2rad($alpha)) * sin(deg2rad($alpha)) + cos(deg2rad($this->lat_a)) * cos(deg2rad($this->lat_b)) * sin(deg2rad($beta)) * sin(deg2rad($beta)) ;
$c = asin(min(1, sqrt($a)));
$distance = 2*$earth_radius * $c;
$distance = round($distance, 4);
$this->measure = $distance;
}
}
公共の距離を持ついくつかの与えられたポイントでテストすると、私は信頼できる結果を得ることができません。
元の計算式に間違いがあるのか、私の実装に間違いがあるのか、よく分かりませんが
どのように解決するのですか?
少し前に、ハバーシンの公式の例を書いて、私のホームページで公開したことがあります。
/**
* Calculates the great-circle distance between two points, with
* the Haversine formula.
* @param float $latitudeFrom Latitude of start point in [deg decimal]
* @param float $longitudeFrom Longitude of start point in [deg decimal]
* @param float $latitudeTo Latitude of target point in [deg decimal]
* @param float $longitudeTo Longitude of target point in [deg decimal]
* @param float $earthRadius Mean earth radius in [m]
* @return float Distance between points in [m] (same as earthRadius)
*/
function haversineGreatCircleDistance(
$latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);
$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
return $angle * $earthRadius;
}
➰ パラメータで渡したのと同じ単位で距離が返ってくることに注意してください。
$earthRadius
. デフォルト値は6371000mなので、結果も[m]単位になります。マイル単位で結果を得たい場合は、例えば 3959 miles とします。
$earthRadius
で、結果は[mi]になります。特に理由がない限り、SI単位にこだわるのは良い習慣だと思います。
編集する
TreyAが正しく指摘したように、Haversine式には以下のような弱点があります。 対蹠点 丸め誤差のため(ただし は は小さい距離では安定しています)。それらを回避するためには ヴィンセンティ式 代わりに
/**
* Calculates the great-circle distance between two points, with
* the Vincenty formula.
* @param float $latitudeFrom Latitude of start point in [deg decimal]
* @param float $longitudeFrom Longitude of start point in [deg decimal]
* @param float $latitudeTo Latitude of target point in [deg decimal]
* @param float $longitudeTo Longitude of target point in [deg decimal]
* @param float $earthRadius Mean earth radius in [m]
* @return float Distance between points in [m] (same as earthRadius)
*/
public static function vincentyGreatCircleDistance(
$latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);
$lonDelta = $lonTo - $lonFrom;
$a = pow(cos($latTo) * sin($lonDelta), 2) +
pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
$b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta);
$angle = atan2(sqrt($a), $b);
return $angle * $earthRadius;
}
関連
-
[解決済み】接続の取得に失敗しました: php_network_getaddresses: getaddrinfo failed: 名前またはサービスが不明
-
[解決済み】 PHP 未定義関数の呼び出し
-
[解決済み】Xampp ローカルホスト/ダッシュボード
-
[解決済み】PHPからPythonスクリプトを実行する
-
[解決済み] * vchiqインスタンスを開くのに失敗しました。
-
[解決済み] PHP - ストリームを開くのに失敗しました : そのようなファイルまたはディレクトリがありません。
-
[解決済み】MySQLのカラム数が1行目の値数と一致しない【非公開
-
[解決済み] 2つの緯度経度点間の距離を計算する?(ハバーシンの公式)
-
[解決済み】2つの座標間の距離を計算する関数
-
[解決済み] PHPを使用して2つの日付の差を計算する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】mysqli_result クラスのオブジェクトを文字列に変換できない
-
[解決済み] SQLSTATE[HY093]: 無効なパラメータ番号: バインドされた変数の数が102行目のトークンの数と一致しない [終了]
-
[解決済み】stdClassクラスのオブジェクトが文字列に変換されない。
-
[解決済み] php5パッケージのインストール候補がない (Ubuntu 16.04)
-
[解決済み】Chrome net::ERR_INCOMPLETE_CHUNKED_ENCODING エラーが発生しました。
-
[解決済み】未定義の関数mysql_query()をLoginで呼び出す【重複
-
[解決済み】メッセージ。Trying to access array offset on value of type null [重複]配列のオフセットにアクセスしようとしています。
-
[解決済み] [Solved] Fatal error: メンバ関数 query() の null への呼び出し。
-
phpのAllowed memory size of 134217728 bytes枯渇問題の解決法
-
[解決済み] PHP 未定義関数への呼び出し