当前位置: 首页 > 知识库问答 >
问题:

如何在MySQL中查询具有地理空间“点”字段的表

强才捷
2023-03-14

我有一个“places”表,其中包含lat、lng和point字段。我一直用哈弗森公式来计算lat,lng的距离,但我读到使用点场更有效?我只是找不到关于怎么做的文件。这是我的查询,因为它现在是查询所有的地方和排序他们的距离

 SELECT `places`.*, `places`.`id` AS `pid`,   
        ((6371*acos(cos(radians(37.776708))*cos(radians(lat))*
          cos(radians(lng)-radians(-122.398050))+sin(radians(37.776708))*
          sin(radians(lat))))*1000) AS `distance` 
   FROM `places` 
  WHERE `page_id` IS NOT null 
  ORDER BY `distance` ASC 
  LIMIT 40 OFFSET 0

我如何将其更改为使用表中的“point”字段而不是LAT/LNG

共有1个答案

张星洲
2023-03-14

要使用MySQL地理空间扩展来完成这类工作,您需要做一些事情。

  1. 您必须使用MyISAM表作为您的地理空间数据。
  2. 表中需要有几何图形列,并且该列不能为空。
  3. 您不能使用问题中提到的球余弦定律距离计算作为您的主要搜索标准。您需要使用一个边界框来代替(也就是说,您需要在您的搜索点的特定距离内搜索点。

您当前的查询只是通过检查places表中的所有点并按邻近顺序排序来找到最接近(37.77671,-122.3980)的点。当你使用地理空间的时候,你正在做一些比这更聪明的事情。你需要建立一个接近限制。我们称它为10.0规约英里的半径。请注意,每纬度有69.0规约英里。

首先给自己做一个有几何图形列的表格,可能是这样的:

CREATE TABLE geoplace (
  id INT NOT NULL,
  geo GEOMETRY NOT NULL,
  PRIMARY KEY id (id),
  SPATIAL KEY geo (geo)
) ENGINE=MYISAM

然后,按如下方式填充它,在每个geo值中放入一个几何point项。

INSERT INTO geoplace
SELECT DISTINCT id,
                GEOMFROMTEXT(
                  CONCAT('POINT(',
                     lat,
                     ' ',
                     lng,
                ')')  ) AS geo
 FROM places

显然,您可以将几何图形列放入任何您想要的表中。但您不能在InnoDB表中创建正常工作的空间索引;该访问方法不支持空间索引。

SELECT id, X(geo), Y(geo), distance FROM (
SELECT id, geo,r,
        units * DEGREES( ACOS(
                   COS(RADIANS(latpoint))
                 * COS(RADIANS(X(geo)))
                 * COS(RADIANS(longpoint) - RADIANS(Y(geo)))
                 + SIN(RADIANS(latpoint))
                 * SIN(RADIANS(X(geo))))) AS distance
 FROM geoplace
 JOIN (
        SELECT 37.776708  AS latpoint,  -122.398050 AS longpoint,
               10.0 AS r, 69.0 AS units
   ) AS p ON (1=1)
 WHERE MbrContains(GeomFromText(
       CONCAT('LINESTRING(',
              latpoint-(r/units),' ',
              longpoint-(r /(units* COS(RADIANS(latpoint)))),
              ',',
              latpoint+(r/units) ,' ',
              longpoint+(r /(units * COS(RADIANS(latpoint)))),
              ')')),  geo)
) AS d
 WHERE distance <= r
 ORDER BY distance
        SELECT 37.776708  AS latpoint,  -122.398050 AS longpoint,
               10.0 AS r, 69.0 AS units

它将使用mbrcontains进行空间矩形搜索,然后使用球面余弦定律公式计算找到的点的距离,然后对它们进行正确排序。与您开始使用的查询相比,这个东西运行得相当快,因为它利用了空间索引。

这在这里写得更详细。

http://www.plumislandmedia.net/mysql/using-mysqls-geospatial-extension-location-finder/

http://www.plumislandmedia.net/mysql/haversine-mysql-nexarent-loc/

 类似资料:
  • 问题内容: 有没有办法从mySQL的子查询中指定父查询字段? 例如: 我已经用PHP编写了一个基本的公告板类型程序。 在数据库中,每个帖子都包含:id(PK)和parent_id(父帖子的ID)。如果帖子本身是父项,则其parent_id设置为0。 我正在尝试编写一个mySQL查询,该查询将查找每个父级帖子以及父级拥有的子级数。 棘手的是,第一个 ID 不知道它应该引用子查询之外的第二个 ID 。

  • 问题内容: 在我的表格中,我有一个名为的字段,格式为。 我如何进行查询,以便将 一天 添加到例如今天的情况下,我想显示in子句以返回带有明天日期的所有记录。 更新: 我尝试了这个: 但不幸的是,即使我添加的间隔大于1,它也会返回相同的记录。 结果: 但是我只想选择明天的日期的记录。 问题答案: 您可以使用以下功能: 它也可以在语句中使用:

  • 有没有想过为什么使用Dociety的ODM会在同一个查询上返回零结果? 更新#1看起来教义\MongoDB\Query\Builder::near()L363有问题。方法参数忽略第二个值($Y)。因此只传递要执行的第一个值。

  • 本文向大家介绍MySQL查询空字段或非空字段(is null和not null),包括了MySQL查询空字段或非空字段(is null和not null)的使用技巧和注意事项,需要的朋友参考一下 现在我们先来把test表中的一条记录的birth字段设置为空。 mysql> update test set t_birth=null where t_id=1; Query OK, 1 row affe

  • 我有一个包含许多文档集合,其结构如下: 纬度范围为[25;55] 该收藏包含大约60万条记录。 我设置了2D_Sphere索引:db.myCollection.createIndex({location:“2DSphere”}) 我获得了所有的记录,但我只期望有几个记录(靠近我的坐标!) 有什么建议吗?提前致谢

  • 问题内容: 我试图弄清楚如何检查一个字段是否为空或为空。我有这个 我需要添加额外的支票,例如 任何想法如何做到这一点? 问题答案: 无论使用 要么 如果只想检查而不是空字符串,则也可以使用或。但这不适用于空字符串。