2017-04-04 23 views
0

我有興趣製作一個網站,該網站將存儲多個位置,並且需要能夠根據用戶的查詢找到它們。類似於Yelp,Zomato,Zillow等網站的功能。我首選的技術堆棧是PHP/MySQL。查詢某個區域中的位置數據庫

這就是說,我有幾個相關的問題。鑑於位置的數據庫,與他們的關聯緯度/經度座標...

  1. 他們如何能夠查詢自己的位置數據庫的特定城市或郵政編碼X距離內返回的人?
  2. 此外,他們如何查詢他們的數據庫的位置,而不是在鄰近範圍內,是在非常具體的城市或國家限制內?他們從哪裏獲得邊界數據,以及如何確定座標是否以有效的方式落在該邊界內?
  3. 最後,我注意到一些網站在他們的網站上有特定城市的鏈接。我預計城市數據將從遠程地圖API中提取,但他們經常會將圖片和其他內容與這些城市相關聯。這些網站是否將所有城市的名稱存儲在自己的數據庫中?他們在哪裏得到他們的名單?
+0

對於#1,您可以使用基於Haversine公式的半徑搜索。給定初始郵政編碼和搜索距離。如果您可以使用谷歌地圖API或類似的東西獲得緯度/經度,則可以使其更加準確。 – JuveLeo1906

+0

通常,距離查找包括存儲每個位置的緯度/經度,並使用函數來計算用戶位置(基於緯度/經度)與數據庫中的記錄之間的距離。對於城市搜索,通常基於地點的城市/州部分地址。 –

+0

這個問題似乎對這個網站有點寬泛,但我建議你需要知道你感興趣的點的緯度/經度。將它轉換爲弧度以方便使用。 Lat是-pi到pi(90S到90N),lon是-pi到pi(180W到180E)。直線距離公式很容易與Google進行比較,並且在當地有足夠接近的估計值。弄清楚在多邊形區域內是否有東西更難,我還沒有想到這一點。 – SandPiper

回答

0

這將有助於您的第一點。

我使用此查詢從起點開始搜索數據庫中的屬性。起點是經度和緯度,$coordX$coordY。我把這些從谷歌地圖API做一個地理代碼查找:

SELECT properties.*, 
    (
     ( ACOS(SIN(".$coordX." * PI()/180) * 
      SIN(coordX * PI()/180) + COS(".$coordX." * PI()/180) * 
      COS(coordX * PI()/180) * COS((".$coordY." - coordY) * 
      PI()/180)) * 180/PI()) * 60 * 1.1515 
     ) 
    AS distance 
FROM properties 
order by distance 

在我的表我個人性質的座標的座標存儲在coordXcoordY列。

0

這裏是MySQL函數,它將採用兩個緯度/經度對,並給出兩點之間的度數距離。 它使用Haversine公式來計算距離。由於地球不是完美的球體,因此在極點和赤道附近存在一些誤差。

  • 要轉換爲英里,乘以3961.
  • 要通過6373.
  • 轉換成公里,乘若要6373000.
  • 轉換爲米,乘以要轉換到腳,乘以(3961 * 5280)20914080.

    DELIMITER $$

    CREATE FUNCTION haversine( LAT1 FLOAT,LO n1 FLOAT, lat2 FLOAT,lon2 FLOAT )返回浮點數 否SQL 確定性 註釋'返回兩個已知經度和緯度點之間的地球上度數的距離。爲了得到英里,由3961乘,並通過6373' 公里 BEGIN RETURN DEGREES(ACOS( COS(RADIANS(LAT1))* COS(RADIANS(LAT2))* COS(RADIANS(lon2) - RADIANS(lon1 ))+ SIN(RADIANS(lat1))* SIN(RADIANS(lat2)) )); END;

    DELIMITER;

使用FLOAT(10,6)類型將列添加到緯度和經度的地址表中。 編寫一個php腳本來保存記錄時對lat/long進行查找。

然後,您可以對錶進行選擇以獲取具有距離的地址列表。您甚至可以按距離排序結果 ,或將結果限制在參考位置的某個半徑範圍內。

SELECT 
    `street`, 
    `city`, 
    `state`, 
    `zip`, 
    (haversine($ref_location_lat,$ref_location_long,`lat`,`long) * 3961) as `distance` 
FROM `address_table` 
WHERE (haversine($ref_location_lat,$ref_location_long,`lat`,`long) * 3961) < 300 // Example for limiting returned records to a raduis of 300 miles. 
ORDER BY haversine($ref_location_lat,$ref_location_long,`lat`,`long) DESC;  // Don't need actual distance for sorting, just relative distance.