Emma--
Can you show sessionInfo(), specifically your versions of R and rgeos?

There was a previous thread in R-sig-geo starting Oct 3, 2013 on negative
buffering, where Roger Bivand, Barry Rowlingson, Robert Hijmaans, and Edzer
Pebesma all chimed in.
https://stat.ethz.ch/pipermail/r-sig-geo/2013-October/019470.html

The issue is that what GEOS does when negative buffering removes the
geometry of a polygons object, which cascades to whether NULL geometries
should be supported in sp objects.  [Part of the issue is that what GEOS
does isn't particularly well-documented.]  rgeos 0.3-2 changed this
behavior from that of 0,3-1, and now removes empty output GEOM objects
(null polygons) before returning a valid sp object.

So, you probably don't need your explicit check for vanished polygons.
 Roger's fix to the C code in gBuffer was much better than my approach to
error trapping in the R code of gBuffer, and worked for my use case of
negative buffering of vegetation polygons (and for polygons with narrow
waists that shrink to become multi-part).

I recall something in the emails last October about allowing a vector of
buffer widths to support your use case of different buffer widths for
different polygons, and I see in the man page for gBuffer in rgeos 0.3-2
that width can be a vector if byid=TRUE.

I hope that this helps.

Tom 2





On Fri, Apr 4, 2014 at 8:28 AM, Jon Olav Skoien <jon.skoien@jrc.ec.europa.eu
> wrote:

> Emma,
>
> I don't know what has changed in rgeos, anyway, your current problem seems
> to be the way you assign the results of gBuffer to a list. gBuffer will
> frequently return NULL (probably the vanishing polygons), which removes
> this element from the list if you try to assign. A simplified example:
>
> aa <- vector("list",10)
> for (i in 1:10) {
>   aa[[i]] <- NULL
>   print(paste(i, length(aa)))
> }
> aa
>
> You can for example try to replace the assignment with
>   bb <- gBuffer(spdf[i,], width=widths[i], capStyle="ROUND")
>     if (!is.null(bb)) buffs[[i]] = bb
>  although you will also have to update your Filter function, as bbox will
> not work on NULL-objects.
>
> Best wishes,
> Jon
>
>
>
>
> On 04-Apr-14 16:20, Brooks E.G.E. wrote:
>
>> Dear List Members
>>
>> Several months ago I wrote a code to buffer a SpatialPolygonsDataFrame.
>> Each attribute of the SPDF needed to be buffered by a different amount
>> (defined by one of the columns within the SPDF), some of which were
>> negative. Some of the negative buffers were large enough to warrant the
>> vanishing of that particular polygon. Since gBuffer on its own could not
>> deal with these aspects, the code included a function which would buffer
>> each polygon individually, add the outputs to a list, remove any features
>> which no longer existed, then convert it back to a SPDF. However I have
>> come back to my code and it no longer works with negative buffers, even on
>> the original datasets. It now produces the following error:
>>
>> Error in names(buffs)[i] <- ID[i] :
>>    'names' attribute [1598] must be the same length as the vector [1597]
>>
>> even though the length of the SPDF is 1747. It does however still work
>> for positive only buffers. The only thing I can think of is that gBuffer
>> has been updated and now deals with vanishing features differently but I
>> have not been able to adapt the code to make it work. Since all elements of
>> the function come from the same object I don't understand how attributes
>> are ending up at different lengths. Also, if I manually do the function
>> step by step, the attributes remain at 1747 and I am not able to reproduce
>> the same error so I am very confused.
>>
>> Here is a reproduction of the code:
>>
>> library(Guerry)
>> data(gfrance)
>>
>> bufferby <- function(spdf,widths,ID){
>>    library(rgeos)
>>    #Create empty buffer list based on spdf
>>    buffs<-vector("list",length(spdf))
>>    #For every item in spdf,
>>    for(i in seq_len(length(spdf))){
>>      #Loop buffer each polygon individually based on widths, and add to
>> 'list'
>>      buffs[[i]] <- gBuffer(spdf[i,], width=widths[i], capStyle="ROUND")
>>      #Name each object in list by ID
>>      names(buffs)[i] <- ID[i]
>>    }
>>    #Filter results by those that worked (i.e. exclude any 'vanished'
>> buffers)
>>    buffs=Filter(function(x){!is.null(bbox(x))},buffs)
>>    #Convert the filtered results to SP
>>    buffsSP<-SpatialPolygons(lapply(1:length(buffs), function(i) {
>>      Pol <- slot(buffs[[i]], "polygons")[[1]]
>>      #Add names to be able to link to other datasets
>>      slot(Pol, "ID") <- names(buffs)[i]
>>      Pol
>>    }))
>>    #Project output (SP) based on input (spdf)
>>    proj4string(buffsSP)<-CRS(projection(spdf))
>>    buffsSP
>> }
>>
>> #Create widths defining column, including negatives
>> gfrance$buffwid<- runif(length(gfrance), min=-200000, max=20000)
>>
>> newbuffs<-bufferby(gfrance,gfrance$buffwid,gfrance$Department)
>> plot(newbuffs)
>>
>> If I define "widths" as a column with only positive values it works fine,
>> but it no longer works if any of the negative features vanish.
>>
>> N.B. This function should (and did) also work for SpatialPoints.
>>
>> Many thanks for any help, and your time.
>>
>> Emma
>>
>>         [[alternative HTML version deleted]]
>>
>> _______________________________________________
>> R-sig-Geo mailing list
>> R-sig-Geo@r-project.org
>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>
>
>
> --
> Jon Olav Skøien
> Joint Research Centre - European Commission
> Institute for Environment and Sustainability (IES)
> Land Resource Management Unit
>
> Via Fermi 2749, TP 440,  I-21027 Ispra (VA), ITALY
>
> jon.skoien@jrc.ec.europa.eu
> Tel:  +39 0332 789205
>
> Disclaimer: Views expressed in this email are those of the individual and
> do not necessarily represent official views of the European Commission.
>
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo@r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

	[[alternative HTML version deleted]]

