Tous les produits
Search
Centre de documentation

ApsaraDB RDS:ST_Split

Dernière mise à jour :Oct 13, 2026

Divise une trajectoire en un tableau de sous-trajectoires. Trois surcharges sont disponibles : division par géométrie, par règle et par index.

La fonction renvoie le type trajectory[]. Utilisez la fonction unnest() pour développer le résultat en lignes individuelles.

Syntaxe

trajectory[] ST_Split(trajectory traj, geometry geom, float8 radius_of_buffer);
trajectory[] ST_Split(trajectory traj, text config);
trajectory[] ST_Split(trajectory traj, int[] indexes);

Paramètres

Paramètre Type Description
traj trajectory Trajectoire à diviser.
geom geometry Objet géométrique servant de limite de division. Seuls les types Point et MultiPoint sont pris en charge.
radius_of_buffer float8 Rayon de la zone tampon autour de la géométrie Point, exprimé en mètres. La trajectoire est divisée lorsqu'elle traverse une limite de cette zone tampon.
config text Chaîne JSON spécifiant une seule règle de division. Consultez la section Règles de division.
indexes int[] Index des points où effectuer la division. Les index commencent à 0.

Fonctionnement

Division par géométrie

Indiquez une géométrie de type Point ou MultiPoint ainsi qu'un rayon de zone tampon. La fonction construit une zone tampon circulaire autour de chaque point et divise la trajectoire à chaque intersection avec la limite de cette zone.

Split a trajectory based on a geometry object.

Si aucune partie de la trajectoire n'intersecte une zone tampon, aucune division n'a lieu et la fonction renvoie la trajectoire d'origine sans modification.

Division par règle

Transmettez une chaîne JSON contenant exactement une clé de règle. Le comportement varie selon la famille de règles :

  • Les règles **cut_point.*** effectuent la division au niveau de points d'échantillonnage spécifiques (point B dans le diagramme).

  • Les règles **cut_edge.*** divisent la trajectoire au niveau d'arêtes spécifiques (point C dans le diagramme).

  • Les règles **drop_edge.*** suppriment entièrement les arêtes correspondantes. Utilisez ces règles pour nettoyer le bruit des données de trajectoire, par exemple en supprimant les segments très longs causés par une perte de signal GPS ou des sauts de position importants.

Split a trajectory based on a rule.

Règles de division

Règle Type de valeur Description
cut_point.max_point Entier positif Divise tous les N points d'échantillonnage.
cut_point.even_divide Entier positif Divise en N parties égales. Si la trajectoire comporte moins d'arêtes que N, chaque arête devient une sous-trajectoire distincte.
cut_edge.time_interval Plage de temps positive Divise à intervalles de temps réguliers. Vous pouvez éventuellement spécifier une heure de référence : "1 hour, 2000-01-01".
cut_edge.geohash Entier pair positif Divise de sorte que chaque sous-trajectoire tienne dans une cellule de grille Geohash à la précision spécifiée. Les données de trajectoire doivent utiliser des coordonnées latitude/longitude.
drop_edge.temporal_length Plage de temps Supprime les arêtes dont la durée dépasse la valeur spécifiée.
drop_edge.spatial_distance_2d Nombre à virgule flottante Supprime les arêtes dont la distance euclidienne 2D dépasse la valeur spécifiée. Si toutes les arêtes dépassent le seuil, la fonction renvoie {}.

Division par index

Transmettez un tableau d'index de points. Pour n index fournis, la fonction renvoie n-1 sous-trajectoires. Il n'est pas nécessaire d'inclure les points de début et de fin de la trajectoire dans le tableau d'index.

Exemples

Configuration des données d'exemple

CREATE TABLE tr_split_traj (id integer, traj trajectory);

INSERT INTO tr_split_traj VALUES (
  3,
  ST_MakeTrajectory(
    'STPOINT'::leaftype,
    st_geomfromtext('LINESTRING(99.027 29.7555,99.313 29.9975,99.852 30.0745,104.879 35.0795,105.044 35.1235,105.187 35.0685,109.906 35.0795,110.071 35.1675,110.192 35.0355,110.544 35.0245,111.017 34.8045)', 4326),
    ARRAY[
      '2010-01-01 14:30'::timestamp,
      '2010-01-01 15:00','2010-01-01 15:10','2010-01-01 15:20',
      '2010-01-01 15:30','2010-01-01 15:40','2010-01-01 15:50',
      '2010-01-01 16:00','2010-01-01 16:10','2010-01-01 16:20',
      '2010-01-01 16:30'
    ],
    '{"leafcount":11,"attributes":{"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140,150,160,170,180,190,200,210,220]}}}'
  )
);

Division par géométrie

Divisez la trajectoire chaque fois qu'elle passe à moins de 23 000 mètres de n'importe quel point dans MULTIPOINT(100 30, 105 35, 110 35). Cette opération produit 4 sous-trajectoires.

SELECT id, unnest(st_split(traj, st_geomfromtext('MULTIPOINT(100 30,105 35,110 35)'), 23000)) AS subtraj
FROM tr_split_traj;
 id | subtraj
