Hơn

Hòa tan / Hợp nhất các Đa giác bị bệnh / Không đều trong R

Hòa tan / Hợp nhất các Đa giác bị bệnh / Không đều trong R


Tôi đang thực hiện một dự án liên quan đến việc tập hợp nhiều chủ thể xoay quanh những phần khó tìm thấy của một hình ảnh. Đầu ra từ người dùng là khá tuyệt vời.

Tuyệt, phải không?

Tuy nhiên, điều tôi muốn là lấy vùng ảnh có 1, 2, 3, 4, v.v. người dùng chọn nó. Và tôi đang sử dụng R để phân tích với các gói sp, raster và maptools (với một chút rgeos được đưa vào khi cần thiết). Về cơ bản, quy trình làm việc của tôi là 1) tạo một đa giác duy nhất từ ​​đầu vào của mỗi người dùng (tôi thực sự có theo dõi từng lựa chọn riêng lẻ cho mỗi người dùng, nhưng có vẻ dễ dàng hơn khi kết hợp chúng thành một SpatialPolygon cho mỗi người dùng) 2) hợp nhất tất cả chúng lại với nhau thành một Đối tượng SpatialPolygonsDataFrame 3) Chỉnh sửa đối tượng bằng cách sử dụng chức năng đếm 4) Đánh giá khu vực của raster với n số người dùng chọn nó

Đây là đầu ra SpatialPolygonsDataFrame để chơi với

Điều này hoạt động tốt, nhưng bị chậm do quá trình phân hóa. Tôi cảm thấy mình có thể làm gì đó với đối tượng SpatialPolygons. Và tôi đã thử một vài thứ với union, gIntersects, gUnion và giao nhau. Tuy nhiên, tôi tiếp tục nhận được các lỗi như sau

Lỗi trong RGEOSBinTopoFunc (spgeom1, spgeom2, byid, id, drop_lower_td, "rgeos_difference"): TopologyException: Input geom 1 không hợp lệ: Tự giao nhau tại hoặc gần điểm

Đủ công bằng. Thường thì một người dùng nhất định SpatialPolygons không hợp lệ khi tôi kiểm tra họ bằng gIsValid. Nhìn vào, nói, chỉ là hai đầu tiên, điều này trở nên rõ ràng rằng có nhiều điểm trùng lặp.

Bạn có thể nhìn thấy các điểm giao nhau khá rõ ràng. Hơn nữa, trong poly2 (màu xanh lam) dường như có một số tự giao cắt, khiến gIsValid trả về false.

Tôi cũng đã thử unionSpatialPolygons (với tránhRGEOS = T) tạo một đối tượng hợp nhấtunionSpatialPolygons (polysData [1: 2,], IDs = names (polysData [1: 2,] @ polygons))Nhưng các đường viền vẫn chồng lên nhau như trong hình trên, chứ không phải là một đường viền bên ngoài đa giác trơn - tức là các đa giác không bị hòa tan với nhau. Sau đó, sử dụng bất kỳ chức năng nào khác trên đối tượng SpatialPolygons mới này, tôi gặp vấn đề tương tự.

Vì vậy, có cách nào để sử dụng đa giác thay vì đi raster không? Nó chắc chắn sẽ làm cho cuộc sống của tôi nhanh hơn, điều đó sẽ rất tuyệt vời. Tôi cảm thấy đây chắc hẳn là một vấn đề phổ biến với một chiếc bánh xe được phát minh ra mà tôi vẫn chưa tìm ra. Suy nghĩ?


Nghe có vẻ như làm sạch hình học sẽ đưa bạn đến con đường đến với giải pháp không raster của bạn… với một thứ gì đó của một chất tẩy rửa có thể giúp sửa chữa hình học xấu:

# Tải thư viện và thư viện dữ liệu có vấn đề (rgeos) tải ("oneImage2_spdf.Rdata")> gIsValid (polysData, reason = T) Lỗi trong RGEOSBinTopoFunc (spgeom1, spgeom2, byid, id, drop_lower_td, "rgeos_union"): TopologyException: geom 0 không hợp lệ: Tự giao nhau tại hoặc gần điểm -119.84228271000001 34.349193950783807 tại -119.84228271000001 34.349193950783807

Đó là dữ liệu vi phạm; có lẽ chỉ một điểm duy nhất, nhưng làm bộ đệm bằng 0 chiều rộng sẽ sửa chữa nó.

# Hãy đệm bằng 0: polysData <- gBuffer (polysData, width = 0, byid = T)

gBuffer không thích điều này - có một CRS chưa dự kiến ​​được gắn vào nó!

Thông báo cảnh báo: Trong gBuffer (polysData, width = 0, byid = T): Đối tượng không gian không được chiếu; GEOS mong đợi tọa độ phẳng

Đã đến lúc lừa rgeos:

# Đặt thành CRS dự kiến ​​- có thể là bất cứ thứ gì polysCRS <- polysData @ proj4string polysData @ proj4string <- CRS ("+ init = epsg: 32737") # Bây giờ đệm nó nhưng giữ nguyên các đối tượng riêng lẻ polysData <- gBuffer (polysData, width = 0 , byid = T) # Đặt lại CRS polysData @ proj4string <- polysCRS ban đầu

Kiểm tra xem hình có hợp lệ không:

> gIsValid (polysData, reason = T) "Hình học hợp lệ"

Nếu không có dữ liệu ban đầu của bạn, tôi không thể chắc chắn rằng điều này sẽ hoạt động, nhưng tôi nghĩ nó có thể giúp ích cho bạn. Tôi đã không mang nó đến đó, giải pháp này có thể vẫn cần một số mức độ tự động hóa, nhưng có thể cung cấp cho bạn một cách chung về phía trước

