Inilah awal (tidak benar-benar diuji ...) Dua asumsi pertama:
- Saya kira tabel trek Anda adalah tabel spasial PostGIS, dengan kolom geom? (Jika tidak, Anda harus menjalankan SELECT AddGeometryColumn (...) untuk mengaturnya menggunakan nilai Lon / Lat)
- Ketika Anda mengatakan "jarak incremental", saya berasumsi maksud Anda jarak akumulasi
Saya membuat dua tabel uji: trek untuk poin dan akumulasi untuk jarak dan waktu yang terakumulasi
geodata=# \d ms.tracks
Table "ms.tracks"
Column | Type | Modifiers
--------------+-----------------------------+-----------------------------------------------------
pk | integer | not null default nextval('tracks_pk_seq'::regclass)
trk_id | integer |
lon | double precision |
lat | double precision |
geom | geometry |
gps_timestmp | timestamp without time zone |
Indexes:
"tracks_pkey" PRIMARY KEY, btree (pk)
Check constraints:
"enforce_dims_geom" CHECK (st_ndims(geom) = 2)
"enforce_geotype_geom" CHECK (geometrytype(geom) = 'POINT'::text OR geom IS NULL)
"enforce_srid_geom" CHECK (st_srid(geom) = 4326)
dan
geodata=# \d accum
Table "ms.accum"
Column | Type | Modifiers
------------+--------------------+-----------
trk_id | integer |
accum_dist | double precision[] |
accum_time | double precision[] |
Sekarang inilah konsep kasar dari fungsi yang mengakumulasi jarak dan waktu, dan menempatkan nilai ke dalam array di tabel akumulasi. Fungsi ini disebut dengan trk_id sebagai parameter.
CREATE OR REPLACE FUNCTION public.calculate_accumulated_track(IN t_id integer) RETURNS void AS
$BODY$
DECLARE
i integer;
-- first date/time in the track
dt1 timestamp;
-- the date/time of following track points
dt2 timestamp;
num_rows integer;
-- first_row will be the primary key of the
-- first track point for the track id passed into the function
first_row integer := 1;
-- Accumulated distance and time, to be inserted into accum table
segment float :=0;
accum_t float;
accum_d float;
BEGIN
-- Initialize a row in the accum table
INSERT INTO accum VALUES (t_id, NULL, NULL);
-- Get the primary key of the first row for this track id.
SELECT pk INTO first_row FROM tracks WHERE trk_id=t_id ORDER BY pk LIMIT 1;
SELECT count(*) INTO num_rows FROM tracks WHERE trk_id=t_id;
SELECT gps_timestmp INTO dt1 FROM tracks WHERE trk_id=t_id ORDER BY gps_timestmp LIMIT 1;
FOR i in 1..num_rows LOOP
SELECT gps_timestmp INTO dt2 FROM tracks WHERE pk=i+first_row;
accum_t := dt2 - dt1;
IF pk==1 THEN
accum_d:=0;
ELSE
SELECT ST_Distance(t1.geom, t2.geom) INTO segment
FROM tracks t1, tracks t2
WHERE t1.pk=i+first_row-1 AND t2.pk=i+first_row;
END IF;
accum_t := accum_d+segment;
-- Now UPDATE the accum table
UPDATE accum SET accum_time[i]=accum_t WHERE trk_id=t_id;
UPDATE accum SET accum_dist[i]=accum_d WHERE trk_id=t_id;
END LOOP;
END;$BODY$
LANGUAGE plpgsql VOLATILE;
ALTER FUNCTION public.calculate_accumulated_track(IN integer) OWNER TO geodba;
Mungkin itu akan membantu Anda memulai.
Cheers, Micha