如何获得geodjango的k个最近邻居?

时间:2017-07-30 22:08:49

标签: python django postgresql postgis geodjango

假设我有以下型号:

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

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

1 个答案:

答案 0 :(得分:2)

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

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

  2. <#>使用边界框本身获取最近邻居来计算物体间距离。

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

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

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

    在回答您的其他问题:How efficient is it to order by distance (entire table) in geodjango时,可能有另一种解决方案:

    通过启用spatial indexing并通过逻辑约束缩小查询范围(如上面链接问题的in my answer所述),您可以实现非常快速的 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]