Comment simplifier un sf
polygone sans introduire d'écarts et de rubans?
Avec un fichier de formes, par exemple, j'utiliserais 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
J'ai essayé sf::st_cast()
ce qui, à partir des pages de manuel, déclare:
Transformer la géométrie en un autre type: simplifier ou convertir explicitement
et:
à l'argument: caractère; type cible, s'il est manquant, une simplification est tentée; lorsque x est de type sfg (c'est-à-dire une seule géométrie), alors to doit être spécifié.
Quand j'ai laissé to
comme manquant, cela n'a pas fonctionné comme prévu (je savais que c'était trop beau pour être vrai!):
library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB
regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB
Actuellement, j'ouvre le fichier avec rgdal::readOGR()
, le simplifie, l'enregistre, puis le charge à nouveau avec sf
.
Y a-t-il une meilleure façon?
rgeos::gSimplify()
La suggestion de @sk de rgeos::gSimplify()
peut effectuer des simplifications tenant compte de la topologie (c'est-à-dire simplifie sans créer de fragments) lorsqu'elle est spécifiée avec les arguments suivants:
library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)
gSimplify
ne conserve pas le @data
cadre, nous devons donc le recréer:
regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)
Et cela entraîne en effet une taille de fichier plus petite (peut modifier l' tol
argument pour le réduire) et j'ai confirmé que cela n'avait créé aucun éclat en l'examinant dans QGIS.
object_size(regions_gSimplify)
# ~8MB
Donc, bien que ce soit une alternative valable, rmapshaper::ms_simplify()
j'ai toujours le même problème, à savoir qu'il ne fonctionne pas avec 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 réponse de @obrl_soil peut également être appliquée gSimplify()
, utilisez-la simplement à la place de ms_simplify()
.
st_simplify
censé faire ça? (pas encore utilisé)st_simplify
, merci de l'avoir signalé. Je préfère l'algorithme parrmapshaper::ms_simplify
défaut à tous les autres que j'ai essayés jusqu'à présent, mais je vais jouer avec la nouvelle option (mise à jour: whoa procéder avec prudence,preserveTopology = TRUE
ne fonctionne certainement pas encore correctement)regions
) mais au-delà, il ne préserve plus la topologie. Comme il se casse à un certain point, je dirais que ce n'est pas un comportement vouluRéponses:
Vous pouvez convertir un objet sf en sp, pour les packages qui ne prennent pas encore en charge sf - je le fais un peu pour les interactions raster / polygone. Vous pourriez donc faire:
la source
sf
qu'objet - fonctionnait parfaitement et peut être utilisée avecrmapshaper::ms_simplify()
ourgeos::gSimplify()
. Merci pour la suggestion!sf::st_simplify()
n'est pas robuste à des tolérances élevées au moment de la rédaction, bien que cela puisse évidemment changer.sf
objets dans rmapshaper .ms_simplify
est disponible pour lessf
objets dans la version de développement. J'adorerais les premiers testeurs - si vous voulez l'essayer, vous pouvez installer avecdevtools::install_github("ateucher/rmapshaper", ref = "sf")
rmapshaper
version 0.3.0, l'appel àas( , "Spatial")
n'est plus requis.