在多个点处打破形状优美的线串

Nob*_*obi 2 python shapely

下面的代码是根据我在这里找到的代码进行修改的,该代码将形状优美的线串在沿线定义的点处分成两段。我还检查了其他问题,但他们没有直接解决我的问题。然而,我想扩展它以将线分成多个段(在多个点),到目前为止我所有的尝试都失败了。如何修改它以将字符串拆分为任意给定数量的段或在多个点((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)`
Run Code Online (Sandbox Code Playgroud)

egu*_*aio 8

和lineString 方法对于此类操作通常很方便projectioninterpolate

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()
Run Code Online (Sandbox Code Playgroud)