我正在尝试使用Django和Postgresql实现基于纬度和经度的邻近搜索。这是我所拥有的模型的抽象版本。
class Item(models.Model):
"""docstring for Item"""
uuid = UUIDField(primary_key=True, auto=True)
name = models.CharField(_("name"), max_length=200)
address = models.CharField(_('street address'), max_length=255, blank=True, null=True)
location = models.CharField(_('location'), max_length=40, blank=True, null=True)
@property
def geo_distance(self, location=None):
if location is not None:
cursor = connection.cursor()
cursor.execute("SELECT geo_distance(CAST('%s')) AS POINT, CAST('%s') AS POINT)" %
self.location, location)
return round(float(cursor.fetchone() * 1.621371192237), 2)
我希望能够在views.py中执行类似的操作:
items = Item.objects.filter(name__istartwith="Anything")
results = []
for item in items:
results.append({
'name': item.name,
'distance': item.geo_distance("(11.23123, -12.123213)")
})
我意识到这不是最好的方法。欢迎任何建议。
答案 0 :(得分:2)
如果您是基于纬度和经度的搜索,我会向您推荐GeoDjango。要计算从X点开始的两点或周围区域之间的距离,您可以使用Haversine formula。最好使用procedure编写距离计算。据我所知,django不支持创建程序,我在计算距离方面做了一些基准测试,我发现程序更快,而不是在django端计算。祝好运。
答案 1 :(得分:1)
嗯,你的代码并不可怕。我想你是因为在for迭代中执行了item.geo_distance()而关注性能?没关系,这必须在某个时候计算。你的解决方案没问题,但这里有一些其他的指示:
关于第二点,过滤数据。我看到你正在过滤名字,这意味着你没有使用距离来过滤。如果你确实想要使用一个点的距离作为过滤器(例如,不超过40英里),那么你会遇到一些新的问题,geopy和geodjango可以帮助。这里常见的解决方案是近似距离(以正方形为单位),根据此近似值过滤数据,然后计算精确距离。