/*
* 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/>.
*/
/* eslint no-loop-func: [0], complexity: [2, 30] */
(function (niviz) {
'use strict';
// --- Module Dependencies ---
var Header = niviz.Header;
var round = niviz.util.round;
/** @module niviz */
/**
* Serialize data into CAAML format
*
* @class CAAML
* @constructor
*/
var CAAML = {};
CAAML.precipiType = [
'-DZ', 'DZ', '+DZ', '-RA', 'RA', '+RA', '-SN', 'SN', '+SN', '-SG', 'SG', '+SG',
'-IC', 'IC', '+IC', '-PE', 'PE', '+PE', '-GR', 'GR', '+GR', '-GS', 'GS', '+GS',
'UP', 'Nil', 'RASN', 'FZRA'
];
CAAML.skyconditions = ['CLR', 'FEW', 'SCT', 'BKN', 'OVC', 'X'];
CAAML.NS = {
caaml: 'http://caaml.org/Schemas/V5.0/Profiles/SnowProfileIACS',
xs: 'http://www.w3.org/2001/XMLSchema'
};
CAAML.addNS = function (node, profile) {
node.setAttribute('xmlns:gml', 'http://www.opengis.net/gml');
node.setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
node.setAttribute('gml:id', profile.info.profile_gmlid
|| niviz.CAAML.defaults.profile_gmlid || 'NA');
};
CAAML.addMetaData = function (station, profile, dom, node) {
var mp = node.appendChild(dom.createElement('caaml:metaDataProperty'));
var md = mp.appendChild((dom.createElement('caaml:MetaData')));
var dr = md.appendChild((dom.createElement('caaml:dateTimeReport')));
dr.textContent = moment().format('YYYY-MM-DDTHH:mm:ss.sssZ');
var sr = md.appendChild(dom.createElement('caaml:srcRef')), pe, na, op;
if (!profile.info.operation) {
pe = sr.appendChild((dom.createElement('caaml:Person')));
pe.setAttribute('gml:id', profile.info.observer_gmlid
|| niviz.CAAML.defaults.observer_gmlid || 'NA');
na = pe.appendChild((dom.createElement('caaml:name')));
na.textContent = profile.info.observer || '';
} else {
op = sr.appendChild((dom.createElement('caaml:Operation')));
op.setAttribute('gml:id', profile.info.operation_gmlid
|| niviz.CAAML.defaults.operation_gmlid || 'NA');
na = op.appendChild((dom.createElement('caaml:name')));
na.textContent = profile.info.operation || '';
var cp = op.appendChild((dom.createElement('caaml:contactPerson')));
pe = cp.appendChild((dom.createElement('caaml:Person')));
pe.setAttribute('gml:id', profile.info.observer_gmlid
|| niviz.CAAML.defaults.observer_gmlid || 'NA');
na = pe.appendChild((dom.createElement('caaml:name')));
na.textContent = profile.info.observer || '';
}
if (profile.info.comment && profile.info.comment.metadata)
CAAML.addNode(dom, md, profile.info.comment.metadata, 'caaml:comment');
if (profile.info.custom_meta) // looping through customData
md.appendChild(profile.info.custom_meta);
};
CAAML.addValidTime = function (profile, gmlid, dom, node) {
var vt = node.appendChild(dom.createElement('caaml:validTime'));
var ti = vt.appendChild((dom.createElement('caaml:TimeInstant')));
ti.setAttribute('gml:id', gmlid);
var tp = ti.appendChild(dom.createElement('caaml:timePosition'));
tp.textContent = profile.date.format('YYYY-MM-DDTHH:mm:ss.sssZ');
};
CAAML.addNode = function (dom, node, parameter, cname, uom, decimals) {
if (parameter !== undefined && parameter !== null) {
var tmp = node.appendChild(dom.createElement(cname));
if (uom !== undefined) tmp.setAttribute('uom', uom);
if (decimals === undefined)
tmp.textContent = parameter;
else
tmp.textContent = parameter.toFixed(decimals);
}
};
CAAML.addPointProfile = function (dom, profile, basenode, feature, attributes, nodes) {
var mc = basenode.appendChild(dom.createElement('caaml:MeasurementComponents')), i, l;
attributes.forEach(function (attribute) {
mc.setAttribute(attribute[0], attribute[1]);
});
nodes.forEach(function (node) {
CAAML.addNode(dom, mc, 'template', node);
});
var m = basenode.appendChild(dom.createElement('caaml:Measurements'));
var ntuples = [];
for (i = feature.layers.length - 1; i >= 0; --i) {
l = feature.layers[i];
ntuples.push(round(profile.top - l.top, 10) + ',' + round(l.value, 10));
}
CAAML.addNode(dom, m, ntuples.join(' '), 'caaml:tupleList');
};
CAAML.addSnowProfile = function (station, profile, dom, root) {
var sp = root.appendChild(dom.createElement('caaml:snowProfileResultsOf'));
var sm = sp.appendChild(dom.createElement('caaml:SnowProfileMeasurements'));
sm.setAttribute('dir', 'top down');
if (profile.info.custom_snow) // looping through customData
sm.appendChild(profile.info.custom_snow);
if (profile.info.comment && profile.info.comment.weather)
CAAML.addNode(dom, sm, profile.info.comment.weather, 'caaml:comment');
if (profile.height || profile.height === 0)
CAAML.addNode(dom, sm, profile.height, 'caaml:profileDepth', 'cm');
if (profile.info.sky !== '')
CAAML.addNode(dom, sm, profile.info.sky, 'caaml:skyCond');
if (profile.info.precipitation)
CAAML.addNode(dom, sm, profile.info.precipitation, 'caaml:precipTI');
if (profile.info.ta || profile.info.ta === 0)
CAAML.addNode(dom, sm, profile.info.ta, 'caaml:airTempPres', 'degC');
if (profile.info.wind) {
if (profile.info.wind.speed)
CAAML.addNode(dom, sm, profile.info.wind.speed, 'caaml:windSpd', 'ms-1');
if (profile.info.wind.dir) {
var dir = sm.appendChild(dom.createElement('caaml:windDir'));
var aspect = dir.appendChild(dom.createElement('caaml:AspectPosition'));
CAAML.addNode(dom, aspect, profile.info.wind.dir, 'caaml:position');
}
}
if (profile.hs || profile.hs === 0 || (profile.swe && profile.density)) {
var hs = sm.appendChild(dom.createElement('caaml:hS'));
var co = hs.appendChild(dom.createElement('caaml:Components'));
if (profile.info.hs === 0) {
// do nothing, outputting anything would be confusing
} else if (profile.hs && (!profile.density || !profile.density.height
|| profile.hs !== profile.density.height)) {
// this is an interesting case: it means that we that either
// density measurement and hs are out of sync or that we have a
// profile with soil; since swe is anyway calculated internally
// we have a preference for hs, it's more consistent
CAAML.addNode(dom, co, profile.hs, 'caaml:snowHeight', 'cm');
// Only output if hs not more than 10cm off density height
if (Header.checkdensity(profile))
CAAML.addNode(dom, co,
Math.round(profile.density.elements[0].average() * profile.hs / 100),
'caaml:swe', 'mm');
} else if (profile.swe && profile.density) {
CAAML.addNode(dom, co, profile.density.height, 'caaml:snowHeight', 'cm');
CAAML.addNode(dom, co, profile.swe, 'caaml:swe', 'mm');
} else {
CAAML.addNode(dom, co, profile.hs, 'caaml:snowHeight', 'cm');
}
}
if (profile.info && (profile.info.hn24 || profile.info.hn24 === 0)) {
var hn24 = sm.appendChild(dom.createElement('caaml:hN24'));
var com = hn24.appendChild(dom.createElement('caaml:Components'));
CAAML.addNode(dom, com, profile.info.hn24, 'caaml:snowHeight', 'cm');
}
if (profile.info.penetration) {
if (profile.info.penetration.ram !== '')
CAAML.addNode(dom, sm, profile.info.penetration.ram, 'caaml:penetrationRam', 'cm');
if (profile.info.penetration.foot !== '')
CAAML.addNode(dom, sm, profile.info.penetration.foot, 'caaml:penetrationFoot', 'cm');
if (profile.info.penetration.ski !== '')
CAAML.addNode(dom, sm, profile.info.penetration.ski, 'caaml:penetrationSki', 'cm');
}
if (profile.info.roughness) {
var sf = sm.appendChild(dom.createElement('caaml:surfFeatures'));
var sfc = sf.appendChild(dom.createElement('caaml:Components'));
CAAML.addNode(dom, sfc, profile.info.roughness, 'caaml:surfRoughness');
}
CAAML.addStratProfile(profile, dom, sm);
CAAML.addTempProfile(profile, dom, sm);
CAAML.addDensityProfile(profile, dom, sm);
if (profile.wetness && profile.wetness.length > 1)
CAAML.addLwcProfile(profile, dom, sm, profile.wetness.elements[1]);
if (profile.ssa && profile.ssa.length > 1)
CAAML.addSSAProfile(profile, dom, sm, profile.ssa.elements[1]);
profile.ramm && profile.ramm.elements.forEach(function (ram) {
CAAML.addHardnessProfile(profile, dom, sm, ram);
});
profile.smp && profile.smp.elements.forEach(function (smp) {
CAAML.addSMPProfile(profile, dom, sm, smp);
});
CAAML.addStabilityProfile(profile, dom, sm);
};
CAAML.addStratProfile = function (profile, dom, node) {
var stratigraphic = [ 'grainshape', 'grainsize', 'hardness', 'wetness' ],
param;
stratigraphic.forEach(function (parameter) {
if (profile[parameter] && profile[parameter].elements[0] &&
profile[parameter].elements[0].layers.length) {
param = parameter;
}
});
if (!param) return;
var sp = node.appendChild(dom.createElement('caaml:stratProfile')),
i = profile[param].layers.length - 1, j = 0;
for ( ; i >= 0; --i) {
++j;
var hardness, wetness, gs1, gs2, gsavg, gsmax;
var l = sp.appendChild(dom.createElement('caaml:Layer'));
var comment = profile.comments && profile.comments.layers[i].value;
if (comment) CAAML.addNode(dom, l, comment, 'caaml:comment');
var depth = round(profile.top - profile[param].layers[i].top, 4);
var thickness = round(profile[param].layers[i].top - profile[param].layers[i].bottom, 4);
hardness = wetness = gs1 = gs2 = gsavg = gsmax = null;
var hlen = profile.hardness && profile.hardness.layers.length,
wlen = profile.wetness && profile.wetness.elements[0] && profile.wetness.layers.length,
gflen = profile.grainshape && profile.grainshape.layers.length,
gslen = profile.grainsize && profile.grainsize.layers.length;
if (profile.hardness && profile.hardness.layers[hlen - j])
hardness = profile.hardness.layers[hlen - j].caamlcode;
if (profile.wetness && profile.wetness.elements[0] && profile.wetness.layers[wlen - j])
wetness = profile.wetness.layers[wlen - j].code;
if (profile.grainshape && profile.grainshape.layers[gflen - j]) {
gs1 = profile.grainshape.layers[gflen - j].value.primary;
gs2 = profile.grainshape.layers[gflen - j].value.secondary;
}
if (profile.grainsize && profile.grainsize.layers[gslen - j]
&& profile.grainsize.layers[gslen - j].value) {
gsavg = profile.grainsize.layers[gslen - j].value.avg;
gsmax = profile.grainsize.layers[gslen - j].value.max;
}
CAAML.addNode(dom, l, depth, 'caaml:depthTop', 'cm');
CAAML.addNode(dom, l, thickness, 'caaml:thickness', 'cm');
if (gs1) CAAML.addNode(dom, l, gs1, 'caaml:grainFormPrimary');
if (gs1 && gs2) CAAML.addNode(dom, l, gs2, 'caaml:grainFormSecondary');
if (gsavg || gsmax) {
var gs = l.appendChild(dom.createElement('caaml:grainSize'));
gs.setAttribute('uom', 'mm');
var co = gs.appendChild(dom.createElement('caaml:Components'));
if (gsavg) CAAML.addNode(dom, co, gsavg, 'caaml:avg');
if (gsmax) CAAML.addNode(dom, co, gsmax, 'caaml:avgMax');
}
if (hardness) CAAML.addNode(dom, l, hardness, 'caaml:hardness', 'N');
if (wetness) CAAML.addNode(dom, l, wetness, 'caaml:lwc', '');
}
};
CAAML.addTempProfile = function (profile, dom, node) {
if (!profile.temperature) return;
var tp = node.appendChild(dom.createElement('caaml:tempProfile')), i;
tp.setAttribute('uomDepth', 'cm');
tp.setAttribute('uomTemp', 'degC');
if (profile.temperature.info.comment) {
var tpmd = tp.appendChild(dom.createElement('caaml:MetaData'));
CAAML.addNode(dom, tpmd, profile.temperature.info.comment, 'caaml:comment');
}
for (i = profile.temperature.layers.length - 1; i >= 0; --i) {
var l = profile.temperature.layers[i];
// Skip null values
if (!l.value && l.value !== 0) continue;
var ob = tp.appendChild(dom.createElement('caaml:Obs'));
CAAML.addNode(dom, ob, round(profile.top - l.top, 4), 'caaml:depth');
CAAML.addNode(dom, ob, round(l.value, 4), 'caaml:snowTemp');
}
};
CAAML.addDensityProfile = function (profile, dom, node) {
if (!profile.density) return;
var tp = node.appendChild(dom.createElement('caaml:densityProfile')), i;
tp.setAttribute('uomDepthTop', 'cm');
tp.setAttribute('uomDensity', 'kgm-3');
tp.setAttribute('uomThickness', 'cm');
if (profile.density.info.comment) {
var tpmd = tp.appendChild(dom.createElement('caaml:MetaData'));
CAAML.addNode(dom, tpmd, profile.density.info.comment, 'caaml:comment');
}
for (i = profile.density.layers.length - 1; i >= 0; --i) {
var l = profile.density.layers[i];
// Skip null values
if (!l.value && l.value !== 0) continue;
var ob = tp.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, ob, round(profile.top - l.top, 4), 'caaml:depthTop');
CAAML.addNode(dom, ob, round(l.top - l.bottom, 4), 'caaml:thickness');
CAAML.addNode(dom, ob, round(l.value, 4), 'caaml:density');
}
};
CAAML.addHardnessProfile = function (profile, dom, node, feature) {
if (!feature) return;
var hp = node.appendChild(dom.createElement('caaml:hardnessProfile')), i;
hp.setAttribute('uomDepthTop', 'cm');
hp.setAttribute('uomThickness', 'cm');
hp.setAttribute('uomDropHeight', 'cm');
hp.setAttribute('uomHardness', 'N');
hp.setAttribute('uomWeightHammer', 'kg');
hp.setAttribute('uomWeightTube', 'kg');
var md = hp.appendChild(dom.createElement('caaml:MetaData'));
if (feature.info.comment)
CAAML.addNode(dom, md, feature.info.comment, 'caaml:comment');
CAAML.addNode(dom, md, 'Ram Sonde', 'caaml:methodOfMeas');
for (i = feature.layers.length - 1; i >= 0; --i) {
var l = feature.layers[i];
var ob = hp.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, ob, round(profile.top - l.top, 4), 'caaml:depthTop');
CAAML.addNode(dom, ob, round(l.top - l.bottom, 4), 'caaml:thickness');
CAAML.addNode(dom, ob, round(l.value, 4), 'caaml:hardness');
CAAML.addNode(dom, ob, l.weightHammer, 'caaml:weightHammer');
CAAML.addNode(dom, ob, l.weightTube, 'caaml:weightTube');
CAAML.addNode(dom, ob, l.nDrops, 'caaml:nDrops');
CAAML.addNode(dom, ob, l.dropHeight, 'caaml:dropHeight');
}
};
CAAML.addSMPProfile = function (profile, dom, node, feature) {
if (!feature || !feature.layers || !feature.layers.length) return;
var hp = node.appendChild(dom.createElement('caaml:hardnessProfile'));
hp.setAttribute('uomDepthTop', 'cm');
hp.setAttribute('uomThickness', 'cm');
hp.setAttribute('uomHardness', 'N');
var md = hp.appendChild(dom.createElement('caaml:MetaData'));
if (feature.info.comment)
CAAML.addNode(dom, md, feature.info.comment, 'caaml:comment');
CAAML.addNode(dom, md, 'Snow Micro Pen', 'caaml:methodOfMeas');
if (feature.info.surf || feature.info.surf === 0)
CAAML.addNode(dom, md, feature.info.surf, 'caaml:surfOfIndentation', 'm2');
CAAML.addPointProfile(
dom, profile, hp, feature, [],
['caaml:depth', 'caaml:penRes']
);
};
CAAML.addLwcProfile = function (profile, dom, node, feature) {
if (!feature) return;
var lp = node.appendChild(dom.createElement('caaml:lwcProfile')), i;
lp.setAttribute('uomDepthTop', 'cm');
lp.setAttribute('uomThickness', 'cm');
lp.setAttribute('uomLwc', '');
if (feature.info.comment) {
var lpmd = lp.appendChild(dom.createElement('caaml:MetaData'));
CAAML.addNode(dom, lpmd, feature.info.comment, 'caaml:comment');
}
for (i = feature.layers.length - 1; i >= 0; --i) {
var l = feature.layers[i];
// Skip null values
if (!l.value && l.value !== 0) continue;
var ob = lp.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, ob, round(profile.top - l.top, 4), 'caaml:depthTop');
CAAML.addNode(dom, ob, round(l.top - l.bottom, 4), 'caaml:thickness');
CAAML.addNode(dom, ob, l.code, 'caaml:lwc');
}
};
CAAML.addSSAProfile = function (profile, dom, node, feature) {
if (!feature) return;
var sp = node.appendChild(dom.createElement('caaml:specSurfAreaProfile')), i;
sp.setAttribute('uomDepthTop', 'cm');
sp.setAttribute('uomThickness', 'cm');
sp.setAttribute('uomSpecSurfArea', 'm2kg-1');
var spmd = sp.appendChild(dom.createElement('caaml:MetaData'));
if (feature.info.comment)
CAAML.addNode(dom, spmd, feature.info.comment, 'caaml:comment');
CAAML.addNode(dom, spmd, feature.info.method || 'other', 'caaml:methodOfMeas');
if (feature.info.pointprofile) {
CAAML.addPointProfile(
dom, profile, sp, feature, [],
['caaml:depth', 'caaml:specSurfArea']);
return;
}
for (i = feature.layers.length - 1; i >= 0; --i) {
var l = feature.layers[i];
// Skip null values
if (!l.value && l.value !== 0) continue;
var ob = sp.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, ob, round(profile.top - l.top, 4), 'caaml:depthTop');
CAAML.addNode(dom, ob, round(l.top - l.bottom, 4), 'caaml:thickness');
CAAML.addNode(dom, ob, round(l.value, 4), 'caaml:specSurfArea');
}
};
CAAML.addStabilityProfile = function (profile, dom, node) {
if (!profile.ct && !profile.rb && !profile.ect && !profile.saw && !profile.sf) return;
var st = node.appendChild(dom.createElement('caaml:stbTests'));
if (profile.ct) CAAML.addCT(profile, dom, st);
if (profile.ect) CAAML.addECT(profile, dom, st);
if (profile.rb) CAAML.addRB(profile, dom, st);
if (profile.sf) CAAML.addSF(profile, dom, st);
if (profile.saw) CAAML.addSAW(profile, dom, st);
};
CAAML.addCT = function (profile, dom, node) {
for (var i = profile.ct.layers.length - 1; i >= 0; --i) {
var l = profile.ct.layers[i];
var ct = node.appendChild(dom.createElement('caaml:ComprTest'));
if (l.nofailure) {
ct.appendChild(dom.createElement('caaml:noFailure'));
continue;
}
if (l.comment) CAAML.addNode(dom, ct, l.comment, 'caaml:comment');
var fo = ct.appendChild(dom.createElement('caaml:failedOn'));
var cl = fo.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, cl, round(profile.top - l.top, 4), 'caaml:depthTop', 'cm');
var re = fo.appendChild(dom.createElement('caaml:Results'));
if (l.character) CAAML.addNode(dom, re, l.character, 'caaml:fractureCharacter');
CAAML.addNode(dom, re, l.value ? Math.round(l.value) : 'CTV', 'caaml:testScore');
}
};
CAAML.addECT = function (profile, dom, node) {
for (var i = profile.ect.layers.length - 1; i >= 0; --i) {
var l = profile.ect.layers[i];
var ect = node.appendChild(dom.createElement('caaml:ExtColumnTest'));
if (l.nofailure) {
ect.appendChild(dom.createElement('caaml:noFailure'));
continue;
}
if (l.comment) CAAML.addNode(dom, ect, l.comment, 'caaml:comment');
var fo = ect.appendChild(dom.createElement('caaml:failedOn'));
var el = fo.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, el, round(profile.top - l.top, 4), 'caaml:depthTop', 'cm');
var re = fo.appendChild(dom.createElement('caaml:Results'));
CAAML.addNode(dom, re, l.text, 'caaml:testScore');
}
};
CAAML.addRB = function (profile, dom, node) {
for (var i = profile.rb.layers.length - 1; i >= 0; --i) {
var l = profile.rb.layers[i];
var rb = node.appendChild(dom.createElement('caaml:RBlockTest'));
if (l.nofailure) {
rb.appendChild(dom.createElement('caaml:noFailure'));
continue;
}
if (l.comment) CAAML.addNode(dom, rb, l.comment, 'caaml:comment');
var fo = rb.appendChild(dom.createElement('caaml:failedOn'));
var cl = fo.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, cl, round(profile.top - l.top, 4), 'caaml:depthTop', 'cm');
var re = fo.appendChild(dom.createElement('caaml:Results'));
if (l.character) CAAML.addNode(dom, re, l.character, 'caaml:fractureCharacter');
if (l.releasetype) CAAML.addNode(dom, re, l.releasetype, 'caaml:releaseType');
CAAML.addNode(dom, re, l.text, 'caaml:testScore');
}
};
CAAML.addSF = function (profile, dom, node) {
for (var i = profile.sf.layers.length - 1; i >= 0; --i) {
var l = profile.sf.layers[i];
var sf = node.appendChild(dom.createElement('caaml:ShearFrameTest'));
if (l.nofailure) {
sf.appendChild(dom.createElement('caaml:noFailure'));
continue;
}
if (l.comment) CAAML.addNode(dom, sf, l.comment, 'caaml:comment');
var fo = sf.appendChild(dom.createElement('caaml:failedOn'));
var cl = fo.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, cl, round(profile.top - l.top, 4), 'caaml:depthTop', 'cm');
var re = fo.appendChild(dom.createElement('caaml:Results'));
if (l.character) CAAML.addNode(dom, re, l.character, 'caaml:fractureCharacter');
CAAML.addNode(dom, re, l.value, 'caaml:failureForce', 'N');
}
};
CAAML.addSAW = function (profile, dom, node) {
for (var i = profile.saw.layers.length - 1; i >= 0; --i) {
var l = profile.saw.layers[i];
var saw = node.appendChild(dom.createElement('caaml:PropSawTest'));
var fo = saw.appendChild(dom.createElement('caaml:failedOn'));
var cl = fo.appendChild(dom.createElement('caaml:Layer'));
CAAML.addNode(dom, cl, round(profile.top - l.top, 4), 'caaml:depthTop', 'cm');
var re = fo.appendChild(dom.createElement('caaml:Results'));
CAAML.addNode(dom, re, l.text, 'caaml:fracturePropagation');
CAAML.addNode(dom, re, l.cutlength, 'caaml:cutLength', 'cm');
CAAML.addNode(dom, re, l.columnlength, 'caaml:columnLength', 'cm');
}
};
CAAML.addLocRef = function (station, profile, dom, root) {
var lr = root.appendChild(dom.createElement('caaml:locRef'));
var op = lr.appendChild(dom.createElement('caaml:ObsPoint'));
op.setAttribute('gml:id', station.id || niviz.CAAML.defaults.station_gmlid || 'NA');
if (profile.info.custom_loc) { // looping through customData
var mp = op.appendChild(dom.createElement('caaml:metaDataProperty'));
var md = mp.appendChild(dom.createElement('caaml:MetaData'));
md.appendChild(profile.info.custom_loc);
}
if (station.position && station.position.description)
CAAML.addNode(dom, op, station.position.description, 'caaml:description');
CAAML.addNode(dom, op, station.name, 'caaml:name');
CAAML.addNode(dom, op, station.position.subtype || '', 'caaml:obsPointSubType');
if (station.position.altitude) {
var vh = op.appendChild(dom.createElement('caaml:validElevation'));
var ep = vh.appendChild(dom.createElement('caaml:ElevationPosition'));
ep.setAttribute('uom', 'm');
var alt = station.position.altitude;
if (alt || alt === 0) alt = Math.round(alt);
CAAML.addNode(dom, ep, alt, 'caaml:position');
}
if (station.position.aspect) {
var va = op.appendChild(dom.createElement('caaml:validAspect'));
var ap = va.appendChild(dom.createElement('caaml:AspectPosition'));
if (station.position.azimuth || station.position.azimuth === 0) {
var azi = station.position.azimuth;
if (!isNaN(azi)) azi = Math.round(azi);
CAAML.addNode(dom, ap, azi, 'caaml:position');
} else {
var aspect = station.position.aspect;
if (!isNaN(aspect)) aspect = Math.round(aspect);
CAAML.addNode(dom, ap, aspect, 'caaml:position');
}
}
if (station.position.angle !== undefined && station.position.angle !== null
&& station.position.direction !== 'flat') {
var vs = op.appendChild(dom.createElement('caaml:validSlopeAngle'));
var sp = vs.appendChild(dom.createElement('caaml:SlopeAnglePosition'));
sp.setAttribute('uom', 'deg');
var angle = station.position.angle;
if (!isNaN(angle)) angle = Math.round(angle);
CAAML.addNode(dom, sp, angle, 'caaml:position');
}
if (station.position.latitude !== undefined && station.position.longitude !== undefined) {
var pl = op.appendChild(dom.createElement('caaml:pointLocation'));
var po = pl.appendChild(dom.createElement('gml:Point'));
po.setAttribute('gml:id', 'POINT_ID');
po.setAttribute('srsName', 'urn:ogc:def:crs:OGC:1.3:CRS84');
po.setAttribute('srsDimension', '2');
var tx = station.position.longitude + ' ' + station.position.latitude;
CAAML.addNode(dom, po, tx, 'gml:pos');
}
};
/**
* Serialize Graph object
*
* @method serialize
* @static
*
* @param {Object} data The profile graph, e.g. SimpleProfile, SLFProfile.
* @returns {String} The serialized result.
*/
CAAML.serialize = function (data) {
var result = '<?xml version="1.0" encoding="UTF-8"?>\n', serializer = new XMLSerializer();
var station = data.station, profile = data.profile;
var dom = document.implementation.createDocument('', '', null);
var root = dom.appendChild(dom.createElementNS(CAAML.NS.caaml, 'caaml:SnowProfile'));
var gmlid = station.id || station.name || 'NA';
gmlid.replace(' ', '');
CAAML.addNS(root, profile);
CAAML.addMetaData(station, profile, dom, root);
CAAML.addValidTime(profile, gmlid + '_3', dom, root);
CAAML.addSnowProfile(station, profile, dom, root);
CAAML.addLocRef(station, profile, dom, root);
result += serializer.serializeToString(root);
result = format(result);
return result;
};
function format (xml) {
var formatted = '', reg = /(>)(<)(\/*)/g, pad = 0, indent, padding;
xml = xml.replace(reg, '$1\r\n$2$3');
xml.split('\r\n').forEach(function(node, index) {
indent = 0;
if (node.match( /.+<\/\w[^>]*>$/ )) {
indent = 0;
} else if (node.match( /^<\/\w/ )) {
if (pad !== 0) {
pad -= 1;
}
} else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
indent = 1;
} else {
indent = 0;
}
padding = '';
for (var i = 0; i < pad; i++) padding += ' ';
formatted += padding + node + '\r\n';
pad += indent;
});
return formatted;
}
// --- Module Exports ---
niviz.CAAML5 = CAAML;
}(niviz));