2017-03-15 13 views
3

다양한 위치의 위도와 경도를 포함하는 POINT 열이있는 테이블이 있습니다.MySQL - 데이터베이스에서 반경 내의 포인트를 찾습니다.

나는 또한 브라우저의 지리적 위치에서 사용자 위치를 가지고 있습니다.

내가 할 수있는 필요한 것은 POINT 값이 10km 반경 (또는 Xkm 반경) 내에있는 테이블의 모든 레코드를 가장 가까운 것부터 순서대로 정렬하는 것입니다.

내 테이블의 POINT 열에 SPATIAL 색인이 있습니다.

+1

당신은 할 수있다 인덱스를 사용하여 원 안에 포인트를 찾지 않습니다. 그러나 인덱싱 된 룩업을위한 경계 상자를 정의하면 중심으로부터의 거리를 기준으로 필터링하면 빠른 결과를 얻을 수 있습니다. – symcbean

답변

8

현재 여러 위치 간의 거리를 계산하는 프로젝트를 진행 중입니다. 주어진 반경 내에있는 object_id를 선택하기 위해 다음 쿼리를 사용하고 있습니다.

SELECT id, 
(6371 * 
    ACOS( 
     COS(RADIANS(db_latitude)) * 
     COS(RADIANS($user_latitude)) * 
     COS(RADIANS($user_longitude) - 
     RADIANS(db_longitude)) + 
     SIN(RADIANS(db_latitude)) * 
     SIN(RADIANS($user_latitude)) 
    ) 
) 
AS distance FROM the_table HAVING distance <= $the_radius ORDER BY distance ASC" 

내가 연구에서 얻은 ACOS 공식은 설명 할 수 없다.

db_latitude = database latitude field 
db_longitude = database longitude field 
$user_latitude = browser latitude coördinate 
$user_longitude = browser longitude coördinate 
$the_radius = the radius that you want to search in 

킬로미터입니다.

+0

안녕하세요 @Bas 및 이것에 대한 감사하지만 내 Lat/Long은 두 개의 별도 플로트가 아닌 MySQL의 'POINT' 필드로 저장됩니다. 필자는이 정보를 저장하는 올바른 방법이라고 생각하여 효율성을위한'SPATIAL' 인덱스를 가질 수있었습니다. – tip2tail

+1

안녕하세요 @ tip2tail, 미안하지만 세부 사항을 간과했습니다. 나는 'POINT'필드에 익숙하지 않다. 이 스택 게시물을 찾으면 도움이 되었습니까? http://stackoverflow.com/a/21170928/5567106 –

+0

MySQL의 X() 및 Y() 함수를 통해 내 POINT를 위도와 경도로 가져와야했지만 이것은 답변이었습니다. . – tip2tail

0

https://ru.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL

장고를 들어 나는이

dist = 20 #дистанция 20 км 
    mylon = 51.5289156201 # долгота центра 
    mylat = 46.0209384922 # широта 
    lon1 = mylon-dist/abs(math.cos(math.radians(mylat))*111.0) # 1 градус широты = 111 км 
    lon2 = mylon+dist/abs(math.cos(math.radians(mylat))*111.0) 
    lat1 = mylat-(dist/111.0) 
    lat2 = mylat+(dist/111.0) 
    profiles = UserProfile.objects.filter(lat__range=(lat1, lat2)).filter(lon__range=(lon1, lon2)) 

그것은 squar의 20km의 모든 사용자를 검색 사용, 당신이 도움이 될 수 있습니다.

+0

안녕하세요 @ Nickita와 이것에 대한 감사합니다. 이것은 위의 대답과 매우 유사합니다. 내 의견을 참조하십시오. – tip2tail

0

나를 위해 실제로 일을 아래의 쿼리

$query = "SELECT *, 
    (6371 * 
    acos( 
    cos(radians(".$user_lat.")) * 
     cos(radians(lat)) * 
     cos(radians(lng) - 
     radians(".$user_lng.")) + 
     sin(radians(".$user_lat.")) * 
      sin(radians(lat)))) 
      AS distance FROM parkings 
      HAVING distance <= ".$radius." ORDER BY distance ASC"; 

    $stmt = $conn->execute($query); 

    $rows = $stmt->fetchAll('assoc'); 

: $의 user_lat와 $ user_lng 브라우저의 위도와 LNG, $ 반경 인은 = 10, 테이블 이름은 주차장