私は変曲点、つまり線の曲線が開始および終了する点を見つけようとしています。画像を見ると、緑の線は道路または小川であり、黒の点は曲線の開始点と終了点です。
これらのポイントの生成を自動化するための高レベルのステップは何ですか?ArcGISデスクトップを使用しており、ArcObjectsを使用すると非常に便利です。
私は変曲点、つまり線の曲線が開始および終了する点を見つけようとしています。画像を見ると、緑の線は道路または小川であり、黒の点は曲線の開始点と終了点です。
これらのポイントの生成を自動化するための高レベルのステップは何ですか?ArcGISデスクトップを使用しており、ArcObjectsを使用すると非常に便利です。
回答:
曲線が線分で構成されている場合、それらの線分のすべての内部点は変曲点になりますが、これは興味深いことではありません。代わりに、曲線はそれらのセグメントの頂点によって近似されていると考える必要があります。これらのセグメントを通して区分的に2回微分可能な曲線をスプライン化することにより、曲率を計算できます。厳密に言えば、変曲点は曲率がゼロの場所です。
この例では、曲率がほぼゼロである長いストレッチがあります。これは、示された点が低曲率領域のそのようなストレッチの端部に近似する必要があることを示唆しています。
したがって、効果的なアルゴリズムは、頂点をスプラインし、中間点の密なセットに沿って曲率を計算し、ほぼゼロの曲率の範囲を識別し(「近い」という意味の合理的な推定値を使用)、それらの範囲の端点をマークします。
R
これらのアイデアを説明するための作業コードを次に示します。一連の座標として表される線ストリングから始めましょう。
xy <- matrix(c(5,20, 3,18, 2,19, 1.5,16, 5.5,9, 4.5,8, 3.5,12, 2.5,11, 3.5,3,
2,3, 2,6, 0,6, 2.5,-4, 4,-5, 6.5,-2, 7.5,-2.5, 7.7,-3.5, 6.5,-8), ncol=2, byrow=TRUE)
曲線のパラメータ化を実現するために、x座標とy座標を別々にスプラインします。(パラメーターはと呼ばれtime
ます。)
n <- dim(xy)[1]
fx <- splinefun(1:n, xy[,1], method="natural")
fy <- splinefun(1:n, xy[,2], method="natural")
プロットと計算のためにスプラインを内挿します。
time <- seq(1,n,length.out=511)
uv <- sapply(time, function(t) c(fx(t), fy(t)))
パラメータ化された曲線の曲率を計算する関数が必要です。スプラインの1次および2次導関数を推定する必要があります。多くのスプライン(3次スプラインなど)では、これは簡単な代数計算です。 R
最初の3つの導関数を自動的に提供します。(他の環境では、導関数を数値的に計算したい場合があります。)
curvature <- function(t, fx, fy) {
# t is an argument to spline functions fx and fy.
xp <- fx(t,1); yp <- fy(t,1) # First derivatives
xpp <- fx(t,2); ypp <- fy(t,2) # Second derivatives
v <- sqrt(xp^2 + yp^2) # Speed
(xp*ypp - yp*xpp) / v^3 # (Signed) curvature
# (Left turns have positive curvature; right turns, negative.)
}
kappa <- abs(curvature(time, fx, fy)) # Absolute curvature of the data
曲線の広がりに関して、曲率ゼロのしきい値を推定することを提案します。これは少なくとも良い出発点です。曲線の曲がり具合に応じて調整する必要があります(つまり、曲線が長くなると増加します)。これは、後で曲率に従ってプロットを色付けするために使用されます。
curvature.zero <- 2*pi / max(range(xy[,1]), range(xy[,2])) # A small threshold
i.col <- 1 + floor(127 * curvature.zero/(curvature.zero + kappa))
palette(terrain.colors(max(i.col))) # Colors
頂点がスプラインされ、曲率が計算されたので、変曲点を見つけるためだけに残ります。それらを表示するには、頂点をプロットし、スプラインをプロットし、その上の変曲点をマークします。
plot(xy, asp=1, xlab="x",ylab="y", type="n")
tmp <- sapply(2:length(kappa), function(i) lines(rbind(uv[,i-1],uv[,i]), lwd=2, col=i.col[i]))
points(t(sapply(time[diff(kappa < curvature.zero/2) != 0],
function(t) c(fx(t), fy(t)))), pch=19, col="Black")
points(xy)
開いた点は元の頂点でxy
あり、黒い点はこのアルゴリズムで自動的に識別される変曲点です。曲線の端点で曲率を確実に計算することはできないため、これらのポイントは特別にマークされていません。
高密度化ツールを使用できます。この場合、角度で高密度化することを選択し、次に、直線で受け入れられる最大角度を選択します。次に、結果ラインにツールを[頂点でラインを分割]に適用します。最後に、shape_lengthが最小道路長より短い線を削除します。
この図には、3つのステップがあります。
1-角度を使用して線を高密度化します。パラメーターとして10度を使用し、スプリットラインを使用しました。図では、曲線は初期段階にあります。
arcpy.Densify_edit("line" , "ANGLE" , "","",10)
arcpy.SplitLine_management("line" , "line_split")
2- shape_lengthが冗長でないセグメントを選択します。表にあるように、これらの冗長な長さは選択していません。次に、それらを選択して新しいフィーチャクラスにします。
arcpy.Select_analysis("line_split" , "line_split_selected")
3-折れ曲がり点である線の端にある頂点を抽出しました。
arcpy.FeatureVerticesToPoints_management("line_split_selected" , "line_split_pnt" , "DANGLE")
元のラインからの最大オフセットをパラメーターとして持つGeneralizeツールを使用して、ケースに合ったオフセットを選択できます。
元の行に「line_cur」、一般化した行に「line_gen」という名前を付けると、「line_gen」で「line_cur」をクリップできます。結果は、「line_cur」の直線セグメントになります。次に、最小道路長よりも長いShape_lengthを選択するSQLクエリを使用して、非常に短いセグメントを削除することにより、いくつかの非常に短いセグメントをクリーンアップできます。