【问题标题】:show distance in km or m of each restaurant以公里或米为单位显示每家餐厅的距离
【发布时间】:2018-03-25 16:18:00
【问题描述】:

我已经使用 postgis 和 geodjango 实现了从给定坐标显示附近餐厅的功能。但是我需要根据用户附近的距离或给定的坐标找到以公里或米为单位的距离。我知道在 SO 中提出了与距离相关的问题,但这个问题有点不同。我正在显示餐厅列表(列表视图)而不是餐厅的详细信息,我将从 id 获得特定的餐厅位置。所以我需要一个想法,我现在应该如何在餐厅列表视图中显示每家餐厅的距离。

我的想法是我应该通过 lat 和 lng(我从 url 传递)作为上下文并使用模板过滤器来计算距离

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 %}

请分享您对我应该如何做的想法

【问题讨论】:

    标签: python django django-views postgis


    【解决方案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() 是解耦的,我会通过一堆已知距离来测试它。根据the testing docs设置你的测试

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

    【讨论】:

    • 非常感谢您的解决方案。我做了以下显示距离但不知道这是否有效。我怎么知道? gist.github.com/SanskarSans/fe05e1d28552b9f5cc077e0ffa23a2f4
    • 将其与您之前代码的响应进行比较。当你点击 url 时会发生什么?
    • 您的解决方案没有问题。我只是在询问确定计算出的距离是否正确的提示:)。另外你对距离计算的代码有什么建议吗?
    • 啊,我明白了。我强烈建议使用一些测试驱动开发。 Django 内置了一些不错的测试工具。我会更新我的答案。
    • 至于距离计算GEOSGeometry 似乎是一个不错的选择并且适合目的,但我只是看了一眼,我对范围和性能要求一无所知。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多