Name

ST_CatmullRomSmoothing — Returns a smoothed version of a geometry, using the Catmull-Rom spline algorithm

Synopsis

geometry ST_CatmullRomSmoothing(geometry geom, integer nSegments = 5);

Description

Smoothes a linear or polygonal geometry using the Catmull-Rom spline algorithm. Unlike ST_ChaikinSmoothing, this is an interpolating spline: the output curve passes through every original vertex. Between each pair of consecutive original vertices, nSegments - 1 new intermediate points are inserted.

The nSegments parameter controls the density of the output. With nSegments = 5 (the default), each original span is divided into 5 sub-segments (inserting 4 new points per span). The minimum value is 2.

At least 4 input vertices are required to apply smoothing; geometries with fewer vertices are returned unchanged. Points and multipoints are always returned unchanged.

[Note]

The output vertex count grows as 1 + (N-1) * nSegments for open lines, and 1 + N * nSegments for closed rings, where N is the number of input vertices. For large geometries, use a simplification function on the result to reduce the number of points (see ST_Simplify, ST_SimplifyPreserveTopology and ST_SimplifyVW).

The result has interpolated values for the Z and M dimensions when present.

This function supports 3d and will not drop the z-index.

Availability: 3.6.0

Examples

Smoothing a 4-point collinear line with default nSegments=5:

SELECT ST_AsText(ST_CatmullRomSmoothing('LINESTRING(0 0, 5 0, 10 0, 15 0)'));

 LINESTRING(0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 0)

Smoothing a Polygon using nSegments = 5 and 10:

nSegments = 5

nSegments = 10

SELECT ST_CatmullRomSmoothing(
            'POLYGON ((20 20, 60 90, 10 150, 100 190, 190 160, 130 120, 190 50, 140 70, 120 10, 90 60, 20 20))',
            generate_series(5, 10, 5) );

Smoothing a LineString using nSegments = 5 and 10:

nSegments = 5

nSegments = 10

SELECT ST_CatmullRomSmoothing(
            'LINESTRING (10 140, 80 130, 100 190, 190 150, 140 20, 120 120, 50 30, 30 100)',
            generate_series(5, 10, 5) );