From 533f45f65271e02ae7004ce977df34505656de86 Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@nibio.no>
Date: Mon, 23 Apr 2018 14:59:04 +0200
Subject: [PATCH] Introducing the Septoria Humidity model and stuff to cater
 for that

---
 src/jax-ws-catalog.xml                        |   2 +-
 .../vips/logic/VIPSLogicApplication.java      |   2 +
 .../session/PointOfInterestBean.java          |   6 +-
 .../nibio/vips/logic/entity/Organization.java |   1 +
 .../vips/logic/service/LogicService.java      |   8 +
 .../vips/logic/service/ModelFormService.java  | 171 ++++++++++++++++++
 .../dnmipointweb/DMIPointWebDataParser.java   |   2 +-
 7 files changed, 189 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/no/nibio/vips/logic/service/ModelFormService.java

diff --git a/src/jax-ws-catalog.xml b/src/jax-ws-catalog.xml
index c074fd31..f6401c8f 100644
--- a/src/jax-ws-catalog.xml
+++ b/src/jax-ws-catalog.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xml"/>
+    <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?singleWsdl" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.singlewsdl.wsdl"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?wsdl" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.wsdl"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?xsd=xsd0" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xsd_xsd0.xsd"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?xsd=xsd1" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xsd_xsd1.xsd"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?xsd=xsd2" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xsd_xsd2.xsd"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?xsd=xsd3" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xsd_xsd3.xsd"/>
     <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?xsd=xsd4" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.xsd_xsd4.xsd"/>
-    <system systemId="https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?singleWsdl" uri="wsdl/dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc.singlewsdl.wsdl"/>
 </catalog>
\ No newline at end of file
diff --git a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
index 78c6e42c..255cbaf0 100755
--- a/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
+++ b/src/main/java/no/nibio/vips/logic/VIPSLogicApplication.java
@@ -54,6 +54,7 @@ public class VIPSLogicApplication extends Application
         resources.add(no.nibio.vips.logic.modules.applefruitmoth.AppleFruitMothService.class);
         resources.add(no.nibio.vips.logic.service.ObservationService.class);
         resources.add(no.nibio.vips.logic.service.WeatherProxyService.class);
+        resources.add(no.nibio.vips.logic.service.ModelFormService.class);
         resources.add(no.nibio.vips.logic.service.JacksonConfig.class);
         //resources.add(no.nibio.vips.coremanager.service.ManagerResourceImpl.class);
     }
@@ -70,6 +71,7 @@ public class VIPSLogicApplication extends Application
         resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class);
         resources.add(no.nibio.vips.logic.service.JacksonConfig.class);
         resources.add(no.nibio.vips.logic.service.LogicService.class);
+        resources.add(no.nibio.vips.logic.service.ModelFormService.class);
         resources.add(no.nibio.vips.logic.service.ObservationService.class);
         resources.add(no.nibio.vips.logic.service.VIPSMobileService.class);
         resources.add(no.nibio.vips.logic.service.WeatherProxyService.class);
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
index c983c3fa..30180926 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java
@@ -30,7 +30,6 @@ import de.micromata.opengis.kml.v_2_2_0.Point;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.ResourceBundle;
 import java.util.Set;
@@ -461,5 +460,10 @@ public class PointOfInterestBean {
                 
     }
 
+    public WeatherStationDataSource getWeatherStationDataSource(String dataSourceName){
+        return em.createNamedQuery("WeatherStationDataSource.findByName", WeatherStationDataSource.class)
+                .setParameter("name", dataSourceName)
+                .getSingleResult();
+    }
     
 }
diff --git a/src/main/java/no/nibio/vips/logic/entity/Organization.java b/src/main/java/no/nibio/vips/logic/entity/Organization.java
index 46397415..b948b010 100755
--- a/src/main/java/no/nibio/vips/logic/entity/Organization.java
+++ b/src/main/java/no/nibio/vips/logic/entity/Organization.java
@@ -83,6 +83,7 @@ public class Organization implements Serializable {
     private Integer defaultMapZoom;
     @Column(name = "default_time_zone")
     private String defaultTimeZone;
+    @JsonIgnore
     @Column(name = "default_vips_core_user_id")
     private Integer defaultVipsCoreUserId;
     @JsonIgnore
diff --git a/src/main/java/no/nibio/vips/logic/service/LogicService.java b/src/main/java/no/nibio/vips/logic/service/LogicService.java
index 837b41de..c3f4a7d0 100755
--- a/src/main/java/no/nibio/vips/logic/service/LogicService.java
+++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java
@@ -859,6 +859,14 @@ public class LogicService {
         }
     }
     
