我有一个数据库,其中包含每个纬度和经度的商店列表。所以根据我输入的当前(纬度,纬度)位置,我想得到一些半径范围内的物品清单,如1公里,5公里等?
算法应该是什么?我需要算法本身的PHP代码。
答案 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。
你也可以这样做:
选择所有纬度和经度
然后计算每条记录的距离。
上述过程可以通过多次重定向完成。
为了优化查询,您可以使用存储过程。
this也可以帮到你。
答案 1 :(得分:6)
您应该选择在空间上启用的数据库,如mysql或postgresql,然后您可以使用它们提供的一些就绪功能。 否则,如果你想手动检查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);