这个问题已经在这里有一个答案:
- 之间找到两个纬度/长点的距离最快的方法 16个回答
我有$latitude = 29.6815400
和$longitude = 64.3647100
,现在在MySQL我想借15米最近的地方,以这些坐标,我打算做此查询:
SELECT *
FROM places
WHERE latitude BETWEEN($latitude - 1, $latitude + 1)
AND longitude BETWEEN($longitude - 1, $logintude + 1)
LIMIT 15;
你认为它是正确的还是你的建议是什么东西?
如何做好BEETWEEN
,因为我要搜索槽最大的近地每小时50公里范围内?
我忘了说,我也可以使用PHP做任何事情之前,运行查询。
注: 我不能使用存储过程 。
这里的PHP公式计算两个点之间的距离:
function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'Mi')
{
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))+
(cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance); $distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch($unit)
{
case 'Mi': break;
case 'Km' : $distance = $distance * 1.609344;
}
return (round($distance,2));
}
然后添加一个查询来获取所有的距离小于或等于上面的一个记录:
$qry = "SELECT *
FROM (SELECT *, (((acos(sin((".$latitude."*pi()/180)) *
sin((`geo_latitude`*pi()/180))+cos((".$latitude."*pi()/180)) *
cos((`geo_latitude`*pi()/180)) * cos(((".$longitude."-
`geo_longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344)
as distance
FROM `ci_geo`)myTable
WHERE distance <= ".$distance."
LIMIT 15";
你可以看看这里类似的计算。
你可以阅读更多在这里
更新:
你要记住,计算longitude2和longitude2你需要知道的是:
纬度的每度为约69英里(111公里)分开。 该范围内变化(由于地球的轻微椭圆形),在两极距离赤道68.703英里(110.567公里)以69.407(111.699公里)。 这是方便的,因为每分钟(度1 /第60)是大约一英里。
经度的程度是在69.172英里(111.321)的赤道最宽,而在两极逐渐缩小到零。 在40℃北或南度经度的之间的距离为53英里(85公里)。
所以要计算$longitude2 $latitude2
根据50公里则约为:
$longitude2 = $longitude1 + 0.449; //0.449 = 50km/111.321km
$latitude2 = $latitude1 + 0.450; // 0.450 = 50km/111km
你必须考虑到,洪水像MySQL任何DBMS重查询不应该是最好的解决办法。
相反,你可以推测一个非常快速的SQL查询选择所有的地方与侧面的简单正方形内的坐标$radius
而不是选择suddently一个完美的圆半径。 PHP
可以过滤多余的。
让我告诉概念:
$lat = 45.0.6072;
$lon = 7.65678;
$radius = 50; // Km
// Every lat|lon degree° is ~ 111Km
$angle_radius = $radius / ( 111 * cos( $lat ) );
$min_lat = $lat - $angle_radius;
$max_lat = $lat + $angle_radius;
$min_lon = $lon - $angle_radius;
$max_lon = $lon + $angle_radius;
$results = $db->getResults("... WHERE latitude BETWEEN $min_lat AND $max_lat AND longitude BETWEEN $min_lon AND $max_lon"); // your own function that return your results (please sanitize your variables)
$filtereds = [];
foreach( $results as $result ) {
if( getDistanceBetweenPointsNew( $lat, $lon, $result->latitude, $result->longitude, 'Km' ) <= $radius ) {
// This is in "perfect" circle radius. Strip it out.
$filtereds[] = $result;
}
}
// Now do something with your result set
var_dump( $filtereds );
这样的MySQL运行并不需要进行全表扫描,而PHP剔除多余的类似的东西非常友好的查询getDistanceBetweenPointsNew()
张贴在本页面功能,从结果设定为中心坐标进行比较的距离你的半径。
为了不浪费的(大)的性能提升,指数的坐标列在数据库中。
快乐的黑客攻击!
我已经做了房屋销售的应用程序类似的东西,从给定点的距离排序,把这个在您的SQL SELECT语句:
((ACOS(SIN(' . **$search_location['lat']** . ' * PI() / 180) * SIN(**map_lat** * PI() / 180) + COS(' . **$search_location['lat']** . ' * PI() / 180) * COS(**map_lat** * PI() / 180) * COS((' . **$search_location['lng']** . ' - **map_lng**) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS "distance"
替换$search_location
与你相关的纬度/经度值和map_lat / map_lng值是包含纬度/经度值的SQL列。 然后,您可以按距离对结果,要么使用where或having子句50公里范围内筛选我们的物业。
作为该方法相比,在事件中,你需要额外的功能,如分页PHP我会建议使用SQL。
晚了一些,但它可以帮助别人 - 如果你想按位置最近的城市,我也不会去距离,因为那么一个孤立的位置将不会检索任何东西。 试试这个:
$G_how_close_to_find_cities = "1.1"; // e.g. 1.1 = 10% , 1.2=20% etc
$G_how_many_cities_to_find_by_coordinates = "10";
$query = "SELECT * from Cities WHERE
Cities__Latitude <= ('".$latitude*$G_how_close_to_find_cities."') AND Cities__Latitude >= ('".$latitude/$G_how_close_to_find_cities."')
AND Cities__Longitude <= ('".$longitude*$G_how_close_to_find_cities."') AND Cities__Longitude >= ('".$longitude/$G_how_close_to_find_cities."')
ORDER BY SQRT(POWER((Cities__Latitude - ".$latitude."),2)+POWER((Cities__Longitude - ".$longitude."),2)) LIMIT 0,".$G_how_many_cities_to_find_by_coordinates;