Tuesday, 15 March 2016

Perform calculations for each Polygon in a MultiPolygon object (Earth Engine)


I have layer that contains many polygons. I want to run calcuation for each polygon in the layer so for each polygon I have the mean and the std. deviation and from this I can run calculation for each polygon in the layer individually.


Right now the situation is that when I calculate for 1 polygon only I get the mean and std. deviation for it so my calculation is good because the data is based on the statistics of this one polygon:


enter image description here


But if I have layer with more than one geometry, as you can see, It takes the mean and std deviation from all the polygons and nor for each one so my calculation is not as I want it to be:


enter image description here


As you can see, the right side polygon got diffferent values because the mean and std deviation are based on all the polygons.


Is there any way to make GEE to take it separately for each polygon and not only for the whole collection? I read about reduce region but as you see it seems like it doesn't work...


My end goal is to get statistic for each polygon separately so I can run my calculation and get info about each polygon .


This is the calculation part:



//calculation
var std2 = ee.Number(tableWithStats.get('NDVI_stdDev')).divide(2);
var mean1 = ee.Number(tableWithStats.get("NDVI_mean"));

print('std2',std2,'mean1',mean1);

// the classes borders
var negBorder=mean1.subtract(std2);
var posBorder=mean1.add(std2);


print('negBord:',negBorder,'posBord:',posBorder);

//create the layers
var imageNDVI=MyImage.select('NDVI');
var gtPOS=MyImage.gt(posBorder).selfMask().rename('range');
var ltNEG=MyImage.lt(negBorder).selfMask().rename('range');
var betMEAN=MyImage.gt(negBorder).and(imageNDVI.lt(posBorder)).selfMask().rename('range');

var pos=gtPOS.select('range').multiply(3);
var neg=ltNEG.select('range').multiply(2);



var ndviClassCol = ee.ImageCollection.fromImages([neg,betMEAN, pos]);

// Mosaic the ImageCollection.
var ndviClassImg = ndviClassCol.mosaic();

// Display the classified mosaic to the Map.
Map.centerObject(geometry, 16);


Map.addLayer(pos,{palette:['9370DB']});
Map.addLayer(neg,{palette:['0fff50']});
Map.addLayer(betMEAN,{palette:['fff200']});

Map.addLayer(ndviClassImg, {palette: ['ff0000', '00ff00', '006622'], min: 1, max: 3},'mosaic');


Edit: When I try the code that Daniel suggested that is not client side on layers with many plots, I get different results.


This is when I check one individual plot out of 2000:


enter image description here



and when I run the code on all the 2000 plots, I wouls excpect to get the sam resulr but I get something different:


enter image description here



Answer



You can split your MultiPolygon into many single Polygons and calculate your stats:


// Check if it's a MultiPolygon
if (geometry instanceof ee.Geometry.MultiPolygon) {
// If it is a MultiPolygon, split it up into separate Polygons
// and do the work on each of them, separately.
// In your code, you printed intermediate values and
// added intermediate layers to your map.

// Because of this, you're forced to do this client-side.
// evaluate() moves to the client-side of things. In this case,
// you get the number of polygons the MultiPolygon consists of.
geometry.coordinates().size().evaluate(function (count) {
for (var i= 0; i < count; i++) { // i is index of the polygon
// Extract the coordinates for the polygon
var polygon = ee.Geometry.Polygon(
ee.List(geometry.coordinates().get(i))
)
// Do work with the simple polygon

calculateMyStats(polygon)
}
})
} else {
// If it's not a MultiPolygon, do work with the complete geometry
calculateMyStats(geometry)
}


function calculateMyStats(geometry) {

// Your old code goes here...
}

https://code.earthengine.google.com/ef876b9230cbf8c6e7854e47ac1c5692


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...