Đây là một khởi đầu (chưa thực sự được thử nghiệm ...) Hai giả định đầu tiên:
- Tôi đoán bảng theo dõi của bạn là bảng không gian PostGIS, với cột geom? (Nếu không, bạn sẽ phải chạy CHỌN AddGeometryColumn (...) để thiết lập nó bằng các giá trị Lon / Lat)
- Khi bạn nói "khoảng cách gia tăng" tôi cho rằng bạn có nghĩa là khoảng cách tích lũy?
Tôi đã thực hiện hai bảng thử nghiệm: theo dõi các điểm và tích lũy cho khoảng cách và thời gian tích lũy
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)
và
geodata=# \d accum
Table "ms.accum"
Column | Type | Modifiers
------------+--------------------+-----------
trk_id | integer |
accum_dist | double precision[] |
accum_time | double precision[] |
Bây giờ đây là bản nháp sơ bộ của hàm tích lũy khoảng cách và thời gian và đặt các giá trị thành mảng trong bảng tích lũy. Hàm này được gọi với trk_id làm tham số.
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;
Có lẽ điều đó sẽ giúp bạn bắt đầu.
Chúc mừng, Micha