라인 피처 연결 및 가장 긴 라인의 길이 결정


12

Stream_to_Feature 도구를 사용하여 만든 강을 나타내는 선 피처 (이미지 참조)가 있습니다. 속성 테이블에는 여러 줄을 나타내는 여러 레코드가 포함되어 있습니다. 문제는 가장 긴 줄 (시각적으로 쉽게 구분 가능)이 테이블에서 한 줄로 표시되지 않고 실제로 여러 개의 작은 줄로 구성되어 있다는 것입니다. 선은 서로 교차하지 않지만 접촉하는 것처럼 보입니다.

ArcObjects 또는 ArcObjects로 변환 할 수있는 수동 방법을 사용하여 이러한 선을 병합 한 다음 가장 긴 선의 길이를 결정하려면 어떻게해야합니까? 더 나은 해결책은 모든 지류를 없애고 강 수로를 줄로 남겨 두는 것입니다.

선 특징-강


1
그들은 전혀 연결합니까? 교차하지 않는다고 말했지만 정점을 공유하지 않는다는 의미입니까?
Nathanus

1
죄송합니다. 더 명확해야했습니다. 정점을 공유하지만 서로 완전히 교차하지는 않습니다.
레이더

강 어귀가 어디 있는지 아십니까? 강은 항상 나무입니까 (각 상류 지점에서 입으로 향하는 하나의 독특한 경로)?
커크 Kuykendall

3
실제로 "가장 긴 줄"의 길이를 원하지 않습니다 . 그것은 한 업스트림 도달에서 다른 원격 업스트림 도달로의 경로 일 수 있습니다. 이것은 스트림의 두 가지 주요 가지가 입 가까이에 합류 할 때 발생합니다. 대신, 입과 스트림의 다른 끝점 사이 에서 가장 긴 경로 를 원합니다 . (이 특성화는 스트림을 나무로 표현할 필요조차 없습니다. 브레이드와 섬이있을 수 있습니다.)
whuber

@ whuber-귀하의 평가가 정확합니다-경로를 사용하여 어떻게 이것을 달성 할 수 있습니까?
레이더

답변:


18

첫째, 이것이 어려운 문제가 아닌 이유를 나타내는 작은 배경 . 강을 통과하는 흐름은 세그먼트가 올바르게 디지털화되면 항상 방향성 비순환 그래프 (DAG) 를 형성하도록 방향을 조정할 수 있습니다 . 결과적으로 토폴로지 정렬 이라고하는 기술을 사용하여 DAG 인 경우에만 그래프를 선형으로 정렬 할 수 있습니다 . 토폴로지 정렬이 빠릅니다. 시간 및 공간 요구 사항은 모두 O (| E | + | V |) (E = 모서리 수, V = 꼭지점 수)이며, 얻을 수있는만큼 좋습니다. 이러한 선형 순서를 만들면 주요 스트림 베드를 쉽게 찾을 수 있습니다.

다음 은 알고리즘스케치입니다 . 개울은 주요 침대를 따라 놓여 있습니다. 입에 부착 된 각 가지를 따라 상류로 이동하고 (입이 합류 인 경우 하나 이상이있을 수 있음) 해당 지점으로 이어지는 주요 침대를 재귀 적으로 찾습니다. 전체 길이가 가장 큰 지점을 선택하십시오. 이것이 주요 침대를 따라 "뒤로"입니다.

이것을 더 명확하게하기 위해, 나는 (비평가되지 않은) 의사 코드를 제공 합니다. 입력은 선분 (또는 호) S (디지털 스트림을 포함 )의 세트이며 , 각각 2 개의 별개의 종점 start (S)와 end (S)와 양의 길이, length (S)를 갖고; 그리고 강 입구 p 는 포인트입니다. 출력은 입을 가장 먼 상류 지점과 연합시키는 일련의 세그먼트입니다.

"표시된 세그먼트"(S, p)로 작업해야합니다. 이들은 세그먼트 S 중 하나와 두 개의 끝점 중 하나 인 p로 구성 됩니다. 프로브 포인트 q 와 엔드 포인트를 공유하는 모든 세그먼트 S 를 찾아 해당 세그먼트를 다른 엔드 포인트로 표시하고 세트를 반환해야합니다.

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

이러한 세그먼트를 찾을 수 없으면 추출은 빈 세트를 리턴해야합니다. 부작용으로, 추출은 세트 A 에서 리턴하는 모든 세그먼트를 제거 하여 A 자체 를 수정해야 합니다.

추출 구현을 제공하지 않습니다. GIS는 q 와 엔드 포인트를 공유하는 세그먼트 S 를 선택하는 기능을 제공합니다 . 그것들을 표시하는 것은 단순히 start (S)와 end (S)를 q 와 비교 하고 두 끝점 중 어느 것을 일치시키지 않는지를 반환하는 것입니다.

이제 문제를 해결할 준비가되었습니다.

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

절차 '추가 (S, B0)은 "스틱 세그먼트 S 배열의 끝 B0는 새로운 배열을 반환한다.

