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
| Parameter | Type | Description |
|---|---|---|
traj | trajectory | Trajectory yang akan dibagi. |
geom | geometry | Objek geometry yang digunakan sebagai batas pemisah. Hanya Point dan MultiPoint yang didukung. |
radius_of_buffer | float8 | Radius buffer di sekitar geometri Point, dalam satuan meter. Trajectory dibagi pada titik-titik tempat lintasan tersebut melewati batas buffer. |
config | text | String JSON yang menentukan satu aturan split. Lihat Split rules. |
indexes | int[] | 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.

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 rules
| Rule | Value type | Description |
|---|---|---|
cut_point.max_point | Positive integer | Membagi setiap N titik pengambilan sampel. |
cut_point.even_divide | Positive integer | Membagi menjadi N bagian yang sama. Jika jumlah edge trajectory lebih sedikit daripada N, setiap edge menjadi sub-trajectory tersendiri. |
cut_edge.time_interval | Positive time range | Membagi pada interval waktu reguler. Secara opsional tentukan waktu jangkar (anchor time): "1 hour, 2000-01-01". |
cut_edge.geohash | Positive even integer | Membagi sehingga setiap sub-trajectory berada dalam satu sel grid Geohash pada presisi yang ditentukan. Data trajectory harus menggunakan koordinat latitude/longitude. |
drop_edge.temporal_length | Time range | Menghapus edge yang durasinya lebih panjang dari nilai yang ditentukan. |
drop_edge.spatial_distance_2d | Floating point | Menghapus 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/3cut_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/10cut_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/2cut_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-trajectorycut_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-trajectorycut_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-trajectorydrop_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-trajectorydrop_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-trajectorycut_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:24Split 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