diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java index 1a91e171272342381272fb766102670c98eed81f..26e104b7696991f599ea3fe0ab22231824c94938 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java @@ -563,7 +563,7 @@ public class ForecastBean { * @param camelCaseName * @return MODELID_CAMEL_CASE_NAME */ - private String getDeCamelizedFieldName(String modelId, String camelCaseName) + public String getDeCamelizedFieldName(String modelId, String camelCaseName) { StringBuilder deCamelizedFieldName = new StringBuilder(modelId.toUpperCase()); for(String phrase : camelCaseName.split("(?=\\p{Lu})")) @@ -573,7 +573,7 @@ public class ForecastBean { return deCamelizedFieldName.toString(); } - + public List<ForecastModelConfiguration> getForecastModelConfigurations(Long forecastConfigurationId) { diff --git a/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/SeptoriaHumidityModelPreprocessor.java b/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/SeptoriaHumidityModelPreprocessor.java index 7a0c1d6ef4b9a2dd3781320d44190abbb463b65c..397362d229bcf902fcf21fd435c0b1f9a7b716fc 100644 --- a/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/SeptoriaHumidityModelPreprocessor.java +++ b/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/SeptoriaHumidityModelPreprocessor.java @@ -19,14 +19,20 @@ package no.nibio.vips.logic.scheduling.model.preprocessor; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Collections; +import java.util.Date; import java.util.List; +import java.util.TimeZone; import no.nibio.vips.entity.ModelConfiguration; import no.nibio.vips.entity.WeatherObservation; +import no.nibio.vips.logic.controller.session.ForecastBean; import no.nibio.vips.logic.entity.ForecastConfiguration; import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; import no.nibio.vips.logic.scheduling.model.ModelRunPreprocessor; import no.nibio.vips.logic.scheduling.model.PreprocessorException; +import no.nibio.vips.logic.util.SessionControllerGetter; import no.nibio.vips.util.WeatherElements; import no.nibio.vips.util.weather.WeatherDataSourceException; import no.nibio.vips.util.weather.WeatherDataSourceUtil; @@ -40,12 +46,24 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{ @Override public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException { + ForecastBean forecastBean = SessionControllerGetter.getForecastBean(); ModelConfiguration retVal = new ModelConfiguration(); retVal.setModelId(this.getModelId()); retVal.setConfigParameter("timeZone", configuration.getTimeZone()); + String[] modelConfigurationValueNames = {"dateSpraying1","dateSpraying2","dateGs31","date3rdUpperLeafEmerging", + "date2ndUpperLeafEmerging","dateUpperLeafEmerging","dateGs75","thresholdRelativeHumidity","thresholdLeafWetness", + "thresholdPrecipitation","slidingHoursPast","slidingHoursAhead","thresholdHumidPeriodHours","sprayingProtectionDays", + "leafLifeTime"}; + for(String modelConfigurationValueName: modelConfigurationValueNames) + { + retVal.setConfigParameter(modelConfigurationValueName, configuration.getForecastModelConfigurationValue(forecastBean.getDeCamelizedFieldName(this.getModelId(),modelConfigurationValueName))); + } + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + format.setTimeZone(TimeZone.getTimeZone(configuration.getTimeZone())); WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil(); try { + Date gs31 = format.parse((String)retVal.getConfigParameter("dateGs31")); List<WeatherObservation> observations = wdsUtil.getWeatherObservations( (PointOfInterestWeatherStation) configuration.getWeatherStationPointOfInterestId(), WeatherObservation.LOG_INTERVAL_ID_1H, @@ -55,13 +73,13 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{ WeatherElements.RELATIVE_HUMIDITY_MEAN, WeatherElements.LEAF_WETNESS_DURATION }, - configuration.getDateStart(), + gs31, configuration.getDateEnd() ); Collections.sort(observations); retVal.setConfigParameter("observations", observations); } - catch(WeatherDataSourceException ex) + catch(WeatherDataSourceException | ParseException ex) { throw new PreprocessorException(ex.getMessage()); } diff --git a/src/main/java/no/nibio/vips/logic/service/ModelFormService.java b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java index 04b997c65113b79fbf652011cef02f47f73f90a0..4d10bb8dc926bedbda60dbb8772fc1835488b357 100644 --- a/src/main/java/no/nibio/vips/logic/service/ModelFormService.java +++ b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java @@ -105,24 +105,6 @@ public class ModelFormService { fModelConf.add(this.getForecastModelConfiguration("leafLifeTime", String.valueOf(leafLifeTime))); fConf.setForecastModelConfigurationSet(fModelConf); - //ModelConfiguration mConf = new ModelConfiguration(); - //mConf.setModelId("SEPTORIAHU"); - //mConf.setConfigParameter("dateSpraying1", dateSpraying1); - //mConf.setConfigParameter("dateSpraying2", dateSpraying2); - //mConf.setConfigParameter("dateGs31", dateGs31); - //mConf.setConfigParameter("date3rdUpperLeafEmerging", date3rdUpperLeafEmerging); - //mConf.setConfigParameter("date2ndUpperLeafEmerging", date2ndUpperLeafEmerging); - //mConf.setConfigParameter("dateUpperLeafEmerging", dateUpperLeafEmerging); - //mConf.setConfigParameter("dateGs75", dateGs75); - //mConf.setConfigParameter("thresholdRelativeHumidity", thresholdRelativeHumidity); - //mConf.setConfigParameter("thresholdLeafWetness", thresholdLeafWetness); - //mConf.setConfigParameter("thresholdPrecipitation", thresholdPrecipitation); - //mConf.setConfigParameter("slidingHoursPast", slidingHoursPast); - //mConf.setConfigParameter("slidingHoursAhead", slidingHoursAhead); - //mConf.setConfigParameter("thresholdHumidPeriodHours", thresholdHumidPeriodHours); - //mConf.setConfigParameter("sprayingProtectionDays", sprayingProtectionDays); - //mConf.setConfigParameter("leafLifeTime", leafLifeTime); - // Data parsing Integer organizationId = Integer.valueOf(organizationId_countryCode.split("_")[0]); diff --git a/src/main/webapp/formdefinitions/models/SEPTORIAHU.json b/src/main/webapp/formdefinitions/models/SEPTORIAHU.json new file mode 100644 index 0000000000000000000000000000000000000000..39907031e2c0540b4dc69896ce3284eaf565dba1 --- /dev/null +++ b/src/main/webapp/formdefinitions/models/SEPTORIAHU.json @@ -0,0 +1,104 @@ +{ + "_licenseNote": [ + "Copyright (c) 2019 NIBIO <http://www.nibio.no/>. ", + "", + "This file is part of VIPSLogic. ", + "VIPSLogic is free software: you can redistribute it and/or modify ", + "it under the terms of the NIBIO Open Source License as published by ", + "NIBIO, either version 1 of the License, or (at your option) any ", + "later version. ", + "", + "VIPSLogic 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 ", + "NIBIO Open Source License for more details. ", + "", + "You should have received a copy of the NIBIO Open Source License ", + "along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. " + ], + "_comment" : "Structure of the specific fields for SEPTORIAHU", + "fields": [ + { + "name" : "dateSpraying1", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : false + }, + { + "name" : "dateSpraying2", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : false + }, + { + "name" : "dateGs31", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : true + }, + { + "name" : "date3rdUpperLeafEmerging", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : true + }, + { + "name" : "date2ndUpperLeafEmerging", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : true + }, + { + "name" : "dateUpperLeafEmerging", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : true + }, + { + "name" : "dateGs75", + "dataType" : "DATE", + "dateFormat" : "yyyy-MM-dd", + "required" : true + }, + { + "name" : "thresholdRelativeHumidity", + "dataType" : "DOUBLE", + "required" : true + }, + { + "name" : "thresholdLeafWetness", + "dataType" : "DOUBLE", + "required" : true + }, + { + "name" : "thresholdPrecipitation", + "dataType" : "DOUBLE", + "required" : true + }, + { + "name" : "slidingHoursPast", + "dataType" : "INTEGER", + "required" : true + }, + { + "name" : "slidingHoursAhead", + "dataType" : "INTEGER", + "required" : true + }, + { + "name" : "thresholdHumidPeriodHours", + "dataType" : "INTEGER", + "required" : true + }, + { + "name" : "sprayingProtectionDays", + "dataType" : "INTEGER", + "required" : true + }, + { + "name" : "leafLifeTime", + "dataType" : "INTEGER", + "required" : true + } + ] +} \ No newline at end of file diff --git a/src/main/webapp/js/forecastConfigurationForm.js b/src/main/webapp/js/forecastConfigurationForm.js index 1d15d5137f2932af3ec395d261aea883c33730e1..256d3e6f839e027b18a1cfc106be7a31b84fc408 100755 --- a/src/main/webapp/js/forecastConfigurationForm.js +++ b/src/main/webapp/js/forecastConfigurationForm.js @@ -194,7 +194,7 @@ function getHTMLInputType(dataType) return "number"; break; case dataTypes.TYPE_DOUBLE: - return "number"; + return "number' step='any"; break; case dataTypes.TYPE_DATE: return "date"; diff --git a/src/main/webapp/public/nordic_septoria_map/nordic_septoria_map.js b/src/main/webapp/public/nordic_septoria_map/nordic_septoria_map.js index 863256bbcbf34eee1736136f981ca8ea6edd9d27..02f0ba9c8ad6065d24813385ec9c05790c426570 100644 --- a/src/main/webapp/public/nordic_septoria_map/nordic_septoria_map.js +++ b/src/main/webapp/public/nordic_septoria_map/nordic_septoria_map.js @@ -295,6 +295,10 @@ var getFeatureDetails = { "rainyDays": function(features) { var properties = features[0].getProperties(); return "GS 32 estimated at " + properties.GS32Date.format("YYYY-MM-DD") + ", GS 71 estimated at " + properties.GS71Date.format("YYYY-MM-DD"); + }, + "HM": function(features) { + var properties = features[0].getProperties(); + return "GS 32 estimated at " + properties.GS32Date.format("YYYY-MM-DD") + ", GS 71 estimated at " + properties.GS71Date.format("YYYY-MM-DD"); } }; @@ -432,7 +436,9 @@ var getResults = { "rainyDays": function(season) { getResultsChain(season, "rainyDays"); }, - "HM": function() { console.info("NOT IMPLEMENTED");}, + "HM": function(season) { + getResultsChain(season,"HM"); + }, }; var calculateResults = { @@ -467,6 +473,23 @@ var calculateResults = { } } return rainyDaysSum; + }, + "HM": function(forecastResults, startDate, endDate){ + var numberOfRiskPeriods = 0; + for(var i in forecastResults) + { + var validTimeStart = moment(forecastResults[i].validTimeStart); + if( + validTimeStart.isSameOrAfter(startDate) + && validTimeStart.isSameOrBefore(endDate) + && forecastResults[i].warningStatus === 4 + && (i > 0 && forecastResults[i-1].warningStatus !== 4) + ) + { + numberOfRiskPeriods++; + } + } + return numberOfRiskPeriods; } } @@ -520,6 +543,27 @@ var getFeatureStyle = { zIndex: featureZIndex++ }) ]; + }, + "HM" : function(feature){ + var numberOfRiskPeriods = parseInt(feature.get("numberOfRiskPeriods")); + var color = numberOfRiskPeriods < 4 ? "green" : "red"; + + return [ + new ol.style.Style({ + image: new ol.style.Circle({ + fill: new ol.style.Fill({ color: color }), + stroke: new ol.style.Stroke({ color: [0,0,0,0], width: 0 }), + radius: 11 + }), + text: new ol.style.Text({ + text: feature.get("numberOfRiskPeriods"), + font: 'bold 12px sans-serif', + fill: new ol.style.Fill({ color: "white" }), + stroke: new ol.style.Stroke({ color: [90,90,90,1], width: 1 }) + }), + zIndex: featureZIndex++ + }) + ]; } }; @@ -552,6 +596,17 @@ var displayResults = { var features = []; features.push(feature); featureOverlays["rainyDays"]["mainMap"].getSource().addFeatures(features); + }, + "HM": function(numberOfRiskPeriods, GS32Date, GS71Date, currentForecast){ + var feature = new ol.Feature({ + geometry:new ol.geom.Point(ol.proj.fromLonLat([currentForecast.locationPointOfInterestId.longitude,currentForecast.locationPointOfInterestId.latitude])), + numberOfRiskPeriods: numberOfRiskPeriods.toString(), + GS32Date: GS32Date, + GS71Date: GS71Date + }); + var features = []; + features.push(feature); + featureOverlays["HM"]["mainMap"].getSource().addFeatures(features); } }; @@ -631,6 +686,9 @@ var getLayerLegend = { + " <tr><td>>= 4</td><td style='color: red; background-color: #777777; font-weight: bold;'>" + geti18nText("risk_high") + "</td></tr>" + " <tr><td><span style='cursor:pointer; color: green;' onclick='showModelInfo[\"rainyDays\"]();'><i class='fas fa-info-circle'></i></span></td><td></td></tr>" + " </table>"; + }, + "HM": function(){ + return "TODO"; } };