【问题标题】:ST_DWithin takes parameter as degree , not meters , why?ST_DWithin 将参数作为度数,而不是米数,为什么?
【发布时间】:2012-01-16 16:50:48
【问题描述】:

ST_DWithin 文档说,第三个参数(距离)以米为单位。但是当我执行一些查询时,它似乎将第三个参数作为“度数”?

这是我的简化表结构:

> \d+ theuser;
                         Table "public.theuser"
  Column  |          Type          | Modifiers | Storage  | Description 
----------+------------------------+-----------+----------+-------------
 id       | bigint                 | not null  | plain    | 
 point    | geometry               |           | main     | 
Indexes:
    "theuser_pkey" PRIMARY KEY, btree (id)
    "point_index" gist (point)
Referenced by:
    ...
Has OIDs: no

所有点都以 SRID=4326 存储。

这是查询:

> select * from theuser where ST_DWithin(point , ST_GeomFromText('POINT(120.9982 24.788)',4326) , 100 );

它将第三个参数(100)作为 'degree' ,所以它返回所有数据,我必须缩小到 0.001 才能找到附近的点。

但是我如何直接将米作为第三个参数传递(我不想做米/度转换)?我的查询有什么问题?为什么 postgreSQL 不像文档所说的那样把它当作米?

环境:

> select version();
                                                  version                                                  
-----------------------------------------------------------------------------------------------------------
 PostgreSQL 8.4.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3, 32-bit

> SELECT postgis_lib_version();
 postgis_lib_version 
---------------------
 1.4.0

如果是SRID导致这个问题,什么SRID直接使用'meter'作为单位? (我尝试转换为 SRID=2163 ,但仍在度数)谢谢。

【问题讨论】:

  • 您能否具体说明您是如何将数据转换为 SRID=2163 的?
  • 您好,我对 postgis 不熟悉。所以我用新的 SRID 值以编程方式重置每个点

标签: postgresql gis postgis srid


【解决方案1】:

来自docs

对于几何:距离以定义的单位指定 几何的空间参考系统。

如果您的数据采用 SRID=4326,则您指定的距离以度为单位。

您要么必须使用ST_Transform 和基于米的坐标系,要么使用以下两个函数之一:ST_Distance_Sphere(更快,不太准确)或ST_Distance_Spheroid

【讨论】:

  • 是的,我也认为这可能是 SRID 的原因。但是什么 SRID 默认使用米?
  • 查看Understanding Map Projections 的前两章,熟悉地理坐标系和投影坐标系之间的区别。选择投影坐标系统取决于几个因素,主要是数据的地理区域以及您计划用它测量的内容。另请参阅 GIS SE 上的选择坐标系](gis.stackexchange.com/questions/2769/…)。
  • +1 没有第三种选择吗?以弧度为单位传递距离(如果可以接受,最快)
  • 根据nsidc.org/data/atlas/epsg_4326.htmlspatialreference.org/ref/epsg/wgs-84,EPSG 4326 的基本单位是度数,而不是弧度。
  • 第一个选项“基于米的坐标系”需要指定一个基于米的坐标系。你能推荐一个可以在全球范围内使用的东西,所以 distance_sphere 可以正常工作吗?更好的解决方案是@sal 建议的 - 将对象转换为地理,然后在 ST_DWithin 内使用适当的球面距离。请注意,ST_DWithin 也比 ST_Distance_Sphere 更快:postgis.net/2013/08/26/tip_ST_DWithin
【解决方案2】:

如果您的 geometry 在 WGS84 中,即 srid 4326,您可以将几何图形转换为 geography 以使单位以米为单位

SELECT *
FROM theuser
WHERE ST_DWithin(
  point::geography,
  ST_GeomFromText('POINT(120.9982 24.788)',4326)::geography,
  100 -- DISTANCE IN METERS
);

【讨论】:

    【解决方案3】:

    我不建议您每次要使用 DWithin 时都转换为米,顺便说一下,如果您想要米,则需要像 Albers projection 这样的等面积投影(有很多),为什么不尝试 ST_Buffer( point,degrees) ,看看它在谷歌地球上做了什么,进行测量并找到一个你喜欢的数字,通常你需要预定义的范围,比如非常接近 = 0.00008,接近 = 0.0005,远 = 0.001,真的很远 = 0.01,真的很远= 0.1 等(都以度为单位)。

    在上一个问题中,您询问了最快的方法,您的方向是正确的。

    【讨论】:

      【解决方案4】:

      正如这里提到的,https://postgis.net/docs/ST_DWithin.html,ST_DWithin 函数有两个不同的签名。

      如果有人想直接使用仪表,带有布尔标志的第二个签名将起作用。

      作为 JPA 示例,我将在下面发布我的查询。

          @Query("select f from Facility as f where dwithin(f.address.coordinates, :center, 10000, true) = TRUE")
          List<Facility> findAllByDistance(@Param("center") Point point);
      

      【讨论】:

        【解决方案5】:

        试试下面的查询,它对我来说很好。

        select * from theuser where ST_DWithin(point , ST_GeomFromText('POINT(120.9982 24.788)',4326) , 0.1/111.325 );
        

        这里,0.1 = 100 米。

        【讨论】:

          猜你喜欢
          • 2013-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-21
          相关资源
          最近更新 更多