首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GeoDjango:我怎样才能得到两点之间的距离?

GeoDjango:我怎样才能得到两点之间的距离?
EN

Stack Overflow用户
提问于 2015-08-19 10:11:36
回答 3查看 6.6K关注 0票数 6

我的Profile模型有以下字段:

代码语言:javascript
复制
location = models.PointField(geography=True, dim=2, srid=4326)

我想使用locations计算这两个GeoDjango之间的距离(考虑到地球是一个球体),这样我就可以将这个距离存储在数据库中。

  1. 如何用GeoDjango计算这个距离?
  2. 结果是什么单位?
  3. 有什么“最好的”方法来存储这些数据吗?浮起来?十进制?

我已经复习了以前类似的问题,但没有发现它们有用。没有任何答案给出足够的解释,什么是正在发生的或为什么它的工作。

我正在使用Django 1.8和GeoDjango所需库的最新版本。

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2015-08-19 13:57:46

在Abhyudit Jain的评论之后,我使用地势计算距离。按照e4c5的建议,我将其添加为属性而不是存储:

代码语言:javascript
复制
from django.contrib.gis.measure import Distance, D
from geopy.distance import distance

@property
def distance(self):
    return Distance(m=distance(self.user_a.profile.location, self.user_b.profile.location).meters)

Geopy默认为https://en.wikipedia.org/wiki/Vincenty%27s_formulae,错误高达0.5%,并且包含了我以后将使用的许多其他功能。

上面的返回一个GeoDjango距离对象,可以方便地在度量之间进行转换。

谢谢你的帮助!

票数 7
EN

Stack Overflow用户

发布于 2015-08-19 12:42:40

如何用GeoDjango计算这个距离?对于两个对象:

代码语言:javascript
复制
a.location.distance(b.location)

假设您有一个对象a,它是您的配置文件模型的一个实例,并且您希望找到到每一个其他配置文件的距离,您可以执行以下查询,如Geodjango参考所述

代码语言:javascript
复制
for profile in Profile.objects.distance(a.location):
    print profile.distance

如果您只想与距离不到1公里的对象进行比较:

代码语言:javascript
复制
for profile in Profile.objects.filter(location__dwithin=(a.location, D(km=1)).distance(a.location):
        print profile.distance

结果是什么单位?

单位可以是你想要的任何东西。返回的是一个距离对象。然而,默认的是米,这就是上面的print语句将显示的内容。

有什么“最好的”方法来存储这些数据吗?浮起来?十进制?

最好的办法就是不去拯救它。通常,在数据库中不保存可以通过简单查询计算的内容。记录的数量将呈指数增长。例如,如果数据库中有N个概要文件,那么它将具有与N-1其他配置文件的一些距离属性。因此,您将在“缓存表”中得到N(N-1)记录数。

票数 4
EN

Stack Overflow用户

发布于 2020-12-30 21:49:51

要获得在GeoQuerySet中计算的距离,可以将annotateGeoDjango距离数据库功能 (不要与距离测量混淆)结合起来。

代码语言:javascript
复制
from django.contrib.gis.db.models.functions import Distance

queryset = Profile.objects.annotate(
    distance=Distance('location', a.location)
)

带注释的距离将是测量。这意味着您可以执行以下操作:

代码语言:javascript
复制
for profile in queryset:
    print(profile.distance.mi)  # or km, etc

若要筛选特定半径范围内的配置文件,可以向filter添加QuerySet。

代码语言:javascript
复制
from django.contrib.gis.db.models.functions import Distance as DistanceDBFunction
from django.contrib.gis.measure import Distance as DistanceMeasure

queryset = Profile.objects.annotate(
    distance=DistanceDBFunction('location', a.location)
).filter(
    distance__lt=DistanceMeasure(mi=1)
)

如果不需要带注释的距离,只需使用距离查找即可。

代码语言:javascript
复制
from django.contrib.gis.measure import Distance

queryset = Profile.objects.filter(
    location__distance_lt=(a.location, Distance(mi=1))
)

注:自Django 1.9以来,其他答案中提到的Profile.objects.distance(a.location)已被废弃。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32092584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档