2012-07-11 54 views
6

我的目標是使用mysql POINT(lat,long)在數據庫中查找附近的實體。我正在嘗試在本教程http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL的底部做些事情。以下是我有:使用POINT的Mysql空間距離 - 不能正常工作

表:

CREATE TABLE mark (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
name VARCHAR(20) DEFAULT NULL, 
loc POINT NOT NULL, 
SPATIAL KEY loc (loc) 
) ENGINE=MyISAM; 

插入一些測試數據:

INSERT INTO mark (loc,name) VALUES (POINT(59.388433,10.415039), 'Somewhere 1'); 
INSERT INTO mark (loc,name) VALUES (POINT(63.41972,10.39856), 'Somewhere 2'); 

聲明的距離函數:

DELIMITER $$ 
CREATE FUNCTION `distance` 
(a POINT, b POINT) 
RETURNS double DETERMINISTIC 
BEGIN 
RETURN 
round(glength(linestringfromwkb(linestring(asbinary(a), 
asbinary(b))))); 
END $$ 
DELIMITER;  

嘗試使用的功能搜索例如:

SELECT name, distance(mark.loc, GeomFromText(' POINT(31.5 42.2) ')) AS cdist 
FROM mark 
ORDER BY 
cdist limit 10; 

或:

SELECT DISTINCT 
dest.name, 
distance(orig.loc, dest.loc) as sdistance 
FROM 
mark orig, 
mark dest 
having sdistance < 10 
ORDER BY 
sdistance limit 10; 

我正的問題是:ERROR 1367(22007):非法非幾何 'aswkb(一個@ 0)' 在分析過程中發現的值,或 ERROR 1416(22003):無法從發送到GEOMETRY字段的數據獲取幾何對象

我似乎無法弄清楚如何解決這個問題。重要的是,'距離'功能可以動態使用。

我自己也嘗試此解決方案:Find the distance between two points in MYSQL. (using the Point Datatype)

這是我的MySQL版本的MySQL版本14.14 5.5.23 DISTRIB,爲Linux下(x86_64)使用readline的5.1

希望某人的專業知識能幫助我。乾杯!

+1

嘗試'輪(glength(LineStringFromWKB(線段形式(GeomFromText(astext(A)),GeomFromText (astext(b))))))' – acraig5075 2012-07-12 08:48:23

+0

@ acraig5075 - 感謝您的建議,我結束了幾乎相同的結果。 – OMA 2012-07-12 11:47:55

回答

7

所以我結束了這個作爲查詢計算距離,例如:

SELECT glength(LineStringFromWKB(LineString(GeomFromText(astext(PointFromWKB(POINT(63.424818,10.402457)))),GeomFromText(astext(PointFromWKB(POINT(663.422238,10.398996)))))))*100 
AS distance; 

我乘以100,以獲得公里的近似值。結果並不確切,但「確定」。如果有人知道更好的方法,請隨時發表評論。

3

定義自定義功能

CREATE DEFINER=`test`@`%` FUNCTION `geoDistance`(`lon1` DOUBLE, `lat1` DOUBLE, `lon2` DOUBLE, `lat2` DOUBLE) 
    RETURNS double 
    LANGUAGE SQL 
    DETERMINISTIC 
    NO SQL 
    SQL SECURITY DEFINER 
    COMMENT '' 
    BEGIN 
    DECLARE v DOUBLE; 
    SELECT cos(radians(lat1)) 
     * cos(radians(lat2)) 
     * cos(radians(lon2) - radians(lon1)) 
     + sin(radians(lat1)) 
     * sin(radians(lat2)) INTO v; 
    RETURN IF(v > 1, 0, 6371000 * acos(v)); 
END 

然後調用

SELECT geoDistance(X(point1), Y(point1), X(spoint2), Y(point2)) 

結果進來米