8 votos

PostGIS - calcular distancia progresiva entre puntos de una ruta en GPX

Estoy intentando crear un perfil de elevación de usar PostGIS-PostgreSQL solo. He importado GPX de datos en mi base de datos PostGis, así que ahora tengo una tabla completa de las coordenadas GPS de la pista y la marca de tiempo de cada uno de los GPS del punto de la pista. Ahora me gustaría construir una segunda tabla que contiene, en una sola fila:

  1. el id de la pista
  2. una matriz de carrozas que representan el incremento de la distancia desde el punto de partida
  3. una matriz de carrozas que representan el tiempo incremental desde el punto de partida

Es posible hacerlo en un solo procedimiento almacenado de SQL?

Gracias,

Andrea

9voto

GriffinHeart Puntos 187

Aquí está un inicio (en realidad no probado...) Dos primeros supuestos:

  • Supongo que las pistas de la tabla es una tabla espacial PostGIS, con una geometría de la columna? (Si no tendrás que correr SELECCIONE AddGeometryColumn(...) para configurarlo mediante el Lon/Lat valores)
  • Cuando usted dice "incremental distancia" estoy asumiendo que te refieres a la distancia acumulada?

He hecho dos tablas de prueba: pistas para los puntos y acum para el acumulado de los distancias y tiempos

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)

y

geodata=# \d accum
              Table "ms.accum"
   Column   |        Type        | Modifiers 
------------+--------------------+-----------
 trk_id     | integer            | 
 accum_dist | double precision[] | 
 accum_time | double precision[] | 

Ahora, aquí hay un borrador de una función que se acumula en las distancias y los tiempos, y coloca los valores en las matrices en la acum tabla. Se llama a esta función con el trk_id como un parámetro.

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;

Tal vez que le ayudarán a empezar.

Saludos, Micha

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X