Điểm trong thuật toán đa giác cho nhiều đa giác


11

Tôi có một bản đồ Google với một loạt các đa giác trên đó.

Đây là một vấn đề tôi quan tâm: Đưa ra một điểm lat, lng, cách tốt nhất để xác định tất cả các đa giác mà điểm này nằm ở đâu?

Cách rõ ràng là chạy một thuật toán "điểm trong đa giác" lặp đi lặp lại cho mỗi đa giác, nhưng tôi đã tự hỏi liệu có một thuật toán hiệu quả để trả lời các truy vấn như vậy đặc biệt là nếu bạn có hàng ngàn đa giác.


Tôi không biết nhiều về API Google Maps, nhưng trình duyệt có xu hướng không phải là nơi tốt nhất để thực hiện các truy vấn lớn như thế này. PostGIS (miễn phí), ArcServer hoặc Oracle Spatial có xu hướng xử lý các yêu cầu như thế này tốt hơn.
canisrufus

Tôi quan tâm đến thuật toán hơn bất cứ điều gì khác. BTW, bạn sẽ làm điều này như thế nào trong PostGIS.
numan

Các url sau đây nói về điểm trong đa giác .. (tôi chưa bao giờ sử dụng điều này) .. hãy thử .. nó có thể cung cấp một số ide. eriestuff.blogspot.com/2008/02/ từ

3
Dưới đây là nhận xét bắt buộc của tôi rằng "đa giác điểm" không có ý nghĩa gì đối với một điểm trên một hình cầu, vì một đa giác trên một hình cầu chỉ chia hình cầu thành hai phần, một trong hai phần có quyền được gọi là 'bên trong'. Là cực bắc hay cực nam 'bên trong' là đa giác xác định đường xích đạo? Hãy nhớ rằng, lat-long không phải là cartesian ...
Spacesman

4
@ Spaces Bạn nhầm lẫn "đa giác" với "đa tuyến." Point-in-polygon tạo cảm giác hoàn hảo trên một hình cầu. Một đa giác không chỉ là ranh giới của nó (một đa giác khép kín): nó bao gồm phần bên trong của nó. Mặc dù một ranh giới đa giác chia hình cầu thành hai thành phần được kết nối, có nhiều cách để chỉ định một trong số chúng là phần bên trong của đa giác, chẳng hạn như bằng một quy ước định hướng (ví dụ: phần bên trong nằm ở bên trái khi đi qua ranh giới ) hoặc bằng cách sử dụng một đại diện raster.
whuber

Câu trả lời:


12

Như với hầu hết tất cả các câu hỏi như vậy, cách tiếp cận tối ưu phụ thuộc vào "trường hợp sử dụng" và cách các tính năng được thể hiện. Các trường hợp sử dụng thường được phân biệt bởi (a) cho dù có nhiều hay ít đối tượng trong mỗi lớp và (b) liệu một (hoặc cả hai) lớp có cho phép tính toán trước một số cấu trúc dữ liệu hay không; nghĩa là, liệu một hoặc cả hai đều đủ tĩnh và không thay đổi để làm cho khoản đầu tư vào tiền mã hóa có giá trị.

Trong trường hợp hiện tại, điều này mang lại các kịch bản sau đây. Thông thường các điểm là động: đó là, chúng không được đưa ra trước. (Nếu chúng có sẵn trước hoặc trong các nhóm rất lớn, một số tối ưu hóa dựa trên việc sắp xếp chúng sẽ khả dụng.) Gọi Q là số điểm truy vấn và P là số đỉnh đa giác .

Dữ liệu đa giác vectơ

(1) Vài điểm, vài đỉnh đa giác trong toto . Sử dụng thủ tục brute-force, chẳng hạn như thuật toán đâm đường cổ điển . Đối với bất kỳ phương pháp tử tế nào, chi phí là O (P * Q), vì chi phí thời gian O (1) để so sánh một điểm với cạnh đa giác và tất cả các so sánh như vậy phải được thực hiện.

(2) Có thể có nhiều đỉnh đa giác, nhưng chúng là động: mỗi lần một điểm được sử dụng trong truy vấn, đa giác đều có thể thay đổi. Một lần nữa sử dụng thuật toán brute-force. Chi phí vẫn là O (P * Q), sẽ lớn vì P sẽ lớn, nhưng không giúp được gì. Nếu các thay đổi nhỏ hoặc được kiểm soát ( ví dụ: đa giác có hình dạng thay đổi một chút hoặc đơn giản là di chuyển chậm), bạn có thể sử dụng phiên bản của giải pháp tiếp theo và tìm cách hiệu quả để cập nhật cấu trúc dữ liệu khi đa giác thay đổi. Đó có thể sẽ là một vấn đề cho nghiên cứu ban đầu.

(3) Nhiều đỉnh đa giác và đa giác tĩnh (nghĩa là lớp đa giác sẽ hiếm khi thay đổi). Tính toán trước một cấu trúc dữ liệu để hỗ trợ tìm kiếm (có thể dựa trên quét dòng hoặc thuật toán tứ giác ). Chi phí tính toán trước cho các thuật toán này là O (P * log (P)), nhưng chi phí của các truy vấn trở thành O (Q * log (P)), do đó tổng chi phí là O ((P + Q) * log ( P)).

