【问题标题】:PostGIS Query always brings back all resultsPostGIS Query 总是带回所有结果
【发布时间】:2020-05-27 16:37:48
【问题描述】:

我第一次使用 PostGIS,无论我在距离查询中使用的距离如何,我都会返回所有结果。我的数据如下所示:

Id                                      GeoLocation
8eb63480-4d63-11ea-b06a-8c1645ef6ad2    POINT (52.6323202 1.2947649)
a0f2dde6-4d64-11ea-b06a-8c1645ef6ad2    POINT (52.6294342 1.2936336)
a0f2dde7-4d64-11ea-b06a-8c1645ef6ad2    POINT (52.6277909 1.2909079)
a0f2dde8-4d64-11ea-b06a-8c1645ef6ad2    POINT (52.6260535 1.2952051)

当我对一个应该在一英里以外的点进行查询时:

SELECT * FROM "Locations"   WHERE ST_DWithin("GeoLocation", 'POINT(52.6219322 1.2630061)', 1);

我得到了所有的行。我的理解是距离参数应该以米为单位,所以我不应该得到任何结果。

可能是坐标格式问题吗?我错过了什么?

【问题讨论】:

  • dwithin 使用与几何 CRS 相同的单位,因此在您的示例中使用度数。所有要素都在给定坐标的 1 度范围内。投射到地理或使用不同的投影来使用米。

标签: postgresql postgis


【解决方案1】:

使用geography 类型的参数,您会得到以米为单位的返回距离,因此您需要将其转换为英里,以防您更喜欢使用此测量单位。如果您可以应付学位,请坚持geometry

WITH locations (geolocation) AS (
  VALUES ('POINT (52.6323202 1.2947649)'),
         ('POINT (52.6294342 1.2936336)'),
         ('POINT (52.6277909 1.2909079)'),
         ('POINT (52.6260535 1.2952051)')
) 
SELECT *
FROM locations 
WHERE ST_DWithin(
          geoLocation::geography, 
          'POINT(52.6219322 1.2630061)'::geography, 1609*2.2) ;

         geolocation          
------------------------------
 POINT (52.6294342 1.2936336)
 POINT (52.6277909 1.2909079)
(2 Zeilen)

编辑:@JGH 指出ST_Distance 不使用空间索引,我之前的建议是使用它而不是ST_DWithin。这意味着我对ST_Distance 的偏好是错误的 :) 无论如何,对于那些仍然愿意使用它的人来说,以下是如何使用ST_Distance 实现类似的结果:

WITH locations (geolocation) AS (
  VALUES ('POINT (52.6323202 1.2947649)'),
         ('POINT (52.6294342 1.2936336)'),
         ('POINT (52.6277909 1.2909079)'),
         ('POINT (52.6260535 1.2952051)')
) 
SELECT *
FROM locations 
WHERE ST_Distance(
          geoLocation::geography, 
          'POINT(52.6219322 1.2630061)'::geography) * 0.000621371 > 2.2 ;

         geolocation          
------------------------------
 POINT (52.6323202 1.2947649)
 POINT (52.6260535 1.2952051)
(2 Zeilen)

延伸阅读:Getting all Buildings in range of 5 miles from specified coordinates

【讨论】:

  • 让我们强调st_distance 不使用空间索引,而st_dwithin 使用。因此它要快得多,应该在where 子句中使用。
  • @JGH 我不知道,谢谢指出。刚刚相应地编辑了我的答案
  • 转换为地理,现在 SELECT * FROM "Locations" WHERE ST_DWithin("GeoLocation", 'POINT(52.6219322 1.2630061)'::geography, 3200);按预期工作 - 谢谢!
【解决方案2】:

由于这些似乎是经度和纬度坐标,您应该使用geography 数据类型。

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2011-02-02
    • 2018-05-28
    相关资源
    最近更新 更多