Get the vertices on a LineString either side of a Point

前端 未结 2 1337
北恋
北恋 2021-01-15 02:46

I have a shapely LineString and have defined a shapely Point which lies along the LineString.

How can I find the vertices of t

2条回答
  •  醉酒成梦
    2021-01-15 02:59

    Newer versions of Shapely (>=1.6.0 (2017-08-21)) provide split function that can split a line by a point:

    from shapely.geometry import LineString, Point
    from shapely.ops import split
    
    line = LineString([(0, 0), (1, 1), (2, 1)])
    point = Point(1.5, 1)
    print(split(line, point))
    # GEOMETRYCOLLECTION (LINESTRING (0 0, 1 1, 1.5 1), LINESTRING (1.5 1, 2 1))
    

    One must take care, though, that due to precision errors this sometimes doesn't work properly:

    line = LineString([(0, 0), (3, 2)])
    point = Point(1, 2 / 3)
    print(split(line, point))
    # GEOMETRYCOLLECTION (LINESTRING (0 0, 3 2))
    print(point.distance(line))
    # 0.0
    

    One way to deal with this is to construct a new LineString that will contain the splitting point.

    new_line = LineString([line.coords[0], point.coords[0], line.coords[1]])
    print(split(new_line, point))
    # GEOMETRYCOLLECTION (LINESTRING (0 0, 1 0.6666666666666666), LINESTRING (1 0.6666666666666666, 3 2))
    

    or if you don't want to do it manually:

    from itertools import chain
    
    all_points_coords = chain(line.coords, point.coords)
    all_points = map(Point, all_points_coords)
    new_line = LineString(sorted(all_points, key=line.project))
    print(split(new_line, point))
    # GEOMETRYCOLLECTION (LINESTRING (0 0, 1 0.6666666666666666), LINESTRING (1 0.6666666666666666, 3 2))
    

提交回复
热议问题