【发布时间】:2016-04-29 21:51:56
【问题描述】:
我正在使用来自http://www.movable-type.co.uk 的 Chris Veness 的脚本我试图使用他的Bounding Circle 脚本对 MySQL 数据库运行查询以仅返回位于给定半径内的行。如下:
<?php
require 'inc/dbparams.inc.php'; // defines $dsn, $username, $password
$db = new PDO($dsn, $username, $password);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$lat = $_GET['lat']; // latitude of centre of bounding circle in degrees
$lon = $_GET['lon']; // longitude of centre of bounding circle in degrees
$rad = $_GET['rad']; // radius of bounding circle in kilometers
$R = 6371; // earth's mean radius, km
// first-cut bounding box (in degrees)
$maxLat = $lat + rad2deg($rad/$R);
$minLat = $lat - rad2deg($rad/$R);
// compensate for degrees longitude getting smaller with increasing latitude
$maxLon = $lon + rad2deg($rad/$R/cos(deg2rad($lat)));
$minLon = $lon - rad2deg($rad/$R/cos(deg2rad($lat)));
$sql = "Select Id, Postcode, Lat, Lon,
acos(sin(:lat)*sin(radians(Lat)) + cos(:lat)*cos(radians(Lat))*cos(radians(Lon)-:lon)) * :R As D
From (
Select Id, Postcode, Lat, Lon
From MyTable
Where Lat Between :minLat And :maxLat
And Lon Between :minLon And :maxLon
) As FirstCut
Where acos(sin(:lat)*sin(radians(Lat)) + cos(:lat)*cos(radians(Lat))*cos(radians(Lon)-:lon)) * :R < :rad
Order by D";
$params = array(
'lat' => deg2rad($lat),
'lon' => deg2rad($lon),
'minLat' => $minLat,
'minLon' => $minLon,
'maxLat' => $maxLat,
'maxLon' => $maxLon,
'rad' => $rad,
'R' => $R,
);
$points = $db->prepare($sql);
$points->execute($params);
?>
<html>
<table>
<? foreach ($points as $point): ?>
<tr>
<td><?= $point->Postcode ?></td>
<td><?= number_format($point->D,1) ?></td>
<td><?= number_format($point->Lat,3) ?></td>
<td><?= number_format($point->Lon,3) ?></td>
</tr>
<? endforeach ?>
</table>
</html>
我重命名了我数据库中现有的列以匹配 Chris Veness 使用的内容 - 我没有使用 $_GET 值,而是输入了一些静态值
- $lat = 51.552971553688500;
- $lon = -3.028690575475280;
- $rad = 25;
这不起作用...而且,我无法找到为什么它不起作用的解决方案,确切地说...尽管我认为@dan08 非常关注与他的回答如下。他比我更了解这些东西。
尽管如此 - 我 [终于] 有了一个可行的解决方案!请看下面我的回答。
【问题讨论】:
-
mysqli 和 pdo 只是与 mysql 对话。实际查询本身并没有真正改变(除了您在准备好的语句中使用的特定类型的占位符)。绝对没有理由
select * from foo在两个库中的行为会有所不同,除非“元”级别的某些内容不同,例如不同的账户。但是,您正在重复使用占位符名称,这是不允许的。 -
错误 500,检查您的日志。
-
我觉得不能在SELECT子句(或者FROM子句)中放参数,因为参数是在制定查询计划之后添加的,查询需要SELECT和FROM子句计划,不能有占位符。 This guy explains it well
-
到目前为止,感谢您如此迅速的反应。我今天一定会尝试你的一些建议并报告回来。 @David Strachan,请您删除重复的标签,因为该问题不是指边界圆或第一次切割。相反,它只是遍历数据库中的每条记录,并通过最接近的距离吐出最近的记录。我已经具备这种能力,但现在我正在尝试对这些结果进行 FirstCut 以使我的操作运行得更快。不过谢谢你的建议。