+    @GET
+    @Path("organization")
+    @Produces("application/json;charset=UTF-8")
+    public Response getOrganizations()
+    {
+        return Response.ok().entity(SessionControllerGetter.getUserBean().getOrganizations()).build();
+    }
+    
     /**
      * Get the client to use for calling VIPSCoreManager REST services programmatically
      * @return 
diff --git a/src/main/java/no/nibio/vips/logic/service/ModelFormService.java b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java
new file mode 100644
index 00000000..3a00a583
--- /dev/null
+++ b/src/main/java/no/nibio/vips/logic/service/ModelFormService.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 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/>.
+ * 
+ */
+
+package no.nibio.vips.logic.service;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.webcohesion.enunciate.metadata.Facet;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import no.nibio.vips.entity.ModelConfiguration;
+import no.nibio.vips.entity.Result;
+import no.nibio.vips.entity.WeatherObservation;
+import no.nibio.vips.gis.GISUtil;
+import no.nibio.vips.logic.entity.Organization;
+import no.nibio.vips.logic.entity.PointOfInterestWeatherStation;
+import no.nibio.vips.logic.entity.WeatherStationDataSource;
+import no.nibio.vips.logic.util.RunModelException;
+import no.nibio.vips.logic.util.SessionControllerGetter;
+import no.nibio.vips.logic.util.SystemTime;
+import no.nibio.vips.util.ParseRESTParamUtil;
+import no.nibio.vips.util.WeatherElements;
+import no.nibio.vips.util.WeatherUtil;
+import no.nibio.vips.util.XDate;
+import no.nibio.vips.util.weather.WeatherDataSourceException;
+import no.nibio.vips.util.weather.WeatherDataSourceUtil;
+
+/**
+ * This is a collection of services for models run from forms (not as part of batch) 
+ * @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+@Path("rest/modelform")
+@Facet("restricted")
+public class ModelFormService {
+
+    @GET
+    @Path("SEPTORIAHU/runmodel")
+    @Produces("application/json;charset=UTF-8")
+    public Response runSeptoriaHumidityModel(
+            @QueryParam("organizationId_countryCode") String organizationId_countryCode,
+            @QueryParam("weatherStationId") String weatherStationId, // Could be special ID from Danish system,
+            @QueryParam("dateSpraying1") String dateSpraying1,
+            @QueryParam("dateSpraying2") String dateSpraying2,
+            @QueryParam("dateGs31") String dateGs31,
+            @QueryParam("date3rdUpperLeafEmerging") String date3rdUpperLeafEmerging,
+            @QueryParam("date2ndUpperLeafEmerging") String date2ndUpperLeafEmerging,
+            @QueryParam("dateUpperLeafEmerging") String dateUpperLeafEmerging,
+            @QueryParam("dateGs75") String dateGs75,
+            @QueryParam("thresholdRelativeHumidity") Double thresholdRelativeHumidity,
+            @QueryParam("thresholdLeafWetness") Double thresholdLeafWetness,
+            @QueryParam("thresholdPrecipitation") Double thresholdPrecipitation,
+            @QueryParam("slidingHoursPast") Integer slidingHoursPast,
+            @QueryParam("slidingHoursAhead") Integer slidingHoursAhead,
+            @QueryParam("thresholdHumidPeriodHours") Integer thresholdHumidPeriodHours,
+            @QueryParam("sprayingProtectionDays") Integer sprayingProtectionDays,
+            @QueryParam("leafLifeTime") Integer leafLifeTime
+    ){
+        try
+        {
+            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]);
+            Organization organization = SessionControllerGetter.getUserBean().getOrganization(organizationId);
+            mConf.setConfigParameter("timeZone", organization.getDefaultTimeZone());
+            TimeZone timeZone =  TimeZone.getTimeZone(organization.getDefaultTimeZone());
+            ParseRESTParamUtil pUtil = new ParseRESTParamUtil();
+            // Start time is gs31, easy
+            Date gs31 = pUtil.parseISODate(dateGs31,timeZone);
+            XDate startTime = new XDate(gs31);
+            startTime.addDays(-1);
+            // End time is whatever comes first of the day after tomorrow or Gs75
+            Date gs75 = pUtil.parseISODate(dateGs75, timeZone);
+            XDate dayAfterTomorrow = new XDate(SystemTime.getSystemTime());
+            dayAfterTomorrow.addDays(2);
+            WeatherUtil wUtil = new WeatherUtil();
+            dayAfterTomorrow = new XDate(wUtil.pragmaticAdjustmentToMidnight(dayAfterTomorrow, timeZone));
+            // The first check here is to see if the systemtime is too early
+            Date endTime = dayAfterTomorrow.after(gs75) ? gs75 : dayAfterTomorrow;
+
+            String countryCode = organizationId_countryCode.split("_")[1];
+            List<WeatherObservation> observations;
+            WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil();
+            PointOfInterestWeatherStation ws;
+            if(countryCode.toLowerCase().equals("dk")){
+                // Create a synthetic weather station to pass into the system
+                // Weather station id is a UTM32N coordinate, e.g. E552700N6322400
+                String[] parts = weatherStationId.split("N");
+                Integer UTM32vE = Integer.valueOf(parts[0].substring(1));
+                Integer UTM32vN = Integer.valueOf(parts[1]);
+                GISUtil gisUtil = new GISUtil();
+                Coordinate UTMc = new Coordinate(UTM32vE, UTM32vN); 
+                Coordinate coordinate = gisUtil.convertCoordinate(UTMc, "EPSG:32632", "EPSG:4326");
+                WeatherStationDataSource wsds = SessionControllerGetter.getPointOfInterestBean().getWeatherStationDataSource("DMI PointWeb");
+                ws = new PointOfInterestWeatherStation();
+                ws.setWeatherStationDataSourceId(wsds);
+                ws.setWeatherStationRemoteId(coordinate.y + "," + coordinate.x);// For some reason, The transformation switches X/Y
+                ws.setTimeZone(organization.getDefaultTimeZone());
+                
+                //observations.stream().forEach(obs->System.out.println(obs.toString()));
+            }
+            else
+            {
+                // Weather station id maps to a regular weather station
+                ws = (PointOfInterestWeatherStation) SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(Integer.valueOf(weatherStationId));
+            }
+            observations = wdsUtil.getWeatherObservations(
+                        ws, 
+                        WeatherObservation.LOG_INTERVAL_ID_1H, 
+                        new String[]{
+                            WeatherElements.TEMPERATURE_MEAN,
+                            WeatherElements.PRECIPITATION,
+                            WeatherElements.RELATIVE_HUMIDITY_MEAN,
+                            WeatherElements.LEAF_WETNESS
+                        }, 
+                        startTime, 
+                        endTime
+                );
+            mConf.setConfigParameter("observations",observations);
+
+            Integer VIPSCoreUserId = organization.getDefaultVipsCoreUserId();
+
+            List<Result>results = SessionControllerGetter.getForecastBean().runForecast(mConf, VIPSCoreUserId);
+
+            return Response.ok().entity(results).build();
+        }
+        catch(WeatherDataSourceException | RunModelException ex)
+        {
+            return Response.serverError().entity(ex.getMessage()).build();
+        }
+    }
+}
diff --git a/src/main/java/no/nibio/vips/util/weather/dnmipointweb/DMIPointWebDataParser.java b/src/main/java/no/nibio/vips/util/weather/dnmipointweb/DMIPointWebDataParser.java
index cf704d31..dde1f480 100644
--- a/src/main/java/no/nibio/vips/util/weather/dnmipointweb/DMIPointWebDataParser.java
+++ b/src/main/java/no/nibio/vips/util/weather/dnmipointweb/DMIPointWebDataParser.java
@@ -110,7 +110,7 @@ public class DMIPointWebDataParser {
         } catch (Exception ex) {
             Logger.getLogger(DMIPointWebDataParser.class.getName()).log(Level.SEVERE, null, ex);
         }
-        System.out.println("Number of extracted weather data = " + retVal.size());
+        //System.out.println("Number of extracted weather data = " + retVal.size());
         return retVal;
     }
 
-- 
GitLab