如何从数据库中获取最近的位置条目?
How to get the nearest location entries from a database?
我在我的数据库中将坐标存储为经纬度对。现在,我需要从给定的经纬度坐标检索给定半径内的所有条目。例如给定坐标48.796777、2.371140,距离20公里,将检索到该点20公里以内的所有记录。
如果它提供任何简化或在更少的 CPU 时间内产生结果,则它足以准确计算点之间的 "straight" 距离,即无需考虑地球曲率。
如何使用 Django 实现这一点?更具体地说,应该如何为这样的查询构造视图(可能还有模型)?
您应该在地理数据库条目上使用 GeoDjango. It allows you to perform distance queries。
from django.contrib.gis.measure import D
from django.contrib.gis.geos import *
from myapp.models import MyResult
pnt = fromstr('POINT(48.796777 2.371140 )', srid=4326)
qs = MyResult.objects.filter(point__distance_lte=(pnt, D(km=20)))
您可以使用geopy
from geopy import distance
_, ne = g.geocode('Newport, RI')
_, cl = g.geocode('Cleveland, OH')
distance.distance(ne, cl).miles
# 538.37173614757057
要优化一点,您可以过滤 用户对象,以便首先粗略估计附近的用户。这样您就不必遍历数据库中的所有用户。这个粗略估计是可选的。为了满足您所有的项目要求,您可能需要编写一些额外的逻辑:
#The location of your user.
lat, lng = 41.512107999999998, -81.607044999999999
min_lat = lat - 1 # You have to calculate this offsets based on the user location.
max_lat = lat + 1 # Because the distance of one degree varies over the planet.
min_lng = lng - 1
max_lng = lng + 1
users = User.objects.filter(lat__gt=min_lat, lat__lt=max__lat, lat__gt=min_lat, lat__lt=max__lat)
# If not 20 fall back to all users.
if users.count() <= 20:
users = User.objects.all()
我认为最好的方法是像 Timmy 建议的那样使用 GeoDjango,但是你必须有一个支持地理的后端(比如 PosGis)。但是,如果您有一个包含自定义纬度和经度字段的模型,我认为它是不可能使用的
class CustomGeoModel(models.Model):
lat = models.CharField(max_length=30)
lon = models.CharField(max_length=30)
试试这个代码。
我正在使用 python、sqlalchemy
这个 sqlalchemy 查询 return 给定的最近对象 point.its 工作 correct.but 这个查询 return 所有 models.but 它工作正常。
我的模型class
#
class City(Base):
__tablename__ = "tbl_City"
city_id = Column(Integer, primary_key=True, unique=True)
geo_coordinates = Column(Geometry('POINT', srid=4326))
我的查询
#
point = city.geo_coordinates
near_citylist = City.query.order_by(City.geo_coordinates.distance_box(point))
没有 GeoDjango
你可以,
objects = YourModel.objects.raw('SELECT *, ( 6371 * acos( cos( radians('+my_lat+') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('+my_long+') ) + sin( radians('+my_lat+') ) * sin( radians( latitude ) ) ) ) AS distance FROM "YourModel" WHERE (6371 * acos( cos( radians('+my_lat+') ) * cos( radians(latitude) ) * cos( radians(longitude) - radians('+my_long+') ) + sin( radians('+my_lat+') ) * sin( radians(latitude) ) ) ) <= 100')
其中my_lat是输入纬度,my_long是输入经度,latitude是Latitude的Model字段,longitude是Longitude的Model字段,100是距离。
我在我的模型中使用了 FloatField 作为纬度和经度。
现在这个 returns 是一个 RawQueryset,如果你需要在查询集上使用额外的过滤器,你可以通过这样做来获得通常的 Django 查询集,
objects = YourModel.objects.filter(pk__in=[i.pk for i in objects])
我在我的数据库中将坐标存储为经纬度对。现在,我需要从给定的经纬度坐标检索给定半径内的所有条目。例如给定坐标48.796777、2.371140,距离20公里,将检索到该点20公里以内的所有记录。
如果它提供任何简化或在更少的 CPU 时间内产生结果,则它足以准确计算点之间的 "straight" 距离,即无需考虑地球曲率。
如何使用 Django 实现这一点?更具体地说,应该如何为这样的查询构造视图(可能还有模型)?
您应该在地理数据库条目上使用 GeoDjango. It allows you to perform distance queries。
from django.contrib.gis.measure import D
from django.contrib.gis.geos import *
from myapp.models import MyResult
pnt = fromstr('POINT(48.796777 2.371140 )', srid=4326)
qs = MyResult.objects.filter(point__distance_lte=(pnt, D(km=20)))
您可以使用geopy
from geopy import distance
_, ne = g.geocode('Newport, RI')
_, cl = g.geocode('Cleveland, OH')
distance.distance(ne, cl).miles
# 538.37173614757057
要优化一点,您可以过滤 用户对象,以便首先粗略估计附近的用户。这样您就不必遍历数据库中的所有用户。这个粗略估计是可选的。为了满足您所有的项目要求,您可能需要编写一些额外的逻辑:
#The location of your user.
lat, lng = 41.512107999999998, -81.607044999999999
min_lat = lat - 1 # You have to calculate this offsets based on the user location.
max_lat = lat + 1 # Because the distance of one degree varies over the planet.
min_lng = lng - 1
max_lng = lng + 1
users = User.objects.filter(lat__gt=min_lat, lat__lt=max__lat, lat__gt=min_lat, lat__lt=max__lat)
# If not 20 fall back to all users.
if users.count() <= 20:
users = User.objects.all()
我认为最好的方法是像 Timmy 建议的那样使用 GeoDjango,但是你必须有一个支持地理的后端(比如 PosGis)。但是,如果您有一个包含自定义纬度和经度字段的模型,我认为它是不可能使用的
class CustomGeoModel(models.Model):
lat = models.CharField(max_length=30)
lon = models.CharField(max_length=30)
试试这个代码。 我正在使用 python、sqlalchemy
这个 sqlalchemy 查询 return 给定的最近对象 point.its 工作 correct.but 这个查询 return 所有 models.but 它工作正常。
我的模型class
#class City(Base):
__tablename__ = "tbl_City"
city_id = Column(Integer, primary_key=True, unique=True)
geo_coordinates = Column(Geometry('POINT', srid=4326))
我的查询
#point = city.geo_coordinates
near_citylist = City.query.order_by(City.geo_coordinates.distance_box(point))
没有 GeoDjango
你可以,
objects = YourModel.objects.raw('SELECT *, ( 6371 * acos( cos( radians('+my_lat+') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('+my_long+') ) + sin( radians('+my_lat+') ) * sin( radians( latitude ) ) ) ) AS distance FROM "YourModel" WHERE (6371 * acos( cos( radians('+my_lat+') ) * cos( radians(latitude) ) * cos( radians(longitude) - radians('+my_long+') ) + sin( radians('+my_lat+') ) * sin( radians(latitude) ) ) ) <= 100')
其中my_lat是输入纬度,my_long是输入经度,latitude是Latitude的Model字段,longitude是Longitude的Model字段,100是距离。
我在我的模型中使用了 FloatField 作为纬度和经度。
现在这个 returns 是一个 RawQueryset,如果你需要在查询集上使用额外的过滤器,你可以通过这样做来获得通常的 Django 查询集,
objects = YourModel.objects.filter(pk__in=[i.pk for i in objects])