2012-08-02 50 views
0

我的函数有问题,需要计算给定坐标之间的距离。正如我所看到的问题是负面的价值观,并且我正在想出如何解决这个问题,所以如果有人能够帮助我,我会非常感激!Mysql距离函数

DELIMITER $$ 

CREATE DEFINER=`sfff_user`@`%` FUNCTION `GetUserDistance`(lat VARCHAR (20), lon VARCHAR (20), userLat VARCHAR (20), userLon VARCHAR (20)) RETURNS int(11) 
BEGIN 
    DECLARE distance INT (11); 

    IF ISNULL(lat) OR ISNULL(lon) OR lat = '' OR lon = '' THEN 
     RETURN 0; 
    ELSE 
     SELECT 
      3956 * 2 * ASIN(SQRT(POWER(SIN((lat - ABS(userLat)) * PI()/180/2), 2) + COS(lat * PI()/180) * COS(ABS(userLat) * PI()/180) * POWER(SIN((lon - userLon) * PI()/180/2), 2))) 
     INTO 
      distance; 

     RETURN distance; 
    END IF; 

END 

例如导致该呼叫:

select GetUserDistance(44, 21, 44, 21) as distance;是这是确定

但是看看这个:

select GetUserDistance('-15.4167', '28.2833', '-15.4167', '28.2833') as distance; 

是这是疯了!

所以,如果你看一看这将是柠不错的功能正确,因为我渴望解决这一:(

感谢。

+0

如果你买得起,用[PostGIS的(https://en.wikipedia.org/wiki/PostGIS),因为它有很多这样的功能已经建立英寸 – feeela 2012-08-02 09:46:32

+0

这不是一个有ABS问题(userLat)?只要用userLat替换它就能解决你的问题。 – Scharron 2012-08-02 09:48:22

+0

@Scharron,不,我不会累,feeela - 不幸的不是:( – Splendid 2012-08-02 10:00:19

回答

0

为了安全起见,你要抛弃VARCHARDECIMAL和@Scharron说没必要的ABS尝试:

CREATE FUNCTION `GetUserDistance`(arg_lat VARCHAR (20), arg_lon VARCHAR (20), arg_userLat VARCHAR (20), arg_userLon VARCHAR (20)) RETURNS int(11) NO SQL 
BEGIN 
    DECLARE distance INT (11); 
    DECLARE lat, lon, userLat, userLon DECIMAL(14,4); 

    SET lat = CAST(arg_lat AS DECIMAL(14,4)); 
    SET lon = CAST(arg_lon AS DECIMAL(14,4)); 
    SET userLat = CAST(arg_userLat AS DECIMAL(14,4)); 
    SET userLon = CAST(arg_userLon AS DECIMAL(14,4)); 

    IF ISNULL(lat) OR ISNULL(lon) OR lat = '' OR lon = '' THEN 
     RETURN 0; 
    ELSE 
     SELECT 
      3956 * 2 * ASIN(SQRT(POWER(SIN((lat - userLat) * PI()/180/2), 2) + COS(lat * PI()/180) * COS(ABS(userLat) * PI()/180) * POWER(SIN((lon - userLon) * PI()/180/2), 2))) 
     INTO 
      distance; 

     RETURN distance; 
    END IF; 
END 
1

this link,公式应该没有ABS

3956 * 2 * ASIN(SQRT(POWER(SIN((lat - userLat) * PI()/180/2), 2) + COS(lat * PI()/180) * COS(ABS(userLat) * PI()/180) * POWER(SIN((lon - userLon) * PI()/180/2), 2)))