2010-08-22 51 views
4

我已經能夠創建php函數來確定給定郵政編碼的一定範圍內的郵政編碼列表。但是,我的下一個任務更復雜一點。用於確定郵編接近度/範圍的MySQL函數

比方說表有以下欄目:

id, 
username 
info 
latitude 
longitude 
range 

的每條記錄都有一個唯一的行ID,一些信息,緯度,經度,並從這些座標的人希望這個條目的最大範圍被發現。因此,如果我使用座標-20和50創建一個條目範圍爲15的條目,這意味着我只希望距座標-20和50的15英里內的人能夠看到我的條目。計算用戶運行搜索的經度和緯度是一件小事。

當用戶搜索數據庫時,應檢索緯度和經度座標的所有記錄,其範圍是lat/long用戶範圍內的值。

所以,這將是

$userLat的使用距離公式來說明代碼的非功能性示例=在運行搜索

$userLong的用戶的緯度=用戶的經度那正在運行搜索

SELECT info FROM table 
WHERE sqrt(($userLat - lat)^2 - ($userLong - long)^2) <= range 
ORDER BY username ASC 

這將是理想的,但從編碼的角度來看它是無效的。有沒有辦法在一個查詢中使用PHP和MySQL來運行上述比較?這將涉及能夠使用給定行中的多個列值運行操作。


UPDATE +溶液

我創造了另一個問題條目,解決了這個問題,有一個非常緊湊的函數來完成這個問題想要什麼。 coderpros給出的功能是它的靈感(他的功能在某些情況下有更好的處理能力)。但是,由於我使用我的功能對輸入進行了很大程度的控制,因此我創建了一個單獨的函數。它可以在下面的鏈接中找到:

MySQL User Defined Function for Latitude Longitude Syntax

回答

6

,我寫一定要爲你做的伎倆這個漂亮可愛的小MySQL的功能。

BEGIN 
    DECLARE x decimal(18,15); 
    DECLARE EarthRadius decimal(7,3); 
    DECLARE distInSelectedUnit decimal(18, 10); 

    IF originLatitude = relativeLatitude AND originLongitude = relativeLongitude THEN 
      RETURN 0; -- same lat/lon points, 0 distance 
    END IF; 

    -- default unit of measurement will be miles 
    IF measure != 'Miles' AND measure != 'Kilometers' THEN 
      SET measure = 'Miles'; 
    END IF; 

    -- lat and lon values must be within -180 and 180. 
    IF originLatitude < -180 OR relativeLatitude < -180 OR originLongitude < -180 OR relativeLongitude < -180 THEN 
      RETURN 0; 
    END IF; 

    IF originLatitude > 180 OR relativeLatitude > 180 OR originLongitude > 180 OR relativeLongitude > 180 THEN 
     RETURN 0; 
    END IF; 

    SET x = 0.0; 

    -- convert from degrees to radians 
    SET originLatitude = originLatitude * PI()/180.0, 
     originLongitude = originLongitude * PI()/180.0, 
     relativeLatitude = relativeLatitude * PI()/180.0, 
     relativeLongitude = relativeLongitude * PI()/180.0; 

    -- distance formula, accurate to within 30 feet 
    SET x = Sin(originLatitude) * Sin(relativeLatitude) + Cos(originLatitude) * Cos(relativeLatitude) * Cos(relativeLongitude - originLongitude); 

    IF 1 = x THEN 
      SET distInSelectedUnit = 0; -- same lat/long points 
      -- not enough precision in MySQL to detect this earlier in the function 
    END IF; 

    SET EarthRadius = 3963.189; 
    SET distInSelectedUnit = EarthRadius * (-1 * Atan(x/Sqrt(1 - x * x)) + PI()/2); 

    -- convert the result to kilometers if desired 
    IF measure = 'Kilometers' THEN 
      SET distInSelectedUnit = MilesToKilometers(distInSelectedUnit); 
    END IF; 

    RETURN distInSelectedUnit; 
END 

它將originLatitude,originLongitude,relativeLatitude,relativeLongitude和measure作爲參數。度量可以簡單地爲MilesKilometers

希望幫助!

+0

非常感謝您的快速和翔實的答覆。請原諒我的白癡,但我不熟悉使用自定義mysql函數。我究竟如何使用這個與PHP? – user396404 2010-08-23 00:24:01

+0

那麼,你需要做的是在你的mySQL數據庫中創建上述功能,然後你可以在你的php中調用它,如下所示: $ sql =「SELECT * FROM users WHERE CalculateDistance(userLat,userLong,relLat,relLong, 'miles)<15; 這有道理嗎? – coderpros 2010-08-23 00:41:02

+0

啊,呃。只是最後一件事,我應該準備好使用它。 在下面的部分: CalculateDistance(userLat,userLong,relLat,relLong,'英里)<15 我會被傳遞userLat和userLong的值作爲PHP變量和relLat和relLong將是列的名稱在MySQL的。另外,15將被該行的範圍列的值替換。你的代碼會這樣做嗎?對不起,只是想確定一下,因爲設置一些東西並花費數小時來貶低錯誤的東西是一場噩夢。我相信你明白。 – user396404 2010-08-23 01:44:48