Take the 2-minute tour ×

If I have a polygonal geometry gbase, like a street (a rectangular strip), and a reference geometry gref, like a central line of gbase. The question is what is the function (here named BestBuffer) that returns a geometry gbest,

gbest = BestBuffer(gbase, gref [,p])

that is the "best fit" for gbase and can be generated from gref by a ST_Buffer (optionally with a shape parametrized by p)?


Formally this is a mathematical optimization problem:

Given: inputs gref and gbase (optional p) and,

gbest = ST_Buffer(gref,w,p)

Sought: parameter w that supply

ST_Area(gbest) = ST_Area(gbase)

NOTE: I think BestBuffer can be a "standard library" function (where is it? please show sources/references), not a external plugin, because the estimation checks are all standard OGC build-in functions.


BestBuffer when gref is a POINT

Illustrating by the trivial case, the buffer of point, that have exact solution:

enter image description here

is the same as "fit a polygon to a square of equal area" (or a circle).

Inputs: gbase a (blue) island, gref is only a point, gref=ST_Centroid(gbase), or another position, and the parameter N, that can be 1 for square and 8 for circle.

Results (pink):

  gbest_square = bestBuffer(gbase,ST_Centroid(gbase),1);
  gbest_circle = bestBuffer(gbase,anotherpoint,8);

You can approximate gbase to gbest without change original area.

BestBuffer when gref is a LINE

Illustrating with the Massachusetts avenue,

    the Massachusetts avenue

gbase and gref

Inputs: gbase, a polygon of a street, gref a (blue) center line in it, and the choice of shape (no endcaps)

Result of gbest=bestBuffer(gbase,gref,'endcap=flat')


is a rectangle (gbest). It is the "best buffer about gref" for Massachusetts avenue, filling the same area as gbase.

Another cases where you may need to draw BestBuffer of polygons and its central lines: when need to show streets, sidewalks, rivers, etc. with uniform width, instead real/irregular ones.

BestBuffer when gref is a POLYGON

enter image description here

In the above illustration, the blue polygon represents a island with your beach, as gbase, and gref the same island without the beach. gbest0 is the "best buffer" for gbase.

Inputs: gbase (blue), gref a (gray). Can be rendered as ST_Difference(gbase,gref), that represent beachs.

Result: gbest0=bestBuffer(gbase,gref), but we want to render as (gbest),

  gbest =  ST_Difference(gbest0,gref)

The goal of the buffer of gref is to generate the "beach geometry", even if gbest not generates an exact gbase-gref geometry: it is a good approximation and have uniform width w, the average width of gbase-gref (w is mean beach width).


Fit the "best curve" about a set of points in an XY chart is a classical statiscal problem, have classical solutions, and have a lot of tools for it. Similarly the "best curve about another curve" is usual when the "best" is a simple one, like a straight line, a parabola, etc. To fit irregular/complex lines
Cubic spline lines are frequently used.

Where are the standard functions tools for "fit the best polygon in a GIS context"? Are there standard libraries? For generic statistical problems we have external packages that can be integrated with postgreSQL and PostGIS...

But for built-in functions: ST_Buffer is a standard function, why not a function BestBuffer in a complementary library?

share|improve this question
Despite the length and detail of this question, I am unable to find a definition or even a clear description of what BestBuffer is supposed to do. Could you perhaps give an example? –  whuber Sep 25 '12 at 21:11
Thanks, I edited and add figures for better description. –  Peter Krauss Sep 26 '12 at 1:52
I still cannot discern a definite problem here. You state, "The goal of the buffer of gref is to generate the beach geometry." Obviously that cannot be done without additional information; for instance, it sounds like you are asking to negatively buffer a polygon and that requires you to stipulate the buffer distance. What, precisely, do you hope the inputs and outputs of your procedure to be? –  whuber Sep 26 '12 at 21:13
Ok, editing: now I am illustrating at first paragraphs, inputs and outputs. –  Peter Krauss Sep 27 '12 at 0:06
Thank you; it is becoming clearer with your example of Massachusetts Avenue. But in what sense is this rectangle "best"? It's not even a true buffer (the ends are clipped instead of rounded) and it seems likely that the buffer of a slightly nonlinear curve might match the original polygon a little better. –  whuber Sep 27 '12 at 0:36
show 1 more comment

1 Answer

up vote 1 down vote accepted

I think if we have a good solution for this other problem (it supplies a buffer_width estimation function) we will also have a simple solution here.

Possible solution when gref is a POLYGON

Using the example of the question illustration,

wbest  = buffer_width(gbase,gref,p); -- estimation
gbest0 = ST_Buffer(gref,wbest,p);
gbest  = ST_Difference(gbest0,gref);

where to use the optional parameterp, you must have a a priory knowledge about the buffer shape/style (like parameters quad_seg, endcap, and join).

Solution when gref is a LINE and gbase a strip

There are restrictions for a generalized use, but is stable for strips (shapes near to a "rectangular strip").

wbest = buffer_width(gbase,gref,0.0,'endcap=flat'); -- estimation
gbest = ST_Buffer(gref,wbest,'endcap=flat');

See question illustration for details.

Solution solution when gref is a POINT

For this trivial case (buffering a central point) a solution exists (!):

gbest = ST_Buffer(ST_Centroid(gbase),buffer_width(gbase,quad_segs),quad_segs) 

where the buffer_width function is the best average width estimator for point-buffers; and quad_segs is a "shape factor" (default is a circle). Below piece of code with a concrete example:

SELECT buffer_width(ST_GeomFromText(
  'POLYGON((150 90,130 54,100 40,63 53,50 90,40 124,99 140,155 126,150 90))'
),2); -- 53.6
SELECT ST_Area(ST_Buffer(ST_GeomFromText('POINT(100 90)'),53.6,'quad_segs=2'));
      -- 8126
SELECT ST_Area(ST_GeomFromText(
);    -- 8126

the polygon is a very deformated octagon, but the buffer generates a regular octagon with the same area, by w=53.6 estimated by the buffer_width function.

share|improve this answer
add comment

Your Answer


