From c0c1154421939b7633fe2ecb4a4e6983108dfbdd Mon Sep 17 00:00:00 2001 From: tuckersiegel <siegel.tucker@gmail.com> Date: Sun, 28 Mar 2021 17:10:26 -0400 Subject: [PATCH] added min and max accumulated gdds --- controllers/freezingDatesController.js | 5 - controllers/minMaxController.js | 134 +++++++++++++++++++++++++ routes.js | 2 + swagger_definition.yaml | 91 +++++++++++++++++ test_server.py | 3 + 5 files changed, 230 insertions(+), 5 deletions(-) create mode 100644 controllers/minMaxController.js diff --git a/controllers/freezingDatesController.js b/controllers/freezingDatesController.js index c8cba3e..6ed2c63 100644 --- a/controllers/freezingDatesController.js +++ b/controllers/freezingDatesController.js @@ -141,11 +141,6 @@ exports.freezing_dates = function (req, res) { location: 1, } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } find(gdd_collection, query, res, freeze_temp); diff --git a/controllers/minMaxController.js b/controllers/minMaxController.js new file mode 100644 index 0000000..28fbc4c --- /dev/null +++ b/controllers/minMaxController.js @@ -0,0 +1,134 @@ +gdd_collection = require('../models/gdd.js'); +utils = require('../lib/utils'); + +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, projection, temps, res, product) { + var total_years = new Date().getFullYear() - new Date(1981, 0, 1, 0, 0, 0, 0).getFullYear() - 1; + const arr_mean = arr => arr.reduce((a,b) => a + b, 0) / arr.length; + collection.find(query, projection).limit(total_years).then(function(data) { + var minimum_year_data = []; + var maximum_year_data = []; + var minimum_mean = 10000000; + var maximum_mean = 0; + var minimum_year = 0; + var maximum_year = 0; + + var { t_base, t_max, t_min } = temps; + + + for (var y = 0; y < total_years; y ++){ + var min_temps = data[y]["min_temps"]; + var max_temps = data[y]["max_temps"]; + var gdds = [] + var gdd_sum = 0; + for (var i = 0; i < min_temps.length; i++) { + gdd_value = utils.calculate_gdd(min_temps[i], t_min, max_temps[i], t_max, t_base, product); + gdd_sum += gdd_value; + gdds.push(gdd_sum); + } + + var gdd_mean = arr_mean(gdds); + if (gdd_mean <= minimum_mean) { + minimum_year_data = gdds; + minimum_mean = gdd_mean; + minimum_year = data[y]["year"]; + } + if (gdd_mean >= maximum_mean) { + maximum_year_data = gdds; + maximum_mean = gdd_mean; + maximum_year = data[y]["year"]; + } + } + + res.json({ + message: "min and max gdd", + minimum: minimum_year_data, + maximum: maximum_year_data, + minimum_year: minimum_year, + maximum_year: maximum_year, + closest_lon: data[0]["location"]["coordinates"][0], + closest_lat: data[0]["location"]["coordinates"][1] + }); + }, function(err) { + res.status(500).send({"internal error": err}) + }) +} + + +exports.min_max = function (req, res) { + var product = req.params.product; + + var latitude = parseFloat(req.body.latitude) + var longitude = parseFloat(req.body.longitude) + + var query = { + location: { + "$near": { + "$geometry": { + "type": "Point", + "coordinates": [longitude, latitude] + }, + }, + }, + } + + var t_base = 50 + var t_max = 86 + var t_min = 50 + + errors = [] + + if (latitude < 24.083334 || latitude > 49.916668) { + errors.push({ + parameter_error: "latitude", + message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668" + }); + } + + + out = utils.product_base_switch(product, errors, t_base, t_min); + t_base = out.t_base; + t_min = out.t_min; + errors = out.errors; + + + + if (longitude < -125 || longitude > -66.5) { + errors.push({ + parameter_error: "longitude", + message: longitude.toString() + " is out of bounds for GDD 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, + year: 1 + } + + temps = { + t_base: t_base, + t_max: t_max, + t_min: t_min, + } + + find(gdd_collection, query, projection, temps, res, product); + + +}; \ No newline at end of file diff --git a/routes.js b/routes.js index 1e9e8b8..8c3fa38 100644 --- a/routes.js +++ b/routes.js @@ -3,10 +3,12 @@ const accController = require("./controllers/gddAccumulatedController") const controller = require("./controllers/gddController") const normController = require("./controllers/gddNormalController") const freezingDatesController = require("./controllers/freezingDatesController") +const minMaxController = require("./controllers/minMaxController") 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/minmax").post(minMaxController.min_max) router.route("/:product/normal/accumulated").post(accController.accumulated_normal_gdd) router.route("/freezing/:temperature").post(freezingDatesController.freezing_dates) diff --git a/swagger_definition.yaml b/swagger_definition.yaml index b89efc9..a8ac069 100644 --- a/swagger_definition.yaml +++ b/swagger_definition.yaml @@ -425,6 +425,97 @@ paths: 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 + /api/{product}/minmax: + post: + summary: Returns maximum and minimum accumulated yearly gdd data + description: Returns the year with the highest and lowest accumulated gdds for a specific location and crop type. Includes both the year and the data for both max and min + produces: + - application/json + consumes: + - application/json + parameters: + - in: path + name: product + required: true + description: Agricultural product to calculate gdd for + schema: + type: string + enum: [corn, cotton, oat, peanut, pea, potato, rice, soybean, sorghum, spring_wheat, sugar_beet, sunflower, tomato, wheat] + 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: min and max gdd + minimum: + type: array + items: + type: number + maximum: + type: array + items: + type: number + minimum_year: + type: number + minimum: 1981 + maximum_year: + type: number + minimum: 1981 + 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: diff --git a/test_server.py b/test_server.py index 687cfb1..856a9f2 100644 --- a/test_server.py +++ b/test_server.py @@ -29,4 +29,7 @@ print (r.json()) print (time.time() - t) r = requests.post("http://localhost:4000/api/freezing/28.2", data=data) print (r.status_code) +print (r.json()) +r = requests.post("http://localhost:4000/api/soybean/minmax", data=data) +print (r.status_code) print (r.json()) \ No newline at end of file -- GitLab