(하천이 실제로 나무라면 섬, 호수, 머리띠 등이 없다면 AA0 에 복사 하는 단계를 생략 할 수 있습니다 .)

LongestUpstreamReach가 반환 한 세그먼트의 합집합을 구성하여 원래 질문에 답합니다.

를 설명하기 위해 원본지도에서 스트림을 고려해 보겠습니다. 그것이 7 개의 호의 집합으로 디지털화되었다고 가정하자. 아크 a 는 포인트 1의 입구에서 시작하여 (아래 그림의 오른쪽에서 회전하는 아래 그림에서 오른쪽으로) 포인트 1의 첫 번째 합류점으로 이동합니다. 긴 아크, 즉 8 단위 길이입니다. 호 b 는 (지도에서) 왼쪽으로 분기하고 길이가 약 2 단위입니다. 원호 (C)의 우측에 분기 및 "B"를 분들께 등 긴 4 개 유닛에 관한, "D"및 "F"우리는지도에서 위에서 아래로 이동하고, 왼쪽 분기를 나타내는 "A", 다른 분기 "c", "e"및 "g"를 정점 0에서 7까지 번호를 매 깁니다. 그래프를 호의 모음으로 추상적으로 나타낼 수 있습니다.

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

나는 그것들이 각각 a ~ g의 길이 8, 2, 4, 1, 2, 2, 2를 가지고 있다고 가정 합니다. 입은 꼭짓점 0입니다.

그림

첫 번째 예는 Extract (5, {f, g})에 대한 호출입니다. 마크 된 세그먼트 세트 {(f, 6), (g, 7)}을 리턴합니다. 꼭짓점 5는 호 fg (지도 하단의 두 호) 의 합류점에 있으며 (f, 6)과 (g, 7)은 각각의 호를 업스트림 끝점으로 표시합니다.

다음 예제는 LongestUpstreamReach (0, A)에 대한 호출입니다. 첫 번째 조치는 Extract (0, A)에 대한 호출입니다. 이 복귀 표시된 부분 (a, 1)를 포함하는 세트 그 세그먼트 제거 세트로부터 A0 이제 {B, C, D, E, F, G를} 같다. 루프의 반복이 하나 있습니다 (여기서 (S, q) = (a, 1)). 이 반복 중에 LongestUpstreamReach (1, A0)가 호출됩니다. 재귀 적으로 시퀀스 (g, e, c) 또는 (f, e, c)를 반환해야합니다. 둘 다 동일하게 유효합니다. 반환하는 길이 (M)는 4 + 2 + 2 = 8입니다. (LongestUpstreamReach는 A0을 수정 하지 않습니다 .) 루프의 끝에서 a를 분할 하십시오.스트림 베드에 추가되고 길이가 8 + 8 = 16으로 증가되었습니다. 따라서 첫 번째 반환 값은 시퀀스 (g, e, c, a) 또는 (f, e, c, a)로 구성됩니다. 두 번째 반환 값에 대해 길이가 16 인 경우 이것은 LongestUpstreamReach가 입에서 상류로 움직이는 방법을 보여줍니다. 각 합류점에서 아직 가장 먼 거리의 지점을 선택하고 경로를 따라 통과 한 세그먼트를 추적합니다.

브레이드와 아일랜드가 많은 경우보다 효율적인 구현이 가능하지만 LongestUpstreamReach가 표시된대로 정확하게 구현되면 대부분의 경우 낭비되는 노력이 거의 없습니다. 시간 (및 스택 깊이)은 총 세그먼트 수에 정비례합니다.


+1 이제 미주리 강을 명명하기 전에 그들이 이것을 알고 있었다면.
커크 Kuykendall

1
@Kirk 1800 년대 초 미국 서부의 재귀적인 탐색은 쉽지 않았습니다.
whuber

이것은 놀랍게도 도움이됩니다! GIS 내부에서이 설정을 가져 와서 작동하면 유용한 코드를 공유 할 수 있는지 살펴 보겠습니다. 건배!
레이더

좋은 답변 whuber
Ragi Yaser Burhum

2

비 분할 선 이 (디졸브 필드에 대해) 다른 차별화 하나 개의 스트림 지점에 몇 가지 방법을 신성해야합니다하지만 도구, 당신이 뭘 하려는지에 도움이 될 수 있습니다. 그래도 ArcInfo 라이센스가 있다고 가정합니다.

이러한 라이센스가없는 경우 ArcObjects 접근 방식을 사용하여 각 정점의 XY를 가져 와서 정점을 채우고로 IPointCollection를 작성 IGeometry하십시오 PolyLineClass.


1

RivEX를 사용할 수 있습니다 . 9.1 ArcGIS 도구입니다 (9.3 및 10에서 작동 함). 하천 네트워크의 토폴로지 문제를 식별하기위한 도구와 여러 처리 도구가 있습니다. 이러한 도구 중 하나가 주 줄기를 찾습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.