¿Cómo simplifico un sf
polí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 to
embargo, 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)
gSimplify
sin embargo, no conserva el @data
marco, 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 tol
argumento 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_simplify
supone que debe hacer eso? (no lost_simplify
, gracias por señalarlo. Prefiero el algoritmormapshaper::ms_simplify
predeterminado que todos los demás que he probado hasta ahora, peropreserveTopology = TRUE
regions
) 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
sf
objeto, 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.sf
objetos en rmapshaper .ms_simplify
está disponible parasf
objetos en la versión de desarrollo. Me encantaría primeros probadores - si quieres probarlo, que puede instalar condevtools::install_github("ateucher/rmapshaper", ref = "sf")
rmapshaper
versión 0.3.0, la llamada aas( , "Spatial")
ya no es necesaria.