简化SF对象的多边形


14

如何在sf不引入间隙和裂缝的情况下简化多边形?

以shapefile为例,我将使用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()手册页中指出的内容:

将几何体转换为另一种类型:简化或显式转换

和:

争论:性格 目标类型,如果缺少,则尝试简化;当x为sfg类型(即单个几何)时,则需要指定to。

当我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()

rgeos::gSimplify()当使用以下参数指定时,@sk的建议可以进行拓扑感知的简化(即在不创建条的情况下进行简化):

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
您可以使用Douglas–Peucker算法吗?GIS世界中的功能简化已广为人知。stackoverflow.com/questions/17217413/...r-bloggers.com/simplifying-spatial-polygons-in-r
SK

1
st_simplify应该那样做吗?(尚未使用)
lbusett

2
哦,我没有注意到st_simplify,谢谢指出。我确实更喜欢rmapshaper::ms_simplify默认算法,而不是到目前为止我尝试过的所有其他算法,但是我会尝试使用新选项(更新:哇,谨慎行事,preserveTopology = TRUE肯定还不能正常工作)
obrl_soil

1
很高兴知道。打开对此的错误报告该怎么办?
lbusett

1
@obrl_soil在我在问题(regions)中使用的多边形上,它的公差最高可达1000,但超出此范围,它将不再保留拓扑。当它在某个特定时刻中断时,我会说这不是故意的行为
Phil

Answers:


16

对于尚不支持sf的程序包,可以将sf对象转换为sp-对于栅格/多边形交互,我可以这样做。因此,您可以执行以下操作:

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

1
这项技术-投射为空间对象,进行简化,然后重新铸造为sf对象-可以完美地工作,并且可以与rmapshaper::ms_simplify()或一起使用rgeos::gSimplify()。谢谢你的建议!
菲尔(Phil)

太棒了,请注意,只有使用rmapshaper的方法才能真正保留互锁多边形的拓扑。如果输入数据都是孤立的,非互锁的多边形,则可以安全地使用任何可用的简化算法。
obrl_soil

我接受这作为答案,因为在sf::st_simplify()撰写本文时,规范性强的工具在高公差下并不可靠,尽管显然这可能会改变。
菲尔(Phil)

8
我目前正在努力支持rmapshaper中的sf对象。适用于开发版本中的对象。我很喜欢早期测试人员-如果您想尝试一下,可以使用ms_simplifysfdevtools::install_github("ateucher/rmapshaper", ref = "sf")
andyteucher

6
rmapshaper0.3.0版本开始,as( , "Spatial")不再需要调用。
路加福音1818年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.