我有经纬度,我想从数据库中提取记录,它有最近的经纬度,如果这个距离比指定的长,就不检索它。

表结构:

id
latitude
longitude
place name
city
country
state
zip
sealevel

当前回答

 +----+-----------------------+---------+--------------+---------------+
| id | email                 | name    | location_lat | location_long |
+----+-----------------------+---------+--------------+---------------+
| 7  | test@gmail.com        | rembo   | 23.0249256   |  72.5269697   |
| 25 | test1@gmail.com.      | Rajnis  | 23.0233221    | 72.5342112   |
+----+-----------------------+---------+--------------+---------------+

$lat = 23.02350629;

$long = 72.53230239;

DB:: 选择 (“ 选择 * 从 ( 选择 , ( (acos(sin)。决。”* pi(美元)/ 180)* sin (lat * pi(+) - 180)因为(”。拉丁语“圆周率(美元)/ 180)* cos (lat * pi () / 180) * cos(("。龙。”- long) * pi(美元)/ 180))* 180 / pi() * 60 * 1515 1。1 . 609344 ) 距离美国 从 \用户 ) \用户 在哪里 距离<= 2");

其他回答

这个问题一点也不难,但是如果你需要优化它,它就会变得更加复杂。

我的意思是,你的数据库中有100个地点还是1亿个?这有很大的不同。

如果位置的数量很小,只需执行->,就可以将它们从SQL中取出并放入代码中

Select * from Location

一旦你把它们转换成代码,用哈弗辛公式计算出每一个纬度/长度与原始值之间的距离,然后排序。

下面是我用PHP实现的完整解决方案。

该解决方案使用http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL中给出的Haversine公式。

值得注意的是,哈弗辛公式在极点处有弱点。这个答案展示了如何实现vincenty大圆距离公式来解决这个问题,但是我选择只使用Haversine,因为它足够适合我的目的。

我将纬度存储为DECIMAL(10,8),经度存储为DECIMAL(11,8)。希望这能有所帮助!

showClosest.php

<?PHP
/**
 * Use the Haversine Formula to display the 100 closest matches to $origLat, $origLon
 * Only search the MySQL table $tableName for matches within a 10 mile ($dist) radius.
 */
include("./assets/db/db.php"); // Include database connection function
$db = new database(); // Initiate a new MySQL connection
$tableName = "db.table";
$origLat = 42.1365;
$origLon = -71.7559;
$dist = 10; // This is the maximum distance (in miles) away from $origLat, $origLon in which to search
$query = "SELECT name, latitude, longitude, 3956 * 2 * 
          ASIN(SQRT( POWER(SIN(($origLat - latitude)*pi()/180/2),2)
          +COS($origLat*pi()/180 )*COS(latitude*pi()/180)
          *POWER(SIN(($origLon-longitude)*pi()/180/2),2))) 
          as distance FROM $tableName WHERE 
          longitude between ($origLon-$dist/cos(radians($origLat))*69) 
          and ($origLon+$dist/cos(radians($origLat))*69) 
          and latitude between ($origLat-($dist/69)) 
          and ($origLat+($dist/69)) 
          having distance < $dist ORDER BY distance limit 100"; 
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result)) {
    echo $row['name']." > ".$row['distance']."<BR>";
}
mysql_close($db);
?>

/资产/ db / db。php

<?PHP
/**
 * Class to initiate a new MySQL connection based on $dbInfo settings found in dbSettings.php
 *
 * @example $db = new database(); // Initiate a new database connection
 * @example mysql_close($db); // close the connection
 */
class database{
    protected $databaseLink;
    function __construct(){
        include "dbSettings.php";
        $this->database = $dbInfo['host'];
        $this->mysql_user = $dbInfo['user'];
        $this->mysql_pass = $dbInfo['pass'];
        $this->openConnection();
        return $this->get_link();
    }
    function openConnection(){
    $this->databaseLink = mysql_connect($this->database, $this->mysql_user, $this->mysql_pass);
    }

    function get_link(){
    return $this->databaseLink;
    }
}
?>

资产/ db - dbSettings。php

<?php
$dbInfo = array(
    'host'      => "localhost",
    'user'      => "root",
    'pass'      => "password"
);
?>

根据上面“使用MySQL进行地理距离搜索”文章的建议,可以通过使用MySQL存储过程来提高性能。

我有一个约17,000个位置的数据库,查询执行时间为0.054秒。

在极端情况下,这种方法会失败,但为了性能考虑,我跳过了三角函数,只是简单地计算对角线的平方。

简单的一个;)

SELECT * FROM `WAYPOINTS` W ORDER BY
ABS(ABS(W.`LATITUDE`-53.63) +
ABS(W.`LONGITUDE`-9.9)) ASC LIMIT 30;

把坐标换成你需要的坐标。这些值必须存储为double类型。这是一个工作中的MySQL 5。x的例子。

干杯

SELECT latitude, longitude, SQRT(
    POW(69.1 * (latitude - [startlat]), 2) +
    POW(69.1 * ([startlng] - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;

其中[starlat]和[startlng]是开始测量距离的位置。