Como simplifico um sf
polígono sem introduzir espaços e lascas?
Com um shapefile, por exemplo, eu usaria 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
Eu tentei o sf::st_cast()
que, nas páginas de manual, afirma:
Transmitir geometria para outro tipo: simplificar ou converter explicitamente
e:
argumentar: personagem; tipo de destino, se ausente, a simplificação é tentada; quando x é do tipo sfg (ou seja, uma única geometria), deve ser especificado.
Quando deixei to
como falta, isso não funcionou como esperado (eu sabia que era bom demais para ser verdade!):
library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB
regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB
Atualmente, estou abrindo o arquivo rgdal::readOGR()
, simplificando-o, salvando-o e carregando-o novamente com sf
.
Existe uma maneira melhor?
rgeos::gSimplify()
A sugestão de @sk rgeos::gSimplify()
pode fazer simplificações com reconhecimento topológico (isto é, simplifica sem criar lascas) quando especificada com os seguintes argumentos:
library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)
gSimplify
não preserva o @data
quadro, portanto, devemos recriá-lo:
regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)
E isso realmente resulta em um tamanho de arquivo menor (pode alterar o tol
argumento para diminuí-lo) e eu confirmei que isso não havia criado lascas ao examiná-lo no QGIS.
object_size(regions_gSimplify)
# ~8MB
Portanto, embora essa seja uma alternativa válida, rmapshaper::ms_simplify()
ainda tenho o mesmo problema, a saber, que não funciona com 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"
A resposta do @obrl_soil também pode ser aplicada gSimplify()
, basta usá-la no lugar de ms_simplify()
.
st_simplify
deveria fazer isso? (não usá-lo, até o momento)st_simplify
, obrigado por apontar. Eu prefiro o algoritmo que ormapshaper::ms_simplify
padrão é sobre todos os outros que eu tentei até agora, mas vou jogar com a nova opção (atualização: whoa prossiga com cautela,preserveTopology = TRUE
definitivamente ainda não funciona corretamente)regions
), mas além disso não preserva mais a topologia. Como ele quebra em um certo ponto eu diria que o comportamento não se destinaRespostas:
Você pode converter um objeto sf em sp, para pacotes que ainda não suportam sf - eu faço isso bastante para interações raster / polígono. Então você poderia fazer:
fonte
sf
objeto - funcionou perfeitamente e pode ser usada comrmapshaper::ms_simplify()
ourgeos::gSimplify()
. Obrigado pela sugestão!sf::st_simplify()
não é robusto com altas tolerâncias no momento da redação, embora obviamente isso possa mudar.sf
objetos no rmapshaper .ms_simplify
está disponível parasf
objetos na versão de desenvolvimento. Eu adoraria primeiros testadores - se você quiser experimentá-lo, você pode instalar comdevtools::install_github("ateucher/rmapshaper", ref = "sf")
rmapshaper
versão 0.3.0, a chamada paraas( , "Spatial")
não é mais necessária.