ST_Buffer — Computes a geometry covering all points within a given distance from a geometry.
geometry ST_Buffer(geometry g1, float radius_of_buffer, text buffer_style_parameters = '');
geometry ST_Buffer(geometry g1, float radius_of_buffer, integer num_seg_quarter_circle);
geography ST_Buffer(geography g1, float radius_of_buffer, text buffer_style_parameters);
geography ST_Buffer(geography g1, float radius_of_buffer, integer num_seg_quarter_circle);
Computes a POLYGON or MULTIPOLYGON that represents all points whose distance from a geometry/geography is less than or equal to a given distance. A negative distance shrinks the geometry rather than expanding it. A negative distance may shrink a polygon completely, in which case POLYGON EMPTY is returned. For points and lines negative distances always return empty results.
For geometry, the distance is specified in the units of the Spatial Reference System of the geometry. For geography, the distance is specified in meters.
The optional third parameter controls the buffer accuracy and style. The accuracy of circular arcs in the buffer is specified as the number of line segments used to approximate a quarter circle (default is 8). The buffer style can be specified by providing a list of blank-separated key=value pairs as follows:
'quad_segs=#' : number of line segments used to approximate a quarter circle (default is 8).
'endcap=round|flat|square' : endcap style (defaults to "round"). 'butt' is accepted as a synonym for 'flat'.
'join=round|mitre|bevel' : join style (defaults to "round"). 'miter' is accepted as a synonym for 'mitre'.
'mitre_limit=#.#' : mitre ratio limit (only affects mitered join style). 'miter_limit' is accepted as a synonym for 'mitre_limit'.
'side=both|left|right' : defaults to 'both'. 'left' or 'right' performs a single-sided buffer on the geometry, with the buffered side relative to the direction of the line. This is only applicable to LINESTRING geometry and does not affect POINT or POLYGON geometries. By default end caps are square when 'left' or 'right' are specified.
|
|
|
|
|
|
|
Buffer can handle invalid inputs and the output is always a valid polygonal geometry. Buffering by distance 0 is sometimes used as a way of repairing invalid polygons. ST_MakeValid is more suitable for this process as it can handle multi-polygons. |
|
|
|
Buffering is sometimes used to perform a within-distance search. For this use case it is more efficient to use ST_DWithin. |
|
|
|
This function ignores the Z dimension. It always gives a 2D result even when used on a 3D geometry. |
Enhanced: 2.5.0 - ST_Buffer geometry support was enhanced to allow for side buffering specification side=both|left|right.
Availability: 1.5 - ST_Buffer was enhanced to support different endcaps and join types. These are useful for example to convert road linestrings into polygon roads with flat or square edges instead of rounded edges. Thin wrapper for geography was added.
Performed by the GEOS module.
This method implements the OGC Simple Features
Implementation Specification for SQL 1.1.
s2.1.1.3
This method implements the SQL/MM specification.
SQL-MM IEC 13249-3: 5.1.30
quad_segs=8 (default)
SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=8');
|
quad_segs=2 (lame)
SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=2');
|
|
endcap=round join=round (default)
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'endcap=round join=round');
|
endcap=square
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'endcap=square join=round');
|
endcap=flat
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'endcap=flat join=round');
|
join=bevel
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'join=bevel');
|
join=mitre mitre_limit=5.0 (default mitre limit)
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'join=mitre mitre_limit=5.0');
|
join=mitre mitre_limit=1
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'join=mitre mitre_limit=1.0');
|
side=left
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'side=left');
|
side=right
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'side=right');
|
side=left join=mitre
SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'
), 10, 'side=left join=mitre');
|
right-hand-winding, polygon boundary side=left
SELECT ST_Buffer(
ST_ForceRHR(ST_Boundary(ST_GeomFromText('POLYGON ((50 50, 50 150, 150 150, 150 50, 50 50))'))),
), 20, 'side=left');
|
right-hand-winding, polygon boundary side=right
SELECT ST_Buffer(
ST_ForceRHR(ST_Boundary(ST_GeomFromText('POLYGON ((50 50, 50 150, 150 150, 150 50, 50 50))'))
), 20,'side=right')
|
A buffered point approximates a circle. A buffered point forcing approximation of (see diagram) 2 points per quarter circle is poly with 8 sides (see diagram)
SELECT ST_NPoints(ST_Buffer(ST_GeomFromText('POINT(100 90)'), 50)) As promisingcircle_pcount,
ST_NPoints(ST_Buffer(ST_GeomFromText('POINT(100 90)'), 50, 2)) As lamecircle_pcount;
promisingcircle_pcount | lamecircle_pcount
------------------------+-------------------
33 | 9
A lighter, less smooth circle using only 2 points per quarter circle is an octagon.
The following example creates a 100 meter octagon in NAD83 longitude/latitude by transforming to the Massachusetts state plane meter projection and then buffering.
SELECT ST_AsText(ST_Buffer( ST_Transform(ST_SetSRID(ST_Point(-71.063526, 42.35785),4269), 26986), 100,2)) As octagon;
POLYGON((236057.5905746494 900908.7599186979,236028.30125276805 900838.0492405792,235957.5905746494 900808.7599186979,235886.87989653074 900838.0492405792,235857.5905746494 900908.7599186979,235886.87989653074 900979.4705968165,235957.5905746494 901008.7599186979,236028.30125276805 900979.4705968165,236057.5905746494 900908.7599186979))
Buffering a polygon by a positive distance and then by the same negative distance is a morphological closing operation. It can be useful for smoothing noisy boundaries, such as simplifying a coastline by removing narrow inlets and bays. The result intentionally changes the shape and area of the input, and the distance must be chosen in the units of the input SRS. For data in a geographic SRS, transform to a projected SRS suited to the operation first; for cartographic visualization in Web Mercator, using that display SRS can be appropriate.
-- Smooth a coastline using a 1 km closing operation, then simplify the result. -- The example uses Massachusetts State Plane meter units for the operation. WITH projected AS ( SELECT id, ST_Transform(geom, 26986) AS geom FROM coast ), closed AS ( SELECT id, ST_Buffer(ST_Buffer(geom, 1000), -1000) AS geom FROM projected ) SELECT id, ST_Transform(ST_SimplifyPreserveTopology(geom, 50), 4326) AS geom FROM closed;
The same technique is described in Paul Ramsey's Removing Complexities. The final simplification step is optional; use ST_SimplifyPreserveTopology when polygonal validity matters, and check the result against the cartographic or analytical tolerance required by the application.
A small negative buffer can also be used as a heuristic to
find narrow polygon spikes. The query below compares how much
area and perimeter remain after erosion. A large
erosion_index indicates that the perimeter
dropped proportionally more than the area. This is only a
preselection aid; the threshold and buffer distance must be
chosen for the data units and the kind of spike being checked.
WITH sample(id, geom) AS (
VALUES
('plain', 'POLYGON((0 0,10 0,10 10,0 10,0 0))'::geometry),
('spike', 'POLYGON((0 0,10 0,10 10,5.2 10,5 16,4.8 10,0 10,0 0))'::geometry)
),
eroded AS (
SELECT id, geom, ST_Buffer(geom, -0.5) AS eroded_geom
FROM sample
),
scored AS (
SELECT id,
round((
ST_Area(eroded_geom) / ST_Area(geom) /
NULLIF(ST_Perimeter(eroded_geom) / ST_Perimeter(geom), 0)
)::numeric, 3) AS erosion_index
FROM eroded
WHERE NOT ST_IsEmpty(eroded_geom)
)
SELECT id, erosion_index, erosion_index > 1.1 AS possible_spike
FROM scored
ORDER BY id;
id | erosion_index | possible_spike -------+---------------+---------------- plain | 0.900 | f spike | 1.147 | t
A variable-distance buffer can be approximated by buffering each vertex of a line by a distance interpolated along the line, building the convex hull for each consecutive pair of vertex buffers, and unioning the segment hulls. As with any geometry buffer, distances are in the units of the input SRS.
-- Taper a line buffer from 5 to 25 units along the line.
WITH line AS (
SELECT 'LINESTRING(0 0, 100 0, 160 40)'::geometry AS geom
),
vertices AS (
SELECT (dump).path[1] AS n,
(dump).geom AS geom,
line.geom AS line_geom
FROM line
CROSS JOIN LATERAL ST_DumpPoints(line.geom) AS dump
),
radii AS (
SELECT n,
geom,
5 + (25 - 5) * ST_LineLocatePoint(line_geom, geom) AS radius
FROM vertices
),
segments AS (
SELECT n,
geom,
radius,
lead(geom) OVER (ORDER BY n) AS next_geom,
lead(radius) OVER (ORDER BY n) AS next_radius
FROM radii
)
SELECT ST_Union(
ST_ConvexHull(
ST_Collect(
ST_Buffer(geom, radius),
ST_Buffer(next_geom, next_radius)
)
)
) AS tapered_buffer
FROM segments
WHERE next_geom IS NOT NULL;