ST_Buffer — Calcule une géométrie couvrant tous les points situés à une distance donnée d'une géométrie.
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);
Calcule un POLYGONE ou un MULTIPOLYGONE représentant tous les points dont la distance par rapport à une geometry/geography est inférieure ou égale à une distance donnée. Une distance négative rétrécit la géométrie au lieu de l'étendre. Une distance négative peut réduire complètement un polygone, auquel cas POLYGON EMPTY est renvoyé. Pour les points et les lignes, les distances négatives renvoient toujours des résultats vides.
Pour les types geometry, la distance est spécifiée dans les unités du système de référence spatiale de la géométrie. Pour les types geography, la distance est spécifiée en mètres.
Le troisième paramètre facultatif contrôle la précision et le style du tampon. La précision des arcs de cercle dans le tampon est spécifiée en tant que nombre de segments de ligne utilisés pour approximer un quart de cercle (la valeur par défaut est de 8). Le style du tampon peut être spécifié en fournissant une liste de paires clé=valeur séparées par des blancs, comme suit :
'quad_segs=#' : nombre de segments de ligne utilisés pour approximer un quart de cercle (8 par défaut).
'endcap=round|flat|square' : style d'endcap (la valeur par défaut est "round"). 'butt' est accepté comme synonyme de 'flat'.
'join=round|mitre|bevel' : style de jointure (la valeur par défaut est "round"). 'miter' est accepté comme synonyme de 'mitre'.
'mitre_limit=#.#' : limite du rapport d'angle (n'affecte que le style d'assemblage en angle). 'miter_limit' est accepté comme synonyme de '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. |
|
|
|
La mise en mémoire tampon est parfois utilisée pour effectuer une recherche à l'intérieur de la distance. Dans ce cas, il est plus efficace d'utiliser ST_DWithin. |
|
|
|
Cette fonction ignore la dimension Z. Elle donne toujours un résultat en 2D, même lorsqu'elle est utilisée sur une géométrie en 3D. |
Amélioration : 2.5.0 - La prise en charge de la géométrie ST_Buffer a été améliorée pour permettre la spécification de la mise en mémoire tampon latérale side=both|left|right.
Disponibilité : 1.5 - ST_Buffer a été amélioré pour prendre en charge différents types de terminaisons et de jointures. Ceux-ci sont utiles, par exemple, pour convertir les lignes de route en routes polygonales avec des bords plats ou carrés au lieu de bords arrondis. Un petit wrapper pour la geography a été ajouté.
Effectué par le module GEOS.
Cette méthode implémente la spécification OGC Simple Features Implementation Specification for SQL 1.1. s2.1.1.3
Cette méthode implémente la spécification SQL/MM. SQL-MM IEC 13249-3: 5.1.30
The textual results are rounded to whole coordinate units for readability. Each result remains available as text, while the manual initially favors the shared input/output figure.
|
quad_segs=8 (par défaut) Code SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=8');Export de raster POLYGON((150 90,149 80,146 71,142 62,135 55,128 48,119 44,110 41,100 40,90 41,81 44,72 48,65 55,58 62,54 71,51 80,50 90,51 100,54 109,58 118,65 125,72 132,81 136,90 139,100 140,110 139,119 136,128 132,135 125,142 118,146 109,149 100,150 90)) Figure |
quad_segs=2 Code SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=2');Export de raster POLYGON((150 90,135 55,100 40,65 55,50 90,65 125,100 140,135 125,150 90)) Figure |
|
endcap=round join=round (par défaut) Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'endcap=round join=round');Export de raster POLYGON((143 157,144 158,146 159,148 160,150 160,152 160,154 159,156 158,157 157,158 156,159 154,160 152,160 150,160 50,160 48,159 46,158 44,157 43,156 42,154 41,152 40,150 40,148 40,146 41,144 42,143 43,142 44,141 46,140 48,140 50,140 126,57 43,56 42,54 41,52 40,50 40,48 40,46 41,44 42,43 43,42 44,41 46,40 48,40 50,40 52,41 54,42 56,43 57,143 157)) Figure |
endcap=square Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'endcap=square join=round');Export de raster POLYGON((143 157,144 158,146 159,148 160,150 160,152 160,154 159,156 158,157 157,158 156,159 154,160 152,160 150,160 50,160 40,140 40,140 126,57 43,50 36,36 50,143 157)) Figure |
|
endcap=flat Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'endcap=flat join=round');Export de raster POLYGON((143 157,144 158,146 159,148 160,150 160,152 160,154 159,156 158,157 157,158 156,159 154,160 152,160 150,160 50,140 50,140 126,57 43,43 57,143 157)) Figure |
join=bevel Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'join=bevel');Export de raster POLYGON((143 157,160 150,160 50,160 48,159 46,158 44,157 43,156 42,154 41,152 40,150 40,148 40,146 41,144 42,143 43,142 44,141 46,140 48,140 50,140 126,57 43,56 42,54 41,52 40,50 40,48 40,46 41,44 42,43 43,42 44,41 46,40 48,40 50,40 52,41 54,42 56,43 57,143 157)) Figure |
|
join=mitre mitre_limit=5.0 (limite de mitre par défaut) Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'join=mitre mitre_limit=5.0');Export de raster POLYGON((160 174,160 50,160 48,159 46,158 44,157 43,156 42,154 41,152 40,150 40,148 40,146 41,144 42,143 43,142 44,141 46,140 48,140 50,140 126,57 43,56 42,54 41,52 40,50 40,48 40,46 41,44 42,43 43,42 44,41 46,40 48,40 50,40 52,41 54,42 56,43 57,160 174)) Figure |
join=mitre mitre_limit=1 Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'join=mitre mitre_limit=1.0');Export de raster POLYGON((148 162,160 157,160 50,160 48,159 46,158 44,157 43,156 42,154 41,152 40,150 40,148 40,146 41,144 42,143 43,142 44,141 46,140 48,140 50,140 126,57 43,56 42,54 41,52 40,50 40,48 40,46 41,44 42,43 43,42 44,41 46,40 48,40 50,40 52,41 54,42 56,43 57,148 162)) Figure |
|
side=left Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'side=left');Export de raster POLYGON((150 50,150 150,50 50,43 57,143 157,144 158,146 159,148 160,150 160,152 160,154 159,156 158,157 157,158 156,159 154,160 152,160 150,160 50,150 50)) Figure |
side=right Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'side=right');Export de raster POLYGON((50 50,150 150,150 50,140 50,140 126,57 43,50 50)) Figure |
|
side=left join=mitre Code SELECT ST_Buffer(
ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
10, 'side=left join=mitre');Export de raster POLYGON((150 50,150 150,50 50,43 57,160 174,160 50,150 50)) Figure |
right-hand winding, polygon boundary side=left Code SELECT ST_Buffer(
ST_ForceRHR(ST_Boundary(ST_GeomFromText(
'POLYGON ((50 50,50 150,150 150,150 50,50 50))'))),
20, 'side=left');Export de raster POLYGON((50 50,50 150,150 150,150 50,50 50)) Figure |
|
right-hand winding, polygon boundary side=right Code SELECT ST_Buffer(
ST_ForceRHR(ST_Boundary(ST_GeomFromText(
'POLYGON ((50 50,50 150,150 150,150 50,50 50))'))),
20, 'side=right');Export de raster POLYGON((50 50,50 70,50 150,150 150,150 50,70 50,50 50),(70 70,130 70,130 130,70 130,70 70)) Figure |
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('POINT(100 90)'::geometry, 50)) As promisingcircle_pcount,
ST_NPoints(ST_Buffer('POINT(100 90)'::geometry, 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. The figure shows the input and output in separate panels because the coordinates are in different SRIDs.
WITH input AS (
SELECT ST_SetSRID(ST_Point(-71.063526, 42.35785), 4269) AS point_4269
), projected AS (
SELECT point_4269,
ST_Transform(point_4269, 26986) AS point_26986
FROM input
)
SELECT point_4269 AS input_point_4269,
ST_Buffer(point_26986, 100, 2) AS octagon_26986
FROM projected;
SRID=4269;POINT(-71.063526 42.35785) | SRID=26986;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;
POLYGON((96.758 -16.301,-0.975 -4.904,-1.913 -4.619,-2.778 -4.157,-3.536 -3.536,-4.157 -2.778,-4.619 -1.913,-4.904 -0.975,-5 0,-4.904 0.975,-4.619 1.913,-4.157 2.778,-3.536 3.536,-2.778 4.157,-1.913 4.619,-0.975 4.904,93.101 15.875,142.322 57.678,146.111 60.787,150.433 63.097,155.123 64.52,160 65,164.877 64.52,169.567 63.097,173.889 60.787,177.678 57.678,180.787 53.889,183.097 49.567,184.52 44.877,185 40,184.52 35.123,183.097 30.433,180.787 26.111,177.678 22.322,173.889 19.213,169.567 16.903,106.36 -15.355,103.242 -16.301,100 -16.62,96.758 -16.301))