Bir polyline için bükülme noktalarını bulmak için algoritma


22

Eğilme noktalarını, yani bir çizgideki eğrilerin başladığı ve bittiği noktaları bulmaya çalışıyorum. Görüntüye bakarsanız, yeşil çizgi bir yol veya dere olabilir ve siyah noktalar eğrilerin başladığı ve bittiği noktalardır. görüntü tanımını buraya girin

Bu noktaların oluşturulmasını otomatikleştirmek için üst düzey adımlar neler olurdu? ArcGIS masaüstü bilgisayarım var ve ArcObjects ile oldukça kullanışlıyım.


Kaynak veriler, çizgi parçalarından oluşan bir çok satırlı ve bunu eğrilerle doğrulamak mı istiyorsunuz, yoksa yay bölümleri zaten var mı?
U2ros

Şu anda, çizgi segmentlerinden yapılmıştır.
Devdatta Tengshe

1
Bu, söz konusu illüstrasyon görünüyor oldukça yayınlanan bir gibi esri.com/news/arcuser/0110/turning.html .
whuber

@whuber: Çok zekice bir gözlem. Bu tam olarak görüntüyü oluşturmak için kullandığım veri kaynağıydı.
Devdatta Tengshe 24:13

Yanıtlar:


15

Eğri çizgi parçalarından oluştuğunda, o zaman bu parçaların tüm iç noktaları ilgi çekici olmayan eğilme noktalarıdır. Bunun yerine, eğri bu bölümlerin köşeleriyle yaklaştığı düşünülmelidir . Bu bölümler boyunca parçalara ayrılabilir iki kat eğri oluşturarak, eğriliği hesaplayabiliriz. Kesin olarak konuşursak bir bükülme noktası, eğriliğin sıfır olduğu bir yerdir.

Örnekte eğriliğin neredeyse sıfır olduğu uzunca uzamalar vardır. Bu, belirtilen noktaların bu tür düşük eğrilikli bölgelerin uçlarına yaklaşması gerektiğini göstermektedir.

Bu nedenle etkili bir algoritma, köşeleri sınırlar, yoğun bir ara nokta kümesi boyunca eğriliği hesaplar, sıfıra yakın eğrilik aralıklarını belirler ("yakın" olmanın ne demek olduğuna dair bazı makul bir tahmin kullanarak) ve bu aralıkların bitiş noktalarını işaretler .

İşte Rbu fikirleri göstermek için çalışma kodu. Koordinat dizisi olarak ifade edilen bir satır dizesiyle başlayalım:

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)

Eğrinin bir parametresini elde etmek için x ve y koordinatlarını ayrı ayrı çizin. (Parametre çağrılacak time.)

n <- dim(xy)[1]
fx <- splinefun(1:n, xy[,1], method="natural")
fy <- splinefun(1:n, xy[,2], method="natural")

Çizim ve hesaplama için spline'ları enterpolasyon yapın :

time <- seq(1,n,length.out=511)
uv <- sapply(time, function(t) c(fx(t), fy(t)))

Parametreli bir eğrinin eğriliğini hesaplamak için bir işleve ihtiyacımız var . Spline'ın birinci ve ikinci türevlerini tahmin etmesi gerekir. Birçok spline'da (kübik splinelar gibi) bu kolay bir cebirsel hesaplamadır. Rotomatik olarak ilk üç türevi sağlar. (Diğer ortamlarda türevlerin sayısal olarak hesaplanması istenebilir.)

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

Sıfır eğriliği için eşiğin derecesine göre bir eşik tahmin etmeyi öneriyorum . Bu en azından iyi bir başlangıç ​​noktasıdır; eğrinin eğriliğine (yani daha uzun eğriler için arttırılmış) göre ayarlanmalıdır. Bu daha sonra eğriliğe göre grafikleri renklendirmek için kullanılacaktır.

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

Artık köşeler eğrilmiş ve eğrilik hesaplanmış olmasına rağmen , sadece bükülme noktalarını bulmak için kalır . Onlara göstermek için köşeleri çizebilir, spline'ı çizebilir ve üzerinde çarpma noktalarını işaretleyebiliriz.

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)

Arsa

Açık noktalar, orjinal köşelerdir xyve siyah noktalar, bu algoritma ile otomatik olarak tanımlanan bükülme noktalarıdır. Eğrilik güvenilir bir şekilde eğrinin uç noktalarında hesaplanamadığından, bu noktalar özel olarak işaretlenmemiştir.


