From b87e421edb00c201fcde76411d008a1ed9adc076 Mon Sep 17 00:00:00 2001
From: tuckersiegel <siegel.tucker@gmail.com>
Date: Thu, 25 Mar 2021 17:46:56 -0400
Subject: [PATCH] freezing dates added

---
 controllers/freezingDatesController.js | 153 +++++++++++++++++++++++++
 routes.js                              |   2 +
 swagger_definition.yaml                |  90 ++++++++++++++-
 test_server.py                         |  33 +++---
 4 files changed, 262 insertions(+), 16 deletions(-)
 create mode 100644 controllers/freezingDatesController.js

diff --git a/controllers/freezingDatesController.js b/controllers/freezingDatesController.js
new file mode 100644
index 0000000..c8cba3e
--- /dev/null
+++ b/controllers/freezingDatesController.js
@@ -0,0 +1,153 @@
+gdd_collection = require('../models/gdd.js');
+utils = require('../lib/utils');
+
+var may_31st = 150
+var sept_1st = 243
+var nov_30th = 330
+
+function is_leap_year(year) {
+    if ((year % 4) == 0) {
+        if ((year % 100) == 0) {
+            if ((year % 400) == 0) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return true;
+        }
+    } else {
+        return false; 
+    }
+}
+
+function send_response(message, gdds, data, res) {
+    res.json({
+        message: message,
+        date: data["last_date"],
+        data: gdds,
+        closest_lon: data["location"]["coordinates"][0],
+        closest_lat: data["location"]["coordinates"][1]
+    })
+}
+
+function find(collection, query, res, freeze_temp) {
+    var total_years = new Date().getFullYear() -  new Date(1981, 0, 1, 0, 0, 0, 0).getFullYear() - 1;
+    
+    collection.find(query).limit(total_years).then(function(data) {
+        var last_freezing_dates = [];
+        var first_freezing_dates = [];
+        for (var y = 0; y < total_years; y ++){
+
+            // console.log(data[i]["location"]);
+            var year = data[y]["year"];
+            if (is_leap_year(year)) {
+                var year_may_31st = may_31st + 1;
+                var year_sept_1st = sept_1st + 1;
+                var year_nov_30th = nov_30th + 1;
+            } else {
+                var year_may_31st = may_31st;
+                var year_sept_1st = sept_1st;
+                var year_nov_30th = nov_30th;
+            }
+
+            var min_temps = data[y]['min_temps'];
+
+            var last = 0;
+            for (var i = 0; i < year_may_31st; i++) {
+                if (min_temps[i] <= freeze_temp) {
+                    last = i;
+                } 
+            }
+
+            var last_date = new Date(year, 0, 1, 0, 0, 0, 0);
+            last_date.setDate(last_date.getDate() + last);          
+            last_date = new Date((1 + last_date.getMonth()).toString() + "//" + last_date.getDate().toString() + "//" + new Date().getFullYear().toString());
+            last_freezing_dates.push(last_date);
+
+            var first = 0;
+            for (var i = year_sept_1st; i < year_nov_30th; i++) {
+                if (min_temps[i] <= freeze_temp) {
+                    first = i;
+                    break;
+                } 
+            }
+
+            var first_date = new Date(year, 0, 1, 0, 0, 0, 0);
+            first_date.setDate(first_date.getDate() + first);          
+            first_date = new Date((1 + first_date.getMonth()).toString() + "//" + first_date.getDate().toString() + "//" + new Date().getFullYear().toString());
+            first_freezing_dates.push(first_date);           
+        }
+
+        res.json({
+            message: "first and last freezing dates for every year from 1981 to last full year",
+            first_freezing_dates: first_freezing_dates,
+            last_freezing_dates: last_freezing_dates,
+            closest_lon: data[0]["location"]["coordinates"][0],
+            closest_lat: data[0]["location"]["coordinates"][1]
+        });
+
+
+    }, function(err) {
+        res.status(500).send({"internal error": err})
+    })
+    
+}
+
+
+exports.freezing_dates = function (req, res) {
+    var product = req.params.product;
+    var freeze_temp = req.params.temperature;
+
+    var latitude = parseFloat(req.body.latitude)
+    var longitude = parseFloat(req.body.longitude)
+
+    var query = {
+        location: { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [longitude, latitude]
+                },
+            },
+        },
+    }
+
+    errors = []
+
+    if (latitude < 24.083334 || latitude > 49.916668) {
+        errors.push({
+            parameter_error: "latitude",
+            message: latitude.toString() + " is out of bounds for freezing date calculations. Must be between 24.083334 - 49.916668"
+        });
+    }   
+
+    if (longitude < -125 || longitude > -66.5) {
+        errors.push({
+            parameter_error: "longitude",
+            message: longitude.toString() + " is out of bounds for freezing date calculations. Must be between -125.0 - -66.5"
+        });
+    }
+
+    if (errors.length > 0) {
+        res.status(400).send({
+            errors: errors
+        })
+    }
+
+    var projection = {
+        min_temps: 1,
+        max_temps: 1,
+        location: 1,
+    }
+
+    temps = {
+        t_base: t_base,
+        t_max: t_max,
+        t_min: t_min,
+    }
+
+    find(gdd_collection, query, res, freeze_temp);
+    
+   
+};
\ No newline at end of file
diff --git a/routes.js b/routes.js
index c6c2066..1e9e8b8 100644
--- a/routes.js
+++ b/routes.js
@@ -2,10 +2,12 @@ const router = require('express').Router();
 const accController = require("./controllers/gddAccumulatedController")
 const controller = require("./controllers/gddController")
 const normController = require("./controllers/gddNormalController")
