我如何获得 geodjango 的 k 最近邻?

How do I get the k nearest neighbors for geodjango?

假设我有以下模型:

class Person:
     id       = models.BigAutoField(primary_key=True)
     name     = models.CharField(max_length=150)
     location = models.PointField()

我将如何使用 geodjango 按位置获取 k 个最近的邻居 (KNN)?
我必须为此编写自定义 SQL 吗?
我正在使用 PostgreSQL 和 PostGIS。

您可以使用 raw() sql 查询来利用 postgis order_by 运算符:

  1. <-> 使用边界框的中心获取最近邻来计算对象间距离。

  2. <#> 使用边界框本身计算对象间距离的最近邻居。

在您的情况下,您想要的似乎是 <-> 运算符,因此原始查询:

knn = Person.objects.raw(
    'SELECT * FROM myapp_person 
    ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
    [location.x, location.y]
)[:k]

由于自己的愚蠢而编辑: 您可以省略 [:k] 以在原始 SQL 查询上添加 LIMIT 1。 (不要像我一样同时使用!)


在回答你的另一个问题的过程中:,另一种可能的解决方案:

通过启用 spatial indexing 并通过逻辑约束缩小查询范围(如上述链接问题的 所述),您可以实现相当快的 KNN查询如下:

current_location = me.location
people = People.objects.filter(
    location__dwithin=(current_location, D(km=50))
).annotate(
    distance=Distance('location', current_location)
).order_by('distance')[:k]