我使用Chris Veness的脚本http://www.movable-type.co.uk我试图使用他的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值,而是输入了的一些静态值
- 拉特=51.552971553688500美元
- $lon=-3.028690575475280
- $rad=25
这不起作用。。。此外,我找不到为什么不起作用的解决方案,确切地说。。。尽管我认为@dan08在下面的回答中很有意思。他比我更了解这些东西。
尽管如此,我终于有了一个可行的解决方案!请看下面我的答案。
Google Devs的那些人是一群聪明的人!
下面是我找到解决方案的链接:用PHP、MySQL和MySQL创建一个商店定位器;谷歌地图
尽管本教程旨在使用Google Maps API,但本教程的前半部分侧重于使用PHP查询数据库并创建边界圆,以便在给定半径内搜索匹配项,并仅返回匹配的结果。
在本教程中,查询是超快速的,并以XML输出结果,这对于集成到API非常有用。我不需要这个功能,所以我稍微简化了一下。
以下是我所拥有的,它非常适合我的需求:
创建一个名为:phpsqlsearch_dbinfo.php的页面
<?
$username="Your_Database_Username";
$password="Your_Database_Password";
$database="The_Name_of_Your_Database";
?>
创建一个名为:phpsqlsearch_genxml.php的新页面
当访问此页面时,我们将一些值传递给它,因为我们使用$_GET来收集"lat"、"ng"answers"radius"值。
例如phpsqlsearch_genxml.php?lat=37&lng=-122&半径=25
<?php
require("phpsqlsearch_dbinfo.php");
// Get parameters from URL
$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];
// Opens a connection to a mySQL server
$connection=mysql_connect (localhost, $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active mySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die ("Can''t use db : " . mysql_error());
}
// Search the rows in the markers table
$query = sprintf("SELECT id, address, name, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM candidates HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",
mysql_real_escape_string($center_lat),
mysql_real_escape_string($center_lng),
mysql_real_escape_string($center_lat),
mysql_real_escape_string($radius));
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
while ($row = @mysql_fetch_assoc($result)){
$ID = mysql_real_escape_string($row['id']);
$name = mysql_real_escape_string($row['name']);
$address = mysql_real_escape_string($row['address']);
$lat = mysql_real_escape_string($row['lat']);
$lng = mysql_real_escape_string($row['lng']);
$distance = mysql_real_escape_string($row['distance']);
echo $name .", ". $address .", Latitude:". $lat .", Longitude:". $lng .", Distance From Home = ". round($distance)." Miles <br /><br />";
// I then insert these matches into a new table for later use.
$new = "INSERT INTO matrix (Marker_ID, Cand_Name, Distance)
VALUES ('$ID', '$name', '$distance')";
$resulting = mysql_query($new);
if (!$resulting) {
die("Invalid query: " . mysql_error());
}
}
?>
最后,为了让这个例子发挥作用,您需要设置数据库。如果您不能访问phpMyAdmin,或者更喜欢使用SQL命令,下面是创建表的SQL语句:
CREATE TABLE `markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;
现在,对于要填充表的示例数据:单击此处-此示例数据集总共包含169行。如果你按照上面的链接,你可以复制以下格式的完整数据集:
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Frankie Johnnie & Luigo Too','939 W El Camino Real, Mountain View, CA','37.386339','-122.085823');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Amici''s East Coast Pizzeria','790 Castro St, Mountain View, CA','37.38714','-122.083235');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Kapp''s Pizza Bar & Grill','191 Castro St, Mountain View, CA','37.393885','-122.078916');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Round Table Pizza: Mountain View','570 N Shoreline Blvd, Mountain View, CA','37.402653','-122.079354');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Tony & Alba''s Pizza & Pasta','619 Escuela Ave, Mountain View, CA','37.394011','-122.095528');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Oregano''s Wood-Fired Pizza','4546 El Camino Real, Los Altos, CA','37.401724','-122.114646');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Round Table Pizza: Sunnyvale-Mary-Central Expy','415 N Mary Ave, Sunnyvale, CA','37.390038','-122.042034');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Giordano''s','730 N Rush St, Chicago, IL','41.895729','-87.625411');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Filippi''s Pizza Grotto','1747 India St, San Diego, CA','32.723831','-117.168326');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Lou Malnati''s Pizzeria','439 N Wells St, Chicago, IL','41.890346','-87.633927');
etc...
etc...
我希望这能帮助到像我一样苦苦挣扎的人。只要对PHP和MySQL有基本的了解,您就可以很快启动并运行它。
祝你好运!
我认为罪魁祸首在于$sql函数内部的计算。
正确。但这不是你想的。
您的主要问题是在select子句中使用占位符lie :lat
。这个评论很好地解释了这个问题。但最重要的是,不能在SELECT和FROM子句中绑定参数,因为它们是在添加参数之前解析的。
使用PDO或MySQLi不会改变这一点。因此,要将这些变量添加到SELECT子句中,请对它们进行适当的清理,并将它们作为字符串插入查询中。
你正在使用我最喜欢的PDO功能之一,命名占位符。所以我建议坚持PDO。
若要调试500错误,您需要检查服务器日志。如果你有一个典型的LAMP堆栈,可能是/var/log/apache2/error.log
。