【问题标题】:How can I query all my data within a distance of 5 meters?如何查询5米范围内的所有数据?
【发布时间】:2023-09-27 08:27:01
【问题描述】:

我正在将 GeoDjango 与 PostGIS 一起使用。然后我遇到了如何查询我的postgres db表以获取5米距离内的所有数据的麻烦。

更新1 我正在使用 GeoDjango 1.2.7

我从这个网址https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoquerysets/#std:fieldlookup-distance_lte找到了一些东西

Zipcode.objects.filter(poly__distance_lte=(geom, D(*m*=5) ))

但不知道如何准备参数和变量。

  1. 什么是poly_distance_lte?是函数吗?
  2. 什么是geom?是一个变量?如何创建?
  3. 什么是D?是一个函数?如果是,mD函数的参数名吗?

【问题讨论】:

  • 请不要在标题中添加标签。

标签: python postgresql postgis geodjango


【解决方案1】:

一般来说,此类查询的最佳 PostGIS 函数是 ST_DWithin()

如果几何在彼此之间的指定距离内,则返回 true。

例如。居住在 1 号商店 1000 米范围内的所有顾客:

SELECT customers.* 
FROM customers, shops
WHERE ST_DWithin(customers.the_geog, shops.the_geog, 1000)
  AND shop.id = 1

ST_DWithin 将使用您应该创建的空间索引,因此优于 ST_Distance。

在 Django 中似乎有一个相应的过滤器,名为 dwithin

返回从查找几何到几何字段的距离在给定距离内的模型。

Zipcode.objects.filter(poly__dwithin=(geom, D(m=5)))
Backend   SQL Equivalent
PostGIS   ST_DWithin(poly, geom, 5)

D(m=5) 返回一个长度为 5 米的距离对象

geom 是您要计算与 Zipcode 对象的距离的几何图形

dwithin() 是使用的函数

poly 是 Zipcode 对象的几何属性

z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')

【讨论】:

  • 就像我之前发布的那样,Dgeom 是什么? mD 的参数名称不是吗? poly 是重点吗? __dwithin 不是函数吗?
  • 我试过了,但无法识别。 D是编译错误。 poly 怎么样?是什么?
  • 感谢您的回复。如何创建空间索引?你的意思是我需要做一些任务来创建它吗?如果是,怎么可能?
  • 关于如何进行空间索引的任何示例
  • +1 用于解释距离与内部,哪个更快(因为 django 文档中 distance_lte 和 dwithin 的语法和用法是相同的,并且没有给出任何提示)
【解决方案2】:

我几天前才这样做。

这相当困难,因为您应该创建一个地理而不是几何点,才能访问米单位。

所以我只是在一个小的额外查询中做了它

extra_where = '''
    ST_Intersects(
            the_geom, geometry(ST_Buffer(ST_GeographyFromText(\'%s\'), %f)))
'''
your_point = 'POINT(1 2)'
your_distance = 5 # meters
YourModule.object.filter(something).extra(where=extra_where%(your_point, your_distance))

注意地理部分和缓冲区部分。

【讨论】:

  • 我有两 (2) 个澄清.. 1) 你为什么不使用 ST_Distance(..)
  • @eros 1 ST_Distance 测试了很多几何体(如果不过滤,可能是整个表中的所有几何体),据我尝试,缓冲和相交性能更好。 2 我自己也是新手,我会尽快更新答案
  • 那里的“the_geom”和“geometry”怎么样? - 多谢。我期待看到您更新的答案。另外,感谢您考虑性能。我错过了那些点。问候。
  • 哦,我已经更新了。 geometry 是 django 和 postgis 中的一个几何字段,您可以在其中存储地图/位置/......无论地理数据如何,表的默认几何图形是“the_geom”。将其替换为您自己的几何字段名称。
  • 您应该使用 ST_DWithin 而不是 buffer+intersects 解决方案。 ST_DWithin 将使用您应该创建的空间索引,因此优于 ST_Distance。创建缓冲区几何图形是不必要的开销。
【解决方案3】:
  1. 什么是poly__distance_lte?是函数吗?

文档页面假定polyZipcode 模型中几何字段的名称。 distance_lte 只是一个查找过滤器,用于查找某个点一定距离内的对象。


  1. 什么是geom?是一个变量?如何创建?

这是一个先前定义的变量。要使用 poly 字段查找距离 A 点 x 英里范围内的 Zipcode 对象,您需要定义点 A。geom 就是该定义。例如,它可能是django.contrib.gis.geos.Point。您可以设置该点的纬度和经度,并将其用作搜索圈的中心。在你得到的例子中,这个中心被命名为geom


  1. 什么是D?是一个函数?如果是,m是D函数的参数名吗?

D 是一个类。更具体地说,它是名为Distance 的类的简称。它们都可以在django.contrib.gis.measure 中找到。您可以使用各种现实世界的距离指标(例如公里、英里、米)来创建此类的实例。在这种情况下,m 代表米。

【讨论】:

    【解决方案4】:
    from django.contrib.gis.measure import Distance, D
    
    d1 = Distance(km=5)
    print d1
    d2 = D(mi=5) # `D` is an alias for `Distance`
    print d2
    5.0 mi
    

    reference from django project

    【讨论】: