Các thuật toán cho các phân đoạn khớp


23

Các thuật toán tốt nhất để phù hợp với phân khúc là gì?

Tôi đang cố gắng khớp các phân đoạn tương ứng từ hai nguồn bản đồ, một nguồn kém chính xác hơn nhưng với tên phân khúc và một chính xác hơn không có tên phân khúc. Tôi muốn bán tự động áp dụng tên phân khúc cho bản đồ chính xác hơn.

Thuật toán được yêu cầu có một mô tả khá mơ hồ vì "khớp" không được xác định rõ và nhiều yếu tố (định hướng, độ dài tương đối, khoảng cách) có thể có trọng số khác nhau trong các tình huống khác nhau; Tuy nhiên, tôi đang tìm kiếm một kiến ​​thức cơ bản về các phương pháp chung để xử lý vấn đề này.

Các triển khai làm việc cho môi trường nguồn mở (PostGIS, tạo hình, ...) được chào đón nồng nhiệt.

Phân đoạn mẫu : Xem mô tả bên dưới hình ảnh.


Bạn có thể đăng một ảnh chụp nhanh dữ liệu của bạn để cung cấp tổng quan về mật độ phân khúc và chúng khác nhau như thế nào không?
Julien

1
Tôi đã đăng một số hình ảnh minh họa trên flickr, xem liên kết.
Adam Matan

1
Bạn có thể thử tìm kiếm "liên kết".
Kirk Kuykendall

Câu trả lời:


14

Các khoảng cách Hausdorff có thể được sử dụng: phù hợp với phân khúc có thể là 'gần' phân đoạn theo khoảng cách này. Nó khá đơn giản để tính toán trên các phân khúc.

Một triển khai java miễn phí có sẵn trong JTS - xem Gói khoảng cách JTS . Bạn cũng có thể xem qua JCS Conflation Suite (hiện đã bị bỏ rơi, bản sao của các nguồn, ví dụ như tại https://github.com/oschrenk/jcs ).


2
Khoảng cách của Hausdorff cũng nằm trong PostGIS, từ GEOS, do đó, nó là thuật toán tương tự như JTS
Nicklas Avén

10

Tôi không biết điều gì sẽ là "tốt nhất", bởi vì điều đó sẽ phụ thuộc vào chi tiết của các phân khúc của bạn.

Một cách tiếp cận thường tốt là băm các phân đoạn thành thông tin hình học quan trọng . Điều này sẽ bao gồm, ở mức tối thiểu, vị trí của trung tâm (x, y), hướng (0 đến 180 độ) và chiều dài. Với các trọng số phù hợp được áp dụng và một số yếu tố định hướng (vì 180 "bao quanh" trở về 0), sau đó bạn có thể áp dụng hầu hết mọi thuật toán phân cụm thống kê cho bộ sưu tập của tất cả các phân đoạn. ( K-nghĩa sẽ là một lựa chọn tốt, nhưng hầu hết các phương pháp phân cấp phải hoạt động tốt. Các phân tích cụm như vậy có xu hướng nhanh và dễ áp ​​dụng.) Lý tưởng nhất là các phân đoạn sẽ xuất hiện theo cặp (hoặc singletons cho các phân đoạn chưa từng có) và phần còn lại dễ.

Một cách để giải quyết vấn đề định hướng là tạo một bản sao của các phân đoạn được dán nhãn. Thêm 180 độ vào hướng của bản sao đầu tiên, nếu nó nhỏ hơn 90 và trừ đi 180 độ so với hướng. Điều này mở rộng tập dữ liệu của bạn (rõ ràng) nhưng mặt khác không thay đổi thuật toán theo bất kỳ cách nào.

Trọng lượng là cần thiết bởi vì sự khác biệt của tọa độ, độ dài và định hướng có thể có nghĩa là những điều hoàn toàn khác nhau liên quan đến sự tương đồng của các phân đoạn tương ứng của chúng. Trong nhiều ứng dụng, sự khác biệt giữa các phân khúc phát sinh từ sự khác biệt về vị trí của các điểm cuối của chúng. Là một xấp xỉ thô, chúng ta có thể mong đợi sự thay đổi điển hình về độ dài phân khúc sẽ giống như biến thể điển hình giữa các điểm cuối của chúng. Do đó, các trọng số liên quan đến x, y và chiều dài phải giống nhau. Phần khó khăn là định hướng trọng số, bởi vì định hướng không thể được đánh đồng với khoảng cách và thậm chí tệ hơn, các phân đoạn ngắn sẽ có nhiều khả năng bị định hướng sai so với các phân đoạn dài. Hãy xem xét một phương pháp thử và sai tương đương với một vài mức độ sai lệch với kích thước của một khoảng cách điển hình giữa các phân đoạn và sau đó điều chỉnh cho đến khi quy trình có vẻ hoạt động tốt. Để được hướng dẫn, hãy đểL là một chiều dài phân khúc điển hình. Sự thay đổi hướng theo một góc nhỏ t độ sẽ quét ra khoảng cách xấp xỉ L / 2 * t / 60 (60 xấp xỉ với số độ trong một radian), là L / 120 lần t . Điều đó cho thấy bắt đầu với trọng số đơn vị cho x, y, và chiều dài và trọng số L / 120 cho hướng.

Tóm lại , gợi ý này là:

  1. Tạo các bản sao của các phân đoạn được dán nhãn (như được mô tả trong đoạn văn về định hướng).

  2. Chuyển đổi từng phân đoạn thành bộ tứ (x, y, chiều dài, hướng L / 120 *) trong đó L là chiều dài phân khúc điển hình.

  3. Thực hiện phân tích cụm của bốn. Sử dụng gói thống kê tốt ( R là miễn phí).

  4. Sử dụng đầu ra phân tích cụm làm bảng tra cứu để liên kết các phân đoạn được gắn nhãn với các phân đoạn chưa được gắn nhãn gần đó.


4

Tôi đã làm việc trong một dự án với yêu cầu tương tự khoảng 5 năm trước. Nó liên quan đến việc kết hợp tọa độ từ các đường trung tâm đường phố (với độ chính xác tọa độ tương đối cao) với các liên kết mạng lưu lượng của Hệ thống giám sát hiệu suất đường cao tốc (HPMS).

Vào thời điểm đó, FHWA không cung cấp bất kỳ công cụ nào để thực hiện loại việc này. Điều đó có thể đã thay đổi, bạn có thể muốn kiểm tra. Ngay cả khi bạn không làm việc với dữ liệu đường cao tốc, các công cụ vẫn có thể có liên quan.

Tôi đã viết nó với ArcGIS, nhưng thuật toán sẽ hoạt động trong nguồn mở, miễn là nó cung cấp các khả năng theo dõi tương tự như ISegmentGraph :

// features is a collection of features with higher geometry
// Links are a collection features with attributes but low res geometry
For each Link in lowResFeatureclass
    point startPoint = SnapToClosestPoint(Link.StartPoint, hiResfeatures);
    if(startPoint == null)
       continue;
    point endPoint = SnapToClosest(Link.EndPoint, hiResfeatures);
    if(endPoint == null)
       continue;
    polyline trace = Trace(hiResfeatures,startPoint,endPoint);
    if(polyline != null)
    {
        // write out a link with high precision polyline
        Write(Link,polyline);
    }
Next Link

4

Đây là một ý tưởng

Nếu bạn xé một trong các linestrings để so sánh và kiểm tra xem các đỉnh có nằm trong khoảng cách so với các linestring khác để so sánh hay không, bạn có thể kiểm soát bài kiểm tra theo nhiều cách.

những ví dụ này hoạt động trong PostGIS (ai có thể đoán :-))

Đầu tiên, nếu chúng ta nói rằng có một trận đấu nếu tất cả các điểm đỉnh trong một linestring trong bảng_1 là 0,5 mét (đơn vị bản đồ) hoặc gần hơn với một linestring trong bảng_2:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points,
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(*)=num_of_points;

Sau đó, chúng ta có thể nói rằng có một trận đấu nếu hơn 60% số đỉnh trong một dòng trong bảng_1 nằm trong khoảng cách của một dòng trong bảng_2

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)/num_of_points::float > 0.6

Hoặc chúng ta có thể chấp nhận rằng một điểm không nằm trong phạm vi:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)-num_of_points <= 1;

Bạn cũng sẽ phải chạy truy vấn với bảng_1 và bảng_2 trong các vai trò đảo ngược.

Tôi không biết nó sẽ nhanh như thế nào. ST_Dumppoints hiện là một hàm sql trong PostGIS và không phải là hàm C làm cho nó chậm hơn mức cần thiết. Nhưng tôi nghĩ dù sao nó cũng sẽ khá nhanh.

Các chỉ mục không gian sẽ giúp ích rất nhiều cho ST_Dwithin có hiệu quả.

NickH HTH


1
+1 Điều này rất giống với phương pháp cuối cùng tôi đã sử dụng (sẽ đăng câu trả lời sớm).
Adam Matan

4

Tôi đã viết mã để xử lý khớp dòng phân đoạn cẩu thả (và chồng lấp chúng) trong Boundary Generator. Tôi đã viết lên toán học (khá cơ bản) đằng sau nó ở đây: http://blog.shoutis.org/2008/10/inside-boundary-generator-computational.html . Mã này là nguồn mở và được liên kết từ bài đăng trên blog đó.

Mã theo một cách tiếp cận thực sự đơn giản:

  • Thử nghiệm phân đoạn sẽ cho bạn biết liệu hai phân đoạn có trùng nhau trong phạm vi dung sai góc và khoảng cách đã cho hay không và mức độ chồng lấp.
  • Một chỉ số không gian nhanh chóng giúp loại bỏ sự cần thiết phải kiểm tra mọi phân đoạn dòng trong tập dữ liệu so với tất cả các phân đoạn dòng khác trong bộ dữ liệu.

Ưu điểm chính của phương pháp này là bạn có được các núm chính xác độc đáo cho góc, khoảng cách và chiều dài chồng chéo hợp lệ; Mặt khác, đó không phải là cách đo lường sự tương đồng của hai phân đoạn dòng, vì vậy, khó hơn nhiều, ví dụ như phân cụm thống kê để xác định các kết quả khớp có thể xảy ra - bạn bị mắc kẹt với các núm chính xác.

Lưu ý: Tôi đoán rằng với các đoạn SQL đủ, bạn có thể nhồi nhét bài kiểm tra phân đoạn vào một mệnh đề WHERE ... :)

Chúc mừng!


+1 Đây là một cách tiếp cận hay; xây dựng tứ giác làm cho nó tính toán vượt trội. Nhưng cần phải chú ý đến các chi tiết: khi xác định độ gần hoặc tương tự của phân đoạn (thay vì giao nhau), bạn cần tính đến thực tế là cấu trúc dữ liệu của bạn không cung cấp một đại diện duy nhất của phân khúc: phân đoạn có nguồn gốc tại x , theo hướng v , có độ dài t bằng nhau, đoạn có nguồn gốc tại x + t v theo hướng -v của chiều dài t .
whuber

1

Tôi đã triển khai một nguyên mẫu thô để khớp bản đồ ở đây , tương đối dễ sử dụng. Nó dựa trên công cụ định tuyến nguồn mở và được viết bằng Java. Thuật toán được sử dụng được mô tả ở đây .

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.