我的功能问题需要计算给定坐标之间的距离。正如我所看到的,问题是负面的价值观,而且我已经没有想法如何解决这个问题,所以如果有人能帮助我,我会非常感激!
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 这是疯了!
所以如果你能看一下,拥有正确的功能会很好,因为我很想解决这个问题:(
感谢。
答案 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)
为了安全起见,您应该VARCHAR
至DECIMAL
,并且@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