Thuật toán để tìm ra các điểm uốn cho một đa tuyến


22

Tôi đang cố gắng tìm ra các điểm uốn, tức là các điểm mà các đường cong trong một đường bắt đầu và kết thúc. Nếu bạn nhìn vào hình ảnh, đường màu xanh lá cây có thể là đường hoặc luồng và các điểm đen là điểm mà các đường cong bắt đầu và kết thúc. nhập mô tả hình ảnh ở đây

Điều gì sẽ là các bước cấp cao để tự động hóa việc tạo ra các điểm này? Tôi có máy tính để bàn ArcGIS và khá tiện dụng với ArcObjects.


Dữ liệu nguồn là một đa tuyến được tạo từ các phân đoạn dòng và bạn muốn phân tích nó bằng các đường cong hoặc nó đã có các phân đoạn cung chưa?
U2ros

Hiện tại, nó được làm từ các phân khúc dòng.
Devdatta Tengshe

1
Hình minh họa trong câu hỏi này trông đáng chú ý giống như được công bố tại esri.com/news/arcuser/0110/turn.html .
whuber

@whuber: Quan sát rất sắc sảo. Đó chính xác là nguồn dữ liệu tôi đã sử dụng để tạo hình ảnh.
Devdatta Tengshe

Câu trả lời:


15

Khi đường cong bao gồm các đoạn đường, thì tất cả các điểm bên trong của các đoạn đó là các điểm uốn, điều này không thú vị. Thay vào đó, đường cong nên được coi là gần đúng bởi các đỉnh của các đoạn đó. Bằng cách chia một đường cong có thể phân biệt hai lần qua các phân đoạn đó, sau đó chúng ta có thể tính toán độ cong. Một điểm uốn, nói đúng ra, sau đó là một nơi mà độ cong bằng không.

Trong ví dụ này có những đoạn dài kéo dài trong đó độ cong gần như bằng không. Điều này cho thấy rằng các điểm được chỉ định phải xấp xỉ các đầu của các khu vực có độ cong thấp như vậy.

Do đó, một thuật toán hiệu quả sẽ chia các đỉnh, tính toán độ cong dọc theo một tập hợp các điểm trung gian dày đặc, xác định các phạm vi độ cong gần bằng 0 (sử dụng một số ước tính hợp lý về ý nghĩa của "gần") và đánh dấu các điểm cuối của các phạm vi đó .

Đây là Rmã làm việc để minh họa những ý tưởng này. Hãy bắt đầu với một chuỗi dòng được biểu thị dưới dạng một chuỗi tọa độ:

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)

Tách các tọa độ xy riêng biệt để đạt được tham số đường cong. (Tham số sẽ được gọi time.)

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

Nội suy các spline cho âm mưu và tính toán:

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

Chúng ta cần một hàm để tính độ cong của đường cong tham số. Nó cần ước tính các dẫn xuất thứ nhất và thứ hai của spline. Với nhiều spline (chẳng hạn như splines khối), đây là một phép tính đại số dễ dàng. Rcung cấp ba dẫn xuất đầu tiên tự động. (Trong các môi trường khác, người ta có thể muốn tính toán các đạo hàm bằng số.)

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

Tôi đề xuất để ước tính một ngưỡng cho độ cong bằng không về phạm vi của đường cong. Điều này ít nhất là một điểm khởi đầu tốt; nó nên được điều chỉnh theo độ cong của đường cong (nghĩa là tăng cho các đường cong dài hơn). Điều này sau đó sẽ được sử dụng để tô màu các ô theo độ cong.

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

Bây giờ các đỉnh đã được chia và độ cong được tính toán, nó vẫn chỉ để tìm các điểm uốn . Để hiển thị chúng, chúng ta có thể vẽ các đỉnh, vẽ đồ thị và đánh dấu các điểm uốn trên nó.

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)

Âm mưu

Các điểm mở là các đỉnh ban đầu xyvà các điểm đen là các điểm uốn được xác định tự động với thuật toán này. Bởi vì độ cong không thể được tính toán một cách đáng tin cậy tại các điểm cuối của đường cong, những điểm đó không được đánh dấu đặc biệt.


Có lẽ thuật ngữ tôi sử dụng là sai. Những gì bạn giả định là chính xác những gì tôi muốn. Câu trả lời của bạn có vẻ đầy hứa hẹn và tôi sẽ phải làm việc với R để xử lý Shapefile của mình.
Devdatta Tengshe

3

