Mysql距离函数

时间:2012-08-02 09:42:05

标签: mysql distance

我的功能问题需要计算给定坐标之间的距离。正如我所看到的,问题是负面的价值观,而且我已经没有想法如何解决这个问题,所以如果有人能帮助我,我会非常感激!

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; 0 ,这是好的

但是看看这个:

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

2129 这是疯了!

所以如果你能看一下,拥有正确的功能会很好,因为我很想解决这个问题:(

感谢。

2 个答案:

答案 0 :(得分: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)))

答案 1 :(得分: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