Reputation: 11
I've saved user's coordinates in the User
model. Post model has latitude
, longitude
and radius
field. Only the users in that vicinity(of Post) will be able to see that post. I don't know how to use filter()
here so I used the following approach:
post=Posts.objects.all()
for a in post:
distance= geopy.distance.geodesic((lat1,lng1), (a.latitude, a.longitude)).km
print(distance)
if distance < a.radius:
p.append(a)
else:
continue
Here, lat1
and lng1
are the coordinates of current User
. Suggest if there is any better way as this seems very inefficient.
Upvotes: 0
Views: 678
Reputation: 12548
Depending on your requirements, you could use a square instead of a circle. Pre-calculate the x-max, x-min, y-max and y-min boundaries for your square and then do a simple User.filter(lat__gt=lat_min, user.lng__gt=lng_min, user.lat__lt=lat_max ...
lookup in the database.
In a past project, I used this:
def get_latlng_bounderies(lat, lng, distance):
"""
Return min/max lat/lng values for a distance around a latlng.
:lat:, :lng: the center of the area.
:distance: in km, the "radius" around the center point.
:returns: Two corner points of a square that countains the circle,
lat_min, lng_min, lat_max, lng_max.
"""
gc = great_circle(kilometers=distance)
p0 = gc.destination((lat, lng), 0)
p90 = gc.destination((lat, lng), 90)
p180 = gc.destination((lat, lng), 180)
p270 = gc.destination((lat, lng), 270)
ret = p180[0], p270[1], p0[0], p90[1]
return ret
Its not a circle, so its not exact around the "corners" of the square, but its much faster, because its a simple float comparision in the database.
Upvotes: 1