I've been following this with some interest as it's an interesting problem. I really like Thierry's solution and I think that he's right in that it should converge across most cases I can think of. I was concerned it would have problems with complex, multi-part polygons or polygons with holes, but I think I've convinced myself that it won't. Very nicely done! I've included a fully working example with a polygon with holes and a small ratio of 2:1:
require(rgeos) spgeom <- readWKT("MULTIPOLYGON(((10 10, 110 10, 110 110, 10 110, 10 10), (20 40, 20 80, 80 80, 80 40, 20 40), (40 20, 40 30, 50 30, 50 20, 40 20)))") plot(spgeom) ratio <- 2 precision <- 1e-6 maxsteps <- 1000 buffer.width <- 100 spgeom.area <- gArea(spgeom) achieved.precision <- 1 steps <- 0 buffered.spgeom <- spgeom while(abs(achieved.precision) > precision & steps < maxsteps) { buffered.perimeter <- gLength(buffered.spgeom) buffer.width <- buffer.width - (achieved.precision * spgeom.area / buffered.perimeter) buffered.spgeom <- gBuffer(spgeom, width=buffer.width) buffered.spgeom.area <- gArea(buffered.spgeom) achieved.precision <- buffered.spgeom.area / spgeom.area - ratio steps <- steps + 1 } plot(buffered.spgeom) -- Forrest R. Stevens Ph.D. Candidate, QSE3 IGERT Fellow Department of Geography Land Use and Environmental Change Institute University of Florida www.clas.ufl.edu/users/forrest On Wed, May 28, 2014 at 6:30 PM, ONKELINX, Thierry <thierry.onkel...@inbo.be > wrote: > Hi Barry, > > I think it is guaranteed to converge. The first estimate of the buffer > width is the extra area divided by the perimeter. That would be to large in > most cases. The adjustments are based on the difference between the target > area and the last buffered area and the perimeter of the last buffer. So > the buffer width is only updated based on the last errors. > > I have tried the examples below. A starlike polygon, a rectangle and a U > shape, all very thin. I applied a large buffer (1e6). It takes 11, 12 and > 12 steps to converge (precision < 1e-7). With small buffers like 1.1 only a > few steps are needed. > The algorithm starts hopping around when the precision < 1e-7). I think > that is due to the precision of gBuffer(), gArea() and/or gLength(). On the > other hand: a precision of 0.00001% seems acceptable to me. > > spgeom <- readWKT("POLYGON((1 0, 10000 10000, 0 1, -10000 10000, -1 0, > -10000 -10000, 0 -1, 10000 -10000, 1 0))") > spgeom <- readWKT("POLYGON((0 0, 0 10000, 1 10000, 1 0, 0 0))") > spgeom <- readWKT("POLYGON((0 0, 0 10000, 1 10000, 1 1, 2 1, 2 10000, 3 > 10000, 3 0, 0 0))") > ratio = 1e6 > > Best regards, > > Thierry > > ir. Thierry Onkelinx > Instituut voor natuur- en bosonderzoek / Research Institute for Nature and > Forest > team Biometrie & Kwaliteitszorg / team Biometrics & Quality Assurance > Kliniekstraat 25 > 1070 Anderlecht > Belgium > + 32 2 525 02 51 > + 32 54 43 61 85 > thierry.onkel...@inbo.be > www.inbo.be > To call in the statistician after the experiment is done may be no more > than asking him to perform a post-mortem examination: he may be able to say > what the experiment died of. ~ Sir Ronald Aylmer Fisher > The plural of anecdote is not data. ~ Roger Brinner > The combination of some data and an aching desire for an answer does not > ensure that a reasonable answer can be extracted from a given body of data. > ~ John Tukey > > ________________________________________ > Van: b.rowling...@gmail.com [b.rowling...@gmail.com] namens Barry > Rowlingson [b.rowling...@lancaster.ac.uk] > Verzonden: woensdag 28 mei 2014 18:18 > Aan: ONKELINX, Thierry > CC: Julie Lee-Yaw; r-sig-geo@r-project.org > Onderwerp: Re: [R-sig-Geo] How to buffer a polygon by area > > On Wed, May 28, 2014 at 3:36 PM, ONKELINX, Thierry > <thierry.onkel...@inbo.be> wrote: > > > while(abs(achieved.precision) > precision & steps < maxsteps){ > > buffered.perimeter <- gLength(buffered.spgeom) > > buffer.width <- buffer.width - achieved.precision * spgeom.area / > > buffered.perimeter > > buffered.spgeom <- gBuffer(spgeom, width = buffer.width) > > achieved.precision <- gArea(buffered.spgeom) / spgeom.area - ratio > > steps <- steps + 1 > > } > > Is this guaranteed to converge? Could there be some polygon for which > the buffer width updating step bounces between two values like the > bistable state of an iterated function? Could a concave polygon have a > smaller perimeter for a larger buffer size? I think yes, but I'm not > sure if that would cause this method to not converge anyway... > > My binary search is guaranteed to converge since buffer area is > strictly increasing with increasing buffer width... > > Barry > * * * * * * * * * * * * * D I S C L A I M E R * * * * * * * * * * * * * > Dit bericht en eventuele bijlagen geven enkel de visie van de schrijver > weer en binden het INBO onder geen enkel beding, zolang dit bericht niet > bevestigd is door een geldig ondertekend document. > The views expressed in this message and any annex are purely those of the > writer and may not be regarded as stating an official position of INBO, as > long as the message is not confirmed by a duly signed document. > > _______________________________________________ > R-sig-Geo mailing list > R-sig-Geo@r-project.org > https://stat.ethz.ch/mailman/listinfo/r-sig-geo > [[alternative HTML version deleted]] _______________________________________________ R-sig-Geo mailing list R-sig-Geo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-geo