Belki de kullandığım terminoloji yanlıştı. Tam olarak istediğim şey buydu. Cevabınız umut verici görünüyor ve Shapefile'imi işlemek için R ile çalışmak zorunda kalacağım.
Devdatta Tengshe

3

Densify aracını kullanabilirsiniz . Bu durumda, açıya göre yoğunlaştırmayı seçersiniz, Sonraki, düz bir çizgide kabul edilen maksimum açıyı seçin. Ardından, sonuç çizgisine, aracın köşelerdeki bölünmüş çizgisine uygulanır . Son olarak, minimum yol uzunluğundan daha küçük shape_length olan çizgileri silin.

görüntü tanımını buraya girin

Bu resimde üç adım görüyoruz:

1- Açıyı kullanarak çizgiyi yoğunlaştırın. Parametre olarak 10 derece kullandım ve splitline kullandık. Resimde, eğri çizgi başlangıç ​​aşamasındadır.

arcpy.Densify_edit("line" , "ANGLE" , "","",10)
arcpy.SplitLine_management("line" , "line_split")

2- shape_length öğesinin yedekli olmadığı bölümleri seçin. Tabloda gördüğümüz gibi, bu fazlalık uzunlukları seçmedim. Sonra onları yeni bir özellik sınıfına seçiyorum.

arcpy.Select_analysis("line_split" , "line_split_selected")

3- Çizgilerin köşelerinde, bükülme noktaları olan köşeleri çıkardık.

arcpy.FeatureVerticesToPoints_management("line_split_selected" , "line_split_pnt" , "DANGLE")

Diğer cevabınızla ilgili aynı yorum ve sorularım var: güzel bir fikir, ancak aynı zamanda istenen sonucu üreteceği ya da eşik açısını nasıl seçmesi gerektiği açık değildir. Çıktının bir gösterimini verebilir misiniz, böylece okuyucular bu önerinin gerçekte ne yaptığını değerlendirebilir mi? Çalışılan örnekler sunmak, ESRI yazılımını bir çözümün parçası olarak önerirken özellikle önemlidir, çünkü algoritmaları genellikle belgelenmemiştir, tam olarak ne yaptıklarını bilmeleri imkansız hale gelir.
whuber

Bunun çalışan bir çözüm olduğundan emin olmak için test etmem gerekiyor, ancak test edemiyorum, verileri özlüyorum, bu yüzden ESRI tarafından önerilen araçların beklendiği gibi çalışacağını düşünüyorum, ancak bu cevapların daha fazla test edilebilir.
geogeek

fikirlerini isimlendirir ve cevap
veremezdik

1
Öyleyse onları yorumlara taşımamı ister misin? BTW, verilerin test edilmesini istiyorsanız, bir başlangıç ​​için, cevabımda gönderdiğim koordinatları kullanabilirsiniz, çünkü sorudaki resme yakındırlar. Peki neden elinizde sadece coğrafi veriler kullanılmıyor?
whuber

2
evet gerçekten bu çözüm sadece düz çizgiler çıkarmak için daha iyi çalışıyor.
geogeek

1

Orijinal çizgiden maksimum ofset değerine sahip olan Genelleştirme aracını parametre olarak kullanabilirsiniz, böylece durumunuza uygun ofseti seçebilirsiniz.

görüntü tanımını buraya girin

Orijinal satırı "line_cur" ve genelleştirilmiş olan "line_gen" olarak adlandırırsak, "line_cur" u "line_gen" ile kesebiliriz. Sonuç, "line_cur" un düz bir parçası olacaktır. Sonra bazı çok kısa segmentleri, minimum yol uzunluğundan daha fazla Shape_length seçen bir sql sorgusu ile silerek temizleyebiliriz.


Bu güzel bir fikir. Yine de pratikte ne kadar işe yarayacağı belli değil. Bulunan bükülme noktalarını gösteren bir örnek gösterebilir misiniz?
whuber

Bir resim içerecek şekilde bir düzenleme yaptım, resim bu aracın nasıl düz çizgilerle yapıştığını açıklıyor, bu yüzden sadece eski düz çizgiler bölümlerini çıkarmak için eski çizgiye bir klip yapmak zorundayız
geogeek

bir şey yok, sorularınızı cevaplamaya hazırım?
geogeek

Resimde tanımlanmış herhangi bir çekim noktası görmüyorum. Tam olarak nerede olurlar? Ve genelleme toleransı nasıl seçilmeli?
whuber

Testi yapmak için bazı verilere ihtiyacım var, ancak deneyimle toleransı seçmemiz gerektiğini düşünüyorum
geogeek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.