diff --git a/ipmd/static/ipmd/js/ipmdlib.js b/ipmd/static/ipmd/js/ipmdlib.js index 1637f2bd54d6bd2f146e958834738dd15438ee9f..58563dd6b76e42aa7986a1a5c18fae66be0742b9 100644 --- a/ipmd/static/ipmd/js/ipmdlib.js +++ b/ipmd/static/ipmd/js/ipmdlib.js @@ -17,6 +17,11 @@ * */ +/** + * Dependencies: + * momentJS + */ + const ipmdDSSApiURL = "https://platform.ipmdecisions.net/api/dss/"; const ipmdWeatherApiURL = "https://platform.ipmdecisions.net/api/wx/"; @@ -192,18 +197,152 @@ function getPragmaticWeatherParameterList(requestedParameters, availableParamete */ function mergeWeatherData(primaryData, secondaryData) { + // Input check + // If one set is null, return the non-null one unchanged + // If both sets are null, return null + if(primaryData == null || secondaryData == null) + { + return primaryData == null ? secondaryData : primaryData; + } - // Where to start in primaryData? + // If the log interval differs, return primaryData + if(primaryData.interval != secondaryData.interval) + { + return primaryData; + } + + // Initialize the result dataset let mergedData = { - timeStart: null, - timeEnd: null, + timeStart: moment(primaryData.timeStart <= secondaryData.timeStart ? primaryData.timeStart : secondaryData.timeStart), + timeEnd: moment(primaryData.timeEnd >= secondaryData.timeEnd ? primaryData.timeEnd : secondaryData.timeEnd), interval: primaryData.interval, - weatherParameters: primaryData.weatherParameters + weatherParameters: function() { + // Copy primaryData's weather parameters + var mergedParams = []; + for(let j=0;j<primaryData.weatherParameters.length;j++) + { + mergedParams.push(primaryData.weatherParameters[j]); + }; + /* + // Check for additional parameters in secondaryData <--- DON'T DO THIS + // Fallback parameters are not considered additional + for(let j=0;j<secondaryData.weatherParameters.length; j++) + { + let element = secondaryData.weatherParameters[j]; + if(!mergedParams.includes(element)) + { + let isNewForSure = true; + let fallbacks = fallbackParams[element]; + if(fallbacks != undefined) + { + for(let i=0; i<fallbacks.length; i++) + { + if(mergedParams.includes(fallbacks[i])) + { + isNewForSure = false; + } + } + } + if(isNewForSure) + { + mergedParams.push(element); + } + } + }*/ + return mergedParams; + }(), + locationWeatherData: [ + { + longitude: primaryData.locationWeatherData[0].longitude, + latitude: primaryData.locationWeatherData[0].latitude + } + ] }; - console.info("primaryData.timeStart=" + primaryData.timeStart); - console.info("mergedData.timeStart=" + mergedData.timeStart); - + // The parameter ordering may differ between primaryData and secondaryData + // We solve this by mapping the parameter in secondaryData to an index in primaryData + paramIndexes = {}; + //console.info(Object.keys(fallbackParams)); + secondaryData.weatherParameters.forEach(element => { + if(mergedData.weatherParameters.includes(element)) + { + paramIndexes[element] = mergedData.weatherParameters.indexOf(element); + } + // Checking for fallback parameters + else if(Object.keys(fallbackParams).includes(element.toString())) + { + fallbackParams[element.toString()].forEach(fbElement=>{ + if(mergedData.weatherParameters.includes(fbElement)) + { + paramIndexes[element] = mergedData.weatherParameters.indexOf(fbElement); + } + }); + } + }); + + // Calculate dimensions of the merged data set + console.info("timeStart=" + mergedData.timeStart.format("YYYY-MM-DD") + ", timeEnd=" + mergedData.timeEnd.format("YYYY-MM-DD")); + let length = (getUnix(mergedData.timeEnd) - getUnix(mergedData.timeStart)) / mergedData.interval; + let width = mergedData.weatherParameters.length; + console.info(length + "*" + width); + let dataSet = Array.from(Array(length), () => new Array(width)); + //console.info(dataSet); + // Keeping track of offsets (if dataset does not cover the entire combined period of the merging datasets) + let primaryOffset = (getUnix(primaryData.timeStart) - getUnix(mergedData.timeStart)) / mergedData.interval; + let secondaryOffset = (getUnix(secondaryData.timeStart) - getUnix(mergedData.timeStart)) / mergedData.interval; + let primaryDataSet = primaryData.locationWeatherData[0].data; + let secondaryDataSet = secondaryData.locationWeatherData[0].data; + + console.info("primaryOffset=" + primaryOffset); + console.info(primaryDataSet); + + // Finally: Merge the data! + for(let i=0;i<dataSet.length;i++) + { + + if(secondaryOffset <= i && i-secondaryOffset < secondaryDataSet.length) + { + for(let j=0; j<secondaryData.weatherParameters.length;j++) + { + if(paramIndexes[secondaryData.weatherParameters[j]] != undefined && !isEmpty(secondaryDataSet[i-secondaryOffset][j])) + { + dataSet[i][paramIndexes[secondaryData.weatherParameters[j]]] = secondaryDataSet[i-secondaryOffset][j]; + } + } + } + if(primaryOffset <= i && i-primaryOffset < primaryDataSet.length ) + { + console.info(i-primaryOffset); + for(let j=0; j<primaryData.weatherParameters.length;j++) + { + if(!isEmpty(primaryDataSet[i-primaryOffset][j])) + { + dataSet[i][j] = primaryDataSet[i-primaryOffset][j]; + } + } + } + } + + mergedData.locationWeatherData[0].data = dataSet; + + //console.info(paramIndexes); + return mergedData; +} + +function getUnix(aDate) +{ + console.info(typeof aDate); + if(typeof aDate == "string") + { + aDate = moment(aDate); + } + return aDate.unix(); + //return aDate.getTime()/1000; +} + +function isEmpty(val) +{ + return val === undefined || val === null; } const fallbackParams = { diff --git a/ipmd/templates/ipmd/saddlegallmidgeform.html b/ipmd/templates/ipmd/saddlegallmidgeform.html index 3985488860c6b58433e160d386abc42510d64f8b..8aeb80df65181e964fd846f69d1476154ad4d5cc 100644 --- a/ipmd/templates/ipmd/saddlegallmidgeform.html +++ b/ipmd/templates/ipmd/saddlegallmidgeform.html @@ -126,7 +126,7 @@ // TODO: Remove this auto-mock!! editor.getValue().optionalData.startDate="2023-08-01"; - editor.getValue().optionalData.endDate="2023-08-10"; + editor.getValue().optionalData.endDate="2023-08-19"; document.getElementById("longitude").value="11.781989"; document.getElementById("latitude").value="59.680468"; //submitData(); @@ -274,14 +274,14 @@ } else { - // Is NULL until method is implemented + // Is useless until method is implemented weatherData = mergeWeatherData(weatherData, forecastData); } } inputData["weatherData"] = weatherData; - //console.info(weatherData); + console.info(weatherData); } // Ready to call server? //console.info(JSON.stringify(inputData));