Kết nối các tính năng của dòng và xác định độ dài của dòng dài nhất


12

Tôi có một tính năng dòng (xem hình ảnh) đại diện cho một dòng sông mà tôi đã tạo bằng công cụ Stream_to_Feature. Bảng thuộc tính chứa một số bản ghi đại diện cho các dòng khác nhau - vấn đề là dòng dài nhất (dễ phân biệt trực quan) không được biểu thị dưới dạng một dòng trong bảng, nó thực sự được tạo thành từ nhiều dòng nhỏ hơn. Các đường có vẻ chạm nhau, mặc dù chúng không giao thoa với nhau.

Làm cách nào tôi có thể hợp nhất các dòng này và sau đó xác định độ dài của dòng dài nhất bằng ArcObjects hoặc phương thức thủ công mà tôi có thể chuyển đổi sang ArcObjects? Một giải pháp thậm chí tốt hơn sẽ liên quan đến việc loại bỏ tất cả các nhánh sông và để lại cho tôi chỉ là dòng sông như một dòng.

Tính năng đường - sông


1
Họ có kết nối gì không? Bạn nói rằng họ không giao nhau, nhưng điều đó có nghĩa là họ không chia sẻ một đỉnh?
Nathanus

1
Xin lỗi - tôi nên đã rõ ràng hơn. Họ chia sẻ các đỉnh, nhưng không hoàn toàn giao thoa với nhau.
Radar

Bạn có biết cửa sông ở đâu không? Có phải dòng sông luôn là một cái cây (một con đường duy nhất từ ​​mỗi điểm đầu nguồn đến miệng)?
Kirk Kuykendall

3
Trên thực tế, bạn không muốn độ dài của "đường dài nhất". Đó có thể là một tuyến đường từ một phạm vi tiếp cận thượng nguồn đến một tiếp cận thượng nguồn từ xa khác. Điều này sẽ xảy ra khi hai nhánh chính của luồng kết hợp gần miệng của nó. Thay vào đó, bạn muốn tuyến đường dài nhất giữa miệng và bất kỳ điểm cuối nào khác trên luồng. (Đặc tính này thậm chí không yêu cầu luồng được biểu diễn dưới dạng cây: nó có thể bện và có đảo.)
whuber

@whuber - đánh giá của bạn là chính xác - có ý tưởng nào để tôi có thể thực hiện việc này bằng cách sử dụng các tuyến đường không?
Radar

Câu trả lời:


18

Đầu tiên, một chút nền tảng để chỉ ra tại sao đây không phải là một vấn đề khó. Dòng chảy qua một dòng sông đảm bảo rằng các phân đoạn của nó, nếu được số hóa chính xác, luôn có thể được định hướng để tạo thành một biểu đồ chu kỳ có hướng (DAG). Đổi lại, một đồ thị có thể được sắp xếp tuyến tính khi và chỉ khi nó là DAG, sử dụng một kỹ thuật được gọi là sắp xếp tôpô . Sắp xếp tôpô rất nhanh: yêu cầu về thời gian và không gian của nó là cả O (| E | + | V |) (E = số cạnh, V = số đỉnh), cũng tốt như nó đạt được. Tạo một thứ tự tuyến tính như vậy sẽ giúp bạn dễ dàng tìm thấy dòng suối chính.

Ở đây, sau đó, là một bản phác thảo của một thuật toán . Miệng suối nằm dọc theo giường chính của nó. Di chuyển ngược dòng dọc theo mỗi nhánh gắn vào miệng (có thể có nhiều hơn một, nếu miệng là hợp lưu) và đệ quy tìm giường chính dẫn xuống nhánh đó. Chọn nhánh có tổng chiều dài lớn nhất: đó là "backlink" của bạn dọc theo giường chính.

