[R-sig-Geo] Remove holes from a SpatialPolygon

Roger Bivand Roger.Bivand at nhh.no
Wed Jan 1 18:27:39 CET 2014


On Tue, 31 Dec 2013, Mark Payne wrote:

> Hi,
>
> I have a SpatialPolygon that I have created through a series of
> processing steps. The SP consists of one outer-boundary, with a series
> of holes punched in it - think of it as the coastline of an island
> with a series of lakes in it. However, I am only interested in the
> "external" coastline and don't want the "lakes". How do I best remove
> these holes?

For reproducibility:

library(maptools)
NZy <- c(-53,-29)
NZx <- c(160,180)
NZ <- Rgshhs(gshhs.c.b, xlim=NZx, ylim=NZy, level=2)$SP
NZp <- slot(NZ, "polygons")
holes <- lapply(NZp, function(x) sapply(slot(x, "Polygons"), slot,
   "hole"))
res <- lapply(1:length(NZp), function(i) slot(NZp[[i]],
   "Polygons")[!holes[[i]]])
IDs <- row.names(NZ)
NZfill <- SpatialPolygons(lapply(1:length(res), function(i)
   Polygons(res[[i]], ID=IDs[i])), proj4string=CRS(proj4string(NZ)))

Using the creation functions should ensure reasonable reconstruction, with 
two reservations:

1) this provides no protection against an exterior ring nesting inside 
another exterior ring, so needing a hole to avoid overlapping, and

2) this doesn't secure the correct construction of comments, needed by 
GEOS/rgeos to place interior rings in the correct exterior rings.

You can handle the latter (and possibly your error with your code), by 
assigning comments or by removing them:

slot(NZfill, "polygons") <- lapply(slot(NZfill, "polygons"),
   checkPolygonsHoles)

will assign comments, seen by:

lapply(slot(NZfill, "polygons"), comment)

or remove them by:

slot(NZfill, "polygons") <- lapply(slot(NZfill, "polygons"),
   "comment<-", NULL)

In rgeos, a NULL comment forces the internal generation of comments, the 
correct comments in the Polygons objects avoid using time to do this, but 
stale comments (like yours) are not corrected, and generate an error.

It is hard to keep track if you don't learn to like and use *apply.

Hope this helps,

Roger

>
> Here is what I have tried so far (bufr is the object of interest)
>
> holes <- sapply(bufr at polygons[[1]]@Polygons,slot,"hole")
> bufr.hole.free <- bufr
> bufr.hole.free at polygons[[1]]@Polygons <-
> bufr.hole.free at polygons[[1]]@Polygons[!holes]
> bufr.hole.free at polygons[[1]]@plotOrder <-
> as.integer(rank(bufr.hole.free at polygons[[1]]@plotOrder[holes]))
>
> However, this fails when I try to use it later with rgeos:
>
> roi.raw <- gDifference(bufr.hole.free,borders)
> Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_difference") :
>  lengths of comment and Polygons slot differ
>
>
> How should I remove the holes in a manner that maintains the integrity
> of the SpatialPolygons class?
>
> Mark
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

-- 
Roger Bivand
Department of Economics, Norwegian School of Economics,
Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; fax +47 55 95 95 43
e-mail: Roger.Bivand at nhh.no



More information about the R-sig-Geo mailing list