Is there a way to push key value pairs in google earth engine in a loop that is using the map() function? - javascript

I am doing a spatiotemporal analysis of LULC on google earth engine.
For this, I have imported Landsat 5 tier 1 TOA reflectance images and filtered them by my preference. Following this I was able to extract the id values of the features in the filtered image collection, I need to create a dictionary in order to be able to assign the unique names from ID extracted by slicing the ID's and assign a value(id itself) to each pair.
The id obtained of images in an image collection is of the type: LANDSAT/LT05/C01/T1_TOA/LT05_148045_19890509
in this,
key:19890509
value:LT05_148045_19890509
both of which can be obtained from slicing the obtained ID
I have filtered the image collection and tried to create a dictionary as follows but it creates an empty dictionary.
// Create a list of image objects.
var imageList = Collection.toList(100);
print('imageList', imageList);
// Extract the ID of each image object.
var dicty = ee.Dictionary({}); //def dict for names
var id_list = imageList.map(function(item) {
var list_nm = ee.Image(item).id();
var lst_nm_slice = ee.Image(item).id().slice(-8,-1);
dicty.lst_nm_slice = list_nm;
return dicty;
});//end of map function
I expect the output of dicty to be a dictionary of key-value pairs with each key value getting assigned dynamically in the aforementioned loop so that I can call the images by using the dictionary key value pairs.

Generally speaking, you want to provide an iterable object to .map() and you get out an iterable like object with the original length (that function applied to each item). Earth Engine processes the function provided into .map() in parallel making it difficult to push values to a single variable in memory within that function. So, a solution to this is to set the ID values that you extract within the function to each image in the collection as a property and then outside of the function get the names and ids of the image into a dictionary. Here is a working code example:
// Create an ImageCollection and filter by space and time
var Collection = ee.ImageCollection('LANDSAT/LT05/C01/T1_TOA')
.filterDate('1990-01-01','1991-01-01')
.filterBounds(ee.Geometry.Point([86.5861,34.7304]));
print('LT5 Image Collection', Collection);
// Extract the ID of each image object and set as property
// within for each image in the collection
var Collection = Collection.map(function(img) {
var img_id = img.id();
var id_slice = img_id.slice(-8);
return img.set('id',id_slice);
});//end of map function
// Get the image IDs and names as lists from the collection
var ids = ee.List(Collection.aggregate_array('id'));
var names = ee.List(Collection.aggregate_array('system:index'));
// Build dictionary from each image ID and name
var out_dict = ee.Dictionary.fromLists(ids,names);
print('Output Dictionary',out_dict);

Related

adding data to firebase realtime database from an object (web)

I have an object containing multiple key value pairs, I want to add all the keys and their values, from inside the object to an existing node, without disturbing the data already present inside the node.
If i write like this
var ref = firebase.database().ref("hams/spam_words/");
ref.update({
new_words_ham //new_word_ham is an object containing n number of words
});
it will add new_words_ham as another child node inside the main node , i cannot have that
even using a forloop on the object does not work
var ref = firebase.database().ref("hams/spam_words/");
for(var i in new_words_ham){
var word = i
ref.update({
i
});
I am new to js as well as to firebase. Please do tell me if i have got any concept wrong
Your existing code
//new_word_ham is an object containing n number of words
firebase.database().ref("hams/spam_words/").update({
new_words_ham
});
Can be rewritten as
firebase.database().ref("hams/spam_words/").update({
new_words_ham: new_words_ham
});
when the shorthand syntax is expanded. What I believe you want is simply
firebase.database().ref("hams/spam_words/").update(new_words_ham);

Insert data in Firebase in Reactjs

During storing an object to my firebase, I am expecting the structure as image below, but what I get was a generated running number as a key. This is my code to store an object to firebase
var location = [];
location.push({
ms_jhr_1 : {
name: value
},
...
});
const a = firebase.database().ref('Food/'+id);
a.set(location);
How do I keep my structure without generate the running number?
The problem is you are using an array to store your data and then setting that array in firebase. To get the expected result you have to modify your code a little bit.
Here use this and remove other code
const a = firebase.database().ref('Food/'+id);
a.set(ms_jhr_1);
So you just need to pass the object you want to store under that id and not the whole array.
Note:- If you want to store multiple entries under one id then you have to push all those entries in an Object and not in array.
So it will look something like this
var location = {};
Now use for loop to insert all your data into this object (Remember, you are adding objects inside an object). You don't need array. Because in firebase data is stored in JSON tree format.
Hope it helps.

Checking for existing array in array before pushing

I missing something when trying to push to an array while preventing duplicates.
I keep figuring out code that will push every occurence of an employee to the new employees array but I cannot figure out how to only push an unique list.
My final array is a 2d array so that can be setValues() back into a column in the Google sheet.
function queryEmployees(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lRow = sh.getLastRow();
var data = sh.getRange(1,1,lRow,2).getValues();
var employees = [];
for(i=0;i<data.length;i++){
if(data[i][0]==='Team member evaluated'){
if(employees.indexOf([data[i][1]])===-1){
employees.push([data[i][1]]);
}
}
}
Logger.log(employees);
Logger.log(employees.length);
SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]
.getRange(1,1,employees.length,1).setValues(employees);
}
IndexOf does not work with objects in arrays without your rewriting the function or writing your own. It works fine with strings, though. So a simple fix is to create a parallel array of strings, which allows us to keep your code almost intact. Thus, add,
var employeesIndex=[];
after your
var employees=[]
change the condition on your inner "if" clause to
(employeesIndex.indexOf(data[i][1])===-1)
and within that if block add a line to update the index
employeesIndex.push(data[i][1]);
That way the index tracks duplicates for you while your employees array contains arrays like you need.

JavaScript - Retrieve variable value generated inside the for loop, externally

Well, I am working with a rest API that fetch information from the same database, but two different tables:
Table #1 contains(Outputs JSON results that contains the below objects):
id
name
type
Table #2 contains(Outputs JSON results that contains the below objects):
id
value (real-time, updated periodically)
What I want to do is to compare the id in Table #1 and compare it to id
in Table #2 and if there is a match between the two id's outputs the sum of (value) from Table #2 with all the values having the same id.
Until now what I am able to do is the following:
File1.js
require('File2.js');
for (a in metricsData){
var metricsID = metricsData[a].id;
}
/* Certainly the below code is not working, but I don't know if it should
be done this way or it can be much more better.
Can't get the values of both metricsID & idFromLoad
if(metricsID === idFromLoad) {
var sum += value;
console.log('The new sum is : '+sum)
} */
File2.js
for(var i in load.updates){
var idFromLoad = load.updates[i].id;
var newVal = load.updates[i].value;
}
So, the big question is how to get the values of both metricsID & idFromLoad outside of the for loop? Is there a better way to achieve what I am trying to do?
What you are trying to accomplish is a little confusing, but to answer the question as described in the title of this post...
Because you have the variable defined inside the loop, it only exists inside the loop. If you want to "remember" the value outside of the loop, you would need to define it outside:
var metricsID;
for (a in metricsData){
metricsID = metricsData[a].id;
}
Note though, that outside the loop, it's value will equal the id of the last item in the loop.
If you are looking for an easy way to look up values in both tables, what you could do is loop through each once and create a map keyed off the id so that you can easily retrieve the value based on the id.
var updatesMap = {};
for(var i in load.updates){
var idFromLoad = load.updates[i].id;
updatesMap[idFromLoad] = load.updates[i].value;
}
Then in your other loop:
for (a in metricsData){
var metricsID = metricsData[a].id;
var updateValue = updatesMap[meticsID]; //this is the value from the other table
}

How to move an object to the top of an array with AngularFire?

I am trying to move an object to the top of an array with AngularFire.
My array in Firebase is simmilar to this:
$scope.todos = [
{title:"Work out", timetag:"new Date()", done: false },
{title:"Home work", timetag:"new Date()", done: false }
];
I created a function that uses vanilla javascript that stores the object to a variable. The function deletes the object from the array that you want to move up to the beginning of the array. The function then replaces the object you stored to a variable to the beginning of the array.
Here is the code I have:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index];
delete $scope.todos[$index];
$scope.todos.splice(0,0, toMove);
$scope.todos.$save();
};
This code snippet is almost completely working the way I want. When I run this on my todo list, It moves the todo task up the array. However when I refresh the page, it doesn't stick.
What are the appropriate AngularFire Methods to completely save or set this type of javascript code to my Firebase Backend?
To preserve the order of the TODOs you could add a property named for example priority.
When a TODO is dragged/moved up the priority list you should then re-set the priority values of the TODOs save them and order them by that property in your template.
Okay so array methods like splice(), push(), pop(), shift(), unshift(), and reverse() will cause the Firebase Array to break.
So my work around was to edit/change the array with standard Javascript Array methods.
Then I store a copy of the local(edited)state array to a variable.
Then I delete the Firebase array.
Then I pushed the keys of the local array to Firebase.
Here is the code below:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index]; //save copy of $index todo
$scope.todos.splice($index,1); //removes item at $index
$scope.todos.splice(0,0, toMove); //adds item toMove to the start of array
var backup = $scope.todos; //copy back up array
for(var b = 0; b<= $scope.todos.length; b++){
$scope.todos.$remove($scope.todos[b]); //remove items from array
}
for(var i = 0; i<= backup.length; i++){
$scope.todos.$add(backup[i]); // add items from back up array
}
};

Categories