2013-07-16 30 views
8

Tôi có mô hình sau.Cách lọc mô hình django có vĩ độ và kinh độ nằm trong bán kính nhất định

class Location(models.Model): 
    name = models.CharField(max_length = 128, blank = True) 
    address =models.CharField(max_length = 200, blank= True) 
    latitude = models.DecimalField(max_digits=6, decimal_places=3) 
    longitude = models.DecimalField(max_digits=6, decimal_places=3) 

    def __unicode__(self): 
     return self.name 

Nếu hiện tại vĩ độ & độ của tôi là:

current_lat = 43.648 
current_long = 79.404 

tôi đã làm một số nghiên cứu và đã xem qua các Haversine Equation mà tính toán khoảng cách giữa hai vị trí tọa độ. Dưới đây là phương trình tôi thấy:

import math 

def distance(origin, destination): 
    lat1, lon1 = origin 
    lat2, lon2 = destination 
    radius = 6371 # km 

    dlat = math.radians(lat2-lat1) 
    dlon = math.radians(lon2-lon1) 
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \ 
     * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2) 
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) 
    d = radius * c 

    return d 

Tôi muốn trả lại tất cả các đối tượng Location rơi trong vòng bán kính 10 km, làm thế nào tôi có thể lọc nó trong một cách mà nó sẽ chỉ trả lại tất cả các đối tượng Location rằng nằm trong bán kính 10 km này?

LocationsNearMe = Location.objects.filter(#This is where I am stuck) 

Liệu có cách nào tôi có thể thực hiện các phương trình Haversine vào lọc để nó chỉ trả về các đối tượng vị trí đó nằm trong bán kính 10 km?

Tôi đang tìm câu trả lời chi tiết. Đánh giá cao sự trợ giúp.

+1

bạn nên thử và sử dụng geodjango https://docs.djangoproject.com/en/dev/ref/contrib/gis/ – user710907

+0

Chắc chắn nhìn vào geodjango, tôi có một giải pháp cho vấn đề này b ut it yêu cầu geodjango: https://gist.github.com/omouse/5623772 –

+0

@omouse cảm ơn đã hướng dẫn tôi đúng hướng, trong giải pháp của bạn, bạn có điểm, nhưng ở đây trong mô hình này, nó được chia thành hai lĩnh vực: kinh độ và vĩ độ. Bạn có thể đặt câu trả lời của bạn cho trường hợp này dưới đây trong phần trả lời. – noahandthewhale

Trả lời

7

Nhưng bạn luôn có thể làm cho đề nghị của cách tiếp cận Brian tốt hơn bằng cách lọc các kết quả từ bước trước (mà hoepfully nên là tập hợp con nhỏ hơn) và cho mỗi bạn kiểm tra xem chúng có nằm trong bán kính hay không.

Người dùng của bạn đang ở điểm đen. Phép tính xấp xỉ của Square được đưa ra bởi Brian trả về các điểm màu xanh lá cây và màu cam. Sự phân kỳ trong khoảng cách có thể là đáng kể trong trường hợp xấu nhất người dùng phải đi sqrt (2) lần xa hơn dự kiến ​​(thêm 40% khoảng cách). Vì vậy, đối với tất cả các điểm màu cam và màu xanh lá cây, bạn nên kiểm tra xem khoảng cách của chúng từ điểm đen hay không (ví dụ euclidian nếu khoảng cách thực sự ngắn như điều hướng trong thành phố) không lớn hơn bán kính giả định.

enter image description here

UPDATE:

Nếu bạn muốn sử dụng khoảng cách Haversine hoặc (tốt hơn) đề cập GeoDjango HAVA một cái nhìn về đoạn này so sánh hai django quan điểm đối phó với lân cận tìm kiếm:

https://gist.github.com/andilabs/4232b463e5ad2f19c155

+0

cảm ơn câu trả lời của bạn, tôi thực sự đánh giá cao sự hiểu biết của bạn về cách giải quyết vấn đề này! :) – noahandthewhale

+0

ý chính bị hỏng. –

+1

Đây là liên kết mới http://andilabs.github.io/django/devops/tools/postgres/postgis/2015/01/31/postgis-geodjango-english.html –

8

Bạn có thể thực hiện các truy vấn theo phạm vi với filter.

LocationsNearMe = Location.objects.filter(latitude__gte=(the minimal lat from distance()), 
              latitude__lte=(the minimal lat from distance()), 
              (repeat for longitude)) 

Thật không may, điều này trả về kết quả dưới dạng một hình vuông hình học (thay vì một vòng tròn)

Các vấn đề liên quan