2017-03-15 83 views
3

我有一個表格,其中包含各個位置的緯度和經度的POINT列。MySQL - 在數據庫中查找半徑範圍內的點

然後,我還從瀏覽器中的地理位置獲取用戶位置。

我需要做的就是查找表格中的所有記錄,其中的POINT值位於半徑10公里(或半徑X公里)內,按照距離最近的第一個排序。

我的表在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,並感謝這一點,但我的經緯度被存儲爲一個MySQL'POINT'字段而不是兩個獨立的浮點數。我的理解是,這是存儲這些信息的正確方式,所以我可以有一個「SPATIAL」索引來提高效率。 – tip2tail

+1

Hi @ 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

Django的我用這個

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)) 

它搜索所有用戶SQUAR20公里。

+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是瀏覽器的緯度和經度, $半徑= 10, 表名是停車場