2014-09-02 123 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