【问题标题】:MySql spatial data query for finding near locations using haversine formula使用haversine公式查找附近位置的MySql空间数据查询
【发布时间】:2014-06-16 11:54:22
【问题描述】:

这里的新手在 mysql 方面有最佳知识,但停留在空间查询上。

我查看了许多与空间数据相关的问题,以查找给定 lat/lon 周围的附近位置,但由于我的空间表格式不同,最终没有正确的结果(如果已经有问题,请提供链接。我不太了解空间数据查询)。

我有一个表格,我们将纬度/经度存储为 几何 类型的 Point 数据类型。!(如果我在这里错了,请见谅)

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; 来获取纬度/经度值。)

  • 还有其他方法可以直接在 my
    上应用半正弦公式吗? 表。?

我正在使用 MySql 服务器版本 5.5

请建议我怎么做。在此先感谢大家。

查找单独的线程here

【问题讨论】:

  • ..在你的表的 desc 中,你有 property => geometry .. 但是在你的查询中,你已经有 select X(cordinates) .. from property .. 了,那么多没有没道理。至少,您似乎应该拥有select X(property) .. from THE_UNSTATED_TABLE_NAME ..no?
  • @elrobis 是的,你是对的。那是我的错误。我很抱歉编辑我的问题。
  • 之前您提到了一条错误消息——您仍然收到错误消息吗?
  • 另外,为了清楚起见,X/Y 值对应 LONG/LAT,而 not LAT/LONG 这是一个常见错误。将您的查询视为SELECT X(property) as long, Y(property) as lat FROM mytable; 可能会有所帮助..换句话说,您是否有可能将这些值颠倒过来?
  • @elrobis 是的,现在我设法使用 x(property) 和 y(property) 分别获得 lat 和 lon。

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


【解决方案1】:

在做了一些研究后以一些下降的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

;

请查看存储的 LATLON,因为存储在 mytable 中的纬度/经度是相反的。

【讨论】:

    【解决方案2】:

    回答:

    有没有其他方法可以直接在我的上应用半正弦公式 表。?

    我在最近解决的一个解决方案中有一个直接的答案。我遇到了 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);
    

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 2014-04-29
      • 2016-03-03
      • 1970-01-01
      • 2017-09-07
      • 2011-07-18
      • 1970-01-01
      相关资源
      最近更新 更多