Spherical Law of Cosines different results between MySQL and PHP

时间:2016-02-03 02:53:15

标签: php mysql distance coordinate-systems cosine

In our app we are using PHP to calculate the distance between to coordinates using Spherical Law of Cosines formula. Though, this isn't scaling so well, so I refactored the code to calculate the distance in MySQL.
When I compare the results between the PHP calculation and the MySQL calculation, I see major differences.

Lat       | Lng        | PHP     | MySQL
47.457131 | -10.615383 | 1112.8  | 7604.07
61.265367 | 19.939854  | 1508.5  | 6905.3
56.64524  | -21.312707 | 1745.6  | 8589.3
37.028064 | 18.732122  | 1957.5  | 4954.33
38.823754 | -17.029437 | 2112    | 7856.57
70.687405 | 11.08298   | 2217.1  | 7969.53

All these distances are calculated between these coordinates and (Lat: 51.0363432, Lng: 3.7351858).

This is the how it was calculated in PHP

public function getDistance($longitude, $latitude)
{
    $pi = pi();
    $dist = (
            (
            acos(
                sin($latitude * $pi / 180)
                *
                sin($this->latitude * $pi / 180)
                +
                cos($latitude * $pi / 180)
                *
                cos($this->latitude * $pi / 180)
                *
                cos(($longitude - $this->longitude) * $pi / 180)
            )
            ) * 180 / $pi
        ) * 60 * 1.1515;

    $metric = $dist / 0.62137;
    return $metric;
}

This is how it's calculated in SQL

public static function getDistanceQuery($lat, $lng, $distance_name, $units)
{
    /*
     *  Allow for changing of units of measurement
     */
    switch ($units) {
        case 'mi':
            //radius of the great circle in miles
            $gr_circle_radius = 3959;
            break;
        default:
            //radius of the great circle in kilometers
            $gr_circle_radius = 6371;
            break;

    }

    /*
     *  Generate the select field for distance
     */
    $distance_select = sprintf(
        "ROUND(
            ( %d
                * acos(
                    cos( radians(%s) )
                    * cos( radians( latitude ) )
                    * cos( radians( longitude ) - radians(%s) )
                    + sin( radians(%s) )
                    * sin( radians( latitude ) )
                )
            )
        , 2 )
        AS %s ",
        $gr_circle_radius,
        $lat,
        $lng,
        $lat,
        $distance_name
    );
    return $distance_select;
}

Are these big differences due to higher precision in SQL, or is there something wrong with one of the codes?

1 个答案:

答案 0 :(得分:2)

I found the issue, I should've done the Math by hand before assuming. The latitude and longitude were flipped the function where the MySQL code is being called.
The results are very close to each other now, with small decimal differences.