0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

2点間の距離を求める

Last updated at Posted at 2021-05-17

2拠点間の距離を求める方法を備忘録として残りておきます。

計算で算出する

/** 
 * 変数は下記が入っているものとする。
 * $lat:現在地の緯度
 * $lng:現在地の経度
 * $comparisonLat:距離を比較する緯度
 * $comparisonLng:距離を比較する経度
*/

// 緯度、経度の移動量を計算
$latDistance = $lat - $comparisonLat;
if ($latDistance < 0) {
    $latDistance *= -1;
}
$lngDistance = $lng - $comparisonLng;
if ($lngDistance < 0) {
    $latDistance *= -1;
}
// 緯度位置における経度量を計算
$latitude = 30.9221438 * cos($lat / 180 * pi());
if ($latitude < 0) {
    $latitude *= -1;
}

/**
 * 緯度や赤道での経度の場合0.00027778度 = 30.9221438mになるので
 * 移動量÷0.00027778*30.9221438の値で三角関数を使う
 */
$distance = (int)(sqrt((abs($latDistance / 0.00027778 * 30.9221438) ** 2) + (abs($lngDistance / 0.00027778 * $latitude) ** 2)));

SQLで求める

Laravel8, MySQL8を使用しています。
SQLで計算する場合は経度と緯度をgeometry型にしておく必要があります。

    /**
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function newQuery()
    {
        $raw = '';
        foreach ($this->geoFields as $column) {
            $raw .= ' ST_AsText(' . $column . ') as ' . $column . ' ';
        }
        return parent::newQuery()->addSelect('*', DB::raw($raw));
    }

    /**
     * 現在地から〇m以内のデータを返す
     * @param float $lat 緯度
     * @param float $lng 経度
     * @param int $distance 距離
     * @return mixed
     */
    public function getData(float $lat, float $lng, int $distance)
    {
        return $this
            ->query()
            ->addSelect(DB::raw("ROUND(
                ST_LENGTH(
                    ST_GeomFromText(
                        CONCAT(
                            'LineString( " . $lat . " " . $lng . " , ', ST_X(position), ' ', ST_Y(position), ')'))) * 111000) AS distance "))
            ->whereRaw("ROUND(
                ST_LENGTH(
                    ST_GeomFromText(
                        CONCAT(
                            'LineString( " . $lat . " " . $lng . " , ', ST_X(position), ' ', ST_Y(position), ')'))) * 111000) < " . $distance)
            ->orderBy('distance')
            ->get();
    }
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?