SQL查询,选择一个给定的坐标最近的地方[复制](SQL query, select nearest

2019-07-18 01:50发布

这个问题已经在这里有一个答案:

  • 之间找到两个纬度/长点的距离最快的方法 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做任何事情之前,运行查询。

注: 我不能使用存储过程

Answer 1:

这里的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";

你可以看看这里类似的计算。

你可以阅读更多在这里

更新:

你要记住,计算longitude2longitude2你需要知道的是:

纬度的每度为约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


Answer 2:

你必须考虑到,洪水像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()张贴在本页面功能,从结果设定为中心坐标进行比较的距离你的半径。

为了不浪费的(大)的性能提升,指数的坐标列在数据库中。

快乐的黑客攻击!



Answer 3:

我已经做了房屋销售的应用程序类似的东西,从给定点的距离排序,把这个在您的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。



Answer 4:

晚了一些,但它可以帮助别人 - 如果你想按位置最近的城市,我也不会去距离,因为那么一个孤立的位置将不会检索任何东西。 试试这个:

$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;


文章来源: SQL query, select nearest places by a given coordinates [duplicate]