¿Cómo simplifico un sfpolígono sin introducir huecos y astillas?
Con un shapefile, por ejemplo, usaría 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
He intentado lo sf::st_cast()que, desde las páginas de manual, dice:
Convertir geometría a otro tipo: simplificar o emitir explícitamente
y:
a argumento: personaje; tipo de destino, si falta, se intenta la simplificación; cuando x es de tipo sfg (es decir, una sola geometría), entonces debe especificarse.
Sin toembargo, cuando me fui como desaparecido, esto no funcionó como se esperaba (¡sabía que era demasiado bueno para ser verdad!):
library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB
regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB
Actualmente estoy abriendo el archivo rgdal::readOGR(), lo simplifico, lo guardo y luego lo vuelvo a cargar con sf.
¿Hay una mejor manera?
rgeos::gSimplify()
La sugerencia de @sk de rgeos::gSimplify()puede hacer simplificaciones topológicamente conscientes (es decir, simplifica sin crear fragmentos) cuando se especifica con los siguientes argumentos:
library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)
gSimplifysin embargo, no conserva el @datamarco, por lo que deberíamos volver a crearlo:
regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)
Y esto de hecho resulta en un tamaño de archivo más pequeño (puede ajustar el tolargumento para hacerlo más pequeño) y confirmó que no había creado ningún fragmento al examinarlo en QGIS.
object_size(regions_gSimplify)
# ~8MB
Entonces, aunque esta es una alternativa válida rmapshaper::ms_simplify(), sigo teniendo el mismo problema, es decir, que no funciona con 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"
La respuesta de @obrl_soil también se puede aplicar gSimplify(), simplemente úsela en lugar de ms_simplify().

st_simplifysupone que debe hacer eso? (no lost_simplify, gracias por señalarlo. Prefiero el algoritmormapshaper::ms_simplifypredeterminado que todos los demás que he probado hasta ahora, peropreserveTopology = TRUEregions) pero más allá de eso ya no conserva la topología. Como se rompe en cierto punto, diría que no es un comportamiento intencionadoRespuestas:
Puede lanzar un objeto sf a sp, para paquetes que aún no admiten sf. Lo hago bastante bien para las interacciones ráster / polígono. Entonces podrías hacer:
fuente
sfobjeto, funcionó perfectamente y se puede usar conrmapshaper::ms_simplify()orgeos::gSimplify(). ¡Gracias por la sugerencia!sf::st_simplify()no es robusto a altas tolerancias al momento de escribir, aunque obviamente esto puede cambiar.sfobjetos en rmapshaper .ms_simplifyestá disponible parasfobjetos en la versión de desarrollo. Me encantaría primeros probadores - si quieres probarlo, que puede instalar condevtools::install_github("ateucher/rmapshaper", ref = "sf")rmapshaperversión 0.3.0, la llamada aas( , "Spatial")ya no es necesaria.