2014-01-19 23 views
1

我意識到這個問題已經被多次提出,但是我看到的每個答案似乎都非常符合OP想要達到的目標。這就是爲什麼我正在尋找一個簡單的使用-90到90之間的緯度值以及-180到180之間的經度值的一般答案。PHP和MySQL使用SPATIAL擴展獲得n個最近點

所以這裏是簡單的前提:有兩個獲取變量由包含lat和lng的php文件接收。查找n最近的點,按距離最近的順序排列。

讓我們設置中,將稱爲位置

CREATE TABLE `trees` 
(
    `TREEID` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `location` point NOT NULL, 
    PRIMARY KEY (`TREEID`), 
    SPATIAL KEY `location` (`location`) 
) ENGINE=MyISAM; 

現在,我們希望用PHP現在的工作

<?php 

//Setup variables 
$lat = trim(mysql_prep($_GET['lat'])); 
$lng = trim(mysql_prep($_GET['lng'])); 
$n = 100; 

//Make sure they are valid lat and lng 
if (!is_numeric($lat) || floatval($lat) < -90 || floatval($lat) > 90 || 
    !is_numeric($lng) || floatval($lng) < -180 || floatval($lng) > 180 ) 
{ 
     die("Invalid lng and lat coordinates."); 
} 
else 
{ 
     //Lets find the n closest points to our $lat, $lng 
     $get_trees = "Select * FROM trees WHERE _____?______ Order by _?_ ASC"; 
     $result = mysql_query($get_trees , SQL_Connection()); 
} 


?> 

一個索引點一個簡單的表,它是從我的理解是有空間的mysql索引的位置,查詢應該相對較快。然而,在做什麼的答案之間有一些爭論。一些用戶可以設置計算海峽距離的函數。一些人在查詢中做了正確的查詢,看起來很亂。根據您想要答案的準確程度,有些切角。大多數常見答案似乎都假設開發者將lat/lng存儲爲雙打,我不確定最好是將這個數學用於點索引。我瀏覽了文檔的空間擴展,並沒有能夠將它拼湊在一起。所以這個問題是,該怎麼做。說明查詢及其所具有的準確性級別以及顯示您預定義的任何SQL函數將會很有幫助。這個問題假設我們尋找最接近特定緯度的點,而不是搜索特定距離內的點(例如20公里內)。我特別尋找一個答案,給出接近100%的正確性,爲n介於100和500.

+0

更簡單的選擇可在http://stackoverflow.com/questions/4995428/storing-lat-lng-values-in-mysql-using-spatial-point-type –

回答

2

好吧,所以我結束了使用haversine。實際上它非常快,並且將它用作獲取積分的ajax請求是個好主意。

$get_trees = "Select TREEID, X(location) as lat, Y(location) as lng, 
(6371000 * 
     acos( 
      cos(radians($lat)) 
     * cos(radians(X(location))) 
     * cos(radians(Y(location)) - radians($lng)) 
     + sin(radians($lat)) 
     * sin(radians(X(location))))) AS distance 


FROM trees ORDER BY distance ASC LIMIT 0 , $n;"; 

$result = mysql_query($get_trees , SQL_Connection()); 

while ($record = mysql_fetch_assoc ($result)) 
{ 
    $tree_identity = $record['TREEID']; 
    $distance_in_meters = $record['distance']; 
    $tree_lat = $record['lat']; 
    $tree_lng = $record['lng']; 
} 

由於公式假設地球是一個球體(恆定半徑),這裏是半徑值,您可以使用:

對於米,採用6371000

英里,使用3959

數公里,使用6371

我希望有人會發現這是很有幫助的,或至少它會給你的如何處理該問題的想法。如果你想要點在一定的距離內,比如10米,加上「HAVING distance < 10」。