MySQL 和 PHP 之间余弦球面定律的不同结果
Spherical Law of Cosines different results between MySQL and PHP
在我们的应用程序中,我们使用 PHP 来计算使用 Spherical Law of Cosines formula 的坐标之间的距离。
不过,这并不是很好地缩放,所以我重构了代码以计算 MySQL.
中的距离
当我比较 PHP 计算和 MySQL 计算的结果时,我发现了主要差异。
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
所有这些距离都是在这些坐标和 (Lat: 51.0363432, Lng: 3.7351858) 之间计算的。
这是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;
}
这是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;
}
这些巨大差异是由于 SQL 中更高的精度,还是其中一个代码有问题?
我发现了问题,我应该在假设之前手工完成数学运算。
纬度和经度在调用 MySQL 代码的函数中翻转。
现在结果非常接近,小数点差异很小。
在我们的应用程序中,我们使用 PHP 来计算使用 Spherical Law of Cosines formula 的坐标之间的距离。
不过,这并不是很好地缩放,所以我重构了代码以计算 MySQL.
中的距离
当我比较 PHP 计算和 MySQL 计算的结果时,我发现了主要差异。
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
所有这些距离都是在这些坐标和 (Lat: 51.0363432, Lng: 3.7351858) 之间计算的。
这是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;
}
这是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;
}
这些巨大差异是由于 SQL 中更高的精度,还是其中一个代码有问题?
我发现了问题,我应该在假设之前手工完成数学运算。
纬度和经度在调用 MySQL 代码的函数中翻转。
现在结果非常接近,小数点差异很小。