MariaDB没有ST_Distance_Sphere的等效函数

时间:2019-12-17 09:11:10

标签: mysql geometry mariadb geospatial

在MySQL 5.7中,有一个名为ST_Distance_Sphere的函数可用于查找半径范围内的点,例如:

CREATE TABLE `places` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(256) DEFAULT NULL,
  `coordinates` point DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Eiffel Tower", POINT(48.858271, 2.293795));

INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Pere Lachaise", POINT(48.861131, 2.394683));

INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Brooklyn", POINT(40.711089, -73.948391));

如果我们要查看距巴黎市中心的卢浮宫不到10公里的所有点,则可以执行以下操作:

SELECT name FROM places
WHERE ST_Distance_Sphere(coordinates, POINT(48.861105, 2.335337)) < 10000

但是MariaDB 10.1+中不支持此类功能

如何在MariaDB中重新创建相同的函数或重新创建相同的查询。以下文章显示了一种重新创建相同功能FUNCTION ST_Distance_Sphere does not exist in MariaDB的方法?

也许是这样吗?

SELECT name FROM places
WHERE ST_Within(
   coordinates, ST_Buffer(POINT(48.861105, 2.335337), 10000)
);

任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

基于@ adam78和@Rick James的建议 我这样解决了:

CREATE FUNCTION st_distance_sphere(pt1 POINT, pt2 POINT)
RETURNS double(10,2)

RETURN 6371000 * 2 * ASIN(
    SQRT(
        POWER(SIN((ST_Y(pt2) - ST_Y(pt1)) * pi()/180 / 2), 2) +
        COS(ST_Y(pt1) * pi()/180 ) *
        COS(ST_Y(pt2) * pi()/180) *
        POWER(SIN((ST_X(pt2) - ST_X(pt1)) * pi()/180 / 2), 2)
    )
)

答案 1 :(得分:0)

我在http://mysql.rjweb.org/doc.php/find_nearest_in_mysql中提供了一种解决方法-但是,它适用于latitudelongitude而不是POINTs的一对数字列。 (可以从POINT()中提取这些内容。)

该链接的主要目的是您的“下一个”问题-如何按距离加快过滤速度。它讨论了5种方法。 (您的代码仍然是性能最低的代码。)

答案 2 :(得分:0)

我只是遇到了同样的问题。 使用ST_DISTANCE 链接:https://mariadb.com/kb/en/st_distance/ 简单的例子:

SELECT ST_DISTANCE(POINT(x y),POINT(x1 y1));

返回坐标单位。