Спростіть багатокутники об'єкта sf


14

Як я спрощую sfбагатокутник, не вводячи прогалини та слайвери?

Наприклад, з файлом форми я б використав 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

Я спробував, sf::st_cast()який зі сторінок man:

Передайте геометрію іншому типу: або спрощуйте, або чітко додайте

і:

аргументувати: характер; цільовий тип, якщо він відсутній, спроба спрощення; коли x має тип sfg (тобто єдину геометрію), тоді його потрібно вказати.

Коли я пішов toяк зниклий, це не спрацювало так, як очікувалося (я знав, що це занадто добре, щоб бути правдою!):

library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB

regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB

В даний час я відкриваю файл rgdal::readOGR(), спрощую його, зберігаючи його, а потім завантажую його знову sf.

Чи є кращий спосіб?


rgeos::gSimplify()

Пропозиція @sk rgeos::gSimplify()може робити топологічно спрощені спрощення (тобто спрощує без створення слайдів), коли це задано за допомогою наступних аргументів:

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

gSimplifyоднак @dataкадр не зберігає , тому нам слід його створити заново:

regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)

І це дійсно призводить до меншого розміру файлу (можна налаштувати tolаргумент, щоб зменшити його), і я підтвердив, що це не створило жодних слайдів, вивчивши його в QGIS.

object_size(regions_gSimplify)
# ~8MB

Тому, хоча це є вагомою альтернативою, у rmapshaper::ms_simplify()мене все ще є та сама проблема, а саме, що вона не працює з 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"

Відповідь @obrl_soil також може бути застосована gSimplify(), просто використовуйте її замість ms_simplify().


1
Чи є у вас доступ до алгоритму Дугласа – Пейкера? Широко відомо про спрощення функцій у світі ГІС. stackoverflow.com/questions/17217413 / ... & r-bloggers.com/simplifying-spatial-polygons-in-r
ск

1
Не st_simplifyповинен цього робити? (поки не користувався ним)
lbusett

2
ой, я не помітив st_simplify, дякую, що вказав на це. Я віддаю перевагу алгоритму, який rmapshaper::ms_simplifyза замовчуванням застосовується над усіма іншими, які я намагався до цього часу, але я буду грати з новою опцією (оновлення: хто продовжувати обережно, preserveTopology = TRUEточно не працює належним чином)
obrl_soil

1
Добре знати. Що щодо відкриття звіту про помилку щодо цього?
lbusett

1
@obrl_soil Це працює на допуски до приблизно 1000 на полігонах, які я використовував у питанні ( regions), але крім цього він більше не зберігає топологію. Оскільки це порушується в певний момент, я б сказав, що це не призначена поведінка
Phil

Відповіді:


16

Ви можете передати об'єкт sf до sp для пакетів, які ще не підтримують sf - я роблю це неабияк для растрових / полігонових взаємодій. Отже, ви можете зробити:

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

1
Цей прийом - кастинг як просторовий об'єкт, спрощення, потім повторне кастинг як sfоб'єкт - працював ідеально, і його можна використовувати з rmapshaper::ms_simplify()або rgeos::gSimplify(). Дякую за пропозицію!
Філ

Класно круто, просто слід пам’ятати, що топологія перемикаючих багатокутників справді зберігається лише з підходом rmapshaper. Якщо ваші вхідні дані - це всі ізольовані, непомітні багатокутники, ви можете сміливо використовувати будь-які доступні спрощення спрощення.
obrl_soil

Я приймаю це як відповідь, оскільки більш канонічне sf::st_simplify()не є надійним при високих допусках на момент написання, хоча очевидно це може змінитися.
Філ

8
Зараз я працюю над підтримкою sfоб’єктів у rmapshaper . ms_simplifyдоступний для sfоб'єктів у версії розробки. Я хотів би ранні тестери - якщо ви хочете спробувати його, можете встановити за допомогоюdevtools::install_github("ateucher/rmapshaper", ref = "sf")
andyteucher

6
Починаючи з rmapshaperверсії 0.3.0, заклик до as( , "Spatial")більше не потрібно.
Лука1018
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.