16

Có mô-đun Python để tôi có thể tạo đối tượng với toạ độ địa lý (vĩ độ và kinh độ) hay không và truy vấn tất cả đối tượng trong phạm vi 5km (tức là bán kính) một tọa độ nhất định?Mô-đun Python để lưu trữ và truy vấn tọa độ địa lý

Tôi đã cố gắng lưu trữ vĩ độ và kinh độ làm khóa trong từ điển (khi chúng được lập chỉ mục theo khóa) và sử dụng một số thuật toán tìm khoảng cách để truy vấn chúng. Nhưng điều này cảm thấy giống như một hack khủng khiếp.

Về cơ bản giống như PostGIS cho PostgreSQL, nhưng tất cả đều nằm trong bộ nhớ của ứng dụng Python của tôi.

Trả lời

16

Có, hãy thử geopy.

import geopy 
import geopy.distance 

pt1 = geopy.Point(48.853, 2.349) 
pt2 = geopy.Point(52.516, 13.378) 

dist = geopy.distance.distance(pt1, pt2).km 
# 878.25 

sau đó bạn có thể truy vấn danh sách của bạn điểm:

[pt for pt in points if geopy.distance.distance(orig, pt).km < 5.] 
+0

Cảm ơn bạn đã trả lời. Tôi đã bỏ qua goepy bởi vì tôi nghĩ rằng nó là hoàn toàn cho mã hóa địa lý. Với ví dụ truy vấn, nó sẽ không lặp qua mọi đối tượng trong 'điểm'? Điều này không hiệu quả bằng việc lập chỉ mục các điểm của PostGIS - có lẽ cách tiếp cận cơ sở dữ liệu sẽ hiệu quả hơn. –

+0

@ Jonathan - bạn nói đúng, nó sẽ lặp qua toàn bộ danh sách các điểm. Tôi không biết về bất kỳ khả năng lập chỉ mục trong geopy. Có lẽ bạn tìm thấy một cái gì đó. – eumiro

5

Tôi biết điều này không phải là chính xác những gì bạn có nghĩa là, nhưng bạn có thể sử dụng GeoDjango với một cơ sở dữ liệu SQLite trong bộ nhớ. Đó là một bộ đầy đủ các công cụ GIS được trưng ra như một ứng dụng Web, làm cho nó trở thành một con dao của quân đội Thụy Sĩ để phát triển nhanh các ứng dụng GIS, đặc biệt là các truy vấn đặc biệt nhỏ.

1

Ý tưởng từ điển của bạn không có vẻ xấu, mặc dù bạn cũng sẽ cần kiểm tra các điểm nằm trong các phím từ điển 'lân cận'.

Nếu bạn không thể tìm thấy công cụ phù hợp và giống như thuật toán mã hóa, bạn có thể triển khai cây phân vùng không gian nhị phân mà afaik là một cách ít hacky hơn để đạt được điều tương tự.

0

Bạn đã xem Shapely chưa? Nó có một số phương thức để truy vấn các đối tượng trong một khoảng cách. Hãy xem Binary Spatial Predicates. Nó có thể chỉ là những gì bạn đang tìm kiếm.

2

Cách tiếp cận thông thường trong GIS là tạo vùng đệm xung quanh điểm quan tâm và truy vấn giao lộ. Như @RyanDalton đề xuất, nếu bạn dự định thực hiện rất nhiều công cụ định vị địa lý, hãy sử dụng Shapely, API GIS cho Python. Bạn nên biết về Shapely ngay cả khi bạn vẫn muốn có một chỉ số không gian (xem bên dưới). Dưới đây là làm thế nào để tạo bộ đệm trong kiểu dáng cân đối:

distance = 3 
center = Point(1, 1) 
pts = [Point(1.1, 1.2),Point(1.2,1.2)] 
center_buf = a.buffer(distance) 
#filters the points list according to whether they are contained in the list 
contained = filter(center_buf.contains,pts) 

Bạn thể chỉ số điểm của bạn mình (giả sử bằng kinh độ chẳng hạn) nếu bạn không có nhiều. Nếu không, bạn cũng có thể sử dụng gói Rtree, kiểm tra liên kết có tên Using Rtree as a cheapo spatial database!

1

Bạn có thể sử dụng SQLite có phần mở rộng Rtree để thực hiện chính xác loại lưu trữ và truy vấn đó. Cách tiếp cận này rất hữu ích nếu dữ liệu của bạn lớn hơn bộ nhớ bạn muốn sử dụng hoặc bạn muốn lưu và thao tác dữ liệu giữa các lần chạy chương trình. Mã lưu trữ và truy vấn thực tế là trong C có nghĩa là nó phải được biên dịch, nhưng lợi ích là hiệu năng phụ trội hơn các giải pháp Python thuần túy như geopy. Hoặc pysqlite hoặc APSW sẽ làm việc cho truy cập SQLite. (Tiết lộ: Tôi là tác giả APSW.)