2011-02-24 58 views
20

Tôi cố gắng để giải quyết vấn đề của việc tìm kiếm những người hàng xóm n gần bằng PostGIS:Tìm n Hàng xóm gần nhất cho điểm đã cho bằng cách sử dụng PostGIS?

Starting Point:

  • Bảng geoname với geonames (từ geonames.org) chứa vĩ độ/kinh độ (WSG- 84)
  • thêm Geom GeometryColumn với SRID = 4326 và datatype = POINT
  • Đầy Geom với các giá trị: UPDATE geoname SET Geom = ST_Se tSRID (ST_Point (kinh độ, vĩ độ), 4326);
  • Tạo index GIST cho Geom (CREATE INDEX geom_index ON geoname SỬ DỤNG GIST (Geom);)/Clustered geom_index: CỤM geom_index ON geoname;)
  • Created PRIMARY KEY chỉ số UNIQUE BTREE cho geonameid

vấn đề: Tìm n (ví dụ 5) hàng xóm gần nhất để một điểm được đưa ra trong bảng geoname đại diện bởi id (geoname.geonameid

có thể giải pháp:.

Lấy cảm hứng từ http://www.bostongis.com/PrinterFriendly.aspx?content_name=postgis_nearest_neighbor, tôi đã thử truy vấn sau đây: Thời gian

"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " + 
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid " + 
"AND ST_DWithin(start.geom, ende.geom, 300) order by distance limit 5" 

chế biến: khoảng 60

Cũng đã cố gắng một cách tiếp cận dựa trên MỞ RỘNG:

"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " + 
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND expand(start.geom, 300) && ende.geom " + 
"order by distance limit 5" 

Thời gian xử lý: khoảng 120s

Ứng dụng dự định là một số loại tự động hoàn thành. Vì vậy, bất kỳ cách tiếp cận nào lâu hơn> 1s đều không được áp dụng. Nói chung có thể đạt được thời gian phản hồi của < 1s với PostGIS không?

+4

Tôi nghĩ bạn có cơ hội tốt hơn tại http://gis.stackexchange.com/ để nhận câu trả lời. –

Trả lời

39

Bây giờ kể từ PostGIS 2.0, có một chỉ số KNN với nhiều loại hình học có sẵn. Điều này cung cấp cho bạn 5 hồ sơ gần nhất bỏ qua khoảng cách xa "vị trí của bạn ...".

SELECT * 
FROM your_table 
ORDER BY your_table.geom <-> "your location..." 
LIMIT 5; 

Xem <-> nhà điều hành in PostgreSQL manual.

+0

Gọn gàng! Một trong số rất nhiều tính năng được phát hành với phiên bản 2.0. Tôi đoán rằng sẽ cho bạn kết quả nhanh hơn? Bạn có biết những gì (khoảng) loại tốc độ bạn có thể mong đợi? – radek

+3

Chỉ cần làm rõ, chỉ số KNN thực sự được triển khai trong PG> 9.1, do đó hãy chắc chắn rằng bạn đã cài đặt đúng phiên bản PG ... nó chắc chắn đáng để kiểm tra ... – Scholle

+0

Đồng thời đánh dấu câu trả lời này vì đó có thể là cách hiệu quả nhất để thực hiện tìm kiếm lân cận gần nhất bằng cách sử dụng công nghệ db phổ biến ... – Scholle

6

Như tôi nghĩ rằng bạn đã được trả lời trong danh sách các đơn vị là ở độ để bạn khu vực gần như tìm kiếm toàn thế giới với 300 độ trong st_dwithin.

Nếu tập dữ liệu của bạn lớn, do đó bạn không thể làm việc trong phép chiếu được đo dự đoán thay vì (tính toán nhanh hơn và ít tốn nhiều CPU hơn), bạn nên cân nhắc sử dụng loại geograpphy thay thế. Sau đó, bạn có thể sử dụng st_dwithin với đồng hồ.

Làm cho mọi thứ nhanh hơn, bạn nên tạo một bảng mới với hình dạng được chuyển đổi thành địa lý.

Nhưng chỉ cần kiểm tra nó, bạn có thể bỏ một cách nhanh chóng:

SELECT start.asciiname, ende.asciiname, 
ST_Distance(start.geom::geography, ende.geom::geography) as distance 
FROM geoname As start, geoname As ende 
WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND 
ST_DWithin(start.geom::geography, ende.geom::geography, 300) 
order by distance 
limit 5; 

HTH Nicklas

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