返回Django附近的位置

时间:2014-09-02 12:48:28

标签: python django

我有一个django模型,它有一个名为LocationField的自定义属性。

class List(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=200)
    location = LocationField(blank=True, max_length=255)

此值中的值存储为格式latitude, longitude的字符串。在我的模板中,我按如下方式传递了一个网址:/nearby?lat='+somevalue+'&long='+somevalue

现在,我希望从List返回附近的条目,具体取决于传递的值。

为此,我编写了一个views.py函数,如下所示:

def nearby(request):
    if request.GET['lat']:
        lat = request.GET['lat']
        longitude = request.GET['long']
        first_query = Playlist.objects.filter(location__istartswith=lat)
        for f in first_query:
           l = f.index(',')
           n_string = f[l:]

为了澄清我所做的事情,first_query会返回以相同latitude开头的所有条目。但是,现在我还要匹配longitude,这就是为什么我正在运行for loop并搜索在latitude,longitude中分隔LocationField的逗号的索引。 n_string获取LocationField的子字符串,然后我计划将其与longitude变量匹配。

我的问题是两部分:

  1. 如何生成匹配纬度的查询以及如何将其返回模板?
  2. 如何检查该区域周围2平方公里的区域?
  3. 这是否有django包?

3 个答案:

答案 0 :(得分:6)

至少有3种方法可以做到这一点:

a)Haersine距离(例如在MySQL中)

def nearby_spots_old(request, lat, lng, radius=5000, limit=50):
    """
    WITHOUT use of any external library, using raw MySQL and Haversine Formula
    http://en.wikipedia.org/wiki/Haversine_formula
    """
    radius = float(radius) / 1000.0

    query = """SELECT id, (6367*acos(cos(radians(%2f))
               *cos(radians(latitude))*cos(radians(longitude)-radians(%2f))
               +sin(radians(%2f))*sin(radians(latitude))))
               AS distance FROM demo_spot HAVING
               distance < %2f ORDER BY distance LIMIT 0, %d""" % (
        float(lat),
        float(lng),
        float(lat),
        radius,
        limit
    )

    queryset = Spot.objects.raw(query)
    serializer = SpotWithDistanceSerializer(queryset, many=True)

    return JSONResponse(serializer.data)

b)使用Geodjango (PostgreSQL + PostGIS)

def nearby_spots_new(request, lat, lng, radius=5000, limit=50):
    """
    WITH USE OF GEODJANGO and POSTGIS
    https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-queries
    """
    user_location = fromstr("POINT(%s %s)" % (lng, lat))
    desired_radius = {'m': radius}
    nearby_spots = Spot.objects.filter(
        mpoint__distance_lte=(user_location, D(**desired_radius))).distance(
        user_location).order_by('distance')[:limit]
    serializer = SpotWithDistanceSerializer(nearby_spots, many=True)

    return JSONResponse(serializer.data)

c)一些聪明的查询(想想广场上的圆圈)

请在此处查看我的回答:How to filter a django model with latitude and longitude coordinates that fall within a certain radius

答案 1 :(得分:1)

您应该使用GIS数据库来存储和执行坐标,搜索等操作。

用于存储位置使用https://docs.djangoproject.com/en/dev/ref/contrib/gis/model-api/#pointfield

作为数据库,您可以使用https://docs.djangoproject.com/en/dev/ref/contrib/gis/install/#postgishttps://docs.djangoproject.com/en/dev/ref/contrib/gis/install/spatialite/

要在附近搜索,您应该使用距离查找,请参阅https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-lookups

中的示例

答案 2 :(得分:0)

是的,这个Geodjango有一个包/项目。您可以阅读官方文档here