如何在Shapely中查找LineString的第2个最近点?

问题描述 投票:0回答:2

给予一定的 LineString 和点 p:

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

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

距离最近的点 p 的计算方法。

n_p = nearest_points(linestring, p)[0]

结论 这是一个完全相同的点,这是正常的,因为线串中也有完全相同的值,但我需要知道最近的点,除了这个点本身之外。第二 最近的点?

python point shapely
2个回答
0
投票

在一般情况下,最简单的解决方案是从你的几何对象中构造一个新的几何对象。LineString 但没有最近的点,然后用这个新的几何体得到最近的点......。

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

point = Point(51.21745162000732, 4.41871738126533)
line = LineString([(51.2176008, 4.4177154), (51.21758, 4.4178548), 
                   (51.2175729, 4.4179023), (51.21745162000732, 4.41871738126533)])

nearest_point = nearest_points(line, point)[0]
line_points_except_nearest = MultiPoint([point for point in linestring.coords 
                                         if point != (nearest_point.x, nearest_point.y)])
second_nearest = nearest_points(line_points_except_nearest, point)[0]

或者,如果你不想构建一个新的对象 因为,例如,内存限制,你可以遍历所有的点,比如说 LineStringheapq.nsmallest:

import heapq

line_points = map(Point, line.coords)
nearest, second_nearest = heapq.nsmallest(2, line_points, key=point.distance)

在你的具体情况下,当所有的点都是直线时,你也可以计算与最近点的邻点的距离。

index = list(line.coords).index((point.x, point.y))
if index == 0:
    second_nearest = Point(line.coords[1])
elif index == len(line.coords) - 1:
    second_nearest = Point(line.coords[-2])
else:
    second_nearest = min(Point(line.coords[index - 1]),
                         Point(line.coords[index + 1]),
                         key=point.distance)

0
投票

求解如下

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

def second_nearest(p, linestring):
  """ Finds nearest point of p in linestring
      if p in linestring, finds second nearest"""
  # coordinates of p and linestring
  p_coords = list(p.coords)[0]
  linestring_coords = list(linestring.coords)

  if p_coords in linestring_coords:
    # form a new linestring if p is in linestring
    linestring_coords.remove(p_coords)
    linestring = LineString(linestring_coords)

  return nearest_points(p, linestring)

p = Point(51.21745162000732, 4.41871738126533)

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

n_p = second_nearest(p, linestring)

print(list(map(str, n_p)))

輸出結果

第一点是p,第二点是线段中离p最近的点,不等于p(所以是第二近点)。

['POINT (51.21745162000732 4.41871738126533)', 
 'POINT (51.2175729 4.4179023)']
© www.soinside.com 2019 - 2024. All rights reserved.