----+--------
  3 | {"trajectory":{"version":1,"type":"STPOINT","leafcount":3,"start_time":"Fri Jan 01 14:30:00 2010","end_time":"Fri Jan 01 15:10:00 2010",...}}
  3 | {"trajectory":{"version":1,"type":"STPOINT","leafcount":2,"start_time":"Fri Jan 01 15:10:00 2010","end_time":"Fri Jan 01 15:20:00 2010",...}}
  3 | {"trajectory":{"version":1,"type":"STPOINT","leafcount":2,"start_time":"Fri Jan 01 15:40:00 2010","end_time":"Fri Jan 01 15:50:00 2010",...}}
  3 | {"trajectory":{"version":1,"type":"STPOINT","leafcount":3,"start_time":"Fri Jan 01 16:10:00 2010","end_time":"Fri Jan 01 16:30:00 2010",...}}
(4 rows)

Cas limite : si la valeur de radius_of_buffer est trop petite pour que la trajectoire intersecte une zone tampon, aucune division ne se produit et la fonction renvoie la trajectoire d'origine sous forme d'un tableau à un seul élément.

Division par règle

Les exemples suivants utilisent tous la même trajectoire de 19 points définie inline.

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
)

**cut_point.max_point — division tous les 4 points (produit 5 sous-trajectoires)**

-- append to the WITH block above
SELECT unnest(ST_split(a, '{"cut_point.max_point":4}')) FROM traj;
-- Result: 5 rows, leafcount 5/5/5/5/3

**cut_point.max_point — division tous les 10 points (produit 2 sous-trajectoires)**

SELECT ST_split(a, '{"cut_point.max_point":10}') FROM traj;
-- Result: 1 row containing an array of 2 sub-trajectories, leafcount 10/10

**cut_point.max_point — division tous les 3 points (produit 7 sous-trajectoires)**

SELECT ST_split(a, '{"cut_point.max_point":3}') FROM traj;
-- Result: 1 row containing an array of 7 sub-trajectories, leafcount 3/4/4/4/4/4/2

**cut_point.even_divide — division en 100 parties égales**

Étant donné que la trajectoire ne comporte que 18 arêtes (19 points) et que 18 < 100, chaque arête devient sa propre sous-trajectoire. Le résultat est un tableau de 18 sous-trajectoires, chacune ayant un leafcount de 2.

SELECT ST_split(a, '{"cut_point.even_divide":100}') FROM traj;
-- Result: 1 row containing an array of 18 sub-trajectories

**cut_edge.geohash — division par précision Geohash 2 (produit 4 sous-trajectoires)**

SELECT ST_split(a, '{"cut_edge.geohash":2}') FROM traj;
-- Result: 1 row containing an array of 4 sub-trajectories

**cut_edge.geohash — division par précision Geohash 20 (produit 19 sous-trajectoires)**

SELECT ST_split(a, '{"cut_edge.geohash":20}') FROM traj;
-- Result: 1 row containing an array of 19 sub-trajectories

**drop_edge.spatial_distance_2d — suppression des arêtes de plus de 13 (produit 1 sous-trajectoire)**

SELECT ST_split(a, '{"drop_edge.spatial_distance_2d":13}') FROM traj;
-- Result: 1 sub-trajectory with leafcount 18 (first long edge removed)

**drop_edge.spatial_distance_2d — suppression des arêtes de plus de 10 (produit 7 sous-trajectoires)**

SELECT ST_split(a, '{"drop_edge.spatial_distance_2d":10}') FROM traj;
-- Result: array of 7 sub-trajectories

**drop_edge.spatial_distance_2d — seuil de 1 (toutes les arêtes supprimées)**

Lorsque le seuil est inférieur à la longueur de toutes les arêtes, chaque arête est supprimée et la fonction renvoie un tableau vide.

SELECT ST_split(a, '{"drop_edge.spatial_distance_2d":1}') FROM traj;
-- Result: {}

**cut_edge.time_interval — division toutes les 50 minutes (produit 5 sous-trajectoires)**

SELECT ST_split(a, '{"cut_edge.time_interval":"50 minute"}') FROM traj;
-- Result: array of 5 sub-trajectories

**cut_edge.time_interval — division toutes les heures avec ancrage au 2000-01-01 (produit 4 sous-trajectoires)**

Utilisez unnest() pour développer le tableau en lignes individuelles.

SELECT unnest(ST_split(a, '{"cut_edge.time_interval":"1 hour, 2000-01-01"}')) FROM traj;
-- Result: 4 rows covering 00:01–01:00, 01:00–02:00, 02:00–03:00, 03:00–03:24

Division par index

3 index — 2 sous-trajectoires

SELECT unnest(ST_split(a, '{1,3,5}'::int[])) FROM traj;
-- Result: 2 rows
-- Sub-trajectory 1: points at indexes 1–3 (start_time 00:12:36, end_time 00:35:10)
-- Sub-trajectory 2: points at indexes 3–5 (start_time 00:35:10, end_time 00:57:44)

6 index (avec doublons et points limites) — 4 sous-trajectoires

Les valeurs d'index en double et les index limites explicites (0 et leafcount-1) sont acceptés. Après déduplication et tri, 5 points de division uniques produisent 4 sous-trajectoires.

SELECT unnest(ST_split(a, '{0}'::int[] || '{0,1,3,5}'::int[] || ST_leafcount(a) - 1)) FROM traj;
-- Result: 4 rows