【问题标题】:Select all geospatial points inside a bounding box选择边界框内的所有地理空间点
【发布时间】:2014-02-08 03:06:03
【问题描述】:

我在 MySQL 数据库中有一个名为“flags”的表,它有 400,000 行。此表由代表英国各地不同位置的地理空间点组成。

我正在创建的应用程序使用 Google 地图。地图上有一个按钮,可以切换地图上的标志可见性。我现在的工作是创建一个 API,当通过边界框时,边界框内的所有标志都会返回(以便它们可以显示在地图上)。

传入的参数是视口当前位置的东北经纬度和西南纬度经度。

我现在需要执行一个 SQL 查询,该查询将返回这组坐标(视口)内的所有地理空间点。

理想情况下,需要优化解决方案,因为要搜索的行数很多。但是,该应用程序确实会强制您在用户显示标志之前放大到某个级别。

标志表:

  • 身份证
  • 坐标
  • 姓名

示例行:

1 | [几何 - 25B] |坚韧AB

坐标字段也可以通过使用 AsText(coordinates) 转换为文字点。但是,X 和 Y 函数会为您执行此操作。

坐标列是数据类型:POINT

我知道要获得一个点的纬度/经度,您可以使用 X 和 Y 函数。例如,一个点的纬度可以这样检索:X(coordinates)

数据库管理系统:MySQL
DBMS 版本:5.6.14

【问题讨论】:

  • 显示flags 表的定义将非常有帮助。您还可以显示该表的六个示例行。此外,由于英国跨越本初子午线,因此经度的符号 (+ -) 很重要。
  • @OllieJones 谢谢奥利,我已经用标志表结构编辑了问题

标签: mysql sql latitude-longitude geospatial


【解决方案1】:

您的geometry 列中的 POINT 数据中的 x 和 y 项可能是以纬度和经度为单位的。

要在 MySQL 中有效地执行此查找,您需要做一些事情。

  • MyISAM 表(或 MySQL 5.7 及更高版本以及 InnoDB 或 MyISAM)
  • 几何列上的 NOT NULL 限定符
  • 空间索引ALTER TABLE flags ADD SPATIAL INDEX (coordinates)
  • 用于创建要搜索的矩形的文本表示的代码
  • 在 SELECT 语句中使用 GeomFromText 和 MBRContains / MBRWithin 函数。

假设您的纬度/经度框是一个以Winchester Cathedral (51.0606, -1.3131) 为中心的一度角矩形。你需要一个围绕该点的边界框。此 MySQL 查询将为穿过该边界框的对角线生成一个 LINESTRING(文本)。

SELECT 
       CONCAT('LINESTRING(',
              latitude-0.5,' ',longitude-0.5,
              ',', 
              latitude+0.5 ,' ',longitude +0.5,
              ')') AS box
   FROM (
      SELECT 51.0606 AS latitude, -1.3131 AS longitude
   ) AS coord

查询会告诉你:

LINESTRING(50.5606 -1.8131,51.5606 -0.8131)

您还可以使用宿主语言中的字符串处理来生成类似类型的文本字符串。你需要的格式是这样的。

 LINESTRING(lat1 long1, lat2 long2) 

然后您可以使用它来搜索您的空间表,如下所示:

SELECT whatever, whatever 
  FROM flags
 WHERE MBRContains(
        GeomFromText( 'LINESTRING(50.5606 -1.8131,51.5606 -0.8131)' ),
        flags.coordinates)     

这将利用空间索引并找到flags 的每一行,其坐标位于该对角线的边界框内。

这里有一些documentation

如果您的flags 表包含的行数少于几十万,您可能会发现具有纬度和经度列(FLOAT 数据类型,索引)的普通表(不是空间表)也可以执行并且更容易开发和调试。

我已经写了一篇关于该技术的教程。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

【讨论】:

  • 感激不尽。很棒的答案,谢谢!几天后我可能需要您的另一件事的帮助,因为您似乎对 MySQL 地理空间主题非常了解。我在您的 Google Plus 上看到了您的电子邮件,您介意我在几天后向您发送一封电子邮件,其中包含指向另一个 Stack 问题的链接吗?非常感谢您的帮助(以防您没有猜到)!
  • @OllieJones 看起来 MySQL 使用 X/Y 作为 Long/Lat,而不是像 SO 中常用的 Lat/Long。 Point(x y) 实际上是 Point(y x)。
  • @kouton,也许您正在考虑 PostgreSQL。据我所知,MySQL 没有为POINT(x y) 中的 x 和 y 分配任何地理语义。如果是这样,也许你可以提供参考。
  • @OllieJones MySQL 存储在 WKT 中,显然应该符合 lng、lat。甚至 PHPMyAdmin 也假设了这一点,并在其地图上错误地绘制了多边形/点。 spatialreference.org/ref/epsg/4326
  • 也谢谢你。在这样的边界框中找到点非常困难。
【解决方案2】:

您可以使用四键。它减少了维度并使空间搜索更容易。我写了一个 php 类 hilbert-curve@phpclasses.org。您还可以从 Microsoft Bing 地图平铺中了解 quadkey。基本上,四键有助于在 x、y、z 坐标处找到图块。来源:http://msdn.microsoft.com/en-us/library/bb259689.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多