2014-01-18 75 views
9

我有一個名爲'flags'的表格,它有一個400,000行的MySQL數據庫。此表格由代表英國各地不同位置的地理空間點組成。選擇邊界框內的所有地理空間點

我創建的應用程序使用Google地圖。在地圖上是一個應該切換地圖上標誌可見性的按鈕。現在我的工作是創建一個API,當通過邊界框時,返回邊界框內的所有標誌(以便它們可以顯示在地圖上)。

傳遞的參數是東北經/緯度和視口的當前位置的西南經/緯度。

我現在需要執行一個SQL查詢,將返回此組座標(視)內的所有地理空間點。

理想情況下,需要優化解決方案,因爲有很多行要搜索。但是,在用戶可以顯示標誌之前,應用程序確實會強制您放大到某個級別。

標誌表:

  • ID
  • 座標

實例行:

1 | [幾何 - 25B] | Tenacy AB

也可以使用AsText(座標)將座標字段轉換爲文字點。但是,X和Y功能可以爲你做到這一點。

座標列的數據類型爲:POINT

我知道,要獲得一個點的緯度/經度,您可以使用X和Y的功能。 X(座標)

DBMS:MySQL的
DBMS版本:5.6.14

+0

顯示'flags'表的定義將非常有幫助。您也可以顯示該表的六個樣本行。此外,由於英國橫跨主要子午線,經度的符號(+ - )將很重要。 –

+0

@OllieJones感謝Ollie,我已經編輯了標誌表結構的問題 – jskidd3

回答

22

假設geometry列中的POINT數據中的x和y項以經度和緯度爲度。

要在MySQL中有效地進行查找,您需要做一些事情。

  • 一個MyISAM表(或MySQL版本5。7及以後無論是InnoDB的或MyISAM數據)上的幾何列
  • 空間索引ALTER TABLE flags ADD SPATIAL INDEX (coordinates)
  • 代碼來創建您要搜索
  • 使用GeomFromText的矩形的文本表示
  • 一個NOT NULL資格和您的SELECT語句中的MBRContains/MBRWithin函數。

假設您的緯度/長方框是一個以Winchester Cathedral (51.0606, -1.3131)爲中心的矩形一度的矩形。你需要一個圍繞這個點的邊框。這個MySQL查詢將生成一個LINESTRING(文本),該行將沿着該邊界框沿着對角線行進。

SELECT 
     CONCAT('LINESTRING(', 
       latitude-0.5,' ',longitude-0.5, 
       ',', 
       latitude+0.5 ,' ',longitude +0.5, 
       ')') AS box 
    FROM (
     SELECT 51.0606 AS latitude, -1.3131 AS longitude 
    ) AS coord 

查詢得到你:

LINESTRING(50.5606 -1.8131,51.5606 -0.8131) 

您還可以使用字符串處理的宿主語言拿出一個類似某種文本字符串。你需要的格式是這個。

LINESTRING(lat1 long1, lat2 long2) 

然後你可以用它來搜索你的空間表如下:

SELECT whatever, whatever 
    FROM flags 
WHERE MBRContains(
     GeomFromText('LINESTRING(50.5606 -1.8131,51.5606 -0.8131)'), 
     flags.coordinates)  

這將利用空間索引和查找的flags每一行,其座標位於該對角線的邊界框內。

這是一些文檔。

http://dev.mysql.com/doc/refman/5.6/en/functions-for-testing-spatial-relations-between-geometric-objects.html#function_mbrcontains

如果您flags表中包含超過幾十萬行越少,你可能會發現,一個普通表(未空間表)隨緯度和經度列(FLOAT數據類型,索引)執行,以及並且更容易開發和調試。

我已經寫了關於該技術的教程。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

+1

我不能夠感謝你。神奇的答案,謝謝!在幾天之內,我可能需要您的幫助,因爲您似乎對MySQL地理空間主題非常瞭解。我在Google Plus上看到了您的電子郵件,如果我在幾天內向您發送了帶有另一個Stack問題鏈接的電子郵件,您是否介意?非常感謝你的幫助(如果你沒有猜到)!當然是 – jskidd3

+0

。祝你的程序好運。 –

+0

@OllieJones看起來像MySQL使用X/Y作爲Long/Lat,而不是像SO中常用的那樣使用Lat/Long。 Point(x y)實際上是Point(y x)。 – kouton

0

您可以使用quadkey例如,一個點的緯度可以這樣檢索。它減小了尺寸並簡化了空間搜索。我寫了一個PHP類hilbert-curve @ phpclasses.org。您還可以閱讀有關Microsoft Bing地圖拼貼的quadkey。基本上,quadkey有助於在x,y,z座標處查找拼貼。來源:http://msdn.microsoft.com/en-us/library/bb259689.aspx