【问题标题】:Extracting the parent polygon from a nested SpatialPolygonsDataFrame or 'Dissolving' holes from a parent ploygon从嵌套的 SpatialPolygonsDataFrame 中提取父多边形或从父多边形中“溶解”孔
【发布时间】:2015-06-07 21:33:39
【问题描述】:

编辑经过更多研究但仍然没有解决方案,我正在添加大量编辑以及指向 .shp 文件的链接。

The shape file is included here

我有一个包含 9 个多边形的 SpatialPolygonsDataFrame,每个多边形还包含多个嵌套多边形 - “孔”。数据摘要在这里。

> summary(data)
Object of class SpatialPolygonsDataFrame
Coordinates:
        min       max
x  483298.9  643204.4
y 4782172.1 4997248.3
Is projected: TRUE 
proj4string :
[+proj=utm +zone=12 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0]
Data attributes:
       Id          IndID  
 Min.   :0   BHS_011_A:1  
 1st Qu.:0   BHS_015_A:1  
 Median :0   BHS_083_A:1  
 Mean   :0   BHS_089_A:1  
 3rd Qu.:0   BHS_091_A:1  
 Max.   :0   BHS_129_A:1  
             (Other)  :3  

structure 的数据示例如下。

Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
  ..@ data       :'data.frame': 9 obs. of  2 variables:
  .. ..$ Id   : int [1:9] 0 0 0 0 0 0 0 0 0
  .. ..$ IndID: Factor w/ 9 levels "BHS_011_A","BHS_015_A",..: 1 2 3 4 5 6 7 8 9
  ..@ polygons   :List of 9
  .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
  .. .. .. ..@ Polygons :List of 5
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 513497 4986246
  .. .. .. .. .. .. ..@ area   : num 76614017
  .. .. .. .. .. .. ..@ hole   : logi FALSE
  .. .. .. .. .. .. ..@ ringDir: int 1
  .. .. .. .. .. .. ..@ coords : num [1:287, 1:2] 509244 507384 507214 507010 506899 ...
  .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. .. .. .. .. .. ..$ : NULL
  .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 509678 4979511
  .. .. .. .. .. .. ..@ area   : num 1462398
  .. .. .. .. .. .. ..@ hole   : logi TRUE
  .. .. .. .. .. .. ..@ ringDir: int -1
  .. .. .. .. .. .. ..@ coords : num [1:7, 1:2] 509301 509269 509194 509007 509412 ...
  .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. .. .. .. .. .. ..$ : NULL
  .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 515572 4988493
  .. .. .. .. .. .. ..@ area   : num 1579348
  .. .. .. .. .. .. ..@ hole   : logi TRUE
  .. .. .. .. .. .. ..@ ringDir: int -1
  .. .. .. .. .. .. ..@ coords : num [1:10, 1:2] 514520 514570 514684 516501 515996 ...
  .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. .. .. .. .. .. ..$ : NULL
  .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"

如下例所示(九个之一),父多边形有多个孔。

data <- readOGR(".", "IndLineBuff")
plot(data[data$IndID == "MTG_005_A",])

这是我第一次涉足sp()rgdal()rgeos() 和其他空间包,我发现了许多关于使用运算符提取区域等有用的帖子,但仍然存在问题保持。虽然this post 提供了接近的解决方案,但我似乎无法调整代码以满足此处描述的需求。

我想获得一个 SpatialPolygonsDataFrame,它只包含来自每组子列表(即 data@polygon)的父(最大)多边形。看来我应该能够只提取父多边形或“溶解”这些洞。

最终结果将是 9 个多边形,每个都是 9 个列表的父级,我可以将其导出为 ESRI shapefile。

任何建议将不胜感激。

