我使用postgis和geodjango实现了从给定坐标显示附近餐厅的功能。但我需要根据用户或给定坐标附近的距离找到以km或m为单位的距离。我知道有关距离的问题在SO中被问到,但这个问题有点不同。我正在显示餐馆列表(列表视图)而不是餐厅的详细信息,我将从id获得特定的餐厅位置。所以我需要一个想法,我现在应该如何在餐厅列表视图中显示每个餐厅的距离。
我的想法是我应该将lat和lng(我从网址传递)作为上下文传递并使用模板过滤器来计算距离
from django.contrib.gis.geos import GEOSGeometry
pnt = GEOSGeometry('SRID=4326;POINT(40.396764 -3.68042)')
pnt2 = GEOSGeometry('SRID=4326;POINT( 48.835797 2.329102 )')
pnt.distance(pnt2)*100
这是详细的代码
def nearby_restaurant_finder(request, current_lat, current_long):
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
user_location = Point(float(current_long), float(current_lat))
distance_from_point = {'km': 500}
restaurants = Restaurant.gis.filter(
location__distance_lte=(user_location, D(**distance_from_point)))
restaurants = restaurants.distance(user_location).order_by('distance')
context = {
'restaurants': restaurants
}
return render(request, 'restaurant/nearby_restaurant.html', context)
url(r'^nearby_restaurant/(?P<current_lat>-?\d*.\d*)/(?P<current_long>-?\d*.\d*)/$',
views.nearby_restaurant_finder, name="nearby-restaurant"),
{% block page %}
{% for restaurant in restaurants %}
<h1>Nearby Restaurants are:</h1>
<h3>{{ restaurant.name }}</h3>
{% empty %}
<h3>No Match Found</h3>
{% endfor %}
{% endblock %}
请分享你我应该怎么做的想法
答案 0 :(得分:1)
我想你几乎就在那里;我会使用python计算距离,然后在模板中显示它们而不是创建过滤器。
我首先用字典或类似的列表更新上下文:
def calculate_distance(restaurant_location, current_lat, current_long):
# this function should return the distance of the restaurant from the user
return distance_calculated
def nearby_restaurant_finder(request, current_lat, current_long):
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
user_location = Point(float(current_long), float(current_lat))
distance_from_point = {'km': 500}
restaurants = Restaurant.gis.filter(location__distance_lte=(user_location, D(**distance_from_point)))
restaurants = restaurants.distance(user_location).order_by('distance')
# create a list of dictionaries with results to display
ctx_restaurants = [
{
'name': restaurant.name,
'distance_from_user': calculate_distance(restaurant.location, current_lat, current_long)
}
for restaurant in restaurants
]
# pass results into context
context = {
'restaurants': ctx_restaurants
}
return render(request, 'restaurant/nearby_restaurant.html', context)
然后我会在某种表中的模板中呈现这个
{% block page %}
<h1>Nearby Restaurants are:</h1>
<table>
{% for restaurant in restaurants %}
<tr>
<td>{{ restaurant.name }}</td>
<td>{{ restaurant.distance_from_user}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
使用TDD:
由于calculate_distance()
被解耦,我会通过传递一堆已知距离来测试它。根据{{3}}
from django.test import TestCase
from myapp.views import calculate_distance
class DistanceTests(TestCase):
def setUp(self):
self.known_cases = [
{'location': XX1, 'lat': XX1, 'long': XX1, 'expected': XX1},
{'location': XX2, 'lat': XX2, 'long': XX2, 'expected': XX2},
]
def test_calculate_distance(self):
for case in self.known_cases:
self.assertEquals(
calculate_distance(case['location'], case['lat'], case['long']),
case['expected']
)