24 votos

Simplificar polígonos de objeto sf

¿Cómo simplifico un sf polígono sin introducir huecos y astillas?

Con un shapefile, por ejemplo, utilizarí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 sf::st_cast() que, desde las páginas de manual, afirma:

Convertir geometría a otro tipo: simplificar o convertir explícitamente

y:

argumento to: carácter; tipo de destino, si falta, se intenta la simplificación; cuando x es de tipo sfg (es decir, una sola geometría) entonces es necesario especificar to.

Cuando me he ido to sin embargo, como falta esto no ha funcionado como 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 con rgdal::readOGR() simplificándolo, guardándolo y volviéndolo a cargar con sf .

¿Hay alguna forma mejor?


rgeos::gSimplify()

La sugerencia de @s.k de rgeos::gSimplify() puede hacer simplificaciones topológicamente conscientes (es decir, simplifica sin crear astillas) cuando se especifica con los siguientes argumentos:

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

gSimplify no conserva el @data marco, por lo que debemos 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 tol para hacerlo más pequeño) y confirmé que esto no había creado ninguna astilla examinándolo en QGIS.

object_size(regions_gSimplify)
# ~8MB

Por tanto, aunque se trata de una alternativa válida a rmapshaper::ms_simplify() Sigo teniendo el mismo problema, a saber, 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"

Respuesta de @obrl_soil también puede aplicarse a gSimplify() Utilícelo en lugar de ms_simplify() .

25voto

obrl_soil Puntos 53

Puedes convertir un objeto sf en sp, para paquetes que todavía no soportan sf - yo lo hago bastante para interacciones raster/polygon. Así que usted podría hacer:

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

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X