All Products
Search
Document Center

PolarDB:Common GanosBase methods for processing trajectory sampling points

Last Updated:Mar 28, 2026

GanosBase provides four categories of functions for preprocessing trajectory sampling-point data: filtering, segmentation, resampling, and simplification. These functions address common data-quality issues in GPS-based trajectory data and are available starting from GanosBase version 5.2.

GanosBase trajectories

Trajectories are spatiotemporal objects used to analyze and process moving objects such as pedestrians, vehicles, ships, and aircraft.

Trajectory data can be represented in two ways:

  • Discrete points: A set of individual sampling points. More sensitive to sampling frequency but algorithmically simpler. Functions for similarity computation and segmentation typically operate on discrete points.

  • Continuous lines: A spatial polyline that evolves over time. Less sensitive to sampling frequency and supports spatial operations on the polyline geometry.

For example, a shared bicycle reports its coordinates (114.35, 39.28) at 17:42:30 on April 11, 2020. This generates the following record:

Timexy
2020-04-11 17:42:30114.3539.28

Additional attributes such as speed can be recorded at each sampling point:

TimexySpeed
2020-04-11 17:42:30114.3539.284.3
2020-04-11 17:43:30114.3639.284.8
2020-04-11 17:45:00114.3539.293.5

These points form a spatiotemporal trajectory, as shown in the following figure.

image

The native GanosBase trajectory engine of PolarDB introduces the trajectory type, indexing, and spatiotemporal operators to resolve issues related to the storage, retrieval, and analysis of moving objects.

Data quality issues in GPS trajectory data

In most business scenarios, trajectory data is collected by systems such as transportation management system (TMS) and automatic identification system (AIS) from GPS signals at a relatively consistent sampling frequency. However, the following issues can degrade trajectory data quality:

  • Drift points: GPS signal noise causes sampling points to deviate significantly from the actual movement path.

  • Stationary noise: Objects that remain in one location for extended periods — such as ships waiting at anchor or vehicles stopped at rest areas — generate excessive redundant points.

  • Uneven point density: Preprocessing steps such as noise reduction can leave gaps in the trajectory, causing uneven sampling that introduces errors in subsequent similarity calculations.

  • Large data volumes: High point density reduces frontend rendering performance, causing program failures and stuttering.

Processing methods

MethodFunctionUse when
Trajectory filteringST_removeDriftPointsGPS drift or speed anomalies are present
Trajectory segmentationST_SplitSplitting a trajectory at specific points or removing segments
Trajectory resamplingST_ResamplePoint density is uneven after preprocessing
Trajectory simplificationST_Compress, ST_CompressSEDReducing point count while preserving movement shape

ST_removeDriftPoints — trajectory filtering

ST_removeDriftPoints removes points that deviate significantly from the expected movement pattern. It handles two types of anomalies:

  • Spatial drift caused by poor GPS signal quality

  • Speed anomalies caused by objects jumping between locations within a short time frame due to dense but imprecise sampling

For more information, see ST_removeDriftPoints.

image

Example

SELECT ST_removeDriftPoints(
    ST_SetSRID(
        ST_MakeTrajectory(
            ARRAY_AGG(ROW(traj.arrival_time::TIMESTAMP, st_x(traj.pts)::DOUBLE PRECISION, traj.lat::DOUBLE PRECISION, traj.rowid)),
            FALSE, '{"rowid"}'::cstring[]
        ), 4326
    ),
    40,   -- maximum speed threshold
    10,   -- minimum distance threshold
    '1 minute'::INTERVAL  -- minimum time interval
) FROM (
    SELECT
        time,
        ST_makepoint(lon, lat) pts,
        lat,
        rowid
    FROM point_table
    WHERE time IS NOT NULL AND lon IS NOT NULL AND lat IS NOT NULL
    ORDER BY rowid
) traj INTO trajectory_table;

ST_Split — trajectory segmentation

ST_Split divides a trajectory into multiple sub-trajectories using geometric objects. It provides three segmentation modes:

ModeDescriptionWhen to use
cut_pointSplits at an existing sampling point. Both resulting sub-trajectories include the split point.Trajectory is too long and needs to be divided at a known point for analysis
cut_edgeSplits at an interpolated point along a trajectory edge (not limited to existing sampling points). Both sub-trajectories include the interpolated point.Dividing trajectories by fixed intervals such as time windows or spatial grids
drop_edgeRemoves a trajectory edge. The two endpoints of the removed edge each become the end of their respective sub-trajectories.Removing stationary segments — for example, discarding periods when a shared bicycle is parked

For more information, see ST_Split.

image

Example (remove edges longer than 10 spatial units in 2D)

WITH traj AS (
    SELECT '{"trajectory":{"version":1,"type":"STPOINT","leafcount":19,...}}'::trajectory AS a
)
SELECT ST_Split(a, '{"drop_edge.spatial_distance_2d":10}') FROM traj;

ST_Resample — trajectory resampling

ST_Resample corrects uneven point distribution across a trajectory. Uneven density typically results from noise-reduction preprocessing and can degrade the performance of local trajectory analysis.

Two resampling strategies are available:

StrategyDescriptionWhen to use
add_pointIncreases point density by interpolating new pointsDetailed analysis such as density statistics or similarity matching
drop_pointDecreases point density by removing pointsExtracting long-term movement trends or simplifying the trajectory

For more information, see ST_Resample.

