我试图获得两点之间的距离,这很好,但我遇到的问题是这些警告信息:
第32行的列'x'截断数据 第82行的列'x'截断数据 第89行的“x”列截断数据
这是我创建的功能:
CREATE FUNCTION `GetDistance`(`lat1` numeric(10, 7), `lon1` numeric(10, 7), `lat2` numeric(10, 7), `lon2` numeric(10, 7))
RETURNS decimal(10,7)
BEGIN
DECLARE x decimal(10, 7);
DECLARE pi decimal(21, 20);
SET pi = 3.14159265358979323846;
SET x = round(sin(lat1 * pi / 180)
* sin(lat2 * pi / 180)
+ cos(lat1 * pi / 180)
* cos(lat2 * pi / 180)
* cos((lon2 * pi / 180) - (lon1 * pi / 180)), 7);
SET x = round(atan((sqrt( 1- power( x, 2))) / x), 7);
RETURN round((1.852 * 60.0 * ((x / pi) * 180)) / 1.609344, 7);
END
以下是lat1
,lon1
和lat2
,lon2
CREATE TABLE `world_cities` (
`latitude` DECIMAL(10,7) NULL DEFAULT NULL,
`longitude` DECIMAL(10,7) NULL DEFAULT NULL,
)
以下是最大/最小值:
"max(latitude)" "min(latitude)" "max(longitude)" "min(longitude)"
"82.4833330" "-54.9333330" "180.0000000" "-179.9833333"
那么,是什么导致了这条警告信息?
以下是调用函数的查询:
SELECT city, region, population, latitude, longitude,
GetDistance(@lat, @lon, latitude, longitude) as dist
FROM world_cities
WHERE MBRContains(LineString(Point(@lat + @kmRange / 111.1, @lon + @kmRange / (111.1 / COS(RADIANS(@lat)))), Point(@lat - @kmRange / 111.1, @lon - @kmRange / (111.1 / COS(RADIANS(@lat))))), location)
and city_id != @city_id
order By dist;
答案 0 :(得分:0)
您返回RETURNS decimal(10,7)
并同时计算远远超过decimal(10,7)
的距离
arctan(a)
的值应介于-pi/2
和pi/2
之间(-1.57 ... 1.57
)。
我们假设x = pi/2
,x / pi = (pi/2) / pi = 1/2
您的距离值将超过6000
,大于decimal(10,7)
。
尝试将RETURNS decimal(10,7)
更改为RETURNS decimal(11,7)
,它应涵盖所有可能的值,并且无需警告即可正常工作。
答案 1 :(得分:0)
请试试这个:
CREATE FUNCTION `GetDistance`(`lat1` numeric(10, 7), `lon1` numeric(10, 7), `lat2` numeric(10, 7), `lon2` numeric(10, 7))
RETURNS decimal(10,7)
BEGIN
DECLARE x decimal(10, 7);
DECLARE pi decimal(21, 20);
SET pi = 3.14159265358979323846;
SET x = cast(sin(lat1 * pi / 180)
* sin(lat2 * pi / 180)
+ cos(lat1 * pi / 180)
* cos(lat2 * pi / 180)
* cos((lon2 * pi / 180) - (lon1 * pi / 180)) as decimal(10, 7));
SET x = cast(atan((sqrt( 1- power( x, 2))) / x) as decimal(10, 7));
RETURN cast((1.852 * 60.0 * ((x / pi) * 180)) / 1.609344 as decimal(10, 7));
END
我怀疑浮点近似误差。
答案 2 :(得分:0)
通过将“x”声明为double
,并将我的返回类型设置为double
,我就能解决问题。
更改此内容:
DECLARE x decimal(10, 7);
对此:
DECLARE x double;