选择边界框内的所有地理空间点

时间:2014-01-18 19:16:41

标签: mysql sql latitude-longitude geospatial

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

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

传递的参数是东北纬度/经度以及视口当前位置的西南纬度/经度。

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

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

旗帜表:

  • ID
  • 坐标
  • 名称

示例行:

1 | [几何 - 25B] | Tenacy AB

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

坐标列是数据类型:POINT

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

DBMS:MySQL
DBMS版本:5.6.14

2 个答案:

答案 0 :(得分:24)

据推测,geometry列中您的POINT数据中的x和y项目的纬度和经度均为。

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

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

假设您的lat / long框是一个以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/

答案 1 :(得分:0)

您可以使用四核。它减小了尺寸并使空间搜索更容易。我写了一个php类hilbert-curve @ phpclasses.org。您还可以从Microsoft Bing地图平铺中阅读有关quadkey的信息。基本上,四元组有助于在x,y,z坐标处找到图块。来源:http://msdn.microsoft.com/en-us/library/bb259689.aspx