PostGIS - Tính khoảng cách lũy tiến giữa các điểm trên đường GPX


8

Tôi đang cố gắng xây dựng một cấu hình độ cao chỉ bằng PostGIS-PostgreSQL. Tôi đã nhập dữ liệu GPX trong cơ sở dữ liệu PostGis của mình, vì vậy bây giờ tôi có một bảng chứa đầy tọa độ GPS của bản nhạc và dấu thời gian của mỗi điểm GPS duy nhất của bản nhạc. Bây giờ tôi muốn xây dựng một bảng thứ hai chứa, trong một hàng duy nhất:

  1. id theo dõi
  2. một mảng phao biểu thị khoảng cách tăng dần từ điểm bắt đầu
  3. một mảng phao biểu thị thời gian tăng dần từ điểm bắt đầu

Có thể làm điều đó trong một thủ tục lưu trữ SQL không?

Cảm ơn,

Andrea

Câu trả lời:


8

Đâ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)

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


Đó là nó! Cảm ơn bạn đã trả lời, đây chính xác là tôi đã cố gắng thực hiện.
Andrea Cremaschi

1
Nhìn qua chức năng lần thứ hai, tôi thấy rằng tích lũy ở trên là khoảng cách cartesian giữa một điểm trên đường đua và điểm đầu tiên. Đó không phải là những gì bạn muốn. Thay vào đó bạn cần khoảng cách dọc theo đường đua . Vì vậy, tôi đã thêm một "phân đoạn" biến đổi và thay đổi cách tính tích lũy để phản ánh khoảng cách tích lũy bằng cách sử dụng từng phân đoạn theo dõi. Có một cái nhìn.
Micha

Vâng, thực tế đó là ý tôi với khoảng cách "tiến bộ" .. Cảm ơn bạn một lần nữa!
Andrea Cremaschi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.