1

我正在尝试获取两点之间的距离,效果很好,但我遇到的问题是这些警告消息:

第 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,lon1lat2,的两列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;
4

3 回答 3

0

您返回RETURNS decimal(10,7)并同时计算远大于 的距离decimal(10,7)
的值arctan(a)应该在-pi/2pi/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),它应该涵盖所有可能的值并且可以在没有警告的情况下工作。

于 2013-08-22T06:12:11.523 回答
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

我怀疑浮点近似错误。

于 2013-08-22T20:30:01.220 回答
0

通过将 'x' 声明为 adouble并将我的返回类型设置为 adouble我能够解决问题。

改变这个:

DECLARE x decimal(10, 7);

对此:

DECLARE x double;
于 2013-08-25T23:51:56.700 回答