【问题标题】:Get closest points of a point from a DB从数据库中获取点的最近点
【发布时间】:2020-10-30 13:52:16
【问题描述】:

我使用 MariaDB 数据库,在其中使用 Hibernate jts.geom.Point 类型存储大量点(纬度和经度)。在数据库中存储为geometry类型。

我想知道在给定某个点的情况下如何获得最接近的 10 点。我如何使用 SQL 查询来做到这一点?或者可能是后端的查询和邮政编码。

谢谢!

【问题讨论】:

  • 一个简单的查询就可以做到这一点。现在,产生一个有效的查询是另一回事。
  • @TheImpaler 那么怎么样?你能举个例子吗?
  • MySQL 或 MariaDB 的哪个版本? st_distance_sphere() 在大多数版本中不可用。

标签: mysql hibernate mariadb topology jts


【解决方案1】:

这里有 5 种算法,具有不同的复杂性和性能。加上Haversine代码。

http://mysql.rjweb.org/doc.php/find_nearest_in_mysql

【讨论】:

    【解决方案2】:

    例如你可以这样做:

    create table t (loc point);
    
    insert into t (loc) values
      (POINT(10, 0)), 
      (POINT(15, 20)),
      (POINT(50, 50));
    

    那么你可以找到离(49, 49)最近的两个点:

    select *,
      st_distance_sphere(loc, POINT(49, 49)) as dist
    from t
    order by st_distance_sphere(loc, POINT(49, 49)) 
    limit 2 -- only the closest two points
    

    结果:

    loc              dist
    ---------------  -----------------
    {"x":50,"y":50}  132584.0664606239
    {"x":15,"y":20}  4416195.256674154
        
    

    请参阅DB Fiddle 的运行示例。

    现在,这行得通,但是对于数百万行,它的效率不会很高。您需要使用“矩形”或“区域”进行预过滤,因此可以使用索引。

    为 MariaDB 编辑

    MariaDB 的语法略有不同。见下文:

    select ST_AsText(t.loc) as point, 
      ST_Distance(loc, POINT(49, 49)) as dist
    from t
    order by ST_Distance(loc, POINT(49, 49))
    limit 2;
    

    结果:

    point         dist
    ------------  ------------------
    POINT(50 50)  1.4142135623730951
    POINT(15 20)  44.68780594300866
    

    请参阅db<>fiddle 的运行示例。

    【讨论】:

    • 它适用于 DB Fiddle,但在我的 MariaDB 控制台中它不起作用:/
    • 你有什么版本的 MariaDB?
    • MariaDB 10.4.13
    • @Ommadawn 你是对的。 MariaDB 没有实现球距离。不过,对于低纬度地区,ST_Distance() 可以产生几乎相同的结果。或者,您可以在 ORDER BY 子句中使用 Haversine 公式。
    • MariaDB 实现了SIN()COS()ASIN()。您可以将公式写为ORDER BY &lt;formula&gt;。 Haversine 公式在en.wikipedia.org/wiki/Great-circle_distance 进行了解释。不应该看起来那么难看;并且会工作。
    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多