我的数据库有坐标条目。我想获取包含指定半径圆内坐标的条目。因此,我使用余弦球面定律。但是在所有数据库条目上检查这种情况的成本太高了。因此,我首先获取位于边界框中的坐标(此框包含上面指定的圆圈),然后spherical law of cosines
在它们上应用 a 。
但问题是即使我有满足条件的条目,MySQL 也会返回 NULL。我分别检查了以上 2 个条件并知道这spherical law of cosines
可行,但是使用其他条件(边界框)时会出现问题。
这个链接有我用于这两种情况的代码。
下面是我的代码:
$R = 3959; // earth's mean radius in mile
// first-cut bounding box (in degrees)
$from_Lat = $userTrip->fromLat; // latitude of centre of bounding circle in degrees
$from_Lon = $userTrip->fromLon; // longitude of centre of bounding circle in degrees
$from_Rad = $userTripLength * 0.25; // radius of bounding circle in kilometers
$from_MaxLat = $from_Lat + rad2deg($from_Rad/$R);
$from_MinLat = $from_Lat - rad2deg($from_Rad/$R);
// compensate for degrees longitude getting smaller with increasing latitude
$from_MaxLon = $from_Lon + rad2deg($from_Rad/$R/cos(deg2rad($from_Lat)));
$from_MinLon = $from_Lon - rad2deg($from_Rad/$R/cos(deg2rad($from_Lat)));
$to_Lat = $userTrip->toLat; // latitude of centre of bounding circle in degrees
$to_Lon = $userTrip->toLon; // longitude of centre of bounding circle in degrees
$to_Rad = $userTripLength * 0.50; // radius of bounding circle in kilometers
$to_MaxLat = $to_Lat + rad2deg($to_Rad/$R);
$to_MinLat = $to_Lat - rad2deg($to_Rad/$R);
// compensate for degrees longitude getting smaller with increasing latitude
$to_MaxLon = $to_Lon + rad2deg($to_Rad/$R/cos(deg2rad($to_Lat)));
$to_MinLon = $to_Lon - rad2deg($to_Rad/$R/cos(deg2rad($to_Lat)));
$sql = "Select userTrip.id, userTrip.fromLat, userTrip.fromLon, userTrip.toLat, userTrip.toLon,
acos(sin(:from_lat)*sin(radians(userTrip.fromLat)) + cos(:from_lat)*cos(radians(userTrip.fromLat))*cos(radians(userTrip.fromLon) - :from_lon)) * :R AS SourceDistance,
acos(sin(:to_lat)*sin(radians(userTrip.toLat)) + cos(:to_lat)*cos(radians(userTrip.toLat))*cos(radians(userTrip.toLon) - :to_lon)) * :R AS DestinationDistance
From (
Select userTrip.id, userTrip.fromLat, userTrip.fromLon, userTrip.toLat, userTrip.toLon,
From userTrip
Where userTrip.userId != $this->userId
AND userTrip.departureTime > '".date('Y-m-d H:i:s')."'
AND userTrip.fromLat Between :from_minLat And :from_maxLat
AND userTrip.fromLon Between :from_minLon And :from_maxLon
AND userTrip.toLat Between :to_minLat And :to_maxLat
AND userTrip.toLon Between :to_minLon And :to_maxLon
)
Where acos(sin(:from_lat)*sin(radians(userTrip.fromLat)) + cos(:from_lat)*cos(radians(userTrip.fromLat))*cos(radians(userTrip.fromLon) - :from_lon)) * :R < :from_rad
AND acos(sin(:to_lat)*sin(radians(userTrip.toLat)) + cos(:to_lat)*cos(radians(userTrip.toLat))*cos(radians(userTrip.toLon) - :to_lon)) * :R < :to_rad";
$params = array(
'from_lat' => $from_Lat,
'from_lon' => $from_Lon,
'from_minLat' => $from_MinLat,
'from_minLon' => $from_MinLon,
'from_maxLat' => $from_MaxLat,
'from_maxLon' => $from_MaxLon,
'from_rad' => $from_Rad,
'to_lat' => $to_Lat,
'to_lon' => $to_Lon,
'to_minLat' => $to_MinLat,
'to_minLon' => $to_MinLon,
'to_maxLat' => $to_MaxLat,
'to_maxLon' => $to_MaxLon,
'to_rad' => $to_Rad,
'R' => $R
);
$stmt = $this->dbLink->prepare($sql);
try
{
$stmt->execute($params);
$matchCandidates = $stmt->fetchAll();
}
catch (PDOException $err)
{
echo $err->getMessage();
}
if ($matchCandidates == null)
throw new ErrorException("No match candidates found!");
这总是显示错误“找不到匹配的候选者!”。在 $params 数组中,我最初将纬度和经度转换为弧度(即使这样也不起作用),但经过大量调试后,我相信它们应该以度为单位。
先感谢您。