显示每家餐馆的公里或米的距离

时间:2017-10-13 13:45:09

标签: python django django-views postgis

我使用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 %}

请分享你我应该怎么做的想法

1 个答案:

答案 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']
            )