【问题标题】:Find the nearest point from a given point in MySQL在MySQL中找到离给定点最近的点
【发布时间】:2018-08-28 13:19:12
【问题描述】:

我有一组点,我从中创建了一个多点。

SET @multi_point = ST_GeomFromText('MULTIPOINT(-118.2845938 34.0252385, -118.2867610 34.0221188, -118.2905912 34.0227248, -118.284119 34.021846, -118.2864676 34.0186438, -118.2886342 34.0203211, -118.2907290 34.0193680, -118.2831326 34.0192874, -118.2828242 34.0205473)');

我还有一个要点

SET @home = ST_GeomFromText('POINT(-118.2819136 34.0261177)')

来自@home我想找到最近的3个点。这是多点@multi_point 的一部分。我想首先使用ST_DISTANCE 确定从@home 点到多点中每个点的距离。但我得到以下信息:

SELECT ST_DISTANCE(@home, @multi_point)

+----------------------------------+
| ST_DISTANCE(@home, @multi_point) |
+----------------------------------+
|            0.0028207205958764945 |
+----------------------------------+

看起来我只得到了点到多点的最短距离。问题:

  1. 有没有办法获得到每个点的最短距离,并自行确定这些点?

  2. 有没有更好的方法来确定从一个点 @home 到另一个点 @multi_point 的最近邻?

编辑我尝试了 Paul Spiegel 将这些点存储在表格中的方法。但是当我存储Point 类型时,它被存储为垃圾值:

+-----------------+---------------------------+
| Name            | Coordinates               |
+-----------------+---------------------------+
| P1              |        [2]pxA@            |
| p2              |        +1Z]:PA@           |
| p3              |        a]KA@              |
| p4              |        X ]qgpA@           |
| p5              |        EW3|U]A@           |
| p6              |        M]bKzA@            |
| p7              |        Ku/]2ƇA@           |
| p9              |        =];A@              |
| p8              |        u`x]A@             |
+-----------------+---------------------------+

另外,当我查询它时,距离为空。

SELECT P.Name, ST_DISTANCE(@home, P.Coordinates) AS dist 
FROM Placemark P ORDER BY dist LIMIT 3;

+--------------+------+
| Name         | dist |
+--------------+------+
| p1           | NULL |
| p2           | NULL |
| p3           | NULL |
+--------------+------+

我该如何解决这个问题?

【问题讨论】:

  • 你能把这些点保存在一个每点一行的表格中吗?
  • 当然。这样就好了。
  • 那么解决方案就很明显了:SELECT p.*, ST_DISTANCE(@home, p.point) as dist FROM points p ORDER BY dist LIMIT 3.
  • 好的。因此,存储点本身会产生一个相当简单的答案。你能在存储这些点的情况下做类似的事情吗?
  • 积分从何而来?也许您可以将它们存储在临时表中。

标签: mysql database geospatial


【解决方案1】:

这里是一个使用临时表的例子:

drop temporary table if exists Placemark;
create temporary table Placemark(
    Name varchar(50),
    Coordinates point
);

insert into Placemark(Name, Coordinates) values
    ('p1', POINT(-118.2845938, 34.0252385)),
    ('p2', POINT(-118.2867610, 34.0221188)),
    ('p3', POINT(-118.2905912, 34.0227248)),
    ('p4', POINT(-118.284119 , 34.021846 )),
    ('p5', POINT(-118.2864676, 34.0186438)),
    ('p6', POINT(-118.2886342, 34.0203211)),
    ('p7', POINT(-118.2907290, 34.0193680)),
    ('p8', POINT(-118.2831326, 34.0192874)),
    ('p9', POINT(-118.2828242, 34.0205473));

SET @home = ST_GeomFromText('POINT(-118.2819136 34.0261177)');

SELECT 
    P.Name,
    ST_AsText(P.Coordinates) as Coordinates,
    ST_DISTANCE(@home, P.Coordinates) AS dist 
FROM Placemark P
ORDER BY dist
LIMIT 3

结果:

Name | Coordinates                    | dist
p1   | POINT(-118.2845938 34.0252385) | 0.00282072059587649
p4   | POINT(-118.284119 34.021846)   | 0.00480741199088132
p9   | POINT(-118.2828242 34.0205473) | 0.00564433773972052

演示:http://rextester.com/GMPK57301

要定义一个点,请使用POINT(-118.2845938, 34.0252385)ST_GeomFromText('POINT(-118.2845938 34.0252385)')。要以可读形式查看值,请使用ST_AsText()

【讨论】:

  • 这实际上根本不做 KNN。
  • @EvanCarroll - KNN 对你来说是什么 - 它与 OP 的问题有什么关系?
  • KNN 是一种算法,它不是“对我而言”的东西。但是,我确实在这里澄清了:dba.stackexchange.com/q/214354/2639。仅供参考,我没有投反对票或任何东西。这将根据与前一行的距离来查找最近的行。它只是与 KNN 没有任何关系。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2013-06-15
  • 2011-05-20
  • 2013-12-25
  • 1970-01-01
  • 2012-02-25
相关资源
最近更新 更多