私は2つのポイントで定義されたLineStringを持っているので、本質的に直線セグメントであり、それにポイントを投影したかったのです。気がついた .project
および.interpolate
。ただし、ポイントがセグメントの「外側」にある場合、セグメント上で最も近いポイントは必要ありませんが、セグメントを拡張して、ポイントを通過し、(拡張された)線分に直交する線を描画します。投影の座標が欲しいです。
たとえば、ポイントがセグメントの「内部」にある場合
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)
ポイントがセグメントの外側にあるときに何をすべきか知っている人はいますか?
これを手動で行うのがおそらく最も簡単です。角度_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.
_