Shapely를 사용하여 개별 선 세그먼트를 하나의 LineString으로 용접


13

파이썬에서 Shapely를 사용 MultiLineString하고 있으며 많은 Linestring객체가 제공됩니다. 모든 LineString객체가 2 개의 꼭짓점 만있는 단순한 선이며 모든 단일 선 (분지 없음)의 일부임을 보장 할 수 있습니다 .

"점을 연결"하고 단일을 만들고 싶습니다 LineString. 이를 위해 재귀 용접 방법을 작성해야합니까, 더 빠른 방법이 있습니까?

답변:


20

당신은 사용할 수 shapely의를 ops.linemerge이를 위해 :

from shapely import geometry, ops

# create three lines
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[1,0], [2,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 2 2), (2 2, 3 3))

# you can now merge the lines
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints LINESTRING (0 0, 1 1, 2 2, 3 3)

# if your lines aren't contiguous
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[2,0], [3,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 1 0), (2 0, 3 0))

# note that it will now merge only the contiguous portions into a component of a new multi-linestring
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints MULTILINESTRING ((0 0, 1 1, 1 0), (2 0, 3 0))

어떤 라인 스트링이 병합되었는지 어떻게 알 수 있습니까? 다음과 같은 목록을 받고 싶습니다. merged = [[line_a, line_b], [line_c]]
james

개별 라인 목록을 반복하고 새로운 병합 라인 contains()이 개별 라인 인지 여부를 확인할 수 있습니다. 포함되지 않은 것은 병합되지 않았을 것입니다. 예 merged_line.contains(line_a)를 들어 부울을 반환 True하거나False
songololo

고마워 라인이 merged_lines에 포함되어 있는지 어떻게 확인합니까?
james

1
아, ".contains (line_a)"가 미리 작성된 함수라는 것을 이해하지 못했습니다. 완전한. 고마워요!
james

1
죄송합니다. 다시 귀찮게하려고합니다.하지만 "가장 가까운"선을 병합 할 사람을 알고 있습니까 (상대 특정 거리 이내)? 병합 해야하는 많은 줄을보고 있기 때문에 묻고 있지만 그 사이의 작은 개울로 인해 병합되지 않습니다.
제임스

2

shapely.ops.linemerge () 메소드를 사용하여 Shapely로 할 수 있다고 생각합니다.

줄 목록을 입력으로 가져와 병합 할 수있는 것처럼 보입니다. 나는 전에 'polygonize'방법을 사용했으며 줄 목록을 가져옵니다.

http://toblerity.org/shapely/manual.html#shapely.ops.linemerge 에서 문서를 살펴보십시오.


1
"가까운"선을 병합하는 방법을 알고 있습니까 (서로 특정 거리 이내)?
제임스

polygonize_full은 다소
나아졌지 만

1

shapely.ops.linemerge()내 라인 중 일부에 실패했기 때문에 수동으로해야했습니다. "복귀"한 선이 동일한 지점을 두 번 이상 통과하면 실패하는 것 같습니다. 필자의 경우 줄이 올바른 순서이므로 작은 함수를 작성하여 병합하기가 쉽다는 것을 알고 있습니다.

from shapely.geometry import LineString
from typing import List


def merge_lines(lines: List[LineString]) -> LineString:
    last = None
    points = []
    for line in merged_line:
        current = line.coords[0]

        if last is None:
            points.extend(line.coords)
        else:
            if last == current:
                points.extend(line.coords[1:])
            else:
                print('Skipping to merge {} {}'.format(last, current))
                return None
        last = line.coords[-1]
    return LineString(points)

누군가에게 도움이되기를 바랍니다.


0

shapely.ops.linemerge선이 연속적이면 ( "팁"이 구성 선의 "꼬리"와 일치하는 경우) 작동하지만 연속적이지 않은 경우 (팁과 꼬리 사이에 간격이있는 경우) 다른 MultiLineString을 반환합니다. 구성 선이 잘 정렬되어 있지만 (한 줄이 다음 줄의 시작 부분 근처에서 끝나고) 끝에서 끝까지 틈이있는 경우 좌표를 추출하여 새 간단한 선으로 만들 수 있습니다. 이 방법은 또한보다 복잡한 서브 라인 (즉, 두 개 이상의 포인트가있는 서브 라인)으로 구성된 다중 라인에도 적용됩니다.

import shapely

# Make a MultiLineString to use for the example
inlines = shapely.geometry.MultiLineString(
    [shapely.geometry.LineString([(0,0),(0,0.9)]), 
     shapely.geometry.LineString([(0,1),(1,1)])]
)

# Put the sub-line coordinates into a list of sublists
outcoords = [list(i.coords) for i in inlines]

# Flatten the list of sublists and use it to make a new line
outline = shapely.geometry.LineString([i for sublist in outcoords for i in sublist])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.