gars_v2
Version:
Geo Assistant Research System
469 lines (391 loc) • 13.6 kB
JavaScript
// Here is the starting point for your application code.
// All stuff below is just to show you how it works. You can delete all of it.
// Use new ES6 modules syntax for everything.
import { remote, webFrame, ipcRenderer } from 'electron'; // native electron module
import env from './env';
import Map from './helpers/map';
import Plot from './helpers/plot';
import error from './helpers/error';
import fileUrl from 'file-url';
console.log('Loaded environment variables:', env);
var map = new Map($('body'));
var plot = new Plot($('.plot-panel'));
var mapData;
var $infoPanel = $('.info-panel');
var indicator = null;
var range_gen = null;
webFrame.setVisualZoomLevelLimits(1, 1);
setViewMode('map');
$('.btn-close').click(() => {
console.log('window closing...');
remote.getCurrentWindow().close();
});
$('.btn-zoomin').click(() => {
map.zoom(map.scale * 1.1);
});
$('.btn-zoomout').click(() => {
map.zoom(map.scale * 0.9);
});
$('.btn-longitude').click(function () {
range_gen = getRange();
indicator = 'lon';
plot.line({
title: mapData.title,
xlabel: 'Longitude',
ylabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
data: mapData.rangeAveX(range_gen.x1, range_gen.y1, range_gen.x2, range_gen.y2)
});
});
$('.btn-latitude').click(function() {
range_gen = getRange();
indicator = 'lat';
plot.line({
title: mapData.title,
xlabel: 'Latitude',
ylabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
data: mapData.rangeAveY(range_gen.x1, range_gen.y1, range_gen.x2, range_gen.y2)
});
});
$('.btn-histogram').click(function(){
range_gen = getRange();
indicator = 'hist';
var binnedData = binData(mapData.accData(range_gen.x1, range_gen.y1, range_gen.x2, range_gen.y2));
plot.hist({
title: mapData.title,
xlabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
ylabel: 'Frequency',
data: binnedData
});
});
$('.btn-open-stat').click(() => {
setViewMode('stat');
initAreaSelector();
map.stop();
plot.empty();
return false;
});
$('.btn-close-stat').click(() => {
setViewMode('map');
disposeAreaSelector();
map.start();
indicator = null;
return false;
});
$('.btn-preyear').click(() => {
var oldpath = mapData.FP;
var oldyear = oldpath.slice(-11).substring(0,4);
var oldmonth = oldpath.slice(-7).substring(0,2);
if (oldmonth==1){
var newpath = oldpath.split(oldyear).join(Number(oldyear)-1);
newpath = newpath.substring(0, newpath.length-7) + '12.png';
} else{
var newmonth = Number(oldmonth)-1;
if (newmonth<10){
newmonth = '0' + newmonth;
};
newpath = oldpath.substring(0, oldpath.length-7) + newmonth + '.png';
};
var path = newpath;
console.log('opening', path);
mapData = null;
disableBtn($('.btn-open-stat'));
disableBtn($('.btn-preyear'));
disableBtn($('.btn-aftyear'));
var uColorbar = fileUrl(path).replace(/\/[^/]*$/, '/colorbar.png');
$infoPanel.find('#colorbar').attr('src', uColorbar);
map.reopen(path)
.then((data) => {
enableBtn($('.btn-open-stat'));
enableBtn($('.btn-preyear'));
enableBtn($('.btn-aftyear'));
mapData = data;
})
.catch(e => {
error('Cannot load image data', e.message);
});
});
$('.btn-aftyear').click(() => {
var oldpath = mapData.FP;
var oldyear = oldpath.slice(-11).substring(0,4);
var oldmonth = oldpath.slice(-7).substring(0,2);
if (oldmonth==12){
var newpath = oldpath.split(oldyear).join(Number(oldyear)+1);
newpath = newpath.substring(0, newpath.length-7) + '01.png';
} else{
var newmonth = Number(oldmonth)+1;
if (newmonth<10){
newmonth = '0' + newmonth;
};
newpath = oldpath.substring(0, oldpath.length-7) + newmonth + '.png';
};
var path = newpath;
console.log('opening', path);
mapData = null;
disableBtn($('.btn-open-stat'));
disableBtn($('.btn-preyear'));
disableBtn($('.btn-aftyear'));
var uColorbar = fileUrl(path).replace(/\/[^/]*$/, '/colorbar.png');
$infoPanel.find('#colorbar').attr('src', uColorbar);
map.reopen(path)
.then((data) => {
enableBtn($('.btn-open-stat'));
enableBtn($('.btn-preyear'));
enableBtn($('.btn-aftyear'));
mapData = data;
})
.catch(e => {
error('Cannot load image data', e.message);
});
});
$('.btn-preyearinplot').click(() => {
var oldpath = mapData.FP;
var oldyear = oldpath.slice(-11).substring(0,4);
var oldmonth = oldpath.slice(-7).substring(0,2);
if (oldmonth==1){
var newpath = oldpath.split(oldyear).join(Number(oldyear)-1);
newpath = newpath.substring(0, newpath.length-7) + '12.png';
} else{
var newmonth = Number(oldmonth)-1;
if (newmonth<10){
newmonth = '0' + newmonth;
};
newpath = oldpath.substring(0, oldpath.length-7) + newmonth + '.png';
};
var path = newpath;
console.log('opening', path);
mapData = null;
disableBtn($('.btn-open-stat'));
disableBtn($('.btn-preyearinplot'));
disableBtn($('.btn-aftyearinplot'));
var uColorbar = fileUrl(path).replace(/\/[^/]*$/, '/colorbar.png');
$infoPanel.find('#colorbar').attr('src', uColorbar);
map.reopen(path)
.then((data) => {
enableBtn($('.btn-open-stat'));
enableBtn($('.btn-preyearinplot'));
enableBtn($('.btn-aftyearinplot'));
mapData = data;
renewAreaSelector();
replot(range_gen, indicator);
})
.catch(e => {
error('Cannot load image data', e.message);
});
});
$('.btn-aftyearinplot').click(() => {
var oldpath = mapData.FP;
var oldyear = oldpath.slice(-11).substring(0,4);
var oldmonth = oldpath.slice(-7).substring(0,2);
if (oldmonth==12){
var newpath = oldpath.split(oldyear).join(Number(oldyear)+1);
newpath = newpath.substring(0, newpath.length-7) + '01.png';
} else{
var newmonth = Number(oldmonth)+1;
if (newmonth<10){
newmonth = '0' + newmonth;
};
newpath = oldpath.substring(0, oldpath.length-7) + newmonth + '.png';
};
var path = newpath;
console.log('opening', path);
mapData = null;
disableBtn($('.btn-open-stat'));
disableBtn($('.btn-preyearinplot'));
disableBtn($('.btn-aftyearinplot'));
var uColorbar = fileUrl(path).replace(/\/[^/]*$/, '/colorbar.png');
$infoPanel.find('#colorbar').attr('src', uColorbar);
map.reopen(path)
.then((data) => {
enableBtn($('.btn-open-stat'));
enableBtn($('.btn-preyearinplot'));
enableBtn($('.btn-aftyearinplot'));
mapData = data;
console.log('data ready');
renewAreaSelector();
replot(range_gen,indicator);
})
.catch(e => {
error('Cannot load image data', e.message);
});
});
ipcRenderer.on('open', function(event, path) {
console.log('opening', path);
mapData = null;
disableBtn($('.btn-open-stat'));
disableBtn($('.btn-preyear'));
disableBtn($('.btn-aftyear'));
var uColorbar = fileUrl(path).replace(/\/[^/]*$/, '/colorbar.png');
$infoPanel.find('#colorbar').attr('src', uColorbar);
map.open(path)
.then((data) => {
enableBtn($('.btn-open-stat'));
enableBtn($('.btn-preyear'));
enableBtn($('.btn-aftyear'));
mapData = data;
})
.catch(e => {
error('Cannot load image data', e.message);
});
});
function setViewMode(mode) {
enableBtn($('.btn[disabled-mode]'));
disableBtn($(`.btn[disabled-mode=${mode}]`));
$('[hidden-mode]')
.css('display', 'block');
$(`[hidden-mode=${mode}]`)
.css('display', 'none');
}
function updateInfoPanel({range}){
$infoPanel.find('#left').text(mapData.longitudeText(range.x1));
$infoPanel.find('#top').text(mapData.latitudeText(range.y1));
$infoPanel.find('#right').text(mapData.longitudeText(range.x2));
$infoPanel.find('#bottom').text(mapData.latitudeText(range.y2));
}
function getRange(){
var areaSelector = map.$img.data('mainImageSelectAreas');
var areas = areaSelector.areas();
if (areas.length === 0) {
error('Selected Area Not Found', 'Select an area first');
}
var area = areas[0];
return area2range(area);
}
function area2range(area) {
var x1 = area.x / map.scale;
var y1 = area.y / map.scale;
var x2 = (area.x + area.width) / map.scale;
var y2 = (area.y + area.height) / map.scale;
x1 = Math.floor(mapData.cols * x1 / map.width);
x2 = Math.ceil(mapData.cols * x2 / map.width);
y1 = Math.floor(mapData.rows * y1 / map.height);
y2 = Math.ceil(mapData.rows * y2 / map.height);
var range = { x1, x2, y1, y2 };
console.log('get range', area);
return range;
}
function initAreaSelector() {
// Document: https://github.com/360Learning/jquery-select-areas
map.$img.selectAreas({
minSize: [0, 0],
maxSize: [1000000, 1000000],
allowDelete: false,
maxAreas: 1,
onChanging: (ev, id, areas) => {
if(areas.length === 0) return;
var range = area2range(areas[0]);
updateInfoPanel({range});
},
onChanged: (ev, id, areas) =>{
var range = area2range(areas[0]);
replot(range, indicator);
}
});
}
function renewAreaSelector(){
range_gen = getRange();
var areaSelector = map.$img.data('mainImageSelectAreas');
var areaSav = areaSelector.areas();
areaSelector.reset();
areaSelector.add(areaSav);
}
function disposeAreaSelector() {
var areaSelector = map.$img.data('mainImageSelectAreas');
areaSelector.destroy();
}
function disableBtn($btn) {
$btn.attr('disabled', true)
.css("pointer-events", "none");
}
function enableBtn($btn) {
$btn.removeAttr('disabled')
.css('pointer-events', 'auto');
}
function binData(data) {
console.log('calculating binData');
var hData, size, bins, max, min, range, width, bin_bottom, bin_top;
hData = new Array(); //the output array
size = data.length; //how many data points
bins = Math.round(Math.sqrt(size)); //determine how many bins we need
bins = bins > 50 ? 50 : bins; //adjust if more than 50 cells
min = mmiinn(data); //highest data value
max = mmaaxx(data); //lowest data value
range = max - min; //total range of the data
width = range / bins; //size of the bins
//place holders for the bounds of each bin
//loop through the number of cells
for (var i = 0; i < bins; i++) {
//set the upper and lower limits of the current cell
bin_bottom = min + (i * width);
bin_top = bin_bottom + width;
//check for and set the x value of the bin
if (!hData[i]) {
hData[i] = new Array();
hData[i][0] = bin_bottom + (width / 2);
}
//loop through the data to see if it fits in this bin
for (var j = 0; j < size; j++) {
var x = data[j];
//adjust if it's the first pass
i == 0 && j == 0 ? bin_bottom -= 1 : bin_bottom = bin_bottom;
//if it fits in the bin, add it
if (x > bin_bottom && x <= bin_top) {
!hData[i][1] ? hData[i][1] = 1 : hData[i][1]++;
}
}
}
$.each(hData, function(i, point) {
if (typeof point[1] == 'undefined') {
hData[i][1] = 0;
}
});
for (i = 0; i < bins; i++){
hData[i][1]=hData[i][1]/size;
};
return hData;
}
function mmaaxx(data){
var l=data.length;
var m=data[0];
for (var k = 1; k < l; k++){
m=Math.max(m,data[k]);
};
return m;
}
function mmiinn(data){
var l=data.length;
var m=data[0];
for (var k = 1; k < l; k++){
m=Math.min(m,data[k]);
};
return m;
}
function replot(range, statu){
switch(statu){
case 'lon':
plot.line({
title: mapData.title,
xlabel: 'Longitude',
ylabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
data: mapData.rangeAveX(range.x1, range.y1, range.x2, range.y2)
});
break;
case 'lat':
plot.line({
title: mapData.title,
xlabel: 'Latitude',
ylabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
data: mapData.rangeAveY(range.x1, range.y1, range.x2, range.y2)
});
break;
case 'hist':
var binnedData = binData(mapData.accData(range.x1, range.y1, range.x2, range.y2));
plot.hist({
title: mapData.title,
xlabel: 'NO2 [x10\xB9\xB3 molecules/cm\xB2]',
ylabel: 'Frequency',
data: binnedData
});
break;
default:
}
}