MySql空间数据查询,用于使用hasrsine公式查找附近位置

时间:2014-06-16 11:54:23

标签: mysql geospatial spatial spatial-index spatial-query

这里的新手掌握了mysql的最佳知识,但坚持空间查询。

我偷看了许多空间数据相关的问题,找到了给定纬度/经度附近的位置,但由于我的空间表格式不同,最终得不到合适的结果(如果已经存在问题,请提供链接。我不知道多少关于空间数据查询)。

我有一个表格,我们将lat / lon存储为 几何类型的数据类型。(对不起,如果我错了)

我的表的

desc 如下:

+-----------+----------------+
| Field     |    Type        |
+-----------+----------------+
|  id       |        Int(10) |
| property  |       geometry |
+-----------+----------------+

当我查询使用select astext(property) from mytable查询查看属性数据时,它将返回

列表
POINT(10.1234 50.12356)

由于纬度和经度。

现在我有haversine公式用于使用mysql计算最近的位置。

在给定的链接编写者 Mr.Ollie 中直接查询列纬度和经度,但在我的问题中,纬度和经度存储为POINT数据类型。

为了获得最近的位置

  • 我是否需要先从表中提取点并在该
  • 上应用查询

(我尝试select X(property),Y(property) from mytable;获取纬度/经度值。)

  • 还有其他方法可以直接在我的身上使用半胱氨酸配方 表。?

我使用的是MySql服务器版 5.5

请建议我怎么做。提前感谢所有人。

找到单独的帖子here

2 个答案:

答案 0 :(得分:2)

做了一些研究后结束了一些下降的Haversine查询

     select id, ( 3959 * acos( cos( radians(12.91841) ) * cos( radians( y(property) ) ) * 
    cos( radians( x(property)) - radians(77.58631) ) + sin( radians(12.91841) ) * 
sin( radians(y(property) ) ) ) ) AS distance from mytable having distance < 10 order by distance limit 10

请查看存储的 LAT LON 与mytable中存储的lat / lon相反的方式。

答案 1 :(得分:0)

回答:

  

还有其他方法可以直接在我的身上使用半胱氨酸配方   表。?

我在最近解决的解决方案中有直接的答案。我遇到了CPU性能问题,必须将公式应用于大量数据。我通过实现数据永不改变并在写入时冗余地应用计算来解决这个问题。 GLength,LineStringFromWKB,LineString和GeomFromText可以满足您的需求:

CREATE TABLE `locations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(255) DEFAULT NULL,
  `device` varchar(255) DEFAULT NULL,
  `location` point DEFAULT NULL,
  `altitude` float DEFAULT NULL,
  `time` datetime DEFAULT NULL,
  `previd` INT UNSIGNED NULL,
  `prevdist` DOUBLE NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  INDEX `idx_user` (`user`),
  INDEX `idx_device` (`device`),
  INDEX `location` (`location`),
  INDEX `idx_time` (`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `locations` SET 
`time` = NOW(), `location`= GeomFromText('POINT(@LAT @LONG)'), `user`= @USER,
`device`= @DEVICE, `altitude`= @ALT,
previd=(SELECT id FROM `locations` AS lc WHERE
  lc.`user`= @USER AND
  lc.`device`= @DEVICE AND
  lc.time < NOW()
  ORDER BY lc.time DESC LIMIT 1),
prevdist=IFNULL(ROUND(GLength(LineStringFromWKB(LineString(GeomFromText('POINT(@LAT @LONG)'), (SELECT location FROM `locations` AS lc WHERE
  lc.`user`= @USER AND
  lc.`device`= @DEVICE AND
  lc.time < NOW() ORDER BY lc.time DESC LIMIT 1)
)))*110400), 0);