2014-09-02 119 views
3

我有一个django模型,它有一个名为LocationField的自定义属性。在Django返回附近的位置

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的字符串。从我的模板中,我传递一个url,如下所示:/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并搜索我的LocationField中分隔latitude,longitude的逗号索引。 n_stringLocationField的子串,然后我打算将它匹配到我的longitude变量。

我的问题是两个部分:

  1. 如何生成的纬度相匹配的查询?如何将其返回模板吗?
  2. 如何检查该区域周围2平方公里的区域?

是否有django软件包?

回答

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) 

三)一些智能查询(想想圆方落款)

在这里看到我的回答: How to filter a django model with latitude and longitude coordinates that fall within a certain radius

+0

非常感谢!第一个工作完美。我正在使用另一个完全不准确的公式! – Newtt 2014-09-04 08:51:30

+0

可能有这样的不准确性的几个原因:例如,铸造问题我在查询而不是'%2f'查找'%d'的错误,另一个问题可以使用常量'6367'作为半径,对于某些地理定位不准确。见这里:http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html – andi 2014-09-04 09:11:27

+0

是在半径in a)以米为单位? – wswld 2017-09-18 13:51:14

0

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

1