Commit 586806da authored by Tomas Pettersson's avatar Tomas Pettersson 🏸

added period

parent 009eb85a
......@@ -66,7 +66,28 @@
<script>
var map = L.map('map').setView([ 58.5, 19.0 ], 5);
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom : 18,
attribution : '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors</a>'
});
map.addLayer(osm);
var containerControl = new L.Control.Container({
position: 'topright',
collapse: true
});
map.addControl(containerControl);
var language = 'en';
var itracerLangData = {
};
var coordinatesLangData = {
"tMarkerstart": "Click map to place point.",
"tPolygonstart": "Hold left mouse button to draw polygon on map.",
......@@ -112,67 +133,82 @@
"coordinates": coordinatesLangData
};
L.Control.SimpleComponent = L.Control.extend({
initialize: function (height, open) {
this._height = '500px';
if (height) {
this._height = height;
}
this.open = false;
if (typeof open === 'boolean') {
this.open = open;
}
},
onAdd: function (map) {
this.container = L.DomUtil.create('div', 'simple-component-control');
var accordionDiv = STWkit.DomUtil.create('div', 'uk-accordion', this.container);
var cardid = 'cardid1';
var forcing = {};
var forcing = false;
var obs = false;
var card = new STWkit.LocationCard(cardid, accordionDiv, language, langData, map, forcing, obs);
card.show();
L.DomEvent.disableClickPropagation(this.container);
return this.container;
},
ready: function(name) { // this method is optional
if (this.open) {
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent('container:showComponent', false, false, {
'name': name,
'show' : true
});
window.dispatchEvent(evt);
}
},
show: function() {},
hide: function() {}
});
var map = L.map('map').setView([ 58.5, 19.0 ], 5);
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom : 18,
attribution : '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors</a>'
});
map.addLayer(osm);
var containerControl = new L.Control.Container({
position: 'topright',
collapse: true
var forcing = {
"model": "NEMO",
"configuration": "NORDIC",
"domain": "NS02"
};
var domainname = "HELCOM";
reqwest({
url: "forcing/config"+STWkit.jsonToQueryString(forcing),
method: 'get',
type: 'json',
success: function (forcing) {
var properties = {
"domain" : domainname,
"lang": language,
"langdata": langData
};
if (forcing.features.length > 0) properties["forcing"] = forcing;
// SimpleCardControl = STWkit.CardControl.extend({
// setup: function (map) {
// this.container = STWkit.DomUtil.create('div', +self.name+'-control');
// this.accordionDiv = STWkit.DomUtil.create('div', 'uk-accordion', this.container);
// var locationid = self.initials+'locationCard';
// self.cardMap[locationid] = new Location(locationid, this.accordionDiv, self.lang, self.langData, map, self.forcing);
// self.cardMap[locationid].show();
// // super.setup(map);
// },
// show: function() {},
// // ready: function(name) {super.ready(name)},
// // clear: function() {super.clear()},
// // hide: function() {super.hide()}
// });
class SimpleCardControl extends STWkit.CardControl {
constructor(options) {super(options);}
setup(map) {
this.container = STWkit.DomUtil.create('div', +self.name+'-control');
this.accordionDiv = STWkit.DomUtil.create('div', 'uk-accordion', this.container);
var options = {};
var initials = '';
options['singlebutton'] = true;
options['multiplebutton'] = true;
options['linebutton'] = true;
options['areabutton'] = true;
options['initials'] = initials;
var locationid = 'locationCard';
this.cardMap[locationid] = new STWkit.LocationCard(locationid, 'Specify location', this.accordionDiv, this.lang, this.langData, map, this.forcing, options);
this.cardMap[locationid].show();
var periodid = 'periodCard';
this.cardMap[periodid] = new STWkit.PeriodCard(periodid, 'Simulation period', this.accordionDiv, this.lang, map, this.domain, this.forcingmodel);
super.setup(map);
var chain = [];
chain[locationid] = periodid;
chain[periodid] = '';
this.cardMap[locationid].oncallback = (gonext) => {
super.callback(chain, locationid, gonext);
};
this.cardMap[periodid].oncallback = (gonext) => {
super.callback(chain, periodid, gonext);
};
}
show() {}
hide() {}
clear() {super.clear()}
ready(name) {super.ready(name)}
}
var cardcontrol = new SimpleCardControl(properties);
containerControl.addComponent("CardControl", cardcontrol);
cardcontrol.accordionDiv = STWkit.DomUtil.create('div', 'uk-accordion', cardcontrol.container);
}
});
map.addControl(containerControl);
containerControl.addComponent("Component1", new L.Control.SimpleComponent());
</script>
</body>
......
var express = require('express');
var path = require('path');
var request = require('request');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
var url = '/demo'
require('../bower_components/leaflet-forcing-boundary/src/routes/forcingboundary')(url,app);
app.use('/bower_components', express.static(path.join(__dirname, '../bower_components')));
app.use('/src', express.static(path.join(__dirname, '../src')));
app.use('/demo', express.static(__dirname));
......
......@@ -5,7 +5,10 @@
"private": true,
"dependencies": {
"express": "4.x",
"path": "latest"
"path": "latest",
"body-parser": "latest",
"request": "latest",
"@turf/within" : "latest"
},
"devDependencies": {
"grunt": "^1.0.1",
......
......@@ -89,13 +89,14 @@ var STWkit;
STWkit.AccordionCard = AccordionCard;
var LocationCard = (function (_super) {
__extends(LocationCard, _super);
function LocationCard(id, title, parentDiv, lang, langData, map, forcing) {
function LocationCard(id, title, parentDiv, lang, langData, map, forcing, options) {
var _this = this;
var locationDiv = STWkit.DomUtil.create('div', 'uk-width-1-1 uk-margin-top', parentDiv);
_this = _super.call(this, id, title, parentDiv, locationDiv) || this;
var self = _this;
self.locationDiv = locationDiv;
if (forcing)
self.forcingBoundary = new Forcing.Boundary(locationDiv, map, forcing);
self.forcingBoundary = new Forcing.Boundary(self.locationDiv, map, forcing);
var satCallbackFn = function (latlngs, geojsonfeature, timestamp, id) {
self.clear();
var geojson = {};
......@@ -105,40 +106,47 @@ var STWkit;
geojson.features[0].properties["simulation"] = {};
self.populateCard(geojson);
};
function legendBox(fieldset, color, text, size) {
var rowDiv = L.DomUtil.create('div', 'uk-form-row uk-margin-remove', fieldset);
var legendBox = L.DomUtil.create('div', 'legend-box', rowDiv);
legendBox.style.backgroundColor = color;
legendBox.style.width = size;
legendBox.style.height = size;
legendBox.title = text;
var legendText = L.DomUtil.create('div', 'legend-text', rowDiv);
legendText.textContent = text;
}
var obsform = L.DomUtil.create('form', 'uk-form uk-form-stacked', locationDiv);
obsform.onsubmit = function (e) {
self.locationForm = L.DomUtil.create('form', 'uk-form uk-form-stacked', self.locationDiv);
self.locationForm.onsubmit = function (e) {
e.preventDefault();
e.stopPropagation();
return false;
};
var typeLabelGrid = L.DomUtil.create('div', 'uk-grid uk-margin-top', obsform);
var initials = (options && options.initials) || '';
var showsingle = (options && options.singlebutton) || true;
var showmultiple = (options && options.multiplebutton) || false;
var showline = (options && options.linebutton) || true;
var showarea = (options && options.areabutton) || true;
var typeLabelGrid = L.DomUtil.create('div', 'uk-grid uk-margin-top', self.locationForm);
var objectlabelDiv = L.DomUtil.create('div', 'uk-width-1-2', typeLabelGrid);
_super.prototype.addLabelDiv.call(_this, objectlabelDiv, "Outlet type", "See more information <a style='color:#faa732;' href='help/classic/#oil-oo-type' target='_blank'>here</a>");
var typeDiv = L.DomUtil.create('div', '', obsform);
typeDiv.id = 'guidefo1';
var typeDiv = L.DomUtil.create('div', '', self.locationForm);
typeDiv.id = 'guide' + initials + '1';
typeDiv.setAttribute('data-uk-button-radio', '');
var typeButtonGrid = L.DomUtil.create('div', 'uk-grid uk-grid-small', typeDiv);
var objectbuttonsDiv = L.DomUtil.create('div', 'uk-width-1-2', typeButtonGrid);
var objectButtonGroup = L.DomUtil.create('div', 'uk-button-group', objectbuttonsDiv);
self.pointButton = L.DomUtil.create('button', 'uk-button uk-button-small', objectButtonGroup);
self.pointButton.textContent = 'Single';
if (!showsingle)
self.pointButton.style.display = 'none';
self.multipleButton = L.DomUtil.create('button', 'uk-button uk-button-small', objectButtonGroup);
self.multipleButton.textContent = 'Multiple';
self.multipleButton.disabled = false;
if (!showmultiple)
self.multipleButton.style.display = 'none';
self.lineButton = L.DomUtil.create('button', 'uk-button uk-button-small', objectButtonGroup);
self.lineButton.textContent = 'Line';
self.lineButton.disabled = false;
if (!showline)
self.lineButton.style.display = 'none';
self.polygonButton = L.DomUtil.create('button', 'uk-button uk-button-small', objectButtonGroup);
self.polygonButton.textContent = 'Area';
if (!showarea)
self.polygonButton.style.display = 'none';
self.pointButton.onclick = function () { self.geometryType = "point"; self.control.setType(self.geometryType); };
self.lineButton.onclick = function () { self.geometryType = "linestring"; self.control.setType(self.geometryType); };
self.multipleButton.onclick = function () { self.geometryType = "multipoint"; self.control.setType(self.geometryType); };
self.polygonButton.onclick = function () { self.geometryType = "polygon"; self.control.setType(self.geometryType); };
self.polygonButton.disabled = false;
self.hasPosition = false;
......@@ -150,11 +158,11 @@ var STWkit;
(self.oncallback && self.oncallback());
}
;
var positionLabelGrid = L.DomUtil.create('div', 'uk-grid uk-margin-top', obsform);
var positionLabelGrid = L.DomUtil.create('div', 'uk-grid uk-margin-top', self.locationForm);
var positionlabelDiv = L.DomUtil.create('div', 'uk-width-1-1', positionLabelGrid);
_super.prototype.addLabelDiv.call(_this, positionlabelDiv, "Position", "See more information <a style='color:#faa732;' href='help/classic/#oil-oo-position' target='_blank'>here</a>");
var positionDiv = L.DomUtil.create('div', '', obsform);
positionDiv.id = 'guideoo2';
var positionDiv = L.DomUtil.create('div', '', self.locationForm);
positionDiv.id = 'guide' + initials + '2';
var positionButtonGrid = L.DomUtil.create('div', 'uk-grid uk-grid-small', positionDiv);
var latlonDiv = L.DomUtil.create('div', 'uk-width-1-2', positionButtonGrid);
var drawDiv = L.DomUtil.create('div', 'uk-width-1-2', positionButtonGrid);
......@@ -211,18 +219,21 @@ var STWkit;
var coordinates = [];
switch (self.geometryType) {
case 'point':
coordinates.push([latlngs[0][0].lng, latlngs[0][0].lat]);
coordinates.push([latlngs[0][0].lng, latlngs[0][0].lat, 0]);
break;
case 'multipoint':
coordinates = geojson.features[0].geometry.coordinates;
for (var i = 0; i < coordinates.length; i++) {
coordinates[i].push(0);
}
break;
case 'linestring':
var center = L.polyline(latlngs).getBounds().getCenter();
coordinates.push([center.lng, center.lat]);
coordinates.push([center.lng, center.lat, 0]);
break;
case 'polygon':
var center = L.polygon(latlngs).getBounds().getCenter();
coordinates.push([center.lng, center.lat]);
coordinates.push([center.lng, center.lat, 0]);
break;
default:
break;
......@@ -236,7 +247,7 @@ var STWkit;
}
});
var content = self.control.onAdd(map);
var coordinateDiv = L.DomUtil.create('div', 'uk-margin-top uk-margin-bottom', locationDiv);
var coordinateDiv = L.DomUtil.create('div', 'uk-margin-top uk-margin-bottom', self.locationDiv);
coordinateDiv.appendChild(content);
self.control.hideTable();
latlngButton.onclick = function () { self.control.latlng(); };
......@@ -253,15 +264,15 @@ var STWkit;
self.exitControl.onAdd = function (map) {
var container = L.DomUtil.create('div', 'exit-control');
var exitPanel = L.DomUtil.create('div', 'uk-panel uk-panel-box', container);
var finnishButton = L.DomUtil.create('button', 'uk-button uk-button-small uk-button-primary uk-margin-right', exitPanel);
finnishButton.textContent = 'Finnish';
finnishButton.onclick = function (e) {
var finishButton = L.DomUtil.create('button', 'uk-button uk-button-small uk-button-primary uk-margin-right', exitPanel);
finishButton.textContent = 'Finish';
finishButton.onclick = function (e) {
map.fire('draw:canceled');
};
finnishButton.style.display = 'none';
finishButton.style.display = 'none';
// 3 is multipoint type in coordinates control
if (self.control.getType() == 3)
finnishButton.style.display = '';
finishButton.style.display = '';
var cancelButton = L.DomUtil.create('button', 'uk-button uk-button-small', exitPanel);
cancelButton.textContent = 'Cancel';
cancelButton.onclick = function (e) {
......@@ -281,7 +292,7 @@ var STWkit;
self.exitControl.addTo(map);
};
// importButton.onclick = function(){self.control.import();};
var clearDiv = L.DomUtil.create('div', 'uk-clearfix', locationDiv);
var clearDiv = L.DomUtil.create('div', 'uk-clearfix', self.locationDiv);
var clearButton = L.DomUtil.create('button', 'uk-button uk-margin-top uk-align-left', clearDiv);
clearButton.textContent = 'Clear';
clearButton.onclick = function () {
......@@ -289,7 +300,7 @@ var STWkit;
};
self.nextButton = L.DomUtil.create('button', 'uk-button uk-margin-top uk-align-right', clearDiv);
self.nextButton.textContent = 'Next';
self.nextButton.id = 'guideoo3';
self.nextButton.id = 'guide' + initials + '3';
self.nextButton.guideFn = function () {
self.nextButton.click();
};
......@@ -327,6 +338,9 @@ var STWkit;
case "point":
self.pointButton.click();
break;
case "multipoint":
self.multipleButton.click();
break;
case "linestring":
self.lineButton.click();
break;
......@@ -362,6 +376,269 @@ var STWkit;
return LocationCard;
}(AccordionCard));
STWkit.LocationCard = LocationCard;
var PeriodCard = (function (_super) {
__extends(PeriodCard, _super);
function PeriodCard(id, title, parentDiv, lang, map, domain, forcingmodel) {
var _this = this;
var periodDiv = L.DomUtil.create('div', 'uk-width-1-1 uk-margin-top', parentDiv);
_this = _super.call(this, id, title, parentDiv, periodDiv) || this;
var self = _this;
self.domain = domain;
self.forcingmodel = forcingmodel;
var form = L.DomUtil.create('form', 'uk-form uk-form-stacked', periodDiv);
form.onsubmit = function (e) {
e.preventDefault();
e.stopPropagation();
return false;
};
self.datetimeFormat = 'YYYY-MM-DD HH:mm';
self.dateFormat = 'YYYY-MM-DD';
self.timeFormat = 'HH:mm';
self.minDate = moment.utc().startOf('hour').subtract(72, 'hours');
self.maxDate = moment.utc().startOf('hour').add(240, 'hours');
var fieldset = L.DomUtil.create('fieldset', '', form);
var availableRowDiv = L.DomUtil.create('div', 'uk-form-row', fieldset);
_super.prototype.addLabelDiv.call(_this, availableRowDiv, "Selected period (UTC)", "See more information <a style='color:#faa732;' href='help/classic/#object-fo-period' target='_blank'>here</a>");
var availableDiv = L.DomUtil.create('div', '', availableRowDiv);
var startRowDiv = L.DomUtil.create('div', 'uk-form-row', fieldset);
_super.prototype.addLabelDiv.call(_this, startRowDiv, "Start date (UTC)", "See more information <a style='color:#faa732;' href='help/classic/#object-fo-start' target='_blank'>here</a>");
var startDiv = L.DomUtil.create('div', 'uk-form-controls uk-form-icon uk-width-1-1', startRowDiv);
var startIcon = L.DomUtil.create('span', 'uk-icon-calendar', startDiv);
self.startDateInput = L.DomUtil.create('input', 'uk-width-1-2', startDiv);
self.startDateInput.type = 'text';
self.startDateInput.placeholder = self.dateFormat;
self.startTimeInput = L.DomUtil.create('input', 'uk-width-1-2', startDiv);
self.startTimeInput.type = 'text';
var durationRowDiv = L.DomUtil.create('div', 'uk-form-row', fieldset);
_super.prototype.addLabelDiv.call(_this, durationRowDiv, "Duration", "See more information <a style='color:#faa732;' href='help/classic/#object-fo-duration' target='_blank'>here</a>");
var durationDiv = L.DomUtil.create('div', 'uk-form-controls uk-form-icon uk-width-1-1', durationRowDiv);
durationDiv.id = 'guideos4';
var durationIcon = L.DomUtil.create('span', 'uk-icon-clock-o', durationDiv);
self.durationHours = L.DomUtil.create('input', 'uk-width-2-6', durationDiv);
self.durationHours.type = 'number';
self.durationHours.value = '48';
self.durationHours.min = '0';
self.durationHours.step = '12';
var hoursSpan = L.DomUtil.create('span', 'uk-width-1-6', durationDiv);
hoursSpan.textContent = " hours";
var clearDiv = L.DomUtil.create('div', 'uk-clearfix', periodDiv);
var clearButton = L.DomUtil.create('button', 'uk-button uk-margin-top uk-align-left', clearDiv);
clearButton.textContent = 'Clear';
clearButton.onclick = function () {
self.clear();
};
self.nextButton = L.DomUtil.create('button', 'uk-button uk-margin-top uk-align-right', clearDiv);
self.nextButton.textContent = 'Next';
self.nextButton.id = 'guideos5';
self.nextButton.guideFn = function () {
self.nextButton.click();
};
AccordionCard.enableNext(self.nextButton, false);
self.nextButton.onclick = function () {
if (!AccordionCard.isEnabled(self.nextButton)) {
AccordionCard.warningMsg('Mandatory fields missing', 'Specify a valid <b>start date</b> and <b>duration</b> period.');
return;
}
(self.oncallback && self.oncallback(true));
};
self.clear();
$(availableDiv).ionRangeSlider({
min: +self.minDate.utc().format("X"),
max: +self.maxDate.utc().format("X"),
from: +self.from.utc().format("X"),
to: +self.to.utc().format("X"),
disable: true,
step: 1800,
grid: false,
type: "double",
force_edges: true,
prettify: function (num) {
return moment(num, "X").utc().format(self.datetimeFormat);
}
});
self.slider = $(availableDiv).data("ionRangeSlider");
self.durationHours.onchange = function () {
var date = moment.utc(self.startDateInput.value + ' ' + self.startTimeInput.value, self.datetimeFormat);
if (self.forward) {
date.add(parseInt(self.durationHours.value), 'hours');
if (self.isDateValid(date)) {
self.to = date;
}
else {
self.durationHours.value = moment.duration(self.to.diff(self.from)).asHours() + '';
}
}
else {
date.subtract(parseInt(self.durationHours.value), 'hours');
if (self.isDateValid(date)) {
self.from = date;
}
else {
self.durationHours.value = moment.duration(self.to.diff(self.from)).asHours() + '';
}
}
self.updateSlider();
};
self.startDateInput.onchange = function (evt) {
self.adjustDateToRange();
self.updateSlider();
};
self.startTimeInput.onchange = function (evt) {
self.adjustDateToRange();
self.updateSlider();
};
UIkit.ready(function () {
if (!self.ready) {
reqwest({
url: "availableTimes/ms/" + self.domain + "_" + self.forcingmodel,
method: 'get',
type: 'json',
success: function (data) {
self.minDate = moment.utc(data.availableTime.start);
self.maxDate = moment.utc(data.availableTime.stop);
var sliderOpt = {};
sliderOpt['min'] = self.minDate.format("X");
sliderOpt['max'] = self.maxDate.format("X");
self.slider.update(sliderOpt);
self.ready = true;
}
});
var startDatePicker = UIkit.datepicker(self.startDateInput, { minDate: self.minDate.format(self.dateFormat), maxDate: self.maxDate.format(self.dateFormat), format: self.dateFormat });
var startTimePicker = UIkit.timepicker(self.startTimeInput, {});
self.defaults();
}
});
return _this;
}
PeriodCard.prototype.isDateValid = function (date) {
var self = this;
if (!date.isValid())
return false;
if (date.isBefore(self.minDate) || date.isAfter(self.maxDate))
return false;
return true;
};
PeriodCard.prototype.getValidDateInfo = function () {
var self = this;
var result = {};
result.valid = false;
var date = moment.utc(self.startDateInput.value + ' ' + self.startTimeInput.value, self.datetimeFormat);
(self.forward) ? date.add(parseInt(self.durationHours.value), 'hours') : date.subtract(parseInt(self.durationHours.value), 'hours');
result.date = date;
if (self.isDateValid(date)) {
result.valid = true;
}
return result;
};
PeriodCard.prototype.validate = function () {
var self = this;
self.status = false;
AccordionCard.enableNext(self.nextButton, false);
var dateinfo = self.getValidDateInfo();
if (typeof dateinfo.valid == 'undefined') {
(self.oncallback && self.oncallback());
return;
}
;
if (moment.duration(self.to.diff(self.from)).asHours() == 0) {
(self.oncallback && self.oncallback());
return;
}
;
if (!dateinfo.valid) {
self.from = moment.utc(self.slider.result.from * 1000);
self.to = moment.utc(self.slider.result.to * 1000);
var duration = moment.duration(self.to.diff(self.from)).asHours();
self.durationHours.value = duration + '';
if (duration == 0)
return;
}
self.status = true;
AccordionCard.enableNext(self.nextButton, true);
(self.oncallback && self.oncallback());
};
PeriodCard.prototype.updateSlider = function () {
var self = this;
var sliderOpt = {};
sliderOpt['from'] = self.from.format("X");
sliderOpt['to'] = self.to.format("X");
self.slider.update(sliderOpt);
self.validate();
};
PeriodCard.prototype.adjustDateToRange = function () {
var self = this;
var date = moment.utc(self.startDateInput.value + ' ' + self.startTimeInput.value, self.datetimeFormat);
if (date.isBefore(self.minDate))
self.startTimeInput.value = self.minDate.startOf('hour').format(self.timeFormat);
if (date.isAfter(self.maxDate))
self.startTimeInput.value = self.maxDate.startOf('hour').format(self.timeFormat);
if (self.forward) {
self.from = date.clone();
self.to = date.add(self.durationHours.value, 'hours');
}
else {
self.to = date.clone();
self.from = date.subtract(self.durationHours.value, 'hours');
}
};
PeriodCard.prototype.defaults = function () {
var self = this;
self.durationHours.value = '48';
self.forward = true;
self.adjustDateToRange();
self.updateSlider();
};
PeriodCard.prototype.populateCard = function (geojson) {
var self = this;
var simulation = geojson.features[0].properties.simulation;
var startDate = moment.utc(simulation.startDate);
var stopDate = moment.utc(simulation.stopDate);