【发布时间】:2015-10-20 06:07:52
【问题描述】:
我有一个数据库,其中包含邮政编码及其地理坐标。数据如下所示
id | Postcode | Longitude | Latitude |
-------------------------------------------------
1 | W12 7GF | 51.51527 | -0.08816 |
-------------------------------------------------
2 | SW16 6GF | 51.51528 | -0.15960 |
-------------------------------------------------
3 | W1 4FT | 51.51528 | -0.11590 |
-------------------------------------------------
我首先要做的是输入一个邮政编码(我现在已经硬编码了)。
$sql = "SELECT * FROM postcodes WHERE `postcode` = 'W14 6TY'";
执行此操作后,我将获得该邮政编码的经度和纬度。我还设置了几个变量。
$lat1 = $row['Latitude'];
$lon1 = $row['Longitude'];
$d = 5;
$r = 3959;
现在我要做的是获取上述邮政编码半径 5 英里范围内的所有其他邮政编码。为此,我会这样做
$latN = rad2deg(asin(sin(deg2rad($lat1)) * cos($d / $r) + cos(deg2rad($lat1)) * sin($d / $r) * cos(deg2rad(0))));
$latS = rad2deg(asin(sin(deg2rad($lat1)) * cos($d / $r) + cos(deg2rad($lat1)) * sin($d / $r) * cos(deg2rad(180))));
$lonE = rad2deg(deg2rad($lon1) + atan2(sin(deg2rad(90)) * sin($d / $r) * cos(deg2rad($lat1)), cos($d / $r) - sin(deg2rad($lat1)) * sin(deg2rad($latN))));
$lonW = rad2deg(deg2rad($lon1) + atan2(sin(deg2rad(270)) * sin($d / $r) * cos(deg2rad($lat1)), cos($d / $r) - sin(deg2rad($lat1)) * sin(deg2rad($latN))));
$query = "SELECT * FROM postcodes WHERE (Latitude <= $latN AND Latitude >= $latS AND Longitude <= $lonE AND Longitude >= $lonW) AND (Latitude != $lat1 AND Longitude != $lon1) ORDER BY Latitude, Longitude ASC LIMIT 30";
$result2 = $conn->query($query);
如您所见,我限制了结果,因为我不希望返回数百个。最后输出数据
echo "<div class='container'>";
echo "<div class='row'>";
echo "<div class='col-md-12 col-sm-12 col-xs-12'>";
echo "<table class=\"table table-striped\">";
echo "<tr><th>Postcode</th><th>Latitude</th><th>Longitude</th><th>Miles, Point A To B</th></tr>\n";
while ($row = $result2->fetch_assoc()) {
echo "<tr><td>$row[Postcode]</td><td>$row[Latitude]</td><td>$row[Longitude]</td>";
echo "<td>".acos(sin(deg2rad($lat1)) * sin(deg2rad($row['Latitude'])) + cos(deg2rad($lat1)) * cos(deg2rad($row['Latitude'])) * cos(deg2rad($row['Longitude']) - deg2rad($lon1))) * $r."</td>";
echo "</tr>\n";
}
echo "</table>\n<br />\n";
echo "</div>";
echo "</div>";
echo "</div>";
正如您在输出中看到的那样,我还计算了英里,点 A 到 B。我无法在数据库查询级别执行此操作,因为我需要对生成的地理坐标进行所有数学运算。
目前,数据按纬度和经度排序。因为这些数字没有多大意义,所以输出看起来有点滑稽。
我的问题是,是否可以根据点之间的最小到最大英里数对输出进行排序?我想我需要删除限制(因此它可以在所有输出上工作),但不确定我是否可以这样做,因为我直到查询之后才计算它。
任何建议表示赞赏。
谢谢
【问题讨论】:
-
将
usort与计算距离并进行比较的比较函数一起使用。 -
usort、array_map、存储过程等。有很多函数可以使用,甚至可以自己编写。做一个谷歌搜索。坦率地说,我很惊讶有一个关于 SO 排序的新问题。哎呀,只需在你的数组上写一个简单的冒泡排序。
-
PHP Sorting的可能重复