Wie kann ich ein sf
Polygon vereinfachen, ohne Lücken und Splitter einzufügen?
Mit einem Shapefile würde ich zum Beispiel Folgendes verwenden 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
Ich habe ausprobiert, sf::st_cast()
was aus den Manpages hervorgeht:
Geometrie in einen anderen Typ umwandeln: entweder vereinfachen oder explizit umwandeln
und:
zu argumentieren: Charakter; Zieltyp, falls fehlt, wird eine Vereinfachung versucht; Wenn x vom Typ sfg ist (dh eine einzelne Geometrie), muss to angegeben werden.
Wenn ich to
als vermisst abgereist bin, hat dies jedoch nicht wie erwartet funktioniert (ich wusste, dass es zu gut ist, um wahr zu sein!):
library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB
regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB
Momentan öffne ich die Datei mit rgdal::readOGR()
, vereinfache sie, speichere sie und lade sie dann erneut mit sf
.
Gibt es einen besseren Weg?
rgeos::gSimplify()
@sk 's Vorschlag von rgeos::gSimplify()
kann topologisch bewusste Vereinfachungen (dh Vereinfachungen ohne das Erstellen von Splittern) durchführen, wenn er mit den folgenden Argumenten angegeben wird:
library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)
gSimplify
behält den @data
Rahmen jedoch nicht bei , daher sollten wir ihn neu erstellen:
regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)
Und dies führt in der Tat zu einer kleineren Dateigröße (kann das tol
Argument optimieren , um es zu verkleinern), und ich bestätigte, dass dies keine Splitter erzeugt hat, indem ich es in QGIS untersuchte.
object_size(regions_gSimplify)
# ~8MB
Also, obwohl dies eine gültige Alternative zu ist, habe rmapshaper::ms_simplify()
ich immer noch das gleiche Problem, nämlich dass es nicht funktioniert mit 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"
Die Antwort von @obrl_soil kann auch auf angewendet werden gSimplify()
, verwenden Sie sie einfach anstelle von ms_simplify()
.
st_simplify
sein? (habe es noch nicht benutzt)st_simplify
, danke, dass du darauf hingewiesen hast . Ich bevorzuge den Algorithmus, derrmapshaper::ms_simplify
standardmäßig allen anderen verwendet wird, die ich bisher ausprobiert habe, aber ich werde mit der neuen Option spielen (Update: whoa mit Vorsicht vorgehen,preserveTopology = TRUE
funktioniert definitiv noch nicht richtig)regions
) verwendet habe, behält aber darüber hinaus die Topologie nicht mehr bei. Da es an einem bestimmten Punkt kaputt geht, würde ich sagen, dass dies kein beabsichtigtes Verhalten istAntworten:
Sie können ein sf-Objekt in sp umwandeln, für Pakete, die sf noch nicht unterstützen - ich mache das ein gutes Stück für Raster / Polygon-Interaktionen. Sie könnten also Folgendes tun:
quelle
sf
Objekt - funktionierte perfekt und kann mitrmapshaper::ms_simplify()
oder verwendet werdenrgeos::gSimplify()
. Danke für den Vorschlag!sf::st_simplify()
bei hohen Toleranzen zum Zeitpunkt des Schreibens nicht robust ist, obwohl sich dies offensichtlich ändern kann.sf
Objekte in rmapshaper .ms_simplify
ist fürsf
Objekte in der Entwicklungsversion verfügbar. Ich würde mich über frühe Testerdevtools::install_github("ateucher/rmapshaper", ref = "sf")
rmapshaper
Version 0.3.0 ist der Aufruf vonas( , "Spatial")
nicht mehr erforderlich.