2014-03-07 32 views
1

我有一個「地點」表,其中包含lat,lng和point字段。我一直在使用半正式公式來計算lat,lng的距離,但我讀到使用點域更有效率?我只是找不到有關如何做到這一點的任何文檔。這是我的查詢,因爲它現在站立查詢所有地點和距離如何在MySQL中查詢具有地理空間「點」字段的表格

SELECT `places`.*, `places`.`id` AS `pid`, 
     ((6371*acos(cos(radians(37.776708))*cos(radians(lat))* 
      cos(radians(lng)-radians(-122.398050))+sin(radians(37.776708))* 
      sin(radians(lat))))*1000) AS `distance` 
    FROM `places` 
    WHERE `page_id` IS NOT null 
    ORDER BY `distance` ASC 
    LIMIT 40 OFFSET 0 

責令我怎樣才能改變這種使用「點」字段的表,而不是緯度/經度

回答

2

有你需要做一些事情來使用MySQL地理空間擴展來完成這種事情。

  1. 您必須爲您的地理空間數據使用MyISAM表。
  2. 您需要在表中有一個GEOMETRY列,並且它必須是NOT NULL。
  3. 您不能使用問題中提到的球形餘弦定律距離計算作爲您的主要搜索條件。您需要使用邊界框(也就是說,您需要在搜索點的特定距離內搜索點)。

您當前的查詢通過檢查找到最靠近的點(37.77671,-122.3980)當你使用地理空間時,你做的事情比這更聰明一些,你需要建立一個接近極限,我們稱它爲10.0法定英里的半徑。有每北緯69.0度法定英里。

那麼,你如何做到這一切?

首先使自己與GE的表ometry列,或許是這樣的:

CREATE TABLE geoplace (
    id INT NOT NULL, 
    geo GEOMETRY NOT NULL, 
    PRIMARY KEY id (id), 
    SPATIAL KEY geo (geo) 
) ENGINE=MYISAM 

然後填充它這樣的事情,把一個幾何Point項目到每個geo值。

INSERT INTO geoplace 
SELECT DISTINCT id, 
       GEOMFROMTEXT(
        CONCAT('POINT(', 
        lat, 
        ' ', 
        lng, 
       ')') ) AS geo 
FROM places 

當然,你可以把幾何列到你想要的任何表。但是你不能在InnoDB表中創建一個有效的空間索引;該訪問方法不支持空間索引。

然後,您需要這樣的查詢來檢索您的信息。

SELECT id, X(geo), Y(geo), distance FROM (
SELECT id, geo,r, 
     units * DEGREES(ACOS(
        COS(RADIANS(latpoint)) 
       * COS(RADIANS(X(geo))) 
       * COS(RADIANS(longpoint) - RADIANS(Y(geo))) 
       + SIN(RADIANS(latpoint)) 
       * SIN(RADIANS(X(geo))))) AS distance 
FROM geoplace 
JOIN (
     SELECT 37.776708 AS latpoint, -122.398050 AS longpoint, 
       10.0 AS r, 69.0 AS units 
    ) AS p ON (1=1) 
WHERE MbrContains(GeomFromText(
     CONCAT('LINESTRING(', 
       latpoint-(r/units),' ', 
       longpoint-(r /(units* COS(RADIANS(latpoint)))), 
       ',', 
       latpoint+(r/units) ,' ', 
       longpoint+(r /(units * COS(RADIANS(latpoint)))), 
       ')')), geo) 
) AS d 
WHERE distance <= r 
ORDER BY distance 

注意查詢的這個偉大的毛球使用您在本節中提供的參數:

 SELECT 37.776708 AS latpoint, -122.398050 AS longpoint, 
       10.0 AS r, 69.0 AS units 

它將使用MbrContains做一個空間矩形搜索,然後計算它找到的點的距離使用球形餘弦定律公式,然後正確命令它們。與開始的查詢相比,這個事情運行得非常快,因爲它利用了空間索引。

這是寫在這裏更詳細。

http://www.plumislandmedia.net/mysql/using-mysqls-geospatial-extension-location-finder/

背景在這裏。

http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

相關問題