在数据库中查找所有距离一组纬度和经度点一定距离范围内的记录。

4

我已经看过所有的例子,目前我得到的如下。

我的表格很简单:

schools(表格名称) - School_ID - 纬度 - 经度 - 县 - 额外信息

这是我的代码:

<?php

 $con = mysql_connect("xxx","xxx","xxx");



 if (!$con) {

            die('Could not connect: ' . mysql_error());

 } else {}



 mysql_select_db("xxx", $con);

 $latitude = "36.265541";

 $longitude = "-119.207153";

 $distance = "1"; //miles



 $qry = "SELECT *, (3958.75 * ACOS(SIN(" . $latitude . " / 57.2958)*SIN(lat / 57.2958)+COS(" . $latitude . " / 57.2958)*COS(lat / 57.2958)*COS(long / 57.2958 - " . $longitude . " / 57.2958))) as distance FROM schools WHERE (3958.75 * ACOS(SIN(" . $latitude . " / 57.2958)*SIN(lat / 57.2958)+COS(" . $latitude . " / 57.2958)*COS(lat / 57.2958)*COS(long / 57.2958 - " . $longitude . " / 57.2958))) <= " . $distance;

 $results = mysql_query($qry);
 if (mysql_num_rows($results) > 0) {
            while($row = mysql_fetch_assoc($results)) {
                            print_r($row);
            }
 } else {}

 mysql_close($con);

 ?>

但是当我尝试运行它时,出现了以下错误:

警告:mysql_num_rows():提供的参数不是有效的MySQL结果资源


这意味着您的查询失败了。打印查询字符串并尝试在命令行中运行它。这将为您提供更详细的失败信息。 - Calvin
2个回答

3

首先,"long"是MySQL中的保留关键字。您需要使用反引号将其括起来,像这样:

`long`
SELECT `long`,lat FROM schools

完整的保留关键字列表可在此处找到:保留关键字

如果您有像phpMyAdmin这样的工具,我建议在那里运行查询测试。

否则,请尝试在执行mysql_query()后在您的代码中执行此操作:

print(mysql_errno().' '.mysql_error());

这将会给你MySQL生成的错误代码和错误信息。查询看起来除了关键词问题之外都没问题,但这将确切地告诉你。


1
说实话,我建议你获取所有学校的经纬度,然后通过循环在你的 PHP 代码中运行 Haversine 函数。

假设这个查询用于查找给定位置附近的学校,我认为被搜索的距离不会很大,不需要考虑地球的曲率。而且地球在任何情况下都不是一个完美的球体,所以如果你想要精确的测量,你必须使用Vincenty的公式。 - Calvin
你可以通过创建一个封闭的边界框来优化这个建议,该边界框围绕着距离等于半径定义的圆形进行。然后创建一个结果包含较少记录的SQL查询。之后在这个集合上进行一次haversine距离计算。 - jottos
1
@Calvin,我不确定你到底想告诉我什么。 我很清楚地知道地球不是一个完美的球体,但使用Haversine算法相当不错,并且在绝对精度不是必需的应用程序中可能是最常见的方法。 @jottos,也许如此,但只要获取它们所有并进行Haversine计算,就可以比他现在拥有的更接近了 :)。 - BobbyShaftoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接