I am trying to write a function which will create a dictionary from an image collection using Sentinel 2 data which will contain label/value pairs where the label comes from the MGRS_TILE property of the image and the value will contain a list of all the images with the same MGRS_TILE id. The label values must be distinct.I want the output to be like this: {'label' : 'tileid1', 'values':[ image1, image2 ...] 'label' : 'tileid2', 'values':[ image3, image4 ...]}
Below is my code: interestImageCollection is my filtered imageCollection object tileIDS is a ee.List type object containg all of the distinct tile ids and field is the name of the image property of my interest which in this case is 'MGRS_TILE'.
var build_selectZT = function(interestImageCollection, tileIDS, field){
//this line returns a list which contains the unique tile ids thanks to the keys function
//var field_list = ee.Dictionary(interestImageCollection.aggregate_histogram(field)).keys();
//.map must always return something
var a = tileIDS.map(function(tileId) {
var partialList=ee.List([]);
var partialImage = interestImageCollection.map(function(image){
return ee.Algorithms.If(ee.Image(image).get(field)==tileId, image, null);
});
partialList.add(partialImage);
return ee.Dictionary({'label': tileId, 'value': partialList});
}).getInfo();
return a;
};
Unfortunately the above function gives me this result: {'label' : 'tileid1', 'values':[], 'label' : 'tileid2', 'values':[]}
I think you can use filter function instead of using if. And if you need it in list form then you could change it to list using toList function.
var build_selectZT = function(interestImageCollection, tileIDS, field){
//.map must always return something
var a = tileIDS.map(function(tileId) {
var partialList=ee.List([]);
// get subset of image collection where images have specific tileId
var subsetCollection = interestImageCollection.filter(ee.Filter.eq(field, tileId));
// convert the collection to list
var partialImage = subsetCollection.toList(subsetCollection.size())
partialList.add(partialImage);
return ee.Dictionary({'label': tileId, 'value': partialList});
}).getInfo();
return a;
};
BUT this would actually give you a list of dictionaries
[{'label':'id1','value':[image1]},{'label':'id2','value':[image2,image3]......}]
If you want to use ee.Algorithms.If like you did in your code then your error is in the "ee.Image(image).get(field)==tileId" part. as .get(field) is returning a server side object, you can't use == to equate it to something, since it is an string type you need to use compareTo instead. However, it returns 0 if the strings are same and since 0 is treated as false, you can return image when condition is false.
return ee.Algorithms.If(ee.String(ee.Image(image).get(field)).compareTo(tileId), null, image);
I still think this is a bad way as you'll get an array full of null in values like
[{'label':'id1','value':[image1, null, null, null, .....]},{'label':'id2','value':[null,image2,image3, null,....]......}]