Để làm cho điều này rõ ràng hơn, tôi cung cấp một số mã giả (chưa được kiểm tra) . Đầu vào là một tập hợp các phân đoạn dòng (hoặc cung) S (bao gồm luồng số hóa), mỗi dòng có hai điểm cuối khác nhau bắt đầu (S) và kết thúc (S) và chiều dài dương, chiều dài (S); và cửa sông p , đó là một điểm. Đầu ra là một chuỗi các phân đoạn hợp nhất miệng với điểm ngược dòng xa nhất.

Chúng tôi sẽ cần phải làm việc với "các phân đoạn được đánh dấu" (S, p). Chúng bao gồm một trong các đoạn S cùng với một trong hai điểm cuối của nó, p . Chúng ta sẽ cần tìm tất cả các phân đoạn S có chung điểm cuối với điểm thăm dò q , đánh dấu các phân đoạn đó bằng các điểm cuối khác của chúng và trả về tập hợp:

Procedure Extract(q: point, A: set of segments): Set of marked segments.

Khi không tìm thấy đoạn nào như vậy, Extract phải trả về tập hợp trống. Là một tác dụng phụ, Extract phải loại bỏ tất cả các phân đoạn nó đang trở lại từ tập A, qua đó thay đổi Một chính nó.

Tôi không đưa ra triển khai Trích xuất: GIS của bạn sẽ cung cấp khả năng chọn các phân đoạn S chia sẻ điểm cuối với q . Đánh dấu chúng chỉ đơn giản là vấn đề so sánh cả bắt đầu (S) và kết thúc (S) với q và trả về bất kỳ điểm nào trong hai điểm cuối không khớp.

Bây giờ chúng tôi đã sẵn sàng để giải quyết vấn đề.

Procedure LongestUpstreamReach(p: point, A: set of segments): (Array of segments, length)
    A0 = A                        // Optional: preserves A
    C = Extract(p, A0)            // Removes found segments from the set A0!
    L = 0; B = empty array
    For each (S,q) in C:          // Loop over the segments meeting point p
        (B0, M) = LongestUpstreamReach(q, A0)
        If (length(S) + M > L) then
            B = append(S, B0)
            L = length(S) + M
        End if
    End for
    Return (B, L)
End LongestUpstreamReach

Quy trình "chắp thêm (S, B0)" dính đoạn S ở cuối mảng B0 và trả về mảng mới.

(Nếu luồng thực sự là một cái cây: không có đảo, hồ, dải bện, v.v. - thì bạn có thể phân phối với bước sao chép A vào A0 .)

Câu hỏi ban đầu được trả lời bằng cách hình thành sự kết hợp của các phân đoạn được trả về bởi LongestUpstreamReach.

Để minh họa , hãy xem xét luồng trong bản đồ gốc. Giả sử nó được số hóa thành một tập hợp gồm bảy cung. Vòng cung a đi từ miệng tại điểm 0 (trên cùng của bản đồ, ở bên phải trong hình bên dưới, được quay) ngược dòng đến ngã ba đầu tiên tại điểm 1. Đó là một cung dài, dài 8 đơn vị. Arc b nhánh bên trái (trong bản đồ) và ngắn, dài khoảng 2 đơn vị. Arc c nhánh ở bên phải và dài khoảng 4 đơn vị, v.v. Để "b", "d" và "f" biểu thị các nhánh bên trái khi chúng ta đi từ trên xuống dưới trên bản đồ và "a", "c", "e" và "g" các nhánh khác và đánh số các đỉnh từ 0 đến 7, chúng ta có thể biểu diễn một cách trừu tượng biểu đồ dưới dạng tập hợp các cung

A = {a=(0,1), b=(1,2), c=(1,3), d=(3,4), e=(3,5), f=(5,6), g=(5,7)}

Tôi sẽ giả sử chúng có độ dài 8, 2, 4, 1, 2, 2, 2 tương ứng từ a đến g . Miệng là đỉnh 0.

Nhân vật

