All Products
Search
Document Center

ApsaraDB RDS:ST_Split

Last Updated:Mar 29, 2026

Membagi sebuah trajectory menjadi array sub-trajectory. Tersedia tiga bentuk overload: split berdasarkan geometry, split berdasarkan aturan, dan split berdasarkan indeks.

Fungsi ini mengembalikan trajectory[]. Gunakan unnest() untuk memperluas hasilnya menjadi baris-baris individual.

Sintaksis

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);

Parameter

ParameterTypeDescription
trajtrajectoryTrajectory yang akan dibagi.
geomgeometryObjek geometry yang digunakan sebagai batas pemisah. Hanya Point dan MultiPoint yang didukung.
radius_of_bufferfloat8Radius buffer di sekitar geometri Point, dalam satuan meter. Trajectory dibagi pada titik-titik tempat lintasan tersebut melewati batas buffer.
configtextString JSON yang menentukan satu aturan split. Lihat Split rules.
indexesint[]Indeks titik tempat pembagian dilakukan. Indeks dimulai dari 0.

Cara kerja

Split berdasarkan geometry

Berikan geometri Point atau MultiPoint beserta radius buffer. Fungsi ini membuat buffer melingkar di sekitar setiap titik dan membagi trajectory setiap kali lintasan melewati batas buffer tersebut.

Split a trajectory based on a geometry object.

Jika tidak ada bagian trajectory yang berpotongan dengan buffer apa pun, tidak terjadi pembagian dan fungsi mengembalikan trajectory asli tanpa perubahan.

Split berdasarkan aturan

Berikan string JSON yang berisi tepat satu kunci aturan. Perilaku fungsi bergantung pada family aturan tersebut:

  • Aturan cut_point.* membagi pada titik pengambilan sampel tertentu (titik B pada diagram).

  • Aturan cut_edge.* membagi pada edge tertentu (titik C pada diagram).

  • Aturan drop_edge.* menghapus seluruh edge yang sesuai. Gunakan aturan ini untuk membersihkan kebisingan dari data trajectory, seperti menghapus segmen yang sangat panjang akibat kehilangan sinyal GPS atau lompatan posisi besar.

Split a trajectory based on a rule.

Split rules

RuleValue typeDescription
cut_point.max_pointPositive integerMembagi setiap N titik pengambilan sampel.
cut_point.even_dividePositive integerMembagi menjadi N bagian yang sama. Jika jumlah edge trajectory lebih sedikit daripada N, setiap edge menjadi sub-trajectory tersendiri.
cut_edge.time_intervalPositive time rangeMembagi pada interval waktu reguler. Secara opsional tentukan waktu jangkar (anchor time): "1 hour, 2000-01-01".
cut_edge.geohashPositive even integerMembagi sehingga setiap sub-trajectory berada dalam satu sel grid Geohash pada presisi yang ditentukan. Data trajectory harus menggunakan koordinat latitude/longitude.
drop_edge.temporal_lengthTime rangeMenghapus edge yang durasinya lebih panjang dari nilai yang ditentukan.
drop_edge.spatial_distance_2dFloating pointMenghapus edge yang jarak Euclidean 2D-nya lebih panjang dari nilai ambang batas yang ditentukan. Jika semua edge lebih panjang dari ambang batas, fungsi mengembalikan {}.

Split berdasarkan indeks

Berikan array indeks titik. Dengan n indeks, fungsi mengembalikan n–1 sub-trajectory. Titik awal dan akhir trajectory tidak perlu dimasukkan dalam array indeks.

Contoh

Persiapan data sampel

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]}}}'
  )
);

Split berdasarkan geometry

Pisahkan trajectory pada setiap titik lintasan yang berada dalam jarak 23.000 meter dari titik mana pun dalam MULTIPOINT(100 30, 105 35, 110 35). Operasi ini menghasilkan 4 sub-trajectory.

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)