Một số cải tiến có sẵn trong các trường hợp đặc biệt , chẳng hạn như

(a) Tất cả các đa giác đều lồi ( tiền xử lý các đa giác có thể được thực hiện nhanh hơn ),

(b) Tất cả các nội thất đa giác đều rời rạc , trong trường hợp đó bạn có thể nghĩ liên kết của chúng là một đa giác đơn (cho phép các thuật toán hiệu quả đơn giản, chẳng hạn như các thuật toán dựa trên tam giác và

(c) Hầu hết các đa giác không quanh co - đó là, chúng chiếm phần lớn các hộp giới hạn của chúng - trong trường hợp đó bạn có thể thực hiện một thử nghiệm ban đầu chỉ dựa trên các hộp giới hạn và sau đó tinh chỉnh giải pháp đó. Đây là một tối ưu hóa phổ biến.

(d) Số lượng điểm lớn. Sắp xếp chúng có thể cải thiện thời gian. Chẳng hạn, khi thực hiện thuật toán quét điểm đa giác từ trái sang phải, bạn sẽ sắp xếp các điểm trên tọa độ đầu tiên của chúng, cho phép bạn quét qua các điểm cùng lúc bạn quét qua các cạnh đa giác. Tôi không biết rằng một tối ưu hóa như vậy đã được công bố. Tuy nhiên, một điều đã được công bố là thực hiện phép tính tam giác bị ràng buộc của sự kết hợp của tất cả các điểm và đa giác: một khi quá trình tam giác đó hoàn thành, việc xác định các điểm bên trong sẽ nhanh chóng. Chi phí tính toán sẽ được chia theo tỷ lệ là O (Q * log (Q) + (P + Q) * log (P + Q)).

Dữ liệu đa giác raster

Điều này cực kỳ dễ dàng: xem lớp đa giác dưới dạng raster chỉ báo nhị phân (1 = bên trong đa giác, 0 = bên ngoài). (Điều này có thể yêu cầu bảng tra cứu để chuyển đổi giá trị raster thành các chỉ báo bên trong / bên ngoài.) Mỗi ​​đầu dò điểm bây giờ yêu cầu O (1) nỗ lực để lập chỉ mục cho ô raster và đọc giá trị của nó. Tổng nỗ lực là O (Q).

Nói chung

Một giải pháp lai đẹptrong trường hợp có nhiều đa giác vectơ tĩnh (trường hợp vectơ 3 ở trên) ban đầu để rasterize đa giác, có lẽ ngay cả với độ phân giải thô, lần này phân biệt bất kỳ ô nào giao với bất kỳ phần nào của ranh giới đa giác (giả sử giá trị là 2) . Sử dụng đầu dò raster (chi phí: O (1)) thường dẫn đến một câu trả lời xác định (điểm được biết là bên trong hoặc bên ngoài), nhưng đôi khi dẫn đến một câu trả lời không xác định (điểm rơi vào một ô qua đó có ít nhất một cạnh vượt qua), trong trường hợp đó, truy vấn vectơ O (log (P)) đắt hơn được thực hiện. Phương pháp này phát sinh thêm một số chi phí lưu trữ cho raster, nhưng trong nhiều trường hợp, ngay cả một raster nhỏ (một MB sẽ cho phép raster 2000 bằng 2000 lưu trữ các giá trị {0,1,2, null}) có thể mang lại lợi thế lớn về thời gian tính toán . Không có triệu chứng,


7

Nếu bạn có các hộp giới hạn đa giác được lưu trữ trong một cái gì đó giống như cây tứ giác thì bạn có thể sử dụng nó để nhanh chóng xác định đa giác nào cần kiểm tra. Ở mức tối thiểu bạn chỉ có thể xem liệu điểm nằm trong mỗi hộp giới hạn đa giác trái ngược với thực hiện một điểm đầy đủ trong đa giác cho mỗi đa giác. Cá nhân tôi sẽ thiết lập một dịch vụ web sẽ lưu trữ các đa giác trong bộ nhớ và sử dụng một cái gì đó như bộ JTS hoặc NetTopology để thực hiện truy vấn giao nhau cho tôi.


1

Trong postgis, ST_Intersects sử dụng các chỉ mục để tìm đầu tiên nếu điểm nằm trong hộp giới hạn của đa giác và sau đó thực hiện kiểm tra lại xem nó có thực sự nằm trong đa giác không. Đó là nhanh, thường rất nhanh.

Nếu bạn đã lưu trữ dữ liệu của mình trong PostGIS, không có nghi ngờ gì rằng cơ sở dữ liệu là nơi thích hợp để thực hiện tính toán. Trong các trường hợp khác, bạn sẽ phải gửi đa giác của mình đến một số chương trình trung gian hoặc máy khách. Điều đó, tự nó sẽ mất nhiều thời gian hơn so với việc tính toán và chỉ cần lấy các đa giác có liên quan.

/ Nicklas

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.