Django 查找距离点x英里以内的对象
我正在努力获取用户位置10英里范围内的所有事件。我的模型看起来像这样:Django 查找距离点x英里以内的对象,django,geodjango,Django,Geodjango,我正在努力获取用户位置10英里范围内的所有事件。我的模型看起来像这样: class User(models.Model): location = models.PointField() ... class Event(models.Model): location = models.PointField() ... 在我的测试中,当我检查用户和事件之间的距离时,我得到值11.5122663513: from geopy.distance import vin
class User(models.Model):
location = models.PointField()
...
class Event(models.Model):
location = models.PointField()
...
在我的测试中,当我检查用户和事件之间的距离时,我得到值11.5122663513
:
from geopy.distance import vincenty
print vincenty(request.user.location, event.location).miles # 11.5122663513
然而,当我查询用户位置10英里范围内的所有事件时,会返回该事件:
Event.objects.filter(location__distance_lte=(request.user.location, D(mi=10))).count() # 1
只有当我将半径降低到小于4英里时,过滤器才会生效:
Event.objects.filter(location__distance_lte=(request.user.location, D(mi=3))).count() # 0
我几乎完全遵循了这个原则,所以我认为我的问题不在于我的问题
造成这种差异的原因是什么?这在很大程度上取决于您使用的数据库类型 因为笛卡尔数学比地理空间数学快得多,所以查询可能会将坐标视为在平面上而不是球体上 他们这样解释: 大多数人都熟悉使用纬度和经度来表示 参考地球表面的一个位置。但是,纬度和 经度是角度,不是距离。换句话说,当 平面上两点之间的最短路径是一条直线, 曲面上两点之间的最短路径(例如 地球)是一个大圆的弧。因此,需要进行额外的计算 需要以平面单位获取距离(例如,公里和 英里)。使用地理坐标系可能会引入 开发人员稍后会遇到复杂的问题。例如,Spatialite就是这样做的 不具备在两个传感器之间执行距离计算的能力 使用地理坐标系的几何图形,例如构建 查询以查找存储为的县边界5英里内的所有点 WGS84 地球表面的一部分可以投射到二维平面上, 或者笛卡尔,平面。投影坐标系尤其重要 适用于特定地区的应用,例如,如果您知道 您的数据库将只覆盖堪萨斯州北部的几何图形,然后您可以 考虑使用特定于该区域的投影系统。此外 投影坐标系以笛卡尔单位定义(例如 米或英尺),简化了距离计算 此外,这可能会受到数据库选择的影响。如果您使用的是Postgres/PostGIS,文档中有以下注释: 在PostGIS中,ST_Distance_Sphere不限制几何体类型 地理距离查询使用。然而,这些 查询可能需要很长时间,因为必须使用较大的圆距离 为查询中的每一行动态计算。这是因为 无法使用传统几何体字段上的空间索引 <>在WGS84距离查询上有更好的性能,考虑使用 而不是数据库中的地理列,因为它们能够 在距离查询中使用它们的空间索引。你可以告诉我去哪里 通过在字段中设置geography=True来使用geography列 定义 您可以通过打印原始SQL来检查这一点:
qs = Event.objects.filter(location__distance_lte=(request.user.location, D(mi=10))
print qs.query
根据您的数据库类型和计划存储的数据量,您有两个选项:
- 在python中再次过滤这些点
- 尝试设置
geography=True
- 设置明确的
- 取一个具有给定半径的点,然后使用
contains
- 使用不同的数据库类型
如果共享原始查询,将更容易了解发生了什么。我最终使用了缓冲区将一个点变为一个圆选项。对于其他选择该选项的人,请确保。