Jak uprościć sfwielokąt bez wprowadzania przerw i fragmentów?
Na przykład z plikiem shapefile użyłbym 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
Próbowałem, sf::st_cast()który na stronach podręcznika stwierdza:
Rzuć geometrię na inny typ: uprość lub jawnie rzutuj
i:
do argumentu: znak; w przypadku braku typu docelowego próbowane jest uproszczenie; gdy x jest typu sfg (tj. pojedyncza geometria), to należy podać.
Kiedy odeszłam tojako zaginiona, nie działało to zgodnie z oczekiwaniami (wiedziałem, że to zbyt piękne, aby mogło być prawdziwe!):
library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB
regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB
Obecnie otwieram plik rgdal::readOGR(), upraszczając go, zapisując, a następnie ładując ponownie sf.
Czy jest lepszy sposób?
rgeos::gSimplify()
Sugestia @sk rgeos::gSimplify()może robić uproszczenia uwzględniające topologię (tj. upraszcza bez tworzenia warstw), jeśli podano następujące argumenty:
library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)
gSimplifynie zachowuje @dataramki, dlatego powinniśmy ją ponownie utworzyć:
regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)
I rzeczywiście powoduje to mniejszy rozmiar pliku (można dostosować tolargument, aby go zmniejszyć) i potwierdziłem, że nie stworzyłem żadnych fragmentów, badając go w QGIS.
object_size(regions_gSimplify)
# ~8MB
Chociaż jest to ważna alternatywa dla rmapshaper::ms_simplify()nadal mam ten sam problem, a mianowicie to, że nie działa z 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"
Odpowiedź @obrl_soil może być również zastosowana gSimplify(), wystarczy użyć jej zamiast ms_simplify().
st_simplifypowinien tego robić? (jeszcze go nie używał)
st_simplify, dzięki za wskazanie tego. Wolę algorytm, który jest rmapshaper::ms_simplifydomyślny niż wszystkie inne, które próbowałem do tej pory, ale zagram z nową opcją (aktualizacja: whoa postępuj ostrożnie, preserveTopology = TRUEzdecydowanie jeszcze nie działa)
regions), ale poza tym nie zachowuje już topologii. Gdy pęka w pewnym momencie, powiedziałbym, że to nie jest zamierzone zachowanie