Django模型属性地理距离

时间:2009-12-05 21:21:14

标签: django

我正在尝试使用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)")
    })

我意识到这不是最好的方法。欢迎任何建议。

2 个答案:

答案 0 :(得分:2)

如果您是基于纬度和经度的搜索,我会向您推荐GeoDjango。要计算从X点开始的两点或周围区域之间的距离,您可以使用Haversine formula。最好使用procedure编写距离计算。据我所知,django不支持创建程序,我在计算距离方面做了一些基准测试,我发现程序更快,而不是在django端计算。祝好运。

答案 1 :(得分:1)

嗯,你的代码并不可怕。我想你是因为在for迭代中执行了item.geo_distance()而关注性能?没关系,这必须在某个时候计算。你的解决方案没问题,但这里有一些其他的指示:

  • 使用geopy(或geodjango)
  • 请务必在源(数据库)中过滤数据。

关于第二点,过滤数据。我看到你正在过滤名字,这意味着你没有使用距离来过滤。如果你确实想要使用一个点的距离作为过滤器(例如,不超过40英里),那么你会遇到一些新的问题,geopy和geodjango可以帮助。这里常见的解决方案是近似距离(以正方形为单位),根据此近似值过滤数据,然后计算精确距离。