查找距离用户指定位置的最近点

时间:2016-06-16 17:05:47

标签: django postgresql python-3.x distance postgis

对于我的应用程序,我需要在我的数据库中找到一个与用户指定的点最接近的点。这是我的模特:

class WaysVerticesPgr(models.Model):
    id = models.BigIntegerField(primary_key=True)
    osm_id = models.BigIntegerField(unique=True, blank=True, null=True)
    cnt = models.IntegerField(blank=True, null=True)
    chk = models.IntegerField(blank=True, null=True)
    ein = models.IntegerField(blank=True, null=True)
    eout = models.IntegerField(blank=True, null=True)
    lon = models.DecimalField(max_digits=11, decimal_places=8, blank=True, null=True)
    lat = models.DecimalField(max_digits=11, decimal_places=8, blank=True, null=True)
    the_geom = models.PointField(blank=True, null=True)

我正在尝试使用此代码查找小半径内的所有点(在本例中为o.oo5度),注释它们之间的距离和输入点,按距离对它们进行排序并返回数组中的第一个:

from django.contrib.gis.db.models.functions import *
from .models import *
from django.contrib.gis.geos import *
from django.contrib.gis.measure import *

def get_closest_point(input):
    input_point_geometry=GEOSGeometry('POINT('+input+')')
    closest = WaysVerticesPgr.objects.filter(the_geom__dwithin=(input_point_geometry,0.005)).annotate(distance_between=input_point_geometry.distance('the_geom')).order_by(distance_between)[:1]
    return closest

但是我得到一个错误' distance()仅适用于其他GEOS Geometries'。当我尝试将the_geom转换为GEOSGeometry格式时:

closest = WaysVerticesPgr.objects.filter(the_geom__dwithin=(input_point_geometry,0.005)).annotate(distance_between=input_point_geometry.distance(GEOSGeometry('the_geom'))).order_by(distance_between)[:1]

我收到错误:

  

'字符串或unicode输入无法识别为WKT EWKT和HEXEWKB'。这有点奇怪,因为the_geom字段的格式为0101000020E6100000E7525C55F65DA1BF8FF5793139C34940,似乎是HEX。

我设法用循环做了很长时间,但这看起来不太好,性能也不好。但有趣的是,在这种情况下转换为GEOSGeometry:

def get_closest_point(input):
    input_point_geometry=GEOSGeometry('POINT('+input+')')
    closest = WaysVerticesPgr.objects.filter(the_geom__dwithin=(input_point_geometry,0.005))

    dict_closest = {}
    list_closest = []
    for i in closest:
        i = GEOSGeometry(i.the_geom)
        distance_between=input_point_geometry.distance(i)
        i = str(i.wkt)
        dict_closest = {'Point':i,'Distance':distance_between}
        list_closest.append(dict_closest)
        sortlist=sorted(list_closest, key=itemgetter('Distance'), reverse=False)
    return sortlist[0]

有人知道如何让它在短时间内发挥作用吗?我使用Django 1.9,Python 3.5和Postgres 9.5PostGIS一起使用。我看到其他线程中的人建议使用另一个看起来像距离=距离(point1,point2)的距离函数,但它给出了一个错误,给出了3个参数,而只接受了1或2(输入是GEOSGeometry格式的两个点) )。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

@ e4c5是的,我检查了一下。事实证明,自Django 1.9以来,GeoQuerySet.distance函数已被弃用。相反,这对我有用:

def get_closest_point(input):
    input_point=GEOSGeometry('POINT('+input+')')
    closest = WaysVerticesPgr.objects.filter(the_geom__dwithin=(input_point_geometry,0.005)).annotate(distance=Distance('the_geom', input_point)).order_by('distance').values('lon','lat')[0]

无论如何,谢谢你(投票给你的答案,但因为我的声誉很低而没有显示)。