package data import ( "database/sql" "time" ) type RadarWeather struct { Alias string Lat float64 Lon float64 DT time.Time Temperature sql.NullFloat64 Humidity sql.NullFloat64 CloudRate sql.NullFloat64 Visibility sql.NullFloat64 DSWRF sql.NullFloat64 WindSpeed sql.NullFloat64 WindDirection sql.NullFloat64 Pressure sql.NullFloat64 } // RadarWeatherNearest returns the nearest radar_weather row to (lat,lon) around dt within a window. // It orders by absolute time difference then squared distance. func RadarWeatherNearest(lat, lon float64, dt time.Time, window time.Duration) (*RadarWeather, error) { from := dt.Add(-window) to := dt.Add(window) const q = ` SELECT alias, lat, lon, dt, temperature, humidity, cloudrate, visibility, dswrf, wind_speed, wind_direction, pressure FROM radar_weather WHERE dt BETWEEN $1 AND $2 ORDER BY ABS(EXTRACT(EPOCH FROM (dt - $3))) ASC, ((lat - $4)*(lat - $4) + (lon - $5)*(lon - $5)) ASC LIMIT 1` row := DB().QueryRow(q, from, to, dt, lat, lon) var rw RadarWeather if err := row.Scan(&rw.Alias, &rw.Lat, &rw.Lon, &rw.DT, &rw.Temperature, &rw.Humidity, &rw.CloudRate, &rw.Visibility, &rw.DSWRF, &rw.WindSpeed, &rw.WindDirection, &rw.Pressure); err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, err } return &rw, nil }