ST_ConcaveHull

Updated at:

Returns the concave hull of a set of geometry objects. Think of it as shrink-wrapping the input geometries — the result hugs the data more tightly than a convex hull, which is more like stretching a rubber band around the set.

Syntax

geometry ST_ConcaveHull(geometry geomA, float targetPercent, boolean allowHoles)

Parameters

Parameter

Type

Description

Default

geomA

geometry

The input geometry object.

—

targetPercent

float

The target ratio of the concave hull area to the convex hull area. Lower values produce a tighter hull but increase processing time and the risk of topology exceptions.

—

allowHoles

boolean

Specifies whether to allow holes in the output polygon.

false

Usage notes

Input type handling

  • For point, LineString, or GeometryCollection inputs, wrap them in ST_Collect before passing to this function.

  • For polygon inputs, use ST_Union instead.

  • Invalid geometry objects cause the function to fail.

ST_ConcaveHull is not an aggregate function. To compute the concave hull over a column of geometries, combine it with ST_Collect or ST_Union:

ST_ConcaveHull(ST_Collect(geom_column), 0.80)

Output dimension is never higher than the dimension of the input geometry.

Tuning `targetPercent`

Start with 0.99. This is fast — sometimes as fast as computing a convex hull — and typically produces a hull whose area is less than 99% of the convex hull area. If the result is not tight enough, try lower values. Processing time increases as the value decreases.

Post-processing for simpler geometry

To simplify the output, pass the result to ST_SimplifyPreserveTopology or ST_SnapToGrid. ST_SnapToGrid is faster because it skips validity checks, but it may produce invalid geometry objects. ST_SimplifyPreserveTopology is slower but verifies the validity of the returned results.

Convex hull vs. concave hull

ST_ConcaveHull computes a convex hull faster than a concave hull. However, the concave hull encloses all input geometry objects more tightly and is useful for image recognition.

Examples

Compare `targetPercent` values on a MULTIPOLYGON

SELECT
  g,
  ST_ConcaveHull(g, 0.99),
  ST_ConcaveHull(g, 0.98)
FROM (
  SELECT 'MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),((0 6,6 3,6 6,0 6)))'::geometry AS g
) AS test;

The three results — the original object, the hull at 0.99, and the hull at 0.98 — are shown below:

123

Compute concave hulls for grouped point observations

Use ST_ConcaveHull with GROUP BY and ST_Collect to estimate the coverage area for each category in a dataset:

SELECT
  category,
  ST_ConcaveHull(ST_Collect(geom), 0.80) AS coverage_area
FROM observations
GROUP BY category;

Related topics