ST_Buffer — あるジオメトリからの距離が指定された距離以下となる点全ての集合となるジオメトリを返します。
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);
ジオメトリ/ジオグラフィからの距離が与えられた距離より短くなる全ての点を表現するPOLYGONまたはMULTIPOLYGONを生成します。距離に負数を指定すると、ジオメトリは拡大されずに縮小されます。負の距離ではポリゴンを完全に縮小し切る可能性があり、その時はPOLYGON EMPTYを返します。ポイントとラインで負の距離を指定すると、常に空を返します。
ジオメトリの場合、指定される距離の単位は、ジオメトリの空間参照系の単位です。ジオグラフィの場合、指定される距離の単位はメートルです。
3番目のパラメータは任意で、バッファの精度とスタイルを扱います。バッファの円弧の精度は四分の一円の近似に使用される辺の数です (デフォルトは8)。バッファのスタイルは キー=値 のペアを空白区切りでリストにして指定します。キーは次の通りです。
'quad_segs=#' : 四分の一円近似に使う辺の数 (デフォルトは8)。
'endcap=round|flat|square' : 終端スタイル (デフォルトは "round")。'butt'は'flat'の同義語として受け付けます。
'join=round|mitre|bevel' : 接続スタイル (デフォルトは"round")。'miter'も'mitre'の同義語として受け付けます。
'mitre_limit=#.#' : マイター比 (訳注: 継ぎ目の内側と外側の距離と線幅との比)の最大値 (継ぎ目スタイルがmiterである場合のみ有効)。'miter_limit'は'mitre_limit'の同義語として受け付けます。
'side=both|left|right' : デフォルトは'both'です。'left'または'right'でジオメトリーの片側へのバッファーが行われますが、左右はラインの方向で決まります。これはLINESTRINGジオメトリーにのみ適用可能です。POINTまたはPOLYGONジオメトリに影響を与えません。'left'または'right'を指定した場合にはデフォルトの終端スタイルは正方形になります。
|
|
|
|
|
|
|
不正な入力を操作することができ、出力は常に妥当なポリゴンジオメトリです。距離 0によるバッファ生成は時々不正なポリゴンの修復方法として使われます。. ST_MakeValidの方がマルチポリゴンも扱えるので、この目的に使うのにより適切です。 |
|
|
|
バッファ作成は時々、距離内にある地物を検索する際に使われます。この使い方については、ST_DWithinの方が効率的です。 |
|
|
|
この関数はZ値を無視します。この関数を3次元ジオメトリ上で使用したとしても、常に2次元の結果となります。 |
Enhanced: 2.5.0 - ST_Bufferのジオメトリ対応版が強化され、バッファを施す側をside=both|left|rightで指定できるようになりました。
Availability: 1.5 - ST_Bufferが強化され、様々な終端と継ぎ目に対応するようになりました。たとえば、道路ラインストリングを道路ポリゴンに変換する際に終端を丸でなく平面や四角で処理したい場合などに使えます。ジオグラフィ用の薄いラッパが追加されました。
GEOSモジュールで実現しています。
このメソッドはOGC Simple Features Implementation Specification for SQL 1.1の実装です。 s2.1.1.3
このメソッドはSQL/MM仕様の実装です。 SQL-MM IEC 13249-3: 5.1.30
quad_segs=8 (デフォルト)
SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=8');
|
quad_segs=2 (不十分)
SELECT ST_Buffer(
ST_GeomFromText('POINT(100 90)'),
50, 'quad_segs=2');
|
|
endcap=round join=round (デフォルト)
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 (デフォルトの最大マイター比)
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');
|
右回り、ポリゴン境界は左
SELECT ST_Buffer(
ST_ForceRHR(ST_Boundary(ST_GeomFromText('POLYGON ((50 50, 50 150, 150 150, 150 50, 50 50))'))),
), 20, 'side=left');
|
右回り、ポリゴン境界は右
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;