Kasus khusus: Jika radius_of_buffer terlalu kecil sehingga trajectory tidak berpotongan dengan zona buffer apa pun, tidak terjadi pembagian dan fungsi mengembalikan trajectory asli sebagai array berisi satu elemen.

Split berdasarkan aturan

Contoh-contoh berikut semuanya menggunakan trajectory 19-titik yang didefinisikan secara 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 — bagi setiap 4 titik (menghasilkan 5 sub-trajectory)

-- tambahkan ke blok WITH di atas
SELECT unnest(ST_split(a, '{"cut_point.max_point":4}')) FROM traj;
-- Hasil: 5 baris, leafcount 5/5/5/5/3

cut_point.max_point — bagi setiap 10 titik (menghasilkan 2 sub-trajectory)

SELECT ST_split(a, '{"cut_point.max_point":10}') FROM traj;
-- Hasil: 1 baris berisi array 2 sub-trajectory, leafcount 10/10

cut_point.max_point — bagi setiap 3 titik (menghasilkan 7 sub-trajectory)

SELECT ST_split(a, '{"cut_point.max_point":3}') FROM traj;
-- Hasil: 1 baris berisi array 7 sub-trajectory, leafcount 3/4/4/4/4/4/2

cut_point.even_divide — bagi menjadi 100 bagian yang sama

Karena trajectory hanya memiliki 18 edge (19 titik), dan 18 < 100, setiap edge menjadi sub-trajectory tersendiri. Hasilnya adalah array berisi 18 sub-trajectory, masing-masing dengan leafcount 2.

SELECT ST_split(a, '{"cut_point.even_divide":100}') FROM traj;
-- Hasil: 1 baris berisi array 18 sub-trajectory

cut_edge.geohash — split berdasarkan presisi Geohash 2 (menghasilkan 4 sub-trajectory)

SELECT ST_split(a, '{"cut_edge.geohash":2}') FROM traj;
-- Hasil: 1 baris berisi array 4 sub-trajectory

cut_edge.geohash — split berdasarkan presisi Geohash 20 (menghasilkan 19 sub-trajectory)

SELECT ST_split(a, '{"cut_edge.geohash":20}') FROM traj;
-- Hasil: 1 baris berisi array 19 sub-trajectory

drop_edge.spatial_distance_2d — hapus edge yang lebih panjang dari 13 (menghasilkan 1 sub-trajectory)

SELECT ST_split(a, '{"drop_edge.spatial_distance_2d":13}') FROM traj;
-- Hasil: 1 sub-trajectory dengan leafcount 18 (edge panjang pertama dihapus)

drop_edge.spatial_distance_2d — hapus edge yang lebih panjang dari 10 (menghasilkan 7 sub-trajectory)

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

drop_edge.spatial_distance_2d — ambang batas 1 (semua edge dihapus)

Ketika ambang batas lebih kecil daripada panjang semua edge, setiap edge dihapus dan fungsi mengembalikan array kosong.

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

cut_edge.time_interval — split setiap 50 menit (menghasilkan 5 sub-trajectory)

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

cut_edge.time_interval — split setiap 1 jam dengan jangkar waktu 2000-01-01 (menghasilkan 4 sub-trajectory)

Gunakan unnest() untuk memperluas array menjadi baris-baris individual.

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

Split berdasarkan indeks

3 indeks — 2 sub-trajectory

SELECT unnest(ST_split(a, '{1,3,5}'::int[])) FROM traj;
-- Hasil: 2 baris
-- Sub-trajectory 1: titik pada indeks 1–3 (start_time 00:12:36, end_time 00:35:10)
-- Sub-trajectory 2: titik pada indeks 3–5 (start_time 00:35:10, end_time 00:57:44)

6 indeks (dengan duplikat dan titik batas) — 4 sub-trajectory

Nilai indeks duplikat dan indeks batas eksplisit (0 dan leafcount–1) diterima. Setelah deduplikasi dan pengurutan, 5 titik pemisah unik menghasilkan 4 sub-trajectory.

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