User memory limit exceeded in GEE - javascript
I started using GEE recently. I wanted to apply the non-parametric Mann-Kendall method to a collection of Sentinel-1 images. However there is a memory error in the code and this is my problem. Link code:https://code.earthengine.google.com/4bf1dbbcd116c8e3f5c584fbb45e8c19
var quadricula = ee.Geometry.Polygon([[-51.20732599322313,-15.60026586116677],[-51.20732599322313,-15.455379154650098],[-51.262600956602036,-15.455379154650098],[-51.262600956602036,-15.60026586116677]]);
//Map.addLayer(quadricula);
// Filter collection to dates of interest.
var Sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD')
.filterDate('2015-01-01', '2022-01-01')
.filterBounds(quadricula);
print('Quantidade de imagens no intervalo definido:',Sentinel1.size());
//===========================================================================//
var wrapper = require('users/adugnagirma/gee_s1_ard:wrapper');
var helper = require('users/adugnagirma/gee_s1_ard:utilities');
//---------------------------------------------------------------------------//
// DEFINE PARAMETERS
//---------------------------------------------------------------------------//
//var geometry = ee.Geometry.Polygon([[-51.20732599322313,-15.60026586116677],[-51.20732599322313,-15.455379154650098],[-51.262600956602036,-15.455379154650098],[-51.262600956602036,-15.60026586116677]]);
//Map.addLayer(geometry);
var parameter = {//1. Data Selection
START_DATE: "2015-01-01",
STOP_DATE: "2022-01-01",
POLARIZATION:'VVVH',
ORBIT : 'BOTH',
GEOMETRY: quadricula, //uncomment if interactively selecting a region of interest
//GEOMETRY: ee.Geometry.Polygon([[[104.80, 11.61],[104.80, 11.36],[105.16, 11.36],[105.16, 11.61]]], null, false), //Uncomment if providing coordinates
//GEOMETRY: ee.Geometry.Polygon([[[112.05, -0.25],[112.05, -0.45],[112.25, -0.45],[112.25, -0.25]]], null, false),
//2. Additional Border noise correction
APPLY_ADDITIONAL_BORDER_NOISE_CORRECTION: true,
//3.Speckle filter
APPLY_SPECKLE_FILTERING: true,
SPECKLE_FILTER_FRAMEWORK: 'MULTI',
SPECKLE_FILTER: 'REFINED LEE',
SPECKLE_FILTER_KERNEL_SIZE: 5,
SPECKLE_FILTER_NR_OF_IMAGES: 10,
//4. Radiometric terrain normalization
APPLY_TERRAIN_FLATTENING: true,
DEM: ee.Image('NASA/NASADEM_HGT/001'),
TERRAIN_FLATTENING_MODEL: 'VOLUME',
TERRAIN_FLATTENING_ADDITIONAL_LAYOVER_SHADOW_BUFFER: 0,
//5. Output
FORMAT : 'DB',
CLIP_TO_ROI: true,
SAVE_ASSETS: false
};
//---------------------------------------------------------------------------//
// DO THE JOB
//---------------------------------------------------------------------------//
//Preprocess the S1 collection
var s1_preprocces = wrapper.s1_preproc(parameter);
var s1 = s1_preprocces[0];
s1_preprocces = s1_preprocces[1];
//---------------------------------------------------------------------------//
// VISUALIZE
//---------------------------------------------------------------------------//
//Visulaization of the first image in the collection in RGB for VV, VH, images
var visparam = {};
if (parameter.POLARIZATION=='VVVH'){
if (parameter.FORMAT=='DB'){
var s1_preprocces_view = s1_preprocces.map(helper.add_ratio_lin).map(helper.lin_to_db2);
var s1_view = s1.map(helper.add_ratio_lin).map(helper.lin_to_db2);
visparam = {bands:['VV','VH','VVVH_ratio'],min: [-20, -25, 1],max: [0, -5, 15]};
}
else {
var s1_preprocces_view = s1_preprocces.map(helper.add_ratio_lin);
var s1_view = s1.map(helper.add_ratio_lin);
visparam = {bands:['VV','VH','VVVH_ratio'], min: [0.01, 0.0032, 1.25],max: [1, 0.31, 31.62]};
}
}
else {
if (parameter.FORMAT=='DB') {
s1_preprocces_view = s1_preprocces.map(helper.lin_to_db);
s1_view = s1.map(helper.lin_to_db);
visparam = {bands:[parameter.POLARIZATION],min: -25,max: 0} ;
}
else {
s1_preprocces_view = s1_preprocces;
s1_view = s1;
visparam = {bands:[parameter.POLARIZATION],min: 0,max: 0.2};
}
}
// Calcula o MRFDI
var MRFDI = s1_preprocces.map(function(image) {
return image.normalizedDifference(['VV', 'VH']).rename('MRFDI');
});
var addMRFDI = function (image) {
var MRFDI = image.expression('(VV - VH)/(VV + VH)', {
'VV' : image.select('VV'),
'VH' : image.select('VH'),
}).float();
return image.addBands(MRFDI.rename('MRFDI'));
};
var MRFDI = s1_preprocces.map(addMRFDI)
.select('MRFDI');
// Calcula o RVI
var RVI = s1_preprocces.map(function(image) {
return image.normalizedDifference(['VV', 'VH']).rename('RVI');
});
var addRVI = function (image) {
var RVI = image.expression('(4*VH)/(VV + VH)', {
'VV' : image.select('VV'),
'VH' : image.select('VH'),
}).float();
return image.addBands(RVI.rename('RVI'));
};
var RVI = s1_preprocces.map(addRVI)
.select('RVI');
Map.centerObject(parameter.GEOMETRY, 12);
Map.addLayer(s1_view.first(), visparam, 'First image in the input S1 collection', true);
Map.addLayer(s1_preprocces_view.first(), visparam, 'First image in the processed S1 collection', true);
//---------------------------------------------------------------------------//
// EXPORT
//---------------------------------------------------------------------------//
//Convert format for export
if (parameter.FORMAT=='DB'){
s1_preprocces = s1_preprocces.map(helper.lin_to_db);
}
//Save processed collection to asset
if(parameter.SAVE_ASSETS) {
helper.Download.ImageCollection.toAsset(s1_preprocces, '',
{scale: 10,
region: s1_preprocces.geometry(),
type: 'float'});
}
print('Quantidade de imagens s1_preprocces:',s1_preprocces.size());
// Define an image collection time series to chart, MODIS vegetation indices
// in this case.
var imgCol = s1_preprocces
.select(['VV', 'VH']);
//=================================================================================//
//mann-kendall
var coll = s1_preprocces.map(function(image) {
return image.select().addBands(image.normalizedDifference(['VH', 'VV']));
})
.filter(ee.Filter.calendarRange(8, 9, 'month'));
Map.addLayer(coll, {}, 'coll');
var afterFilter = ee.Filter.lessThan({
leftField: 'system:time_start',
rightField: 'system:time_start'
});
var joined = ee.ImageCollection(ee.Join.saveAll('after').apply({
primary: coll,
secondary: coll,
condition: afterFilter
}));
var sign = function(i, j) { // i and j are images
return ee.Image(j).neq(i) // Zero case
.multiply(ee.Image(j).subtract(i).clamp(-1, 1)).int();
};
var kendall = ee.ImageCollection(joined.map(function(current) {
var afterCollection = ee.ImageCollection.fromImages(current.get('after'));
return afterCollection.map(function(image) {
// The unmask is to prevent accumulation of masked pixels that
// result from the undefined case of when either current or image
// is masked. It won't affect the sum, since it's unmasked to zero.
return ee.Image(sign(current, image)).unmask(0);
});
// Set parallelScale to avoid User memory limit exceeded.
}).flatten()).reduce('sum', 2);
var palette_sens = {min: -0.001, max: 0.001, palette: [
'red', 'white', 'green']};
var palette = ['red', 'white', 'green'];
// Stretch this as necessary.g
Map.addLayer(kendall, {palette: palette}, 'kendall');
var slope = function(i, j) { // i and j are images
return ee.Image(j).subtract(i)
.divide(ee.Image(j).date().difference(ee.Image(i).date(), 'days'))
.rename('slope')
.float();
};
var slopes = ee.ImageCollection(joined.map(function(current) {
var afterCollection = ee.ImageCollection.fromImages(current.get('after'));
return afterCollection.map(function(image) {
return ee.Image(slope(current, image));
});
}).flatten());
var sensSlope = slopes.reduce(ee.Reducer.median(), 2); // Set parallelScale.
Map.addLayer(sensSlope, palette_sens, 'sensSlope');
var epochDate = ee.Date('1970-01-01');
var sensIntercept = coll.map(function(image) {
var epochDays = image.date().difference(epochDate, 'days').float();
return image.subtract(sensSlope.multiply(epochDays)).float();
}).reduce(ee.Reducer.median(), 2);
Map.addLayer(sensIntercept, {}, 'sensIntercept');
Map.addLayer(table, {color: 'blue'});
I hope to resolve this impasse without changing the adopted time interval and reducing the size of the study area.
Related
Cannot plot 2 separate graphs using FlotJs
Im trying to plot 2 separate graphs (actually it will be 9 but for now there are only 2) using flotJS, somehow the data mixes and plots the same mixed data on both graphs Here is my JS code: var graphData1, graphData2, graphData3 = []; var graphBuffer = 1000; var xmin = 0; var xmax = 5; var options = { xaxes: [ {position: 'bottom', autoScale: 'none', min: 0, max: 5} ], yaxes: [ {position: 'left', autoScale: 'none', min: -1.5, max: 1.5} ], zoom: {interactive: true}, pan: {interactive: true} }; function deleteGraph() { graphData1 = graphData2 = graphData3 = []; $.plot("#graph1", [{graphData1}], options); $.plot("#graph2", [{graphData2}], options); //$.plot("#graph3", [{graphData3}], options); } function updateGraph(data) { var datatmp = data.data; // Formatea y Almacena datos a graficar datatmp.forEach(function (sample) { graphData1.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor1.toFixed(4))]); //graphData2.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor2.toFixed(4))]); }); $.plot("#graph1", [graphData1], options); $.plot("#graph2", [graphData2], options); } and with this code the output is: As you can see its plotting the same information on both graphs even when //graphData2.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor2.toFixed(4))]); is commented However if i remove the comment the result is this: As you can see its mixing the data and plotting the same mixed data on both graphs How can i plot different data on different graphs? Thanks for your help...
You are setting graphData1 = graphData2 so they are the same array. Then you push all your data points into that one array which is shown in both charts. Replace var graphData1, graphData2, graphData3 = []; // and function deleteGraph() { graphData1 = graphData2 = graphData3 = []; with var graphData1 = [], graphData2 = [], graphData3 = []; // and function deleteGraph() { graphData1 = []; graphData2 = []; graphData3 = [];
How do I update data in a SmoothieChart without spamming the the second value in TimeSeries?
I want to build some kind of stock trading website using JSON function getJSON(_url, _type) { var request = new XMLHttpRequest(); request.open("GET", _url, true); request.onload = function () { if (request.status == 200 && request.readyState == 4) { Callback(JSON.parse(request.responseText), _type); } else error("reach"); }; request.send(null); } and a callback function to get data. function Callback(_data, _type) { switch (_type) { case 1.1: initAktien(_data); break; case 1.2: updateAktien(_data); break; } } In order to visualize the stocks I'm using SmoothieChart. var lines = []; var smoothie = new SmoothieChart({ tooltip: true, millisPerPixel: 50, minValueScale: 0, grid: {fillStyle: '#99d6ff', strokeStyle: '#6c7d82', verticalSections: 8, borderVisible: false}, labels: {disabled: true, fontSize: 9}, minValue: 0, horizontalLines: [{color: '#000000', lineWidth: 1, value: 0}, {color: '#4d0f00', lineWidth: 2, value: 100}] }); smoothie.streamTo(document.getElementById("aktien-grafik"), 500); A little heads up in case you're wondering: "Aktien" means stocks, "preis" means price, and "anzahlVerfügbar" means available amount. I got this code from someone else and I'm supposed to "fix" it. That's why it's partially in German. function initAktien(_data) { var stocks = document.getElementById("aktien"); var amount = document.getElementById("amount"); for (var i = 0; i <= _data.length - 1; i++) { var stockoption = document.createElement("option"); stockoption.innerHTML = _data[i].name; stocks.appendChild(stockoption); } for (var j = 1; j <= 5; j++) { var amountoption = document.createElement("option"); amountoption.innerHTML = j; amount.appendChild(amountoption); } } function updateAktien(_data) { var select = document.getElementById("aktien").selectedIndex; document.getElementById("kurs").innerHTML = _data[select].preis; document.getElementById("anz").innerHTML = _data[select].anzahlVerfuegbar; //spam is because of here lines.push(new TimeSeries()); lines[select].append(new Date().getTime(), _data[select].preis); smoothie.addTimeSeries(lines[select], {lineWidth: 2, strokeStyle: "#000000"}); } I can render the graph just fine and I even get an overlay displaying the timestamp and the and the price and the time. Unfortunately it spams the price in the overlay which slows the site down quite fast. Removing the overlay doesn't solve the problem since the price is appended nonstop somewhere at the point I marked. I don't know how to keep the data updating and the chart drawing without spamming that value.
I don't think it's the best solution, but it works. It's somewhat redundant code. function initAktien(_data) { var stocks = getID("aktien"); var amount = getID("amount"); for (var i = 0; i <= _data.length - 1; i++) { var stockoption = document.createElement("option"); stockoption.innerHTML = _data[i].name; stocks.appendChild(stockoption); lines.push(new TimeSeries()); lines[i].append(new Date().getTime(), _data[i].preis.toFixed(2)); smoothie.addTimeSeries(lines[i], {lineWidth: 2, strokeStyle: "#000000"}); } } function updateAktien(_data) { var select = getID("aktien").selectedIndex; getID("kurs").innerHTML = _data[select].preis.toFixed(2); getID("anz").innerHTML = _data[select].anzahlVerfuegbar; //Grafik update lines[select].append(new Date().getTime(), _data[select].preis.toFixed(2)); }
React setstate with datamaps?
I am using Datamaps for this example. I have a Datamap that, when clicked in .datamaps-subunit.MI, changes the color of the portion. I would also like to store a number into my React state. However, the code below results in a this.setState is not a function error. lemap:function(){ var map = new Datamap({ element: document.getElementById('maincontains'), scope: 'usa', fills: {defaultFill: 'rgb(217, 217, 217)'}, done: function(datamap) { datamap.svg.select('.datamaps-subunit.MI').on('click', function(geography) { var m = {}; var bis = this; m[geography.id] = 'pink'; datamap.updateChoropleth(m); this.setState({trumpnum: 12}); }); } }); },
Fixed it by adding var sting = this right beneath the function. lemap:function(){ var sting = this; var map = new Datamap({ element: document.getElementById('maincontains'), scope: 'usa', fills: {defaultFill: 'rgb(217, 217, 217)'}, done: function(datamap) { datamap.svg.select('.datamaps-subunit.MI').on('click', function(geography) { var m = {}; var bis = this; m[geography.id] = 'pink'; datamap.updateChoropleth(m); sting.setState({trumpnum: 12}); }); } }); },
Amcharts' stockchart : lines in javascript too simple versus old flash version
I have to update an old amcharts' stockchart in the flash version to the javascript version. I made it, but the result is too different for my client. The flash version : The new javascript version : As you can see, the graph's lines on the new version are really too simple compare to the old version, there isn't enough details. This is the code of the new graph : var chart = new AmCharts.AmStockChart(); chart.dataSets = dataSets; var stockPanel = new AmCharts.StockPanel(); stockPanel.showCategoryAxis = true; stockPanel.numberFormatter = {precision:2, decimalSeparator:',', thousandsSeparator:' '}; stockPanel.percentFormatter = {precision:2, decimalSeparator:',', thousandsSeparator:' '}; var graph = new AmCharts.StockGraph(); graph.valueField = 'value'; graph.openField = 'open'; graph.closeField = 'close'; graph.comparable = true; graph.type = 'line'; graph.minDistance = 0; graph.noStepRisers = true; graph.clustered = false; stockPanel.addStockGraph(graph); var stockLegend = new AmCharts.StockLegend(); stockLegend.markerType = 'bubble'; stockLegend.markerSize = 8; stockLegend.periodValueText = '[[value.close]]'; stockLegend.valueTextComparing = '[[value]] | [[percents.value]]%'; stockLegend.periodValueTextComparing = '[[value.close]] | [[percents.value.close]]%'; stockLegend.horizontalGap = 1; stockLegend.spacing = 100; stockPanel.stockLegend = stockLegend; chart.panels = [ stockPanel ]; var categoryAxesSettings = new AmCharts.CategoryAxesSettings(); chart.categoryAxesSettings = categoryAxesSettings; var scrollbarSettings = new AmCharts.ChartScrollbarSettings(); scrollbarSettings.color = '#000'; scrollbarSettings.gridColor = '#fff'; scrollbarSettings.backgroundColor = '#fff'; scrollbarSettings.gridColor = '#fff'; scrollbarSettings.graphFillColor = '#F5F5F5'; //jsonData.funds.color; scrollbarSettings.selectedGraphFillColor = '#CCDDE9'; scrollbarSettings.selectedBackgroundColor = '#fff' scrollbarSettings.graph = graph; scrollbarSettings.graphType = 'line'; scrollbarSettings.usePeriod = "MM"; chart.chartScrollbarSettings = scrollbarSettings; var periodSelector = new AmCharts.PeriodSelector(); periodSelector.position = 'top'; periodSelector.fromText = ''; periodSelector.toText = ' - '; periodSelector.periodsText = ''; periodSelector.dateFormat = 'DD/MM/YYYY'; periodSelector.periods = [ { period: 'MM', count: 1, label: '1M' }, { period: 'MM', count: 3, label: '3M' }, { period: 'YYYY', count: 1, label: '1Y' }, { period: 'YYYY', count: 3, label: '3Y' }, { period: 'YYYY', count: 5, label: '5Y' }, { period: 'YTD', label: 'YTD' }, { period: 'MAX', label: 'MAX' } ]; chart.periodSelector = periodSelector; chart.write('fund_historic'); Which parameter do I have to add or change ? Thanks
OK I found it. When I compared the flash settings file, I see the max_series parameter fixed to 300, the double of the default value of the javascript version. So this is the solution : var categoryAxesSettings = new AmCharts.CategoryAxesSettings(); categoryAxesSettings.maxSeries = 300; chart.categoryAxesSettings = categoryAxesSettings;
I want to multiply chart data according as array length
I used this ,to multiply doughnut chart according as array(arr) has,but it can't change to object,(data has string type).So chart doesn't appear here..,how fix it var arr=['HTML','CSS','JS'],i,data; data ='['; for(i=0;i<arr.length;i++){ if(i==arr.length-1){ data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]}'; } else{ data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]},'; } } data += ']'; var dat = data; window.onload = function () { var ctx = document.getElementById("chart-area").getContext("2d"); window.myBar = new Chart(ctx).Doughnut(dat,{ responsive: true, }); }; //want like this dat =[{value:"300",color:"#fff",highlight:"#aaa",label:"HTML"}, {value:"200",color:"#fff",highlight:"#aaa",label:"CSS"}];
You are creating your array as a String. You need to create an array of objects [{},{},{}]. The method used to INSERT a new object in an array is PUSH(). Check the fiddle. Now it´s working OK (move the mouse on the screen to see the chart is there (you will only see it when mouse is over it): window.onload = function() { var arr = ['HTML', 'CSS', 'JS'], i, data; data = []; for (i = 0; i < arr.length; i++) { if (i == arr.length - 1) { data.push({ value: "300", color: "#fff", highlight: "#aaa", label: arr[i] }); } else { data.push({ value: "300", color: "#fff", highlight: "#aaa", label: arr[i] }); } } var dat = data; var ctx = document.getElementById("chart-area").getContext("2d"); window.myBar = new Chart(ctx).Doughnut(dat, { responsive: true, }); }; <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://rawgit.com/nnnick/Chart.js/master/Chart.js"></script> <canvas id="chart-area"></canvas>