2012-07-19 25 views
5

Tôi đang sử dụng geodjango và có một bộ sưu tập các điểm trong cơ sở dữ liệu của mình. Để có được một queryset điểm trong một khu vực nhất định tôi sử dụng này:Làm thế nào để trả về một bản ghi với khoảng cách thấp nhất từ ​​một điểm sử dụng geodjango?

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m)) 

Câu hỏi của tôi là làm thế nào tôi có thể trở lại chỉ có một điểm (điểm với khoảng cách thấp nhất) từ quan điểm tôi đã trôi qua nó?

EDIT

tôi nên đề cập đến mà tôi đang đi qua trong tọa độ và mong muốn tạo ra một đối tượng Point với họ. Sau đó vượt qua điểm đó như là nguồn gốc và bộ lọc chống lại điều đó. Ví dụ tôi đã cố gắng:

from spots.models import * 
from django.contrib.gis.geos import * 

origin = Point(28.011030, -26.029430) 
distance_m = 1000 

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m)) 
for q in queryset: 
    print q.distance 

Đoạn mã này mang lại cho tôi lỗi này:

Traceback (most recent call last): 
    File "<console>", line 2, in <module> 
AttributeError: 'Spot' object has no attribute 'distance' 

Điều thú vị là đủ nếu tôi làm như sau:

origin = Spot.objects.get(name='Montecasino').point 
distance_m = 1000 

for city in Spot.objects.distance(origin): 
    print(city.name, city.distance) 

(u'Design Quarter Parking', Distance(m=677.347841801)) 
(u'Montecasino', Distance(m=0.0)) 
(u'Fourways', Distance(m=1080.67723755)) 

Trả lời

4

Cuối cùng, một giải pháp thu thập từ các manh mối từ GeoDjango distance filter with distance value stored within model - query dẫn tôi đến số post này. Từ thông tin này, tôi có thể thu thập rằng bạn PHẢI ĐẶC BIỆT các thông số đo trong truy vấn khoảng cách của bạn. Bạn sẽ thấy trong đoạn mã bên dưới, tôi nhập đo lường là D. Sau đó, sử dụng nó trong truy vấn. Nếu bạn không xác định nó, bạn sẽ nhận được lỗi này:

ValueError: Tuple required for `distance_lte` lookup type. 

Để chỉ mất điểm với khoảng cách thấp nhất tôi đã sử dụng order_by('distance')[:1][0]

from spots.models import * 
from django.contrib.gis.geos import * 
from django.contrib.gis.measure import D 

distance_m = 20000 
origin = Point(28.011030, -26.029430) 

closest_spot = Spot.objects.filter(point__distance_lte=(origin, D(m=distance_m))).distance(origin).order_by('distance')[:1][0] 
+0

bạn có thể giải thích lý do tại sao bạn có' [: 1] [0] 'ở cuối – Sevenearths

+1

Vui lòng thực hiện điều này trước khi bạn gỡ lỗi: [https://docs.djangoproject.com/en/1.6/ref/contrib/gis/db-api/# compatibility-bảng] chỉ cần dành một vài giờ vô nghĩa gỡ lỗi point__distance_lte khi nó không được hỗ trợ cho Mysql – PKaura

0
queryset = Spot.objects.distance(origin).filter(distance__lte=distance_m) 
point = queryset.order_by('distance')[:1][0] 

https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoquerysets/#distance

+2

Thử đề xuất của bạn Tôi gặp lỗi. 'FieldError: Không thể giải quyết từ khóa 'khoảng cách' vào trường. Lựa chọn là: tác giả, created_on, id, tên, điểm, slug, updated_on' Không có trường khoảng cách nào trên mô hình của tôi. – darren

+0

@ darren nó có thể xảy ra khi bạn quên người dùng 'đối tượng = GeoManager()' Nó đến từ 'từ django.contrib.gis.db.models.manager nhập khẩu GeoManager' trong cài đặt tôi DATABASES nhớ sử dụng '' ENGINE ':' django.contrib.gis.db.backends.postgis ', ' – andi

0

tôi đang tìm kiếm một ví dụ về cách sắp xếp kết quả chống lại một vị trí với geodjango, vì vậy trường hợp sử dụng của tôi rất gần với trường hợp này. Mặc dù giải pháp được chấp nhận đã hoạt động, nhưng hiệu suất rất xấu cho một tập hợp dữ liệu lớn (hơn 140000 hàng).

Câu chuyện ngắn: hàm distance_lte phải tính khoảng cách xuất xứ cho mỗi hàng của bảng và không thể sử dụng chỉ mục địa lý. Dường như chức năng dwithin có thể tận dụng các chỉ số như vậy và không cần phải thực sự tính toán khoảng cách đến nguồn gốc cho mỗi hàng trước khi trước khi hạn chế được thực hiện, vì vậy đó là cách hiệu quả hơn:

origin = Point(28.011030, -26.029430) 
closest_spot = Spot.objects.filter(point__dwithin=(origin, 1)) \ 
    .distance(origin).order_by('distance')[:1][0] 

Chức năng dwithin làm việc với dữ liệu địa lý ở mức độ ("1" trong truy vấn).