2

I will be deploying PostGIS in the next few day. I've never done this before, nor have I ever worked with and geo-spacial data in the past.

I will have two datasets: weather data (A) and coordinate data (B).

  • (A) will have records containing a lat, long, altitude, time and a measurement value.

  • (B) will have records containing a lat, long, altitude and time.

I would like to pull out a bunch of records from (B), which together would represent a trajectory through space and time.

I would then like to, for each record extracted from (B), query (A) for the measurement value which corresponds to the lat, long, altitude and time from (B)... give or take some distance (eg, within 10 seconds or within 1km radius from the record from (B)).

An example would be I have a GPS device taped around my head and I am flying through the clouds. As I fly, I record my lat, long, altitude and time of measurement. When I get home, I want to look at the weather data that I have available and show what the temperature was at lat_x, long_x, altitude_x and time_x. I want to do this for each measurement that I made while flying so that I can work out what temperatures I experienced during my flight. However, since I know my measurements may not be 100% accurate, I'd like to give a bit of tolerance to the time of my measurement, as well as to the location (imagine I have a donut with radius r around my center).

How can I achieve this? What functions should I look to use?

Happy to clarify further if needed.

UPDATE

As requested, some example data & expected output.

  • altitude is in feet.
  • temp in deg c

Weather data (A):

CREATE TEMP TABLE weather AS
SELECT lat, lon, alt, time::timestamp, temp
FROM ( VALUES
  ( 23, 7  , 30000, '2017-01-01 00:01:00', -4  ),
  ( 35, 13 , 33000, '2017-01-01 00:01:30', -9  ),
  ( 45, 19 , 36000, '2017-01-01 00:02:00', -11 ),
  ( 53, 30 , 40000, '2017-01-01 00:02:30', -15 )
) AS t(lat, lon, alt, time, temp);

Flight path (B):

CREATE TEMP TABLE flightpath AS
SELECT id, lat, lon, alt, time::timestamp
FROM ( VALUES
  ( 1, 7 , 9 , 29000, '2017-01-01 00:01:05' ),
  ( 1, 35, 14, 34000, '2017-01-01 00:01:31' ),
  ( 1, 44, 19, 37000, '2017-01-01 00:01:59' ),
  ( 1, 55, 31, 40100, '2017-01-01 00:02:28' ),
  ( 2, 20, 9 , 60000, '2017-01-01 00:14:05' )
) AS t(id, lat, lon, alt, time);

In the above example, I would expect to extract all records from (B) where id = 1. I'd then want to go over each record in (A) and extract records within some range according to lat, lon, altitude & time. So, for example, I would like a tolerance of +-3 for lat, lon, altitude and time... I would then expect to see a new table:

id | lat | lon | altitude (feet) | time                | temperature (c)
------------------------------------------------------------------------
1  | 7   | 9   | 29000           | 2017-01-01 00:01:05 | no measurement 
1  | 35  | 14  | 34000           | 2017-01-01 00:01:31 | -9
1  | 44  | 19  | 37000           | 2017-01-01 00:01:59 | -11
1  | 55  | 31  | 40100           | 2017-01-01 00:02:28 | -15
  • Please Edit your question and add some sample data and the expected output based on that data. Formatted text please, no screen shots – a_horse_with_no_name Feb 6 '17 at 11:08
  • What do you mean a difference of +/- 3 for alt and lat/long. +/- for lat/long is variable distance measurement based on the projection you're using. Also confused about the alt differences here. – Evan Carroll Feb 6 '17 at 23:40
  • Also, why doesn't the id=2 show as no measurement? – Evan Carroll Feb 6 '17 at 23:41
1

First, to make sense of this we convert to use geography points, rather than lat-long. I assume this is in WGS84. We do this because measuring a difference in lat/long doesn't make any sense. As you approach the poles the differences between 3 degrees of lat/long will be nothing compared to the equator.

BEGIN;
  ALTER TABLE flightpath ADD COLUMN geog geography;
  UPDATE flightpath SET geog =
    ST_SetSRID(ST_MakePoint(lon, lat), 4326)::geography;
  ALTER TABLE flightpath DROP COLUMN lon, DROP COLUMN lat;
COMMIT;

BEGIN;
  ALTER TABLE weather ADD COLUMN geog geography;
  UPDATE weather SET geog =
    ST_SetSRID(ST_MakePoint(lon, lat), 4326)::geography;
  ALTER TABLE weather DROP COLUMN lon, DROP COLUMN lat;
COMMIT;

Now you can use ST_DWithin and datetime math.

SELECT
  id,
  f.alt,
  f.time,
  coalesce(w.temp::text, 'no temperature') AS temp
FROM flightpath AS f
LEFT OUTER JOIN weather AS w
  ON (
    (
      w.time - f.time < '3 minutes'::interval      -- diff in time
      AND  f.time - w.time < '3 minutes'::interval
    )
    AND abs(w.alt - f.alt) <= 1000                 -- diff in alt
    AND ST_DWithin(w.geog, f.geog, 1000000)        -- diff in distance (meters)
  )
WHERE id = 1
ORDER BY f.alt;

That outputs something like this..

 id |  alt  |        time         |      temp      
----+-------+---------------------+----------------
  1 | 29000 | 2017-01-01 00:01:05 | no temperature
  1 | 34000 | 2017-01-01 00:01:31 | -9
  1 | 37000 | 2017-01-01 00:01:59 | -11
  1 | 40100 | 2017-01-01 00:02:28 | -15
0
select
        b.id,
        b.lat,
        b.lon,
        b.altitude,
        b.time,
        case when a.temperature is null then 'no measeurement'::text
        else a.temperature::text end
from
        flight_path b
left join weather a on
        b.lat between a.lat-3 and a.lat+3
        and b.lon between a.lon-3 and a.lon+3
        and a.altitude between a.altitude-1000 and a.altitude+1000
        and b.time between a.time-'10s'::interval and a.time+'10s'::interval
where id = 1
;
  • Thank you! I will have a look and test tomorrow or Wednesday and then get back to you! Much appreciated! – pookie Feb 6 '17 at 14:01
  • You can have a few difficulties if more than one point in the weather table are within range of one of the points of flight_path, but you could probably GROUP BY b.id and take the average a.temperature ... – joanolo Feb 6 '17 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.