Joining temporal and spatial data
Time

This is really bad:

AND 
to_timestamp(floor((extract('epoch' from l.time::timestamp) / 600 )) * 600) = 
to_timestamp(floor((extract('epoch' from s.time::timestamp) / 600 )) * 600)


Instead, try to rewrite that in terms of l.time, ignoring epoch. I have no idea of the interval you want.

AND l.time BETWEEN s.time AND (s.time + '10 minutes');


Or whatever. If you're trying to assign arbitrary timestamps into 10 minutes intervals or whatever, there is no need to cast back to timestamp. You may consider writing your own function for convenience,

CREATE FUNCTION myIntervalExtract(ts timestamp with time zone)
RETURNS int
AS $$
  SELECT floor( extract(epoch FROM l.time::timestamp) / 600 )::int * 600;
$$ LANGUAGE sql
IMMUTABLE;


Now you can create a functional index on both myIntervalExtract(l.time) and myIntervalExtract(s.time) using the above. That will satisfy the join so long as you join 

FROM l
JOIN s ON myIntervalExtract(l.time) = myIntervalExtract(s.time)


GIS

ST_Contains(ST_Buffer()..) 


This is also an antipattern. You'll want to rewrite that to ST_DWithin. you should also aim not to have ST_Transform in your join conditions. Instead, consider using geography on the table.

FROM t1 JOIN t2 ON ST_DWithin(t1.polygeog, t2.geogpoint, distance_in_meters)