Example (add interpolated points so consecutive points are no more than 5 minutes apart)

SELECT ST_Resample(ST_OnlyST(traj), '{"add_point.period_lesser":"5 minute"}')
FROM table;

Trajectory simplification

Trajectory simplification (lossy compression) reduces the number of sampling points while preserving the overall movement shape. This decreases storage requirements and improves rendering performance.

Two simplification functions are available:

FunctionAlgorithmWhen to useReference
ST_CompressDouglas-Peucker2D trajectories where all sampling points lie on the same planeST_Compress
ST_CompressSEDSynchronized Euclidean Distance (SED)Spatiotemporal trajectories that include a time dimensionST_CompressSED

How the algorithms work

The Douglas-Peucker algorithm specifies a tolerance value — the maximum allowed deviation between the original and simplified trajectory. Starting from the endpoints, it iteratively identifies the point farthest from the simplified path, adds it back, and repeats until all remaining points fall within the tolerance. The algorithm operates in 2D and requires all points to lie on the same plane.

image

For spatiotemporal trajectories, applying the 2D Douglas-Peucker algorithm can produce incorrect results. When an object is stationary, its trajectory forms a vertical line along the time axis that collapses to a single point in 2D — causing the standard algorithm to drop one of the line's endpoints and distort the 3D structure. ST_CompressSED uses Synchronized Euclidean Distance (SED) instead of perpendicular Euclidean distance, which preserves the temporal dimension and produces accurate compression for spatiotemporal data.

Best practices

Remove drift points from ship trajectory data

To build an accurate ship navigation trajectory from AIS point data, construct a trajectory from the collected latitude and longitude values, remove GPS drift points, and save the cleaned trajectory.

SELECT
    ST_removeDriftPoints(
        ST_SetSRID(
            ST_MakeTrajectory(
                ARRAY_AGG(ROW(traj.arrival_time::TIMESTAMP, st_x(traj.pts)::DOUBLE PRECISION, traj.lat::DOUBLE PRECISION, traj.rowid)),
                FALSE, '{"rowid"}'::cstring[]
            ), 4326
        ),
        40,
        10,
        '1 minute'::INTERVAL
    )
FROM (
    SELECT
        time,
        ST_makepoint(lon, lat) pts,
        lat,
        rowid
    FROM point_table
    WHERE time IS NOT NULL
      AND lon IS NOT NULL
      AND lat IS NOT NULL
    ORDER BY rowid
) traj INTO trajectory_table;

Resample drone trajectory points and calculate point density

To analyze drone movement patterns, segment the trajectory into 5-minute intervals, resample the points within each interval, and calculate point density for use as input to a machine learning model.

SELECT
    ST_Density(
        ST_Resample(ST_OnlyST(traj),
        '{"add_point.period_lesser":"5 minute"}'),
        100, '30 minute'
    )
FROM table;

Simplify freight vehicle trajectories by removing long stationary edges

To focus analysis on active travel segments in freight vehicle trajectory data, remove long edges — which typically represent stationary periods — and generate shorter, analyzable sub-trajectories.

WITH traj AS (
    SELECT
        '{"trajectory":{"version":1,"type":"STPOINT","leafcount":19,"start_time":"2000-01-01 00:01:19.067179","end_time":"2000-01-01 03:24:25.946085","spatial":"LINESTRING(-100 -100 -100,-88.8925775739675 -86.6512698383691 -92.3767832526937,-79.6904716538265 -80.6515727923252 -84.2357598245144,-75.8435507711644 -73.7572890928326 -80.5007370118983,-70.6238425321256 -67.8213750167439 -74.5733173238113,-61.6014582272619 -61.0636760429479 -67.9874239303172,-56.1098577060426 -54.4264591250879 -64.5007972046733,-46.9800617334743 -49.4026757289345 -61.6160059720278,-41.7122942996211 -46.3224360072054 -56.5283147455193,-35.5646221285375 -38.1688933617746 -49.2775720101781,-31.7230528349367 -33.6970051738123 -44.1693710885011,-23.1585765127093 -26.5895827477798 -40.6539742602035,-16.7020264320696 -21.6133877349397 -37.3055470525287,-12.1044529232507 -14.1236051704424 -28.2295028120279,-3.77185660181567 -7.74744770256802 -24.3842111621052,0.488159407706304 -3.68223926316326 -19.9478872027248,6.33406881305078 4.54123636645575 -15.0410129944794,15.6666049417108 10.5611746329814 -11.2770220567472,14 11 -10)","timeline":["2000-01-01 00:01:19.067179","2000-01-01 00:12:36.116007","2000-01-01 00:23:53.164835","2000-01-01 00:35:10.213663","2000-01-01 00:46:27.262491","2000-01-01 00:57:44.311319","2000-01-01 01:09:01.360147","2000-01-01 01:20:18.408975","2000-01-01 01:31:35.457803","2000-01-01 01:42:52.506631","2000-01-01 01:54:09.555459","2000-01-01 02:05:26.604287","2000-01-01 02:16:43.653115","2000-01-01 02:28:00.701943","2000-01-01 02:39:17.750771","2000-01-01 02:50:34.799599","2000-01-01 03:01:51.848427","2000-01-01 03:13:08.897255","2000-01-01 03:24:25.946085"]}}'::trajectory AS a
)
SELECT ST_Split(a, '{"drop_edge.spatial_distance_2d":10}') FROM traj;