Search code examples
geospatialspatialr-rasterrgeo

Dissolve output of rasterToPolygons


When using rasterToPolygons within the raster package each cell that meets the formula criteria becomes its own polygon:

library(raster)
r <- raster(nrow=18, ncol=36)
r[] <- runif(ncell(r)) * 10
r[r>8] <- NA
pol <- rasterToPolygons(r, fun=function(x){x>6})
plot(pol)

I however want each polygon that has an adjacent side or corner to be part of one larger polygon, decreasing the number of total polygons. Is there any way to accomplish this?


Solution

  • This can be accomplished by using the poly2nb function in the spdep package to define the neighbors of each polygon, using the function created below to create a vector of region assignments, using spCbind from the maptools package to bind regions to pol, then finally dissolving over regions using the unionSpatialPolygons function from maptools. The basic structure of the created function is if at least one of the polygon's neighbors has been assigned to a group then assign polygon and neighbors to that group else assign polygon and neighbors to new group.

    library(raster)
    library(spdep)
    library(maptools)
    
    r <- raster(nrow=18, ncol=36)
    r[] <- runif(ncell(r)) * 10
    r[r>8] <- NA
    pol <- rasterToPolygons(r, fun=function(x){x>6}, dissolve = T)
    plot(pol)
    
    nb <- poly2nb(pol)
    
    create_regions <- function(data) {
      group <- rep(NA, length(data))
      group_val <- 0
      while(NA %in% group) {
        index <- min(which(is.na(group)))
        nb <- unlist(data[index])
        nb_value <- group[nb]
        is_na <- is.na(nb_value)
        if(sum(!is_na) != 0){
          prev_group <- nb_value[!is_na][1]
          group[index] <- prev_group
          group[nb[is_na]] <- prev_group
        } else {
          group_val <- group_val + 1
          group[index] <- group_val
          group[nb] <- group_val
        }
      }
      group
    }
    
    region <- create_regions(nb)
    pol_rgn <- spCbind(pol, region)
    pol2 <- unionSpatialPolygons(pol_rgn, region)
    plot(pol2)