web-dev-qa-db-ja.com

線分への点の射影Python Shapely

私は2つのポイントで定義されたLineStringを持っているので、本質的に直線セグメントであり、それにポイントを投影したかったのです。気がついた .projectおよび.interpolate。ただし、ポイントがセグメントの「外側」にある場合、セグメント上で最も近いポイントは必要ありませんが、セグメントを拡張して、ポイントを通過し、(拡張された)線分に直交する線を描画します。投影の座標が欲しいです。

enter image description here

たとえば、ポイントがセグメントの「内部」にある場合

from shapely.geometry import Point
from shapely.geometry import LineString
point = Point(0.2, 0.5)
dist = LineString([(0, 1), (1, 1)]).project(point)
list(LineString([(0, 1), (1, 1)]).interpolate(dist).coords)

ポイントがセグメントの外側にあるときに何をすべきか知っている人はいますか?

7
sofaruntitled

これを手動で行うのがおそらく最も簡単です。角度_x - u - v_をalphaと表すと、

_cos(alpha) = (v - u).(x - u) / (|x - u|*|v - u|)
_

ここで、_._は内積を表し、_| |_はユークリッドノルムを表します。したがって、dからP(x)の距離uは次のようになります。

_d = cos(alpha)*|x - u| = (v - u).(x - u) / |v - u|
_

dを計算すると、投影点P(x)は次のように簡単に取得できます。

_P(x) = u + d*(v - u)/|v - u|
_

実装:

_import numpy as np
from shapely.geometry import Point
from shapely.geometry import LineString

point = Point(0.2, 0.5)
line = LineString([(0, 1), (1, 1)])

x = np.array(point.coords[0])

u = np.array(line.coords[0])
v = np.array(line.coords[len(line.coords)-1])

n = v - u
n /= np.linalg.norm(n, 2)

P = u + n*np.dot(x - u, n)
print(P) #0.2 1.
_
7
ewcz