如何在 Shapely 中获取 LineString 的端点

How to get the endpoint of a LineString in Shapely

Linestring1 = LINESTRING (51.2176008 4.4177154, 51.21758 4.4178548, **51.2175729 4.4179023**, *51.21745162000732 4.41871738126533*)
Linestring2 = LINESTRING (*51.21745162000732 4.41871738126533*, **51.2174025 4.4190475**, 51.217338 4.4194807, 51.2172511 4.4200562, 51.2172411 4.4201077, 51.2172246 4.4201654, 51.2172067 4.420205, 51.2171806 4.4202355, 51.2171074 4.4202929, 51.2170063 4.4203409, 51.2169564 4.4203641, 51.2168076 4.4204243, 51.2166588 4.4204833, 51.2159018 4.420431, 51.2154117 4.4203843)

考虑到这两条线串是从一个更大的线串上剪下来的,如何获取线串的端点?

- 点 (51.21745162000732 4.41871738126533) 已删除

- linestring 1 的新最后一个元素 = “ 51.2175729 4.4179023

- linestring 2的新第一个元素 = " 51.2174025 4.4190475

简而言之,我想获取第一部分 (linestring1) 的新最后一个值和第二部分 (linestring2) 的新第一个值,但没有剪切它们的点。我怎样才能完成这项工作?

解决了两个例程,允许按如下方式拆分线串。

  1. 函数:split_first returns 第一个点,以及没有第一个点的 LineString

  2. 函数:split_last return 最后一个点,第一个点的 LineString 不包括最后一个

代码

from shapely.ops import nearest_points
from shapely.geometry import Point
from shapely.geometry import LineString

def split_first(linestring):
  " returns first point and linestring without first point "
  coords = list(linestring.coords)

  p, *x = coords
  return Point(p), LineString(x)

def split_last(linestring):
  " returns first point and linestring without first point "

  *x, p = list(linestring.coords) = list(linestring.coords)

  return Point(p), LineString(x)

测试

数据

linestring = LineString([(51.2176008,4.4177154), (51.21758,4.4178548), (51.2175729,4.4179023), (51.21745162000732,4.41871738126533)])

第一个点,不包括第一个点的线串

p, l = split_first(linestring)
print(p)
print(l)

POINT (51.2176008 4.4177154)
LINESTRING (51.21758 4.4178548, 51.2175729 4.4179023, 51.21745162000732 4.41871738126533)

第一个最后一点,线串不包括最后一个

p, l = split_last(linestring)
print(p)
print(l)

POINT (51.21745162000732 4.41871738126533)
LINESTRING (51.2176008 4.4177154, 51.21758 4.4178548, 51.2175729 4.4179023)

要获取 LineString 的端点,您只需访问其 boundary 属性:

from shapely.geometry import LineString

line = LineString([(0, 0), (1, 1), (2, 2)])
endpoints = line.boundary
print(endpoints)
# MULTIPOINT (0 0, 2 2)
first, last = line.boundary
print(first, last)
# POINT (0 0) POINT (2 2)

或者,您可以从 coords 坐标序列中获取第一个点和最后一个点:

from shapely.geometry import Point
first = Point(line.coords[0])
last = Point(line.coords[-1])
print(first, last)
# POINT (0 0) POINT (2 2)

但是,在您的具体情况下,由于您要删除第一行的最后一个点和第二行的第一个点,并且只有在获得端点之后,您才应该构造新的 LineString 对象首先使用相同的 coords 属性:

from shapely.wkt import loads

first_line = loads("LINESTRING (51.2176008 4.4177154, 51.21758 4.4178548, 51.2175729 4.4179023, 51.21745162000732 4.41871738126533)")
second_line = loads("LINESTRING (51.21745162000732 4.41871738126533, 51.2174025 4.4190475, 51.217338 4.4194807, 51.2172511 4.4200562, 51.2172411 4.4201077, 51.2172246 4.4201654, 51.2172067 4.420205, 51.2171806 4.4202355, 51.2171074 4.4202929, 51.2170063 4.4203409, 51.2169564 4.4203641, 51.2168076 4.4204243, 51.2166588 4.4204833, 51.2159018 4.420431, 51.2154117 4.4203843)")
first_line = LineString(first_line.coords[:-1])
second_line = LineString(second_line.coords[1:])
print(first_line.boundary[1], second_line.boundary[0])
# POINT (51.2175729 4.4179023) POINT (51.2174025 4.4190475)

类似于的解决方案,您可以通过解压您想要的那个并使用*_忽略其余部分来获得他们的coords

from shapely.geometry import LineString

linestring1 = LineString([(51.2176008, 4.4177154), (51.21758, 4.4178548),
                         (51.2175729, 4.4179023),
                         (51.21745162000732, 4.41871738126533)])
linestring2 = LineString([(51.21745162000732, 4.41871738126533),
                         (51.2174025, 4.4190475), (51.217338, 4.4194807),
                         (51.2172511, 4.4200562), (51.2172411, 4.4201077),
                         (51.2172246, 4.4201654), (51.2172067, 4.420205),
                         (51.2171806, 4.4202355), (51.2171074, 4.4202929),
                         (51.2170063, 4.4203409), (51.2169564, 4.4203641),
                         (51.2168076, 4.4204243), (51.2166588, 4.4204833),
                         (51.2159018, 4.420431), (51.2154117, 4.4203843)])

*_, last_new_1, last_1 = linestring1.coords
first_2, first_new_2, *_ = linestring2.coords

print(last_new_1)
print(first_new_2)
# (51.2175729, 4.4179023)
# (51.2174025, 4.4190475)