+const freezingDatesController = require("./controllers/freezingDatesController")
 
 router.route("/:product/daily/:year/accumulated").post(accController.accumulated_gdd)
 router.route("/:product/daily/:year").post(controller.year_gdd)
 router.route("/:product/normal").post(normController.normal)
 router.route("/:product/normal/accumulated").post(accController.accumulated_normal_gdd)
+router.route("/freezing/:temperature").post(freezingDatesController.freezing_dates)
 
 module.exports = router;
diff --git a/swagger_definition.yaml b/swagger_definition.yaml
index 4633b9b..b89efc9 100644
--- a/swagger_definition.yaml
+++ b/swagger_definition.yaml
@@ -354,4 +354,92 @@ paths:
                                                   example: latitude
                                               message:
                                                   type: string
-                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668     
\ No newline at end of file
+                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668   
+
+    /api/freezing/{temperature}:
+      post:
+          summary: Returns first and last freezing dates for all years
+          description: "Returns first and last freezing dates for a specific temperature, lat and lon. NOTE: Returned date years are all the current year."
+          produces:
+              - application/json
+          consumes:
+              - application/json
+          parameters:
+            - in: path
+              name: temperature
+              required: true
+              description: Freezing temperature to use (between 25F and 32F)
+              schema:
+                  type: number
+                  example: 28
+          requestBody:
+              content:
+                  application/json:
+                      schema:
+                          type: object
+                          required:
+                              - longitude
+                              - latitude
+                          properties:
+                              latitude:
+                                  description: latitude to calculate gdd on
+                                  type: number
+                                  minimum: 24.083334
+                                  maximum: 49.916668
+                                  example: 38.99
+                              longitude:
+                                  description: longitude to calculate gdd on
+                                  type: number
+                                  minimum: -125.0
+                                  maximum: -66.5
+                                  example: -76.94
+                  
+          responses:
+              200:
+                  description: Success
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  message:
+                                      type: string
+                                      example: first and last freezing dates for every year from 1981 to last full year
+                                  first_freezing_dates:
+                                      type: array
+                                      items:
+                                          type: string
+                                          format: date
+                                  last_freezing_dates:
+                                      type: array
+                                      items:
+                                          type: string
+                                          format: date
+                                  closest_lat:
+                                      type: number
+                                      minimum: 24.083334
+                                      maximum: 49.916668
+                                      example: 38.99
+                                  closest_lon:
+                                      type: number
+                                      minimum: -125.0
+                                      maximum: -66.5
+                                      example: -76.94
+              400:
+                  description: Bad Request
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  errors:
+                                      type: array
+                                      items:
+                                          type: object
+                                          properties:
+                                              parameter_error:
+                                                  type: string
+                                                  example: latitude
+                                              message:
+                                                  type: string
+                                                  example: 22.5 is out of bounds for freezing date calculations. Must be between 24.083334 - 49.916668     
\ No newline at end of file
diff --git a/test_server.py b/test_server.py
index ed6b546..687cfb1 100644
--- a/test_server.py
+++ b/test_server.py
@@ -8,22 +8,25 @@ data = {
 }
 
 t = time.time()
-r = requests.post("http://localhost:4000/api/soybean/daily/1981", data=data)
-print (r.status_code)
-print (r.json())
-print (time.time() - t)
-print ()
-r = requests.post("http://localhost:4000/api/soybean/daily/2016", data=data)
-print (r.status_code)
-print (r.json())
-print (time.time() - t)
-print ()
-r = requests.post("http://localhost:4000/api/soybean/normal", data=data)
+# r = requests.post("http://localhost:4000/api/soybean/daily/1981", data=data)
+# print (r.status_code)
+# print (r.json())
+# print (time.time() - t)
+# print ()
+# r = requests.post("http://localhost:4000/api/soybean/daily/2016", data=data)
+# print (r.status_code)
+# print (r.json())
+# print (time.time() - t)
+# print ()
+# r = requests.post("http://localhost:4000/api/soybean/normal", data=data)
+# print (r.status_code)
+# print (r.json())
+# print (time.time() - t)
+# print ()
+r = requests.post("http://localhost:4000/api/soybean/daily/2021", data=data)
 print (r.status_code)
 print (r.json())
 print (time.time() - t)
-print ()
-r = requests.post("http://localhost:4000/api/soybean/daily/2021", data=data)
+r = requests.post("http://localhost:4000/api/freezing/28.2", data=data)
 print (r.status_code)
-print (r.json())
-print (time.time() - t)
\ No newline at end of file
+print (r.json())
\ No newline at end of file
-- 
GitLab