Ví dụ đầu tiên là lệnh gọi Trích xuất (5, {f, g}). Nó trả về tập hợp các phân đoạn được đánh dấu {(f, 6), (g, 7)}. Lưu ý rằng đỉnh 5 nằm ở hợp lưu của các cung fg (hai cung ở dưới cùng của bản đồ) và (f, 6) và (g, 7) đánh dấu mỗi cung này bằng các điểm cuối ngược dòng của chúng .

Ví dụ tiếp theo là cuộc gọi đến LongestUpstreamReach (0, A). Hành động đầu tiên cần thực hiện là gọi tới Trích xuất (0, A). Điều này trả về một tập hợp chứa phân đoạn được đánh dấu (a, 1) nó loại bỏ phân đoạn a khỏi bộ A0 , hiện bằng {b, c, d, e, f, g}. Có một lần lặp của vòng lặp, trong đó (S, q) = (a, 1). Trong lần lặp này, một cuộc gọi được thực hiện cho LongestUpstreamReach (1, A0). Đệ quy, nó phải trả về chuỗi (g, e, c) hoặc (f, e, c): cả hai đều có giá trị như nhau. Độ dài (M) mà nó trả về là 4 + 2 + 2 = 8. (Lưu ý rằng LongestUpstreamReach không sửa đổi A0 .) Ở cuối vòng lặp, hãy phân đoạn ađã được thêm vào giường luồng và độ dài đã được tăng lên 8 + 8 = 16. Do đó, giá trị trả về đầu tiên bao gồm chuỗi (g, e, c, a) hoặc (f, e, c, a), với độ dài 16 trong cả hai trường hợp cho giá trị trả về thứ hai. Điều này cho thấy LongestUpstreamReach chỉ di chuyển ngược dòng từ miệng, chọn tại mỗi ngã ba nhánh với khoảng cách xa nhất chưa đi và theo dõi các đoạn đi qua tuyến đường của nó.

Việc triển khai hiệu quả hơn là có thể khi có nhiều dải bện và đảo, nhưng đối với hầu hết các mục đích, sẽ có ít nỗ lực lãng phí nếu LongestUpstreamReach được triển khai chính xác như được hiển thị, bởi vì tại mỗi ngã ba không có sự trùng lặp giữa các tìm kiếm trong các nhánh khác nhau: điện toán thời gian (và độ sâu ngăn xếp) sẽ tỷ lệ thuận với tổng số phân đoạn.


+1 Bây giờ nếu chỉ họ đã biết điều này trước khi đặt tên sông Missouri.
Kirk Kuykendall

1
@Kirk Khám phá đệ quy về miền Tây nước Mỹ vào đầu những năm 1800 không hề dễ dàng :-).
whuber

Điều này thật hữu ích! Tôi sẽ xem liệu tôi có thể cài đặt thiết bị này trong hệ thống GIS của mình không và chia sẻ một số mã hữu ích sau khi tôi làm việc. Chúc mừng!
Radar

Người trả lời tốt đẹp
Ragi Yaser Burhum

2

Công cụ Unsplit Line có thể hữu ích cho những gì bạn đang cố gắng thực hiện, mặc dù bạn sẽ cần phải phân chia một số phương pháp để phân biệt một nhánh luồng này với một nhánh khác (đối với trường hòa tan). Điều này giả định rằng bạn có giấy phép ArcInfo.

Nếu bạn không có giấy phép như vậy, bạn có thể xem xét phương pháp ArcObjects lấy XY của mỗi đỉnh, điền IPointCollectionvào chúng và sau đó tạo IGeometrynhư một PolyLineClass.


1

Bạn có thể sử dụng RivEX, đây là công cụ ArcGIS 9.1 (sẽ hoạt động trong 9.3 và 10). Nó có các công cụ để xác định các vấn đề tô pô với mạng lưới sông và nhiều công cụ xử lý. Một công cụ như vậy tìm thấy thân chính .

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.