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?

  • 1
    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, 2012 at 21:11
  • Thanks, I edited and add figures for better description. Sep 26, 2012 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, 2012 at 21:13
  • Ok, editing: now I am illustrating at first paragraphs, inputs and outputs. Sep 27, 2012 at 0:06
  • 1
    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, 2012 at 0:36

1 Answer 1


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(
  'POLYGON((150 90,130 54,100 40,63 53,50 90,40 124,99 140,155 126,150 90))')
);    -- 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.