使用MySQL空间数据在Google地图上获取最近的地点

时间:2011-01-10 09:55:00

标签: php google-maps geocoding geo

我有一个数据库,其中包含每个纬度和经度的商店列表。所以根据我输入的当前(纬度,纬度)位置,我想得到一些半径范围内的物品清单,如1公里,5公里等?

算法应该是什么?我需要算法本身的PHP代码。

3 个答案:

答案 0 :(得分:31)

您只需使用以下查询。

例如,您输入的纬度和经度为37和-122度。并且您希望从当前给定的纬度和经度搜索25英里范围内的用户。

SELECT item1, item2, 
    ( 3959 * acos( cos( radians(37) ) 
                   * cos( radians( lat ) ) 
                   * cos( radians( lng ) 
                       - radians(-122) ) 
                   + sin( radians(37) ) 
                   * sin( radians( lat ) ) 
                 )
   ) AS distance 
FROM geocodeTable 
HAVING distance < 25 
ORDER BY distance LIMIT 0 , 20;

如果您想要以kms为单位的搜索距离,请在上述查询中将3959替换为6371。

你也可以这样做:

  1. 选择所有纬度和经度

  2. 然后计算每条记录的距离。

  3. 上述过程可以通过多次重定向完成。

  4. 为了优化查询,您可以使用存储过程。

    this也可以帮到你。

答案 1 :(得分:6)

您应该选择在空间上启用的数据库,如mysqlpostgresql,然后您可以使用它们提供的一些就绪功能。 否则,如果你想手动检查this是否有抬头。

答案 2 :(得分:6)

如果您正在寻找用于计算两组坐标之间距离的PHP代码,这是我改编的一个类,它将计算以千米为单位的距离。但是,如果您正在使用数据库,我建议您查看您的数据库是否能够进行空间计算(我知道SQL Server和MySQL是我的首选)。

这是您可能想要查看的SQL解决方案的有趣链接。 Optimising a haversine formula SQL call in PHP

class Distance
{
    /**
     * Mean raidus of the earth in kilometers.
     * @var double
     */
    const RADIUS    = 6372.797;

    /**
     * Pi divided by 180 degrees. Calculated with PHP Pi constant.
     * @var double
     */
    const PI180         = 0.017453293;

    /**
     * Constant for converting kilometers into miles.
     * @var double
     */
    const MILES     = 0.621371192;

    /**
     * Calculate distance between two points of latitude and longitude.
     * @param double $lat1 The first point of latitude.
     * @param double $long1 The first point of longitude.
     * @param double $lat2 The second point of latitude.
     * @param double $long2 The second point of longitude.
     * @param bool $kilometers Set to false to return in miles.
     * @return double The distance in kilometers or miles, whichever selected.
     */
    public static function getDistance($lat1, $long1, $lat2, $long2, $kilometers = true)
    {
        $lat1   *= self::PI180;
        $long1  *= self::PI180;
        $lat2   *= self::PI180;
        $long2  *= self::PI180;

        $dlat = $lat2 - $lat1;
        $dlong = $long2 - $long1;

        $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlong / 2) * sin($dlong / 2);
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

        $km = self::RADIUS * $c;

        if($kilometers)
        {
            return $km;
        }
        else
        {
            return $km * self::MILES;
        }
    }
}

//example
echo Distance::getDistance(40.686748, -89.555054, 40.453078, -88.939819);