All Products
Search
Document Center

ApsaraDB RDS:ST_CurveRecognize

Last Updated:Mar 28, 2026

Identifies curves in a trajectory and returns the curvature radius and position of each curve's center point.

Syntax

Syntax 1 — Use when the default expansion radii are sufficient:

SETOF trpeak ST_CurveRecognize(trajectory traj, float8 radius_threshold, float8 angle_threshold, float8 angle_compress_threshold DEFAULT 0);

Syntax 2 — Use when you need precise control over how far the curve boundary extends from the center point:

SETOF trpeak ST_CurveRecognize(trajectory traj, float8 radius_threshold, float8 angle_threshold, float8 expansion_radius1, float8 expansion_radius2, float8 angle_compress_threshold DEFAULT 0);

With Syntax 1, expansion_radius1 defaults to radius_threshold * 2 and expansion_radius2 defaults to radius_threshold * 4.

Parameters

Input parameters

ParameterTypeDefaultDescription
trajtrajectoryThe trajectory to analyze.
radius_thresholdfloat8The curvature radius threshold for identifying the center point of a curve. The function collects all consecutive trajectory points whose curvature radius is smaller than this value, then selects the point with the smallest curvature radius as the center point.
angle_thresholdfloat8The minimum rotation angle for a boundary point to be retained. If a boundary point's rotation angle is smaller than this value, the point is removed and the curve is split into two separate curves at that location.
expansion_radius1float8radius_threshold * 2The curvature radius threshold at each candidate boundary point. Only points whose curvature radius is smaller than this value are included in the curve boundary. (Syntax 2 only)
expansion_radius2float8radius_threshold * 4The average curvature radius threshold from a candidate boundary point to the center point. Only points where this average is smaller than this value are included in the curve boundary. (Syntax 2 only)
angle_compress_thresholdfloat80The minimum rotation angle for a point to be sampled. Points with a rotation angle smaller than this value are skipped, reducing sampling density and preventing over-sampling from obscuring curve detection.

Return values

ST_CurveRecognize returns a set of trpeak records, one per detected curve. Each record contains:

FieldDescription
locThe serial number of the center point within the trajectory's turning-point sequence. If loc = n, the center point is the (n + 1)th turning point of the trajectory.
heightThe curvature radius at the center point. A positive value indicates a clockwise curve; a negative value indicates a counterclockwise curve.
startlocThe serial number of the curve's start point.
endlocThe serial number of the curve's end point.

How it works

ST_CurveRecognize identifies curves in three steps:

  1. Identify center points. Scan all consecutive trajectory points whose curvature radius is smaller than radius_threshold. From each such group, select the point with the smallest curvature radius as the curve's center point.

  2. Expand the curve boundary. Starting from each center point, extend the boundary outward to include adjacent points that meet both conditions:

    • The point's curvature radius is smaller than expansion_radius1.

    • The average curvature radius from that point to the center point is smaller than expansion_radius2.

  3. Validate and split boundary points. For each boundary point, compare its rotation angle against angle_threshold:

    • If the rotation angle exceeds the threshold, the boundary expands outward in both directions.

    • If the rotation angle falls below the threshold, the boundary point is removed. The curve splits into two parts at that point, each with a rotation angle above the threshold at every boundary.

Example

The following example runs ST_CurveRecognize on a 16-point trajectory with radius_threshold = 15 and angle_threshold = 1. The trajectory data repeats the same 8-point path twice, so the same physical curves appear at two different time segments.

SELECT (ST_CurveRecognize(
  '{"trajectory":{"version":1,"type":"STPOINT","leafcount":16,
    "start_time":"2000-01-01 00:00:00","end_time":"2000-01-16 00:00:00",
    "spatial":"LINESTRING(0 0,1 1,2 2,4 3,3 4,5 7,8 8,7 4,0 0,1 1,2 2,4 3,3 4,5 7,8 8,7 4)",
    "timeline":["2000-01-01 00:00:00","2000-01-02 00:00:00","2000-01-03 00:00:00",
                "2000-01-04 00:00:00","2000-01-05 00:00:00","2000-01-06 00:00:00",
                "2000-01-07 00:00:00","2000-01-08 00:00:00","2000-01-09 00:00:00",
                "2000-01-10 00:00:00","2000-01-11 00:00:00","2000-01-12 00:00:00",
                "2000-01-13 00:00:00","2000-01-14 00:00:00","2000-01-15 00:00:00",
                "2000-01-16 00:00:00"]}}',
  15,   -- radius_threshold
  1     -- angle_threshold
)).*;

Output:

 loc |       height        | startloc | endloc
-----+---------------------+----------+--------
   2 |    5.70087712549569 |        2 |      2
   4 |  2.1023796041628637 |        4 |      8
  10 |    5.70087712549569 |       10 |     10
  12 |  2.1023796041628637 |       12 |     15
   3 | -1.1785113019775793 |        3 |      3
  11 | -1.1785113019775793 |       11 |     11
(6 rows)

The output contains 6 rows representing 3 distinct curves, each detected twice because the trajectory repeats:

  • Rows with loc = 2 and loc = 10 (height ≈ 5.70, positive): the same clockwise curve, encountered in the first and second pass through the path.

  • Rows with loc = 4 and loc = 12 (height ≈ 2.10, positive, startloc to endloc spanning multiple points): a wider clockwise curve with an extended boundary.

  • Rows with loc = 3 and loc = 11 (height ≈ −1.18, negative): the same counterclockwise curve in both passes.