Đầu tiên, tôi tạo một số đa giác không gian

polypoints1 <- matrix (c (1,2,2,1,1,2,2,1,1,2), ncol = 2) polypoints2 <- matrix (c (1,3,3,1,1,3 , 3,1,1,3), ncol = 2) polypoints3 <- matrix (c (1,2,2,1,1,2,2,1,1,2) + 1,1, ncol = 2) polypoints4 < - ma trận (c (1,2,2,1,1,2,2,1,1,2) + 0,5, ncol = 2) p1 <- Đa giác (đa điểm1) ps1 <- Đa giác (danh sách (p1), 1 ) sps1 <- SpatialPolygons (list (ps1)) p2 <- Polygon (polypoints2) ps2 <- Polygons (list (p2), 2) sps2 <- SpatialPolygons (list (ps2)) p3 <- Polygon (polypoints3) ps3 <- Polygons (list (p3), 3) sps3 <- SpatialPolygons (list (ps3)) p4 <- Polygon (polypoints4) ps4 <- Polygons (list (p4), 4) sps4 <- SpatialPolygons (list (ps4))

Tôi lập kế hoạch cho họ chỉ để xem

plot (sps2, col = 'green') plot (sps1, add = T, col = 'blue') plot (sps3, add = T, col = 'yellow') plot (sps4, add = T, col = 'Purple ')

Tôi đã hợp nhất chúng thành một bản spdf

data = data.frame (c (x = rep (1,4)), row.names = c (1: 4)) sps <- SpatialPolygons (list (ps1, ps2, ps3, ps4)) spdf <- SpatialPolygonsDataFrame ( sps, dữ liệu)

Bạn có thể xác định đa giác nào chồng chéo như vậy:

gIntersects (spdf, spdf, byid = T)

Từ lệnh trên, bạn có thể tạo một số loại vòng lặp để thực hiện các kết hợp chồng chéo bên dưới (tôi chỉ bỏ qua sps4 cho ngắn gọn tại thời điểm này)

poly2a <- gIntersection (spdf [2,], spdf [1,], drop_lower_td = T) poly2a <- SpatialPolygonsDataFrame (poly2a, data.frame (c (x = 1), row.names = c (1))) âm mưu (poly2a, add = T, col = 'red')

Lần này chúng ta cần thay đổi ID vì chúng ta sẽ chuyển các mã này sau

poly2b <- gIntersection (spdf [2,], spdf [3,], drop_lower_td = T) poly2b <- spChFIDs (poly2b, "2") poly2b <- SpatialPolygonsDataFrame (poly2b, data.frame (c (x = 1), row.names = c (2))) plot (poly2b, add = T, col = 'red')

Hợp nhất các đa giác chồng lên nhau thành một spdf khác

spdf_overlaps <- rbind (poly2a, poly2b) poly2 <- unionSpatialPolygons (spdf_overlaps, rep (1,2)) plot (poly2, add = T, col = 'blue')

Bây giờ chúng ta có poly2 là nơi chúng ta có 2 lớp chồng lên nhau (ngoại trừ kết hợp với sps4), sau đó để tìm ra 3 lớp, chúng ta chỉ cần kiểm tra xem poly2 và spdf chồng chéo ở đâu (nếu bạn tạo một phiên bản tự động hơn của điều này, bạn sẽ cần đảm bảo rằng 'poly2' không bao gồm sps4 như trong ví dụ này)

gIntersects (poly2, spdf [4,], byid = T) poly3 <- gIntersection (poly2, spdf [4,], drop_lower_td = T) plot (poly3, add = T, col = "red")

Kiểm tra nó ra

gIsValid (poly2) gIsValid (poly3)

Ngoài ra, bạn luôn có thể thực hiện giả lập, dễ dàng hơn nhiều, nhưng bạn mất một số chi tiết tùy thuộc vào kích thước ô của bạn:

Đầu tiên hãy tạo lưới:

bb <- bbox (spdf) cs <- c (0,1,0.1) # kích thước ô cc <- bb [, 1] + (cs / 2) # ô bù cd <- trần (diff (t (bb)) / cs ) # số ô trên mỗi hướng grd <- GridTopology (cellcentre.offset = cc, cellsize = cs, cells.dim = cd) sp_grd <- SpatialGridDataFrame (grd, data = data.frame (id = 1: prod (cd)) )

Sau đó, tạo lưới thành một đa giác được sử dụng để chồng lên nhau

thư viện (Grid2Polygons) lưới <- Grid2Polygons (sp_grd) lô (lưới)

Sau đó, đếm số đa giác chồng lên mỗi ô lưới

count <- apply (gContains (spdf, grid, byid = T), 1, sum)

Cuối cùng, âm mưu nó!

plot (lưới) for (i in 1: length (grid)) {plot (grid [i,], col = rev (heat.colors (3)) [count [i]], add = T)}

Việc áp dụng bộ đệm với width = 0 có thể rủi ro đối với một số đa giác, ví dụ: trường hợp của đa giác bowtie, thay đổi rất nhiều hình học nguồn. Bạn có thể thử sử dụng gói cleangeo nhằm mục đích sửa các đối tượng không gian. Bạn có thể cài đặt nó từ Github hoặc từ CRAN. Bạn có thể sử dụng mã đơn giản này để sửa đối tượng không gian của mình:

thư viện (cleangeo) polysData.clean <- clgeo_Clean (polysData) #check tính hợp lệ về hình học của đầu ra gIsValid (polysData.clean)