PostGIS-GPXパス上のポイント間の累進距離を計算します


8

PostGIS-PostgreSQLのみを使用して標高プロファイルを作成しようとしています。GPXデータをPostGisデータベースにインポートしました。これで、トラックのGPS座標とトラックのすべてのGPSポイントのタイムスタンプを含むテーブルができました。次に、1行に2つ目のテーブルを作成します。

  1. トラックID
  2. 始点からの増分距離を表すフロートの配列
  3. 開始点からの増分時間を表す浮動小数点数の配列

単一のSQLストアドプロシージャでそれを行うことは可能ですか?

おかげで、

アンドレア

回答:


8

これが始まりです(実際にはテストされていません...)最初の2つの仮定:

  • あなたのトラックテーブルは、geom列を持つPostGIS空間テーブルだと思いますか?(そうでない場合は、SELECT AddGeometryColumn(...)を実行して、Lon / Lat値を使用して設定する必要があります)
  • 「インクリメンタルディスタンス」と言うときは、累積距離を意味していると思いますか?

私は2つのテストテーブルを作成しました。ポイントのトラックと、累積された距離と時間の累積です。

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[] | 

次に、距離と時間を累積し、値をaccumテーブルの配列に入れる関数の大まかなドラフトを示します。この関数は、trk_idをパラメーターとして呼び出されます。

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;

多分それはあなたが始めるのを助けるでしょう。

乾杯、ミチャ


それでおしまい!答えてくれてありがとう、これはまさに私が達成しようとしていたことです。
Andrea Cremaschi

1
関数をもう一度見ると、上のaccum_dがトラック上のポイントと最初のポイントの間のデカルト距離であることがわかります。それはあなたが望んでいたことではありません。むしろ、トラックに沿った距離が必要です。そこで、変数「セグメント」を追加し、各トラックセグメントを使用して累積距離を反映するようにaccum_dの計算を変更しました。見てください。
Micha

ええ、実際、それは「プログレッシブ」距離を意味するものでした。
Andrea Cremaschi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.