diff --git a/VIPSWeb/settings.py b/VIPSWeb/settings.py index c6951cc69447b24204cb9ee2c35a8a425a514f47..8bce708f42be28c1fbef1966c27516e2a73a3f63 100644 --- a/VIPSWeb/settings.py +++ b/VIPSWeb/settings.py @@ -132,6 +132,7 @@ INSTALLED_APPS = ( 'messages', 'organisms', 'information', + 'cerealblotchmodels', 'VIPSWeb' ) diff --git a/VIPSWeb/static/css/vipsweb.css b/VIPSWeb/static/css/vipsweb.css index 1807d648c3ba43ad63f5395ee290549065c29915..703ecf1f91826c77730917fd6803331d1eb39f2f 100644 --- a/VIPSWeb/static/css/vipsweb.css +++ b/VIPSWeb/static/css/vipsweb.css @@ -369,10 +369,10 @@ footer a:hover { color: rgba(49, 171, 110, 1); } -input[type="checkbox"] { +ul.cropList input[type="checkbox"] { display:none; } -input[type="checkbox"] + label span { +ul.cropList input[type="checkbox"] + label span { display:inline-block; width:19px; height:19px; @@ -381,13 +381,14 @@ input[type="checkbox"] + label span { background:url("./icons/checkbox_unchecked.png") left top no-repeat; cursor:pointer; } -input[type="checkbox"]:checked + label span { +ul.cropList input[type="checkbox"]:checked + label span { background:url("./icons/checkbox_checked.png") left top no-repeat; } -input[type="radio"] { +ul.cropList input[type="radio"] { display:none; } +ul.cropList input[type="radio"] + label span { display:inline-block; width:19px; @@ -397,7 +398,7 @@ input[type="radio"] + label span { background:url("./icons/checkbox_unchecked.png") left top no-repeat; cursor:pointer; } -input[type="radio"]:checked + label span { +ul.cropList input[type="radio"]:checked + label span { background:url("./icons/checkbox_checked.png") left top no-repeat; } diff --git a/VIPSWeb/static/js/forecastmap.js b/VIPSWeb/static/js/forecastmap.js index 931eeab4d4f6885a5ac35d60c47a1f098a4ceb85..5abe83f06763c27cc2871ed229493c7c74b13aef 100644 --- a/VIPSWeb/static/js/forecastmap.js +++ b/VIPSWeb/static/js/forecastmap.js @@ -54,7 +54,9 @@ function initForecastMap(lonLat, zoomLevel, mapAttribution) /*var backgroundLayer = new ol.layer.Tile({ source: new ol.source.BingMaps({ key: 'AgBNAZzyzjb-tmdpNGxAQGtvVQryg5Vm3ZekaYVk2iwWNmu41CVxdPYjTXrKQ9ac', - imagerySet: 'Aerial' + // imagerySet: "Aerial" + //imagerySet: 'Road' + imagerySet: "AerialWithLabels" }) }) */ @@ -64,6 +66,7 @@ function initForecastMap(lonLat, zoomLevel, mapAttribution) forecastLayer = new ol.layer.Vector({ source: new ol.source.KML({ url: "http://" + settings.vipslogicServerName + "/rest/forecastresults/aggregate/" + settings.vipsOrganizationId + "?" + buildPathParamString("cropOrganismId", getSelectedCropIds()), + //url: "http://localhost:8000/static/test/20150428bih.kml", projection: ol.proj.get('EPSG:3857') }) }); diff --git a/VIPSWeb/urls.py b/VIPSWeb/urls.py index e0bb25f318be28ef4a2b01e8389dd678cf670d44..6d2ea83fb5d10599da986b806b772db39753f822 100644 --- a/VIPSWeb/urls.py +++ b/VIPSWeb/urls.py @@ -44,6 +44,7 @@ urlpatterns = patterns('', url(r'^messages/', include('messages.urls', namespace = "messages")), url(r'^organisms/', include('organisms.urls', namespace = "organisms")), url(r'^information/', include('information.urls', namespace = "information")), + url(r'^blotch/', include('cerealblotchmodels.urls', namespace = "cerealblotchmodels")), # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls)), diff --git a/cerealblotchmodels/__init__.py b/cerealblotchmodels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/cerealblotchmodels/admin.py b/cerealblotchmodels/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e --- /dev/null +++ b/cerealblotchmodels/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/cerealblotchmodels/models.py b/cerealblotchmodels/models.py new file mode 100644 index 0000000000000000000000000000000000000000..71a836239075aa6e6e4ecb700e9c42c95c022d91 --- /dev/null +++ b/cerealblotchmodels/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/cerealblotchmodels/templates/cerealblotchmodels/barleynetblotchform.html b/cerealblotchmodels/templates/cerealblotchmodels/barleynetblotchform.html new file mode 100644 index 0000000000000000000000000000000000000000..73b7e76465ecc94b7edf35ab6fe3010d24ab61d2 --- /dev/null +++ b/cerealblotchmodels/templates/cerealblotchmodels/barleynetblotchform.html @@ -0,0 +1,252 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% comment %} + +# +# Copyright (c) 2015 NIBIO <http://www.nibio.no/>. +# +# This file is part of VIPSWeb. +# VIPSWeb 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. +# +# VIPSWeb 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 VIPSWeb. If not, see <http://www.nibio.no/licenses/>. +# + +{% endcomment %} +{% load i18n %} +{% block title%}{% trans "Barley net blotch" %}{%endblock%} + +{% block content %} +<h1>{% trans "Barley net blotch" %}</h1> + +<form role="form" id="barleynetblotchForm"> + <div class="row"> + <div class="col-md-12"> + <h2>{% trans "Background data for the barley net blotch model" %}</h2> + </div> + </div> + <div class="row"> + <div class="col-md-6 form-group"> + <input type="hidden" name="timeZone" value="Europe/Oslo"/> + <label for="weatherStationId">{% trans "Weather station" %}</label> + <select name="weatherStationId" id="weatherStationId" class="form-control"> + </select> + <label for="sowingDate">{% trans "Sowing date" %}</label> + <input type="date" name="sowingDate" class="form-control"/> + <label for="cropOrganismId">{% trans "Crop" %}</label> + <select name="cropOrganismId" id="cropOrganismId" class="form-control"> + </select> + <input type="checkbox" name="sameCropAsLastSeason"/> + <label for="sameCropAsLastSeason">{% trans "Same crop as last season" %}</label><br/> + <input type="checkbox" name="plowed"/> + <label for="plowed"><span>{% trans "Plowed" %}</span></label><br/> + </div> + <div class="col-md-6 form-group"> + <label for="observationDate">{% trans "Observation date" %}</label> + <input type="date" name="observationDate" class="form-control"/> + <label for ="observationValue">{% trans "% Infected leaves" %}</label> + <input type="number" name="observationValue" class="form-control"/> + <label for="sprayingDate">{% trans "Spraying date" %}</label> + <input type="date" name="sprayingDate" class="form-control"/> + <label for="preparationId">{% trans "Preparation" %}</label> + <select name="preparationId" id="preparationId" class="form-control"> + </select> + <label for="preparationDose">{% trans "Preparation dose" %} (ml/daa)</label> + <input type="number" name="preparationDose" class="form-control"/> + + </div> + </div> + <div class="row"> + <div class="col-md-6 form-group"> + <button type="button" class="btn btn-default" onclick="runModel();">{% trans "Run model" %}</button> + </div> + </div> + +</form> +<div class="row" id="runningModelMessage" style="display:none"> + <div class="col-md-12"> + <div class="alert alert-info" role="alert">{% trans "Model is running, please wait" %}</div> + </div> +</div> +<div class="row" id="errorMessageContainer" style="display:none"> + <div class="col-md-12"> + <div class="alert alert-danger" role="alert" id="errorMessage"></div> + </div> +</div> +<div id="results" style="display:none;"> + + <div class="table-responsive"> + <table id="resultsTable" class="table table-striped"> + </table> + </div> +</div> +{% endblock %} +{% block customJS %} +<script type="text/javascript" src="{% url "views.settings_js" %}"></script> +<script type="text/javascript" src="/static/organisms/organismsUtil.js"></script> +<script type="text/javascript"> + function runModel() + { + document.getElementById("results").style.display="none"; + document.getElementById("errorMessageContainer").style.display="none"; + document.getElementById("runningModelMessage").style.display="block"; + // TODO: Validate form + var formStr = $("#barleynetblotchForm").serialize(); + var request = $.ajax({ + type:"GET", + url: "http://" + settings.vipslogicServerName + "/rest/barleynetblotchmodel/runmodel/" + settings.vipsOrganizationId + "?" + formStr, + statusCode:{ + 200: renderResults, + 400: handleAjaxError, + 401: handleAjaxError, + 404: handleAjaxError, + 500: handleAjaxError + } + }); + console.log(formStr); + } + + var renderResults = function(data,textStatus, jqXHR) + { + // First attempt: A table! + var headingLine = "<tr><td style=\"font-weight: bold;\">Time</td>"; + if(data.length > 0) + { + var allKeys = data[0].keys; + for(var i in allKeys) + { + headingLine +="<td style=\"font-weight: bold;\">" + allKeys[i] + "</td>"; + } + headingLine +="<td style=\"font-weight: bold;\">Warning Status</td>"; + headingLine += "</tr>"; + + var table = ["<table border=\"1\">",headingLine]; + for(item in data) + { + var resultLine = "<tr><td>" + new Date(data[item].resultValidTime) + "</td>"; + for(var i in allKeys) + { + resultLine +="<td>" + data[item].allValues[allKeys[i]] + "</td>"; + } + resultLine +="<td style=\"background-color:"; + var st = data[item].warningStatus; + resultLine += st===0 ? "gray" : st===1 ? "blue" : st===2 ? "green" : st===3 ? "yellow" : "red"; + resultLine +=";\">" + st + "</td>"; + resultLine += "</tr>"; + table.push(resultLine); + } + table.push("</table>"); + document.getElementById("resultsTable").innerHTML=table.join(""); + } + else + { + document.getElementById("resultsTable").innerHTML="<h2>No data returned</h2>"; + } + document.getElementById("runningModelMessage").style.display="none"; + document.getElementById("errorMessageContainer").style.display="none"; + document.getElementById("results").style.display="block"; + console.log(data); + }; + + $(document).ready(function() { + initWeatherStations(); + initCrops(); + initPreparations(); + }); + function initWeatherStations(){ + // Fetching information asynchronously from server + var request = $.ajax({ + type:"GET", + url: "http://" + settings.vipslogicServerName + "/rest/poi/organization/" + settings.vipsOrganizationId, + statusCode:{ + 200: function(data,textStatus, jqXHR){ + // Building result HTML + var wsHTML=["<option value=\"-1\">-- {% trans "Select weather station" %} --</option>"]; + for(var i in data) + { + var ws = data[i]; + + //console.log(ws); + wsHTML.push("<option value=\"" + ws["pointOfInterestId"] + "\">" + ws["name"] + "</option>"); + } + document.getElementById("weatherStationId").innerHTML = wsHTML.join(""); + }, + 400: handleAjaxError, + 401: handleAjaxError, + 404: handleAjaxError, + 500: handleAjaxError + } + }); + } + + function initCrops() + { + // Fetching information asynchronously from server + var request = $.ajax({ + type:"GET", + url: "http://" + settings.vipslogicServerName + "/rest/barleynetblotchmodel/barleyvarieties/" + settings.vipsOrganizationId, + statusCode:{ + 200: function(data,textStatus, jqXHR){ + // Building result HTML + var cropHTML=["<option value=\"-1\">-- {% trans "Select crop" %} --</option>"]; + for(var i in data) + { + var crop = data[i]; + + //console.log(ws); + cropHTML.push("<option value=\"" + crop["cropOrganismId"] + "\">" + getOrganismLocalNameWithFallback(crop,settings.currentLanguage,settings.defaultLanguage) + "</option>"); + } + document.getElementById("cropOrganismId").innerHTML = cropHTML.join(""); + }, + 400: handleAjaxError, + 401: handleAjaxError, + 404: handleAjaxError, + 500: handleAjaxError + } + }); + } + + function initPreparations() + { + // Fetching information asynchronously from server + var request = $.ajax({ + type:"GET", + url: "http://" + settings.vipslogicServerName + "/rest/barleynetblotchmodel/preparations/" + settings.vipsOrganizationId, + statusCode:{ + 200: function(data,textStatus, jqXHR){ + // Building result HTML + var preparationHTML=["<option value=\"-1\">-- {% trans "Select preparation" %} --</option>"]; + for(var i in data) + { + var preparation = data[i]; + + //console.log(ws); + preparationHTML.push("<option value=\"" + preparation["preparationId"] + "\">" + preparation["preparationName"] + "</option>"); + } + document.getElementById("preparationId").innerHTML = preparationHTML.join(""); + }, + 400: handleAjaxError, + 401: handleAjaxError, + 404: handleAjaxError, + 500: handleAjaxError + } + }); + } + + // Error handling when collecting forecast information from server fails + var handleAjaxError = function(jqXHR,textStatus,errorThrown){ + var message = jqXHR.responseJSON !== undefined ? jqXHR.responseJSON.message : jqXHR.responseText; + document.getElementById("runningModelMessage").style.display="none"; + document.getElementById("errorMessage").innerHTML = "<h1>Error</h1><pre>" + message + "</pre>"; + document.getElementById("errorMessageContainer").style.display="block"; + }; +</script> +{% endblock %} \ No newline at end of file diff --git a/cerealblotchmodels/templates/cerealblotchmodels/index.html b/cerealblotchmodels/templates/cerealblotchmodels/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e34160dda9330545103bd47cdbd568d3a8a99602 --- /dev/null +++ b/cerealblotchmodels/templates/cerealblotchmodels/index.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% comment %} + +# +# Copyright (c) 2015 NIBIO <http://www.nibio.no/>. +# +# This file is part of VIPSWeb. +# VIPSWeb 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. +# +# VIPSWeb 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 VIPSWeb. If not, see <http://www.nibio.no/licenses/>. +# + +{% endcomment %} +{% load i18n %} +{% block title%}{% trans "Cereal blotch models" %}{%endblock%} +{% block content %} +<h1>{% trans "Cereal blotch models" %}</h1> + + +{% endblock %} \ No newline at end of file diff --git a/cerealblotchmodels/tests.py b/cerealblotchmodels/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/cerealblotchmodels/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/cerealblotchmodels/urls.py b/cerealblotchmodels/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..b5e0bde83b38a27701e0026975f76e18f12bf568 --- /dev/null +++ b/cerealblotchmodels/urls.py @@ -0,0 +1,25 @@ +# +# Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. +# +# This file is part of VIPSWeb. +# VIPSWeb is free software: you can redistribute it and/or modify +# it under the terms of the Bioforsk Open Source License as published by +# Bioforsk, either version 1 of the License, or (at your option) any +# later version. +# +# VIPSWeb 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 +# Bioforsk Open Source License for more details. +# +# You should have received a copy of the Bioforsk Open Source License +# along with VIPSWeb. If not, see <http://www.bioforsk.no/licenses/>. +# +from django.conf.urls import patterns, url +from cerealblotchmodels import views + +urlpatterns = patterns('cerealblotchmodels.views', + # ex: /forecasts/ + url(r'^$', views.index, name='index'), + url(r'barleynetblotch/', views.barleynetblotchform, name='barleynetblotchform') +) \ No newline at end of file diff --git a/cerealblotchmodels/views.py b/cerealblotchmodels/views.py new file mode 100644 index 0000000000000000000000000000000000000000..110aafc132f13fd37f1925c0e60912e302f8c3d9 --- /dev/null +++ b/cerealblotchmodels/views.py @@ -0,0 +1,20 @@ +from django.shortcuts import render + +# Create your views here. + + +def index(request): + + #forecast_configurations.sort(key=lambda x: x.date_start, reverse=False) + context = { + + } + return render(request, 'cerealblotchmodels/index.html', context) + +def barleynetblotchform(request): + + #forecast_configurations.sort(key=lambda x: x.date_start, reverse=False) + context = { + + } + return render(request, 'cerealblotchmodels/barleynetblotchform.html', context) \ No newline at end of file diff --git a/organisms/static/organisms/organismsUtil.js b/organisms/static/organisms/organismsUtil.js new file mode 100644 index 0000000000000000000000000000000000000000..a64454e609040a64354067c399a183ace1c0b985 --- /dev/null +++ b/organisms/static/organisms/organismsUtil.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSWeb. + * VIPSWeb 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. + * + * VIPSWeb 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 VIPSWeb. If not, see <http://www.nibio.no/licenses/>. + * + */ + +/** + * Utility JavaScript. Used here and there. To whom it may concern... + * + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ + +function getOrganismLocalNameWithFallback(organism, currentLanguage, defaultLanguage) +{ + // Priority: Local name in current language, local name in default language, trade name, latin name + var localeSet = organism["organismLocaleSet"]; + // Current language or default language + var langs = [currentLanguage,defaultLanguage] + for(var li in langs) + { + for(var i in localeSet) + { + if(localeSet[i]["organismLocalePK"]["locale"] == langs[li]) + { + return localeSet[i]["localName"]; + } + } + } + if(organism["tradeName"] != null && organism["tradeName"] != "") + { + return organism["tradeName"]; + } + return organism["latinName"]; +}