Đơn giản hóa đa giác của đối tượng sf


14

Làm cách nào để đơn giản hóa một sfđa giác mà không giới thiệu các khoảng trống và các phần tử?

Ví dụ, với một shapefile, tôi sẽ sử dụng rmapshaper::ms_simplify():

library("pryr")
library("rgdal")
library("rmapshaper")

download.file("https://borders.ukdataservice.ac.uk/ukborders/easy_download/prebuilt/shape/England_gor_2011.zip",
              destfile = "regions.zip")
unzip("regions.zip")
regions <- readOGR(".", "england_gor_2011")
object_size(regions)
# ~13MB

regions <- ms_simplify(regions)
object_size(regions)
# < 1MB

Tôi đã thử sf::st_cast(), từ các trang người đàn ông, nói:

Truyền hình học sang loại khác: đơn giản hóa hoặc truyền rõ ràng

và:

để tranh luận: nhân vật; loại mục tiêu, nếu thiếu, đơn giản hóa được thử; khi x thuộc loại sfg (nghĩa là một hình học đơn) thì cần phải được chỉ định.

Khi tôi bỏ tolỡ vì điều này không hoạt động như mong đợi (tôi biết điều đó là quá tốt để trở thành sự thật!):

library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB

regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB

Hiện tại tôi đang mở tệp rgdal::readOGR(), đơn giản hóa nó, lưu tệp này, sau đó tải lại tệp này với sf.

Có cách nào tốt hơn?


rgeos::gSimplify()

Đề xuất của @sk rgeos::gSimplify()có thể thực hiện các đơn giản hóa theo cấu trúc liên kết (nghĩa là đơn giản hóa mà không tạo các phần tử) khi được chỉ định với các đối số sau:

library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)

gSimplifyTuy nhiên, không bảo tồn @datakhung, vì vậy chúng ta nên tạo lại nó:

regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)

Và điều này thực sự dẫn đến kích thước tệp nhỏ hơn (có thể điều chỉnh tolđối số để làm cho nó nhỏ hơn) và tôi đã xác nhận điều này đã không tạo ra bất kỳ phần tử nào bằng cách kiểm tra nó trong QGIS.

object_size(regions_gSimplify)
# ~8MB

Vì vậy, mặc dù đây là một thay thế hợp lệ cho rmapshaper::ms_simplify()tôi vẫn có cùng một vấn đề, cụ thể là nó không hoạt động với sf:

regions_sf <- sf::read_sf("england_gor_2011.shp")
object_size(regions_sf)

regions_gSimplify <- gSimplify(regions_sf, topologyPreserve = TRUE, tol = 0.05)
# Error in gSimplify(regions_sf, topologyPreserve = TRUE, tol = 0.05) : 
# no slot of name "proj4string" for this object of class "sf"

Câu trả lời của @obrl_soil cũng có thể được áp dụng gSimplify(), chỉ cần sử dụng nó thay cho ms_simplify().


1
Bạn có quyền truy cập vào thuật toán Douglasucker Peucker không? Nó được biết đến rộng rãi cho các tính năng đơn giản hóa trong thế giới GIS. stackoverflow.com/questions/17217413/ từ & r-bloggers.com/simplifying-spatial-polygons-in-r
sk

1
Không phải st_simplifylàm điều đó? (chưa sử dụng nó)
lbusett

2
ooh, tôi đã không nhận thấy st_simplify, cảm ơn vì đã chỉ ra nó. Tôi thích thuật toán rmapshaper::ms_simplifymặc định hơn tất cả các thuật toán khác mà tôi đã thử từ trước đến nay, nhưng tôi sẽ chơi với tùy chọn mới (cập nhật: whoa tiến hành thận trọng, preserveTopology = TRUEchắc chắn vẫn chưa hoạt động chính xác)
obrl_soil

1
Tốt để biết. Điều gì về việc mở một báo cáo lỗi về điều này?
lbusett

1
@obrl_soil Nó hoạt động với dung sai lên tới khoảng 1000 trên đa giác tôi đã sử dụng trong câu hỏi ( regions) nhưng ngoài ra nó không còn bảo tồn cấu trúc liên kết. Khi nó bị phá vỡ tại một thời điểm nhất định, tôi nói rằng đó không phải là hành vi có chủ đích
Phil

Câu trả lời:


16

Bạn có thể truyền đối tượng sf thành sp, đối với các gói chưa hỗ trợ sf - Tôi thực hiện điều này một chút công bằng cho các tương tác raster / đa giác. Vì vậy, bạn có thể làm:

simplepolys <- rmapshaper::ms_simplify(input = as(sfobj, 'Spatial')) %>%
  st_as_sf()

1
Kỹ thuật này - đúc như một đối tượng không gian, đơn giản hóa, sau đó đúc lại như một sfđối tượng - hoạt động hoàn hảo và có thể được sử dụng với rmapshaper::ms_simplify()hoặc rgeos::gSimplify(). Cám ơn vì sự gợi ý!
Phil

Mát mẻ mát mẻ, chỉ cần lưu ý rằng cấu trúc liên kết của đa giác lồng vào nhau chỉ thực sự được bảo tồn với cách tiếp cận của rmapshaper. Nếu dữ liệu đầu vào của bạn là tất cả các đa giác bị cô lập, không lồng vào nhau, bạn có thể sử dụng một cách an toàn bất kỳ thuật toán đơn giản hóa nào có sẵn.
obrl_soil

Tôi chấp nhận đây là câu trả lời vì kinh điển hơn sf::st_simplify()không mạnh ở mức dung sai cao tại thời điểm viết, mặc dù rõ ràng điều này có thể thay đổi.
Phil

8
Tôi hiện đang làm việc về hỗ trợ cho sfcác đối tượng trong rmapshaper . ms_simplifycó sẵn cho sfcác đối tượng trong phiên bản phát triển. Tôi yêu những người thử nghiệm sớm - nếu bạn muốn dùng thử, bạn có thể cài đặt vớidevtools::install_github("ateucher/rmapshaper", ref = "sf")
andyteucher

6
Kể từ rmapshaperphiên bản 0.3.0, cuộc gọi đến as( , "Spatial")không còn cần thiết nữa.
Luke1018
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.