【问题讨论】:

    标签: r spatial rgdal sp maptools


    【解决方案1】:

    当我第一次了解 sp 和相关软件包时,我发现 Barry Rowlingson 的网站非常有用。

    它包括:

    回答您的问题,这很混乱,因为您正在处理事物列表的列表,但可以做到。

    以下代码似乎可以工作(我已经在我已经拥有的 shapefile 上测试了它(一个 bit),而不是下载你的)。如果您在阅读后将 NSWACTA 替换为 shapefile 的名称,它应该适用于您的情况。虽然没有承诺:-)。

    第一部分是介绍性的,展示所有类列表的情况。希望这可以帮助您弄清楚发生了什么。它是 dropHole 函数,它的方法实际上可以满足您的需求。

    class(NSWACTA)
    # NSWACTA has class sp::SpatialPolygonsDataFrame
    slotNames(NSWACTA)
    # The SpatialPolygonsDataFrame has a slot called @polygons
    class(NSWACTA@polygons)
    # The @polgyons slot contains a list
    class(NSWACTA@polygons[[1]])
    # Elements of that list are of class sp::Polygons 
    slotNames(NSWACTA@polygons[[1]])
    # An sp::Polygons class has several slots, one of which is @Polygons
    class(NSWACTA@polygons[[1]]@Polygons)
    # The @Polygons slot contains a list
    class(NSWACTA@polygons[[1]]@Polygons[[1]])
    # The entries in the @Polygons list are of class sp::Polygon
    slotNames(NSWACTA@polygons[[1]]@Polygons[[1]])
    # An sp::Polygon has several slots. 
    # @coords holds the coordinates which define the boundary.
    # @hole is a logical field indicating whether or not the sp::Polygon is a hole 
    
    setGeneric('dropHole',def=function(poly, ...){
      standardGeneric('dropHole')
    })
    
    # Drop a single sp::Polygon if it is holey
    setMethod('dropHole',signature=signature('Polygon'),
              def=function(poly) {
                #return only Polygons which are not holes
                if (poly@hole) NULL else poly
              }
              )
    
    # Drop holey sp::Polygon entries in the @Polygons list of an sp::Polygons class
    setMethod('dropHole', signature = signature('Polygons'),
              def = function(poly) {
                noHoles <- lapply(poly@Polygons, dropHole)
                #Remove the NULL entries from the list
                noHoles <- Filter(Negate(is.null), noHoles)
                # Turn back into a (single) Polygons
                # The generator function (sp::Polygons) fills in the other slots!
                # return the new sp:Polygons object
                sp::Polygons(noHoles, ID = poly@ID)
              }
              )
    
    # Drop holey parts of sp::Polygons in the @polygons list 
    # of an sp::SpatialPolygonsDataFrame
    setMethod('dropHole', signature = signature('SpatialPolygonsDataFrame'),
              def = function(poly) {
                noHoles <- lapply(poly@polygons, dropHole)
                # Put the un holey Polygons list back into the @polygons slot 
                poly@polygons <- noHoles
                #return the modified SpatialPolygonsDataFrame 
                poly
              }
              )
    
    newmap <- dropHole(NSWACTA)
    

    这是第一部分的输出。 注意注意名称的大小写以及单数和复数之间的区别! (即多边形、多边形、多边形)

    d> class(NSWACTA)
    [1] "SpatialPolygonsDataFrame"
    attr(,"package")
    [1] "sp"
    d> # NSWACTA has class sp::SpatialPolygonsDataFrame
    d> slotNames(NSWACTA)
    [1] "data"        "polygons"    "plotOrder"   "bbox"        "proj4string"
    d> # The SpatialPolygonsDataFrame has a slot called @polygons
    d> class(NSWACTA@polygons)
    [1] "list"
    d> # The @polgyons slot contains a list
    d> class(NSWACTA@polygons[[1]])
    [1] "Polygons"
    attr(,"package")
    [1] "sp"
    d> # Elements of that list are of class sp::Polygons 
    d> slotNames(NSWACTA@polygons[[1]])
    [1] "Polygons"  "plotOrder" "labpt"     "ID"        "area"     
    d> # An sp::Polygons class has several slots, one of which is @Polygons
    d> class(NSWACTA@polygons[[1]]@Polygons)
    [1] "list"
    d> # The @Polygons slot contains a list
    d> class(NSWACTA@polygons[[1]]@Polygons[[1]])
    [1] "Polygon"
    attr(,"package")
    [1] "sp"
    d> # The entries in the @Polygons list are of class sp::Polygon
    d> slotNames(NSWACTA@polygons[[1]]@Polygons[[1]])
    [1] "labpt"   "area"    "hole"    "ringDir" "coords" 
    d> # An sp::Polygon has several slots. 
    d> # @coords holds the coordinates which define the boundary.
    d> # @hole is a logical field indicating whether or not the sp::Polygon is a hole
    

    【讨论】:

      【解决方案2】:

      以下 hack 可能会起作用:

      data@polygons = lapply(data@polygons, function(x) { x@Polygons = x@Polygons[1]; x})
      plot(data[data$IndID == "MTG_005_A",])
      

      在您的情况下,您似乎已经缓冲了线性要素左右,并且希望消除由此产生的多边形中的孔洞。 9 个多边形中的每一个似乎都由主多边形和一组整体组成。该函数选择此列表的第一个,返回所需的列表列表。要了解类结构,请仔细研究?"SpatialPolygons-class"?"Polygons-class"?"Polygon-class"

      【讨论】:

      • 不错。非常光滑。你介意添加一些细节来帮助我理解这个功能吗?您的代码运行良好,但引入了一个新问题。例如,现在对 gArea(data, byid = T) 进行编码会导致以下错误“RGEOSMiscFunc(spgeom, byid, "rgeos_area") 中的错误:注释和多边形槽的长度不同。”是否可以在不丢失功能的情况下“破解” data@polygons?
      • 非常有帮助。谢谢。
      猜你喜欢
      • 2012-09-21
      • 2021-03-05
      • 2015-06-19
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      相关资源
      最近更新 更多