簡體   English   中英

在多個點斷開勻稱的線串

[英]Break a shapely Linestring at multiple points

下面的代碼是從我在此處找到的代碼修改而來的,該代碼在沿直線定義的點將勻稱的Linestring分成兩段。 我還檢查了其他問題,但它們沒有直接解決我的查詢。 但是,我想擴展它以將線分成多個段(在多個點),到目前為止,我所做的所有嘗試都失敗了。 如何修改以將字符串分成任意給定數量的段或在多個點上說((4,5),(9,18)和(6,5))。

input: 

line = LineString([(1,2),(8,7),(4,5),(2,4),(4,7),(8,5),(9,18),(1,2),(12,7),(4,5),(6,5),(4,9)])
       breakPoint = Point(2,4)

from shapely.geometry import Point,LineString

def make_line_segment(line_string, breakPoint):
    geoLoc = line_string.coords
    j = None
    for i in range(len(geoLoc) - 1):
        if LineString(geoLoc[i:i + 2]).intersects(breakPoint):
           j = i
           break
    assert j is not None
    # Make sure to always include the point in the first group
    if Point(geoLoc[j + 1:j + 2]).equals(breakPoint):
        return geoLoc[:j + 2], geoLoc[j + 1:]
    else:
        return geoLoc[:j + 1], geoLoc[j:]

line1,line2 = make_line_segment(line,breakPoint)
line1 = LineString(line1)
line2 = LineString(line2)
print line1, line2

output: `LINESTRING (1 2, 8 7, 4 5, 2 4) LINESTRING (2 4, 4 7, 8 5, 9 18, 1 2, 12 7, 4 5, 6 5, 4 9)`

projectioninterpolate lineString方法通常可用於此類操作。

from shapely.geometry import Point, LineString

def cut(line, distance):
    # Cuts a line in two at a distance from its starting point
    # This is taken from shapely manual
    if distance <= 0.0 or distance >= line.length:
        return [LineString(line)]
    coords = list(line.coords)
    for i, p in enumerate(coords):
        pd = line.project(Point(p))
        if pd == distance:
            return [
                LineString(coords[:i+1]),
                LineString(coords[i:])]
        if pd > distance:
            cp = line.interpolate(distance)
            return [
                LineString(coords[:i] + [(cp.x, cp.y)]),
                LineString([(cp.x, cp.y)] + coords[i:])]

def split_line_with_points(line, points):
    """Splits a line string in several segments considering a list of points.

    The points used to cut the line are assumed to be in the line string 
    and given in the order of appearance they have in the line string.

    >>> line = LineString( [(1,2), (8,7), (4,5), (2,4), (4,7), (8,5), (9,18), 
    ...        (1,2),(12,7),(4,5),(6,5),(4,9)] )
    >>> points = [Point(2,4), Point(9,18), Point(6,5)]
    >>> [str(s) for s in split_line_with_points(line, points)]
    ['LINESTRING (1 2, 8 7, 4 5, 2 4)', 'LINESTRING (2 4, 4 7, 8 5, 9 18)', 'LINESTRING (9 18, 1 2, 12 7, 4 5, 6 5)', 'LINESTRING (6 5, 4 9)']

    """
    segments = []
    current_line = line
    for p in points:
        d = current_line.project(p)
        seg, current_line = cut(current_line, d)
        segments.append(seg)
    segments.append(current_line)
    return segments

if __name__ == "__main__":
    import doctest
    doctest.testmod()

在這種方法中,首先,我在起點處拆分了點列表,並形成了如下的線列表,

# List of coordinates
coords = [(1,2),(8,7),(4,5),(2,4),(4,7),(8,5),(9,18),(1,2),(12,7),(4,5),(6,5),(4,9)]



no_seg = 3 #Number of segments, you need from 'coords'
coords_sub = np.array_split(coords, no_seg)

list_lines = [] # empty list

for i in range(len(X_sub)):
    list_lines.append(LineString(X_sub[i]))

list_lines[1] # Displays the second line of the list

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM