/*
* niViz -- snow profiles visualization
* Copyright (C) 2015 WSL/SLF - Fluelastrasse 11 - 7260 Davos Dorf - Switzerland.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
(function (niviz) {
'use strict';
// --- Module Dependencies ---
var properties = Object.defineProperties;
var Position = niviz.Position;
/** @module niviz */
/**
* Meteorological Data.
*
* @class Meteo
* @constructor
*/
function Meteo() {
/**
* @property id
* @type String
*/
this.id;
/**
* @property position
* @type Position
*/
this.position = new Position();
/**
* @property data
* @type Array<Meteo.Data>
*/
this.data = [];
this.min = {};
this.max = {};
this.plot = {};
}
Meteo.prototype.push = function (data) {
this.data.push(data);
return this;
};
properties(Meteo.prototype, {
/**
* @property from
* @type Moment
*/
from: {
get: function () {
return (this.empty) ? null : this.data[0].timestamp;
}
},
/**
* @property to
* @type Moment
*/
to: {
get: function () {
return (this.empty) ? null : this.data[this.length - 1].timestamp;
}
},
/**
* @property length
* @type Number
*/
length: {
get: function () { return this.data.length; }
},
/**
* @property empty
* @type Boolean
*/
empty: {
get: function () { return this.data.length === 0; }
}
});
/**
* Get the closest index for the given date.
*
* @method index
*
* @param {Moment} date
* @return Number
*/
Meteo.prototype.index = function (date) {
var i = 0, ii = this.data.length, meteo, diff, min;
if (!moment.isMoment(date)) return this.$index;
if (this.$index) {
meteo = this.data[this.$index];
if (meteo.timestamp.diff(date) <= 0) {
i = this.$index;
} else {
i = this.$index;
for (i; i >= 0; --i) {
meteo = this.data[i];
diff = Math.abs(meteo.timestamp.diff(date));
if (diff < min || min === undefined) {
min = diff;
this.$index = i;
}
if (this.$index !== i) break; // diff is becoming bigger
}
return this.$index;
}
}
for (i; i < ii; ++i) {
meteo = this.data[i];
diff = Math.abs(meteo.timestamp.diff(date));
if (diff < min || min === undefined) {
min = diff;
this.$index = i;
}
if (this.$index !== i) break; // diff is becoming bigger
}
return this.$index;
};
/**
* Convert Kelvin to Celsius.
*
* @method celsius
* @static
* @param {Number} value A temperature in degrees Kelvin
* @return {Number} degrees Celsius
*/
Meteo.celsius = function (value) {
if (!value) return value;
return value - 273.15;
};
/**
* Convert a percentage value ranging from [0, 1] to [0, 100].
*
* @method percent
* @static
* @param {Number} value A percentage value ranging from 0 to 1
* @return {Number} A percentage value from 0 to 100
*/
Meteo.percent = function (value) {
if (!value) return value;
return 100 * value;
};
/**
* Conversion functions present.
*
* @property conversions
* @static
* @type {Object}
*/
Meteo.conversions = {
'K to °C': Meteo.celsius,
'x 100': Meteo.percent
};
/**
* The default meteo parameters preconfigured for the Meteograph.
*
* @property params
* @static
* @type {Object}
*/
Meteo.params = {
name: 'params', type: 'meteo', hint: 'test',
values: [ 'none', 'K to °C', 'x 100' ],
default: [{ name: 'p', display: 'Air pressure', unit: 'Pa',
convert: 'none', min: '', max: '', log: false, color: '#AEAEAE' },
{ name: 'ta', display: 'Air temperature', unit: '°C',
convert: 'K to °C', min: '', max: '', log: false, color: '#8324A4' },
{ name: 'rh', display: 'Relative humidity', unit: '%',
convert: 'x 100', min: 0, max: 100, log: false, color: '#50CBDB' },
{ name: 'tsg', display: 'Snow ground temperature', unit: '°C',
convert: 'K to °C', min: '', max: '', log: false, color: '#DE22E2' },
{ name: 'tss', display: 'Snow surface temperature', unit: '°C',
convert: 'K to °C', min: '', max: '', log: false, color: '#FA72B7' },
{ name: 'hs', display: 'Snow height', unit: 'm',
convert: 'none', min: '', max: '', log: false, color: '#000000' },
{ name: 'vw', display: 'Wind velocity', unit: 'm/s',
convert: 'none', min: '', max: '', log: false, color: '#297E24' },
{ name: 'dw', display: 'Wind direction', unit: '°',
convert: 'none', min: '', max: '', log: false, color: '#64DD78' },
{ name: 'vw_max', display: 'Gust wind velocity', unit: 'm/s',
convert: 'none', min: '', max: '', log: false, color: '#244A22' },
{ name: 'rswr', display: 'Reflected SW radiation', unit: 'W/m\u00b2',
convert: 'none', min: '', max: '', log: false, color: '#7D643A' },
{ name: 'oswr', display: 'Outgoing SW radiation', unit: 'W/m\u00b2',
convert: 'none', min: '', max: '', log: false, color: '#7D643A' },
{ name: 'iswr', display: 'Incoming SW radiation', unit: 'W/m\u00b2',
convert: 'none', min: '', max: '', log: false, color: '#F9CA25' },
{ name: 'ilwr', display: 'Incoming LW radiation', unit: 'W/m\u00b2',
convert: 'none', min: '', max: '', log: false, color: '#D99521' },
{ name: 'psum', display: 'Precipitation', unit: 'mm',
convert: 'none', min: '', max: '', log: false, color: '#2431A4' },
{ name: 'psum_ph', display: 'Precipitation phase', unit: '',
convert: 'none', min: '', max: '', log: false, color: '#7E8EDF' }
]
};
/**
* The default meteo parameter groups preconfigured for the Meteograph.
*
* @property group
* @static
* @type {Object}
*/
Meteo.group = {
name: 'group', type: 'meteogroup', hint: 'test',
values: [],
default: [{ name: 'tsurf', display: 'Temperature', unit: '°C',
group: 'ta,tss', min: '-30', max: '30', log: false }
]
};
/**
* Get the configuration for a specific meteo parameter by going through both the
* parameter groups and individual parameter configurations. Return an object
* with all necessary properties to graph a meteo parameter / group.
*
* @method getconfig
* @param {String} parameter
* @param {Array<Object>} parameters
* @param {Array<Object>} groups
* @return {Object}
*/
Meteo.prototype.getconfig = function (parameter, parameters, groups, use_settings) {
var config;
parameters.forEach(function (p) {
if (p.name === parameter) config = p;
});
if (!config) groups.forEach(function (p) {
if (p.name === parameter) config = p;
});
if (config && use_settings) {
return {
name: config.display || config.name,
color: config.color,
unit: config.unit === '' ? undefined : config.unit,
convert: Meteo.conversions[config.convert],
min: config.min === '' ? undefined : parseFloat(config.min),
max: config.max === '' ? undefined : parseFloat(config.max),
log: !!config.log
};
} else if (this.plot[parameter] && !use_settings) {
var plot = this.plot[parameter], obj = { name: parameter };
if (plot.description) obj.name = plot.description;
if (plot.unit) obj.unit = plot.unit;
if (plot.min !== undefined) obj.min = plot.min;
if (plot.max !== undefined) obj.max = plot.max;
if (plot.color) obj.color = plot.color;
return obj;
} else {
var plot = this.plot[parameter], obj = { name: parameter };
return obj;
}
return { name: parameter };
};
/**
* An object representing all meteorogical parameters measured at one point in time.
*
* @class MeteoData
* @constructor
*/
function MeteoData () {}
// --- Module Export ---
Meteo.Data = MeteoData;
niviz.Meteo = Meteo;
}(niviz));