Bạn có thể sử dụng công cụ Densify . Đối với trường hợp này, bạn chọn tăng mật độ theo góc, Tiếp theo, chọn góc tối đa được chấp nhận theo một đường thẳng. Sau đó áp dụng cho dòng kết quả cho công cụ Chia dòng tại các đỉnh . Cuối cùng, xóa các dòng có shape_length nhỏ hơn chiều dài đường tối thiểu.

nhập mô tả hình ảnh ở đây

Trong bức tranh này, chúng ta thấy ba bước:

1- Mật độ dòng sử dụng góc. Tôi đã sử dụng 10 độ làm tham số, và chúng tôi đã sử dụng splitline. Trong ảnh, đường cong đang trong giai đoạn ban đầu.

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

2- Chọn các phân đoạn có hình dạng_length không dư thừa. Như chúng ta thấy trong bảng, tôi đã không chọn những độ dài dư thừa đó. Sau đó, tôi chọn chúng vào một lớp tính năng mới.

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

3- Chúng tôi đã trích xuất các đỉnh nằm trong các cạnh của các đường, đó là các điểm uốn.

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

Tôi có cùng nhận xét và câu hỏi liên quan đến câu trả lời khác của bạn: đó là một ý tưởng hay, nhưng đồng thời cũng không rõ ràng rằng nó sẽ tạo ra kết quả mong muốn, cũng như cách người ta nên chọn góc ngưỡng. Bạn có thể cung cấp một minh họa về đầu ra để độc giả có thể đánh giá đề xuất này thực sự làm gì? Việc cung cấp các ví dụ hoạt động đặc biệt quan trọng khi đề xuất phần mềm ESRI như một phần của giải pháp, bởi vì thuật toán của chúng thường không được ghi lại, khiến chúng ta không thể biết chính xác những gì chúng đang làm.
whuber

để chắc chắn rằng đó là một giải pháp hiệu quả, tôi cần kiểm tra nó, nhưng tôi không thể kiểm tra nó, tôi đang thiếu dữ liệu, vì vậy tôi cho rằng các công cụ được đề xuất bởi ESRI sẽ hoạt động như mong đợi, nhưng câu trả lời này cần phải được kiểm tra thêm.
geogeek

chúng ta có thể đặt tên cho chúng là ý tưởng và không trả lời
geogeek

1
Bạn có muốn tôi chuyển chúng thành bình luận không? BTW, nếu bạn muốn kiểm tra dữ liệu, bạn có thể - để bắt đầu - sử dụng tọa độ tôi đã đăng trong câu trả lời của mình, vì chúng gần với hình minh họa trong câu hỏi. Nhưng tại sao không sử dụng bất kỳ dữ liệu địa lý nào bạn có?
whuber

2
có thực sự giải pháp này đang làm việc tốt hơn trong việc trích xuất chỉ các đường thẳng.
geogeek

1

Bạn có thể sử dụng công cụ Generalize có phần bù tối đa từ dòng ban đầu làm tham số, vì vậy bạn có thể chọn phần bù phù hợp với trường hợp của bạn.

nhập mô tả hình ảnh ở đây

Nếu chúng ta đặt tên cho dòng ban đầu là "line_cur" và một dòng "line_gen" được khái quát hóa, thì chúng ta có thể cắt "line_cur" theo "line_gen". Kết quả sẽ là đoạn thẳng của "line_cur". Sau đó, chúng tôi có thể xóa một số đoạn rất ngắn bằng cách xóa chúng bằng truy vấn sql, chọn Shape_length lớn hơn chiều dài đường tối thiểu.


Đây là một ý tưởng tốt đẹp. Mặc dù vậy, không rõ nó sẽ hoạt động tốt như thế nào trong thực tế. Có lẽ bạn có thể hiển thị một ví dụ cho thấy các điểm uốn được tìm thấy?
whuber

Tôi đã thực hiện chỉnh sửa để bao gồm một hình ảnh, hình ảnh giải thích cách công cụ này có thể tạo một đường thẳng với các đoạn thẳng, vì vậy chúng tôi phải tạo một clip thành dòng cũ, để trích xuất các đoạn thẳng cũ
geogeek

Có bất cứ điều gì không rõ ràng tôi có sẵn để trả lời câu hỏi của bạn?
geogeek

Tôi không thấy bất kỳ điểm uốn nào được xác định trong hình minh họa. Chính xác thì họ sẽ ở đâu? Và làm thế nào nên chọn dung sai cho khái quát?
whuber

Tôi cần một số dữ liệu để thực hiện thử nghiệm, nhưng tôi nghĩ chúng ta nên chọn dung sai bằng thử nghiệm
geogeek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.