Skip to content
Snippets Groups Projects
Commit 41a7d083 authored by Brita Linnestad's avatar Brita Linnestad
Browse files

Merge branch 'UpdateRognebærmøll' into 'develop'

Update rognebærmøll

See merge request !22
parents 3248b7b9 941aa9ea
No related branches found
No related tags found
1 merge request!22Update rognebærmøll
document.addEventListener('DOMContentLoaded', setBasis); class ApplefruitMoth
document.title="Rognebærmøllvarsling"; {
serverUri = "https://" + settings.vipsCoremanagerServerName;
runUri= this.serverUri + "/models/DAYDEGREES/run";
weatherStationDataURL = "https://lmt.nibio.no/services/rest/vips/getdata/forecastfallback";
var stations = new Array(); gridDataURL = "https://weather.vips.nibio.no/rest/grid/openmeteo/";
var serverUri = "https://" + settings.vipsCoremanagerServerName; TIMEZONE_OSLO = "Europe/Oslo";
var runUri= serverUri + "/models/DAYDEGREES/run"; DATE_FORMAT = "YYYY-MM-DD";
WEATHER_DATASOURCE_TYPE_COORDINATES = "coordinates";
WEATHER_DATASOURCE_TYPE_WEATHERSTATION = "weatherstation";
basisTemp = "0";
constructor() {
this.weatherStationIds = [];
this.weatherStations = [];
}
var emptyChart; renderWeatherstations = async function () {
console.info("Load weatherstations - start")
try {
const weatherStations = await window.lmtPoiMap();
this.weatherStations = weatherStations;
this.weatherStationIds = weatherStations.map(ws => ws.id);
const select = document.getElementById('weatherStationId');
// Add an option for each weather station
this.weatherStations.forEach(station => {
const option = document.createElement('option');
option.value = station.id;
option.textContent = station.name;
select.appendChild(option);
});
console.info("Load weatherstations - finished")
} catch (error) {
console.error('Error:', error);
}
}
getSelectedWeatherstation()
{
let wsSelect = document.getElementById("weatherStationId");
return wsSelect.options[wsSelect.selectedIndex].value != "-1" ? wsSelect.options[wsSelect.selectedIndex].value : undefined;
}
getSelectedCoordinate()
{
let longitude = parseFloat(document.getElementById("longitude").value);
let latitude = parseFloat(document.getElementById("latitude").value);
return (Number.isNaN(longitude) || Number.isNaN(latitude) ? undefined : [longitude, latitude]);
}
function setBasis () { getSelectedDates()
{
let path = "https://lmt.nibio.no/services/rest/weatherstation/mapweatherstations"; let startDate = document.getElementById("startdate").value;
let endDate = document.getElementById("enddate").value;
$.getJSON(path, function( mapStations ) {
allStations = mapStations;
allStations.sort(function(a,b) { if(!startDate)
return a.name.toString().localeCompare(b.name.toString()); {
}); let date = new Date();
date.setDate(date.getDate() - 7);
for(var i=0;i<allStations.length;i++){ date.setDate(date.getDate());
stations[i]=([mapStations[i].weatherstationId, mapStations[i].name]); startDate = date.toISOString().split('T')[0];
document.getElementById("startdate").value = startDate;
} }
for (let i = 0; i < stations.length; i++ ) { if(!endDate){
let option = document.createElement("option"); let date = new Date();
option.text = stations[i][1]; date.setDate(date.getDate() + 9);
option.value = stations[i][0]; endDate = date.toISOString().split('T')[0];
document.getElementById("weatherstation").appendChild(option);
document.getElementById("enddate").value = endDate;
} }
emptyChart = true; return [startDate, endDate];
setStartText(); }
displayResults(emptyChart);
});
getSelectedWeatherdataSourceType()
} {
return document.getElementById("coordinates").checked ? this.WEATHER_DATASOURCE_TYPE_COORDINATES : document.getElementById("weatherstation").checked ? this.WEATHER_DATASOURCE_TYPE_WEATHERSTATION : undefined;
}
/**
* Calls the dayDegreemodel in the VIPS forecasting system
* Displays data when results are returned
*/
runModel () {
let selectedDates = this.getSelectedDates();
let selectedWeatherStationId = this.getSelectedWeatherstation();
let selectedCoordinate = this.getSelectedCoordinate();
if(selectedWeatherStationId == undefined && selectedCoordinate == undefined)
{
return;
}
let stationName;
let startDate = selectedDates[0];
let endDate = selectedDates[1];
function getBasis () {
try
{
let dailyDataResponse = undefined;
if(selectedWeatherStationId != undefined && this.getSelectedWeatherdataSourceType() == this.WEATHER_DATASOURCE_TYPE_WEATHERSTATION)
{
stationName = this.weatherStations.find(ws => ws.id === Number(selectedWeatherStationId)).name;
// Get the hourly data for the past X days
dailyDataResponse = fetch(
this.weatherStationDataURL + "?weatherStationId=" + selectedWeatherStationId
+ "&elementMeasurementTypes[]=TM"
+ "&timeZone=" + this.TIMEZONE_OSLO
+ "&startDate=" + startDate
+ "&endDate=" + endDate
+ "&logIntervalId=2"
);
}
else if(this.getSelectedWeatherdataSourceType() == this.WEATHER_DATASOURCE_TYPE_COORDINATES && selectedCoordinate != undefined)
{
stationName = 'valgte koordinater';
dailyDataResponse = fetch(
this.gridDataURL + "?longitude=" + selectedCoordinate[0] + "&latitude=" + selectedCoordinate[1]
+ "&elementMeasurementTypes[]=TM"
+ "&timeZone=" + document.getElementById("timezone").value
+ "&startDate=" + startDate
+ "&endDate=" + endDate
+ "&logIntervalId=2"
);
}
else
{
console.error("Location not set. Aborting.")
return;
}
dailyDataResponse
.then(response => {
if (!response.ok) {
throw new Error("Response status: " + response.status);
}
return response.json();
})
.then(dailyData => {
this.getDaydegrees(dailyData, startDate, endDate, stationName);
})
.catch(error => console.error('Error:', error));
}
catch(error)
{
console.error(error.message);
}
}
var basisTemp = "0"; getDaydegrees (data, start, end, name) {
var startTime = document.getElementById('startdate').value;
var endTime = document.getElementById('enddate').value; let modelConfig = {
var weatherStation = document.getElementById('weatherstation').value; "loginInfo":{
"username":"testuser",
"password":"testpass"
},
"modelId":"DAYDEGREES",
"configParameters":{
"basisTemp": this.basisTemp,
"observations": data
}
};
var temperature = []; let request = $.ajax({
type:"POST",
url: this.runUri,
data: JSON.stringify(modelConfig),
dataType: "json",
contentType: "application/json; charset=utf-8",
})
.done((data, textStatus, jqXHR) => {
this.displayResults(data, start, end, name);
})
.fail((jqXHR, textStatus,errorThrown ) => {
alert( "Request failed: " + errorThrown );
})
;
}
weatherstationId = weatherStation;
if (startTime > endTime) {
alert("Datoen er ikke gyldig");
return false;
}
emptyChart = false;
$.getJSON("https://lmt.nibio.no/services/rest/vips/getdata/forecastfallback?weatherStationId="+weatherStation+"&elementMeasurementTypes[]=TM&logInterval=1d&startDate="+startTime+"&startTime=00&endDate="+endTime+"&endTime=23&timeZone=Europe/Oslo", function( observations ) {
$.getJSON("https://lmt.nibio.no/services/rest/weatherstation/getstation?weatherStationId="+weatherStation, function( weatherstation ) {
allObservations = weatherstation;
var name = String(weatherstation.name);
console.info(observations);
runModel(basisTemp, observations, name, startTime, endTime);
});
});
}
/**
* Calls the dayDegreemodel in the VIPS forecasting system
* Displays data when results are returned
*/
function runModel (basisTemp, data, name, start, end) {
var modelConfig = { setStartText () {
"loginInfo":{
"username":"testuser", document.getElementById("textInfo").innerText = "";
"password":"testpass"
}, let infotext = document.createElement("p");
"modelId":"DAYDEGREES", infotext = "<p>Varmesum, med basistemperatur 0 °C, vert rekna ut frå middeltemperaturen 2 m over bakken for den valde vêrstasjonen. </p>";
"configParameters":{
"basisTemp": basisTemp, document.getElementById("textInfo").innerHTML=infotext;
"observations": data }
}
};
var request = $.ajax({
type:"POST",
url: runUri,
data: JSON.stringify(modelConfig),
dataType: "json",
contentType: "application/json; charset=utf-8",
})
.done(function(data, textStatus, jqXHR) {
displayResults(data, basisTemp, name, start, end);
})
.fail(function( jqXHR, textStatus,errorThrown ) {
alert( "Request failed: " + errorThrown );
})
;
}
function displayResults(data, basisTemp, name, start, end) {
displayResults (data, start, end, name) {
let date = new Array(); let date = new Array();
let series = []; let series = [];
...@@ -117,11 +213,12 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -117,11 +213,12 @@ function displayResults(data, basisTemp, name, start, end) {
let temperature = new Array(); let temperature = new Array();
let forecast = new Array(); let forecast = new Array();
let emptyChart = false;
if(!emptyChart) { if(!emptyChart) {
for (var i = 0; i < data.length; i++){ for (let i = 0; i < data.length; i++){
var localTime = new Date(data[i].validTimeStart); let localTime = new Date(data[i].validTimeStart);
const offset = localTime.getTimezoneOffset() const offset = localTime.getTimezoneOffset()
localTime= new Date(localTime.getTime() - (offset*60*1000)) localTime= new Date(localTime.getTime() - (offset*60*1000))
...@@ -135,6 +232,7 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -135,6 +232,7 @@ function displayResults(data, basisTemp, name, start, end) {
localTime = localTime.toISOString().split('T')[0]; localTime = localTime.toISOString().split('T')[0];
time.push(localTime); time.push(localTime);
} }
// Fill the gap between temperature and forecast // Fill the gap between temperature and forecast
let index = temperature.length-1; let index = temperature.length-1;
forecast[index]=temperature[index]; forecast[index]=temperature[index];
...@@ -152,8 +250,8 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -152,8 +250,8 @@ function displayResults(data, basisTemp, name, start, end) {
document.getElementById("textInfo").innerText = ""; document.getElementById("textInfo").innerText = "";
let infotext = document.createElement("p"); let infotext = document.createElement("p");
var text1 = "<p>Varmesum, med basistemperatur 0 °C, rekna ut frå middeltemperaturen 2 m over bakken for den valde vêrstasjonen. </p>"; let text1 = "<p>Varmesum, med basistemperatur 0 °C, rekna ut frå middeltemperaturen 2 m over bakken for den valde vêrstasjonen. </p>";
var text2 = "<p><b>" + lastValue + "</b> døgngrader\n\n</p>"; let text2 = "<p><b>" + lastValue + "</b> døgngrader\n\n</p>";
infotext = text1 + text2; infotext = text1 + text2;
...@@ -163,24 +261,20 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -163,24 +261,20 @@ function displayResults(data, basisTemp, name, start, end) {
for (var i = 0; i < 10; i++){ for (var i = 0; i < 10; i++){
time.push(null); time.push(null);
forecast.push(null); forecast.push(null);
name = 'Alvdal'; name = '-';
start = '-'; start = '-';
end = '-'; end = '-';
} }
} }
let chartExist = Chart.getChart("daydegreesum");
var chartExist = Chart.getChart("daydegreesum");
if(chartExist != undefined){ if(chartExist != undefined){
chartExist.destroy(); chartExist.destroy();
} }
var ctx = document.getElementById("daydegreesum").getContext('2d'); let ctx = document.getElementById("daydegreesum").getContext('2d');
series[0] = { series[0] = {
label: "Døgngrader", label: "Døgngrader",
data: temperature, data: temperature,
...@@ -203,16 +297,16 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -203,16 +297,16 @@ function displayResults(data, basisTemp, name, start, end) {
spanGaps: true spanGaps: true
}; };
var data = { let dataset = {
labels: time, labels: time,
datasets: series datasets: series
}; };
var text = String("Varmesum for " + name + " i perioden " + start + " til " + end ); let text = String("Varmesum for " + name + " i perioden " + start + " til " + end );
new Chart(ctx, { new Chart(ctx, {
type: 'line', type: 'line',
data: data, data: dataset,
options: { options: {
scales: { scales: {
x: { x: {
...@@ -328,19 +422,9 @@ function displayResults(data, basisTemp, name, start, end) { ...@@ -328,19 +422,9 @@ function displayResults(data, basisTemp, name, start, end) {
} }
} }
}); });
}
}
function setStartText (){
document.getElementById("textInfo").innerText = "";
let infotext = document.createElement("p");
infotext = "<p>Varmesum, med basistemperatur 0 °C, vert rekna ut frå middeltemperaturen 2 m over bakken for den valde vêrstasjonen. </p>";
document.getElementById("textInfo").innerHTML=infotext;
} }
export default ApplefruitMoth;
...@@ -23,6 +23,244 @@ ...@@ -23,6 +23,244 @@
{% endcomment %} {% endcomment %}
{% load i18n %} {% load i18n %}
{% block title%}{% trans "Apple fruit moth forecasting" %}{%endblock%} {% block title%}{% trans "Apple fruit moth forecasting" %}{%endblock%}
{% block customJS %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.0.2"></script>
<script type="text/javascript" src="{% static "js/3rdparty/ol.js" %}"></script>
<script type="text/javascript" src="{% url "javascript-catalog" %}"></script>
<script type="text/javascript" src="{% url "views.settings_js" %}"></script>
<script type="text/javascript" src="{% static "js/util.js" %}"></script>
<script type="text/javascript" src="{% static "applefruitmoth/js/map.js" %}"></script>
<script type="text/javascript" src="{% static "applefruitmoth/js/applefruitmoth.js" %}"></script>
<script src="{% static "js/3rdparty/moment-with-locales.min.js" %}"></script>
<script type="text/javascript">
$(document).ready(function() {
initMap("appleFruitMothForecastMap","{{settings.MAP_ATTRIBUTION|safe}}");
});
</script>
<script type="module">
const modulePath = `${settings.vipslogicProtocol}://${settings.vipslogicServerName}/js/mapModal.js`;
import MapModal from 'https://logic.testvips.nibio.no/js/mapModal.js';
const selectWeatherstationElement = document.getElementById("weatherStationId");
window.lmtPoiMap = function() {
return fetch("https://lmt.nibio.no/services/rest/weatherstation/mapweatherstations")
.then(response => response.json())
.then(mapStations => {
mapStations.sort((a, b) => a.name.toString().localeCompare(b.name.toString()));
return mapStations.map(station => {
// If they don't match, return the id as weatherstationId
return { "id": station.weatherstationId, "name": station.name };
})})
.catch(error => console.error('Error:', error));
}
window.storeUserSettings = function() {
let userSettings = {};
userSettingsFields.forEach((fieldId) => {
userSettings[`{{ form_id }}.${fieldId}`] = document.getElementById(fieldId).value;
});
userSettingsRadios.forEach((radioName) => {
document.getElementsByName(radioName).forEach((radioElement) => {
if(radioElement.checked)
{
userSettings[`{{ form_id }}.${radioName}`] = radioElement.value;
}
});
});
storeLocalSettings(userSettings);
console.info("Store current user settings", userSettings);
}
import ApplefruitMoth from "../static/applefruitmoth/js/applefruitmoth.js";
const applefruitMoth = new ApplefruitMoth();
const inputLatitudeElement = document.getElementById("latitude");
const inputLongitudeElement = document.getElementById("longitude");
const userSettingsFields = ["latitude","longitude","timezone","weatherStationId"];
const userSettingsRadios = ["weatherdataType","radioDays"];
let poiIdList = []
let selectedPoint = null;
let selectedFeature = undefined;
let startDate;
let endDate;
function selectCoordinates(coordinatesData) {
const selectedLatitude = coordinatesData ? coordinatesData.latitude : undefined;
const selectedLongitude = coordinatesData ? coordinatesData.longitude : undefined;
if(selectedLatitude && selectedLongitude) {
inputLatitudeElement.value = selectedLatitude;
inputLongitudeElement.value = selectedLongitude;
}
getTimezoneForPoint(selectedLatitude, selectedLongitude);
runModel()
}
window.loadUserSettings = () => {
let userSettings = getLocalSettings(getNameSpaced("{{ form_id }}",userSettingsFields.concat(userSettingsRadios)), false);
console.info("User settings available when page is loaded", userSettings)
// Settings found, render form and run model
if(Object.keys(userSettings).length > 0)
{
userSettingsFields.forEach((fieldId) =>{
document.getElementById(fieldId).value = userSettings[`{{ form_id }}.${fieldId}`];
});
userSettingsRadios.forEach((radioName) => {
let radioValue = userSettings[`{{ form_id }}.${radioName}`];
document.getElementsByName(radioName).forEach((radioElement) => {
radioElement.checked = (radioElement.value == radioValue);
});
});
if(document.getElementById("coordinates").checked)
{
displayCoordinatesInput();
getTimezoneForPoint(inputLatitudeElement.value, inputLongitudeElement.value);
}
else
{
displayWeatherstationInput();
}
}
}
window.onload = async(event) => {
startDate = document.getElementById("startdate");
endDate = document.getElementById("endDate");
await applefruitMoth.renderWeatherstations();
loadUserSettings()
runModel();
}
// We need to do it this way to keep the "this" reference of the class
window.runModel = function () { storeUserSettings(); applefruitMoth.runModel(); };
window.openCoordinatesMap = () => {
if (inputLatitudeElement.value && inputLongitudeElement.value) {
selectedPoint = -1;
selectedFeature = {
"type": "FeatureCollection", "features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [parseFloat(inputLongitudeElement.value), parseFloat(inputLatitudeElement.value)]
},
"properties": {
"pointOfInterestId": selectedPoint,
}
}]
};
} else {
selectedPoint = undefined;
selectedFeature = undefined;
}
const isPoiMap = false; // Map should enable selection of coordinates (not pois)
const allowNewPoints = true; // User should be able to select new pois
import(modulePath).then((module) => {
const MapModal = module.default;
const coordinatesMapInstance = new MapModal('coordinates-map', selectedFeature, 'nb', isPoiMap, allowNewPoints, selectCoordinates);
coordinatesMapInstance.openModal(selectedPoint);
}).catch((error) => {
console.error('Error loading module MapModal for coordinatesMap', error);
});
}
function selectPoi(poiData)
{
const selectedId = poiData ? poiData.pointOfInterestId : undefined;
if (selectedId) {
const optionIndex = Array.from(selectWeatherstationElement.options).findIndex(option => option.value == selectedId);
if (optionIndex !== -1) {
selectWeatherstationElement.selectedIndex = optionIndex;
}
}
runModel();
}
window.openPoiMap = () => {
fetch("https://lmt.nibio.no/services/rest/weatherstation/ipmdecisions", {
method: 'GET'
})
.then(response => response.json())
.then(geoJson => {
// FILTER with only Ids from the Cydia station list
let filteredFeatures = geoJson["features"]
.filter(feature => applefruitMoth.weatherStationIds.indexOf(feature.id) >= 0)
.map(feature => {
feature["properties"]["pointOfInterestName"] = feature["properties"]["name"];
feature["properties"]["pointOfInterestId"] = feature["id"];
feature["properties"]["pointOfInterestTypeId"] = 1; // Type = Weather station
return feature;
});
geoJson["features"] = filteredFeatures;
const isPoiMap = true; // Map should enable selection of pois
const allowNewPoints = false; // User should not be able to create new pois
import(modulePath).then((module) => {
const MapModal = module.default;
const poiMapInstance = new MapModal('poi-map', geoJson, 'nb', isPoiMap, allowNewPoints, selectPoi);
const selectedPoiId = applefruitMoth.getSelectedWeatherstation();
poiMapInstance.openModal(selectedPoiId);
}).catch((error) => {
console.error('Error loading module MapModal for poiMap', error);
});
})
.catch(error => {
console.error('Unable to retrieve weatherstation geojson', error);
});
}
window.displayWeatherstationInput = function () {
document.getElementById("weatherstation").checked = true;
document.getElementById('input-weatherstation').style.display="block";
document.getElementById('input-coordinates').style.display="none";
}
window.displayCoordinatesInput = function () {
document.getElementById("coordinates").checked = true;
document.getElementById('input-weatherstation').style.display="none";
document.getElementById('input-coordinates').style.display="block";
selectWeatherstationElement.selectedIndex = 0;
}
const getTimezoneForPoint = (latitude, longitude) => {
getLocationInformation(latitude, longitude).then(locationInfo => {
document.getElementById("timezone").value = locationInfo.timezone;
document.getElementById("gridPointInfo").innerHTML = `<b>{% trans "Location name" %}</b> ${locationInfo.location}<br>
<b>{% trans "Latitude" %}</b> ${locationInfo.latitude}<br>
<b>{% trans "Longitude" %}</b> ${locationInfo.longitude}<br>
<b>{% trans "Timezone" %}</b> ${locationInfo.timezone}`
});
}
</script>
{% endblock %}
{% block content %} {% block content %}
<h1>{% trans "Apple fruit moth forecasting" %}</h1> <h1>{% trans "Apple fruit moth forecasting" %}</h1>
<div class="singleBlockContainer"> <div class="singleBlockContainer">
...@@ -76,31 +314,57 @@ ...@@ -76,31 +314,57 @@
<div class="row"><br><br> <div class="row"><br><br>
<div style="font-size:75%;" id="setBasis"></div> <div style="font-size:75%;" id="setBasis"></div>
<div class="col-md-3"> <div class="col-md-4">
<div class="form-group">
<label for="weatherstation">Målestasjon</label> <div class="form-group">
<select id="weatherstation" class="form-control"></select> <h4>Jeg vil bruke værdata</h4>
<div class="radio">
<label>
<input type="radio" name="weatherdataType" id="coordinates" value="coordinates" onchange="displayCoordinatesInput();">
fra et punkt i kartet
</label>
<div id="input-coordinates" class="form-inline" style="margin-top: 10px; display: none;"">
<input type="hidden" class="form-control" name="latitude" id="latitude" placeholder="Breddegrad" aria-label="Breddegrad">
<input type="hidden" class="form-control" name="longitude" id="longitude" placeholder="Lengdegrad" aria-label="Lengdegrad">
<input type="hidden" class="form-control" name="timezone" id="timezone" placeholder="Tidssone" aria-label="Tidssone">
<div id="gridPointInfo"></div>
<button type="button" class="btn btn-primary" onclick="openCoordinatesMap();" style="margin-left: 5px;"><i class="fa fa-map-marker fa-lg"></i>&nbsp;&nbsp;Velg i kart</button>
</div>
<div id="coordinates-map" class="map-modal"></div>
</div> </div>
<div class="radio">
<label>
<input type="radio" name="weatherdataType" id="weatherstation" value="weatherstation" onchange="displayWeatherstationInput();">
fra en værstasjon
</label>
<div id="input-weatherstation" class="form-inline" style="margin-top: 10px; display: none;">
<select name="weatherStationId" id="weatherStationId" class="form-control" style="width: 60%;" onchange="runModel()">
<option value="-1">-- Velg værstasjon --</option>
</select>
<button type="button" class="btn btn-primary" onclick="openPoiMap()" style="margin-left: 5px;"><i class="fa fa-map-marker fa-lg"></i>&nbsp;&nbsp;Velg i kart</button>
</div>
<div id="poi-map" class="map-modal"></div>
</div>
<span class="help-block" id="{{ form_id }}_latitude_validation"></span>
<span class="help-block" id="{{ form_id }}_weatherStationId_validation"></span>
<span class="help-block" id="{{ form_id }}_longitude_validation"></span>
<br>
<div class="form-group"> <div class="form-group">
<label for="startdate">Dato for full blom i rogn</label> <label for="startdate">Dato for full blom i rogn</label>
<input type="date" id="startdate" class="form-control"> <input type="date" id="startdate" class="form-control" onchange="runModel()">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="enddate">Sluttdato, med prognose 9 døgn fram i tid</label> <label for="enddate">Sluttdato, med prognose 9 døgn fram i tid</label>
<input type="date" value=moment().add(7,'days').format('YYYY-MM-DD'); id="enddate" class="form-control"> <input type="date" id="enddate" class="form-control" onchange="runModel()">
</div> </div>
<br>
<div class="form-group">
<button type="button" class="btn btn-primary" onclick="getBasis(this)">Beregn</button>
<br><br><br>
</div>
</div> </div>
<div class="col-md-9"> </div>
<div class="col-md-8">
<div class="col-md-2"></div> <div class="col-md-2"></div>
<div class="col-md-9"> <div class="col-md-9">
<br> <br>
...@@ -108,9 +372,8 @@ ...@@ -108,9 +372,8 @@
<img id="image" src="{% static 'applefruitmoth/applefruitmoth.png' %}" style="width:100%; height:auto;"> <img id="image" src="{% static 'applefruitmoth/applefruitmoth.png' %}" style="width:100%; height:auto;">
<p style="padding-left: 10px;padding-top: 5px;font-style: italic;">Foto: Sverre Kobro og E. Fløistad, NIBIO</p> <p style="padding-left: 10px;padding-top: 5px;font-style: italic;">Foto: Sverre Kobro og E. Fløistad, NIBIO</p>
</div> </div>
<div class="col-md-1"></div>
</div> </div>
<div class="col-md-1"></div>
</div> </div>
<br> <br>
</div> </div>
...@@ -130,25 +393,32 @@ ...@@ -130,25 +393,32 @@
{% endblock %} {% endblock %}
{% block customCSS %} {% block customCSS %}
<!--[if lte IE 9]>
<style type="text/css">#oldIEWarning{display: block !important;}</style>
<![endif]-->
<link type="text/css" rel="stylesheet" href="{{settings.VIPSLOGIC_PROTOCOL}}://{{settings.VIPSLOGIC_SERVER_NAME}}/css/3rdparty/leaflet.css" />
<link type="text/css" rel="stylesheet" href="{{settings.VIPSLOGIC_PROTOCOL}}://{{settings.VIPSLOGIC_SERVER_NAME}}/css/mapModal.css" />
<link rel="stylesheet" href="{% static "css/3rdparty/ol.css" %}" type="text/css"> <link rel="stylesheet" href="{% static "css/3rdparty/ol.css" %}" type="text/css">
<style>
input#latitude, input#longitude {
width: 30%;
display: inline-block;
margin: 10px 10px 10px 0;
}
select#weatherStationId {
width: 60%;
display: inline-block;
margin: 10px 10px 10px 0;
}
.main-label {
font-size: 1.8rem;
font-weight: 500 !important;
}
.space {
margin-top: 40px;
}
</style>
{% endblock %} {% endblock %}
{% block customJS %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.0.2"></script>
<script type="text/javascript" src="{% static "js/3rdparty/ol.js" %}"></script>
<script type="text/javascript" src="{% url "javascript-catalog" %}"></script>
<script type="text/javascript" src="{% url "views.settings_js" %}"></script>
<script type="text/javascript" src="{% static "js/util.js" %}"></script>
<script type="text/javascript" src="{% static "applefruitmoth/js/map.js" %}"></script>
<script type="text/javascript" src="{% static "applefruitmoth/js/applefruitmoth.js" %}"></script>
<script src="{% static "js/3rdparty/moment-with-locales.min.js" %}"></script>
<script type="text/javascript">
$(document).ready(function() {
initMap("appleFruitMothForecastMap","{{settings.MAP_ATTRIBUTION|safe}}");
});
</script>
{% endblock %}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment