복붙노트

[SQL] SQL 쿼리, 주어진 좌표에 의해 가까운 곳을 선택 [중복]

SQL

SQL 쿼리, 주어진 좌표에 의해 가까운 곳을 선택 [중복]

내가 가진 $ 위도 = 29.6815400 및 $ 경도 = 64.3647100 지금 MySQL은 내가이 좌표에 15 개 가까운 장소를 취할 내가이 쿼리를 할 계획입니다 싶습니다에 :

SELECT *
FROM places
WHERE latitude  BETWEEN($latitude  - 1, $latitude  + 1)
AND   longitude BETWEEN($longitude - 1, $logintude + 1)
LIMIT 15;

당신은 올바른 생각하십니까 아니면 다른 뭔가를 제안합니까?

내가 km 가까운 장소의 범위 (50)의 최대 물마루 검색 할 때문에 방법 사이를 할까?

나는 쿼리를 실행하기 전에 나는 또한 할 일을 아무것도 PHP를 사용할 수있는 말을 잊어 버렸습니다.

참고 : 내가 저장 프로 시저를 사용할 수 없습니다.

해결법

  1. ==============================

    1.여기서, 두 지점 사이의 거리를 계산하는 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 :

    위도 각각의 정도는 약 떨어져 육십구마일 (111km)입니다. 범위는 극에서 69.407 (111.699 km)에 적도에서 68.703 마일 (110.567 km)에서 (때문에 지구의 약간 타원형 모양)에 따라 다릅니다. 각 분 (정도의 1 / 60)는 약 1.6km 떨어져 있기 때문에 편리합니다.

    경도의 정도는 69.172 마일 (111.321)의 적도 최광 차차 극 0으로 수축. 경도의 정도와 남쪽 40 ° 북쪽 또는 거리 53 개의 마일 (85km)입니다.

    그래서 계산 $ longitude2 $ latitude2 후 약 50km에 따라에 :

    $longitude2 = $longitude1 + 0.449; //0.449 = 50km/111.321km
    $latitude2 = $latitude1 + 0.450; // 0.450 = 50km/111km
    
  2. ==============================

    2.당신은 무거운 쿼리의 MySQL과 같은 어떤 DBMS를 범람하는 것이 최선의 해결책이 될 수 없습니다 것을 고려해야합니다.

    당신은 무거운 쿼리의 MySQL과 같은 어떤 DBMS를 범람하는 것이 최선의 해결책이 될 수 없습니다 것을 고려해야합니다.

    대신 대신 suddently 완벽한 원의 반경을 선택하는, 측면 $ 반경의 단순한 사각형 내부의 좌표로 모든 장소를 선택하는 매우 빠른 SQL 쿼리를 추측 할 수 있습니다. 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 비슷한 () 함수를 중심으로 결과 집합의 좌표에서의 거리를 비교,이 페이지에 게시하여 잉여를 제거합니다 동안 전체 테이블 스캔을 필요로하지 않는 매우 친절 쿼리를 실행 당신의 반경.

    데이터베이스에 (큰) 성능 향상을하지 않는 낭비하기 위해, 인덱스 좌표 열합니다.

    해피 해킹!

  3. ==============================

    3.나는 주어진 지점에서 거리 의해 수행 판매 주택 앱 비슷한, 주문을했습니다, 당신의 SQL select 문이 장소 :

    나는 주어진 지점에서 거리 의해 수행 판매 주택 앱 비슷한, 주문을했습니다, 당신의 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"
    

    당신의 관련 위도 / 경도의 LNG 값과 map_lat와 $ SEARCH_LOCATION 교체 / map_lng 값은 위도 / 경도의 LNG 값이 포함 된 SQL 열이 있습니다. 그런 다음 50km 범위 내에서 우리의 속성을 필터링하는 거리 중 하나를 사용 a 또는 HAVING 절에 의한 결과를 주문할 수 있습니다.

    접근하면 페이징 등의 추가 기능을 필요로하는 경우에 PHP에 비해 나는 SQL을 사용하는 것이 좋습니다 것입니다.

  4. ==============================

    4.A는 후반 비트하지만 사람을 도움이 될 수 있습니다 - 당신은 위치에 따라 가장 가까운 도시를 원하는 경우 다음 고립 된 위치에 아무것도 검색하지 않기 때문에, 나는 거리를 갈 것입니다. 이 시도:

    A는 후반 비트하지만 사람을 도움이 될 수 있습니다 - 당신은 위치에 따라 가장 가까운 도시를 원하는 경우 다음 고립 된 위치에 아무것도 검색하지 않기 때문에, 나는 거리를 갈 것입니다. 이 시도:

    $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;
    
  5. from https://stackoverflow.com/questions/14254641/sql-query-select-nearest-places-by-a-given-coordinates by cc-by-sa and MIT license