Get an array of specific parameters from Image Collection of Google Earth Engine - google-earth-engine

I've got an Image Collection like:
ImageCollection : {
features : [
0 : {
type: Image,
id: MODIS/006/MOD11A1/2019_01_01,
properties : {
LST_Day_1km : 12345,
LST_Night_1km : 11223,
system:index : "2019-01-01",
system:asset_size: 764884189,
system:footprint: LinearRing,
system:time_end: 1546387200000,
system:time_start: 1546300800000
},
1 : { ... }
2 : { ... }
...
],
...
]
From this collection, how can I get an array of objects of specific properties? Like:
[
{
LST_Day_1km : 12345,
LST_Night_1km : 11223,
system:index : "2019-01-01"
},
{
LST_Day_1km : null,
LST_Night_1km : 11223,
system:index : "2019-01-02"
}
...
];
I tried ImageCollection.aggregate_array(property) but it allows only one parameter at one time.
The problem is that the length of "LST_Day_1km" is different from the length of "system:index" because "LST_Day_1km" includes empty values, so it's hard to combine arrays after get them separately.
Thanks in advance!

Whenever you want to extract data from a collection in Earth Engine, it is often a straightforward and efficient strategy to first arrange for the data to be present as a single property on the features/images of that collection, using map.
var wanted = ['LST_Day_1km', 'LST_Night_1km', 'system:index'];
var augmented = imageCollection.map(function (image) {
return image.set('dict', image.toDictionary(wanted));
});
Then, as you're already familiar with, just use aggregate_array to extract that property's values:
var list = augmented.aggregate_array('dict');
print(list);
Runnable complete example:
var imageCollection = ee.ImageCollection('MODIS/006/MOD11A1')
.filterDate('2019-01-01', '2019-01-07')
.map(function (image) {
// Fake values to match the question
return image.set('LST_Day_1km', 1).set('LST_Night_1km', 2)
});
print(imageCollection);
// Add a single property whose value is a dictionary containing
// all the properties we want.
var wanted = ['LST_Day_1km', 'LST_Night_1km', 'system:index'];
var augmented = imageCollection.map(function (image) {
return image.set('dict', image.toDictionary(wanted));
});
print(augmented.first());
// Extract that property.
var list = augmented.aggregate_array('dict');
print(list);
https://code.earthengine.google.com/ffe444339d484823108e23241db04629

Related

Indexing data in my firebase realtime database rules based on the nested value

I have the following JSON tree from my realtime database:
{
"old_characters" :
{
"Reptile" : {
"kick" : 20,
"punch" : 15
},
"Scorpion" : {
"kick" : 15,
"punch" : 10
},
"Sub-zero" : {
"kick" : 30,
"punch" : 10
}
},
"new_characters" : {
//...ect
}
}
Is it possible to set rules in my firebase console so that I can index my data based on the character with the highest value of kick?
The constraints are:
- character_name are dynamic.
- Key "kick" is static, but its value is dynamic.
Result should be:
Sub-zero first (kick 30)
Reptile second (kick 20)
Scorpion third (kick 15)
What you want seems to be a fairly simple Firebase query on the kick property:
var ref = firebase.dababase().ref('old_characters');
var query = ref.orderByChild('kick');
query.once(function(snapshot) {
snapshot.forEach(function(characterSnapshot) {
console.log(characterSnapshot.key);
console.log(characterSnapshot.child('kick').val());
});
});
You'll note that this prints the results in ascending order. You can:
either reverse the results client-side
or add an inverted property with -1 * score to each character and then order on that
To learn more about the inverting/sorting descending, have a look at some of these previous questions:
firebase -> date order reverse
Sorting in descending order in Firebase database
sorting numbers with firebase

How to separate multiple columns from a range in an array?

I have a range of data in a Google Sheet and I want to store that data into an array using the app script. At the moment I can bring in the data easily enough and put it into an array with this code:
var sheetData = sheet.getSheetByName('Fruit').getRange('A1:C2').getValues()
However, this puts each row into an array. For example, [[Apple,Red,Round],[Banana,Yellow,Long]].
How can I arrange the array by columns so it would look: [[Apple,Banana],[Red,Yellow],[Round,Long]].
Thanks.
It looks like you have to transpose the array. You can create a function
function transpose(data) {
return (data[0] || []).map (function (col , colIndex) {
return data.map (function (row) {
return row[colIndex];
});
});
}
and then pass the values obtained by .getValues() to that function..
var sheetData = transpose(sheet.getSheetByName('Fruit').getRange('A1:C2').getValues())
and check the log. See if that works for you?
Use the Google Sheets API, which allows you to specify the primary dimension of the response. To do so, first you must enable the API and the advanced service
To acquire values most efficiently, use the spreadsheets.values endpoints, either get or batchGet as appropriate. You are able to supply optional arguments to both calls, and one of which controls the orientation of the response:
const wb = SpreadsheetApp.getActive();
const valService = Sheets.Spreadsheets.Values;
const asColumn2D = { majorDimension: SpreadsheetApp.Dimension.COLUMNS };
const asRow2D = { majorDimension: SpreadsheetApp.Dimension.ROWS }; // this is the default
var sheet = wb.getSheetByName("some name");
var rgPrefix = "'" + sheet.getName() + "'!";
// spreadsheetId, range string, {optional arguments}
var single = valService.get(wb.getId(), rgPrefix + "A1:C30");
var singleAsCols = valService.get(wb.getId(), rgPrefix + "A1:C30", asColumn2D);
// spreadsheetId, {other arguments}
var batchAsCols = valService.batchGet(wb.getId(), {
ranges: [
rgPrefix + "A1:C30",
rgPrefix + "J8",
...
],
majorDimension: SpreadsheetApp.Dimension.COLUMNS
});
console.log({rowResp: single, colResp: singleAsCols, batchResponse: batchAsCols});
The reply will either be a ValueRange (using get) or an object wrapping several ValueRanges (if using batchGet). You can access the data (if any was present) at the ValueRange's values property. Note that trailing blanks are omitted.
You can find more information in the Sheets API documentation, and other relevant Stack Overflow questions such as this one.

How to access final element in Handlebars.js array?

Given the following data structure:
{
"name" : "test",
"assetType" : "Home",
"value" : [
{
"value" : "999",
"date" : "10/03/2018"
},
{
"value" : "1234.56",
"date" : "10/04/2018"
}
]
}
How can I directly access the first and last element of value in Handlebars? My code is:
<td>{{value.[0].value}}</td>
<td>{{value.[value.length - 1].value}}</td>
The first statement works fine, but I cannot figure out how to access the last element. value.length inside the []'s does not return any value, but rendering value.length outside of the array works fine.
I tried using #first and #last in the array but those don't seem to work either.
As already pointed out, you can easily solve this with a template helper:
Template.myTemplate.helpers({
first (arr) {
return arr && arr[0]
},
last (arr) {
return arr && arr[arr.length - 1]
},
atIndex (arr, index) {
return arr && index >= 0 && index <= arr.length - 1 && arr[index]
}
})
You can then create a context using #with where the context object is the result of the helpers. Inside this context you can access properties using this.
Accessing values with the name value would look like the following:
<td>{{#with first value}}{{this.value}}{{/with}}</td>
<td>{{#with last value}}{{this.value}}{{/with}}</td>
<td>{{#with atIndex value 5}}{{this.value}}{{/with}}</td>

Filtering / Querying by the Contents of a List in DynamoDB

I am attempting to filter a DynamoDB query by the contents of a Map contained within a List. Here's an example of the structure I'm dealing with.
{
'EventType': 'git/push'
'EventTime': 1416251010,
'Commits': [
{
'id': '29d02aff...',
'subject': 'Add the thing to the place'
},
{
'id': '9d888fec...',
'subject': 'Spelling errors'
},
...
]
}
The hash key is EventType and range key EventTime. I am trying to write a filter that filters the result of a query to a specific id. Is is possible to create a DynamoDB filter expression that correctly filters the query like this? (My first thought was to use contains (a, a), but I don't think that will work on a List of Maps.)
This isn't currently supported by DynamoDB's API's expression language (as of November 2014) but there are some workarounds mentioned here.
I found a solution and I tested it, and it is working fine.
Here's what I did,
// created a schema like that:
var Movie = dynamo.define('example-nested-attribute', {
hashKey : 'title',
timestamps : true,
schema : {
title : Joi.string(),
releaseYear : Joi.number(),
tags : dynamo.types.stringSet(),
director : Joi.object().keys({
firstName : Joi.string(),
lastName : Joi.string(),
titles : Joi.array()
}),
actors : Joi.array().items(Joi.object().keys({
firstName : Joi.string(),
lastName : Joi.string(),
titles : Joi.array()
}))
}
});
and then you can query of a nested array of objects:
var params = {};
params.UpdateExpression = 'SET #year = #year + :inc, #dir.titles = list_append(#dir.titles, :title), #act[0].firstName = :firstName ADD tags :tag';
params.ConditionExpression = '#year = :current';
params.ExpressionAttributeNames = {
'#year' : 'releaseYear',
'#dir' : 'director',
'#act' : 'actors'
};
params.ExpressionAttributeValues = {
':inc' : 1,
':current' : 2001,
':title' : ['The Man'],
':firstName' : 'Rob',
':tag' : dynamo.Set(['Sports', 'Horror'], 'S')
};

How to pre-select an option in a dropdown knockout js

I've looked at this other question, but can't get my select box to work correctly:
Binding initial/default value of dropdown (select) list
I've got the following Game object:
function Game(visitingTeamDetails, homeTeamDetails, game) {
if (arguments.length > 0) {
this.VisitingTeamDetails = visitingTeamDetails;
this.HomeTeamDetails = homeTeamDetails;
this.GameId = ko.observable(game.GameId);
this.HomeTeamName = ko.observable(game.HomeTeamName);
this.VisitingTeamName = ko.observable(game.VisitingTeamName);
this.SportTypeName = ko.observable(game.SportTypeName);
this.HomeAccountName = ko.observable(game.HomeAccountName);
this.VisitingAccountName = ko.observable(game.VisitingAccountName);
this.GameDateString = ko.observable(game.GameDateString);
this.GameTimeString = ko.observable(game.GameTimeString);
this.AvailableSportTypes = ko.observableArray(game.Sports);
this.sportTypeFunction = function () {
for (sportType in this.AvailableSportTypes()) {
if (this.AvailableSportTypes()[sportType].Name == this.SportTypeName()) {
return this.AvailableSportTypes()[sportType];
}
}
return null;
};
this.SportType = ko.observable(game.SportType);
}
}
SportType is an object with Name and SportTypeId.
I have the following template:
<td rowspan="3"><select data-bind="options: AvailableSportTypes, value: SportType, optionsText:'Name', optionsCaption: 'Choose...'" class="sportType"></select></td>
AvailableSportTypes is a list of SportType.
The list is coming in with the names of the SportTypes in the drop down list, but I can't make the initial selection be SportType. I wrote sportTypeFunction to show myself that the data was coming in correctly, and it would select the correct value, but changing my selection in the drop down would not update SportType.
I'm sure I'm doing something wrong. Anyone see it?
Thanks
When game.SportType gets passed in, it needs to be a reference to the an item in the game.AvailableSportTypes and not just an object that looks the same.
Basically two objects are not equal unless they are actually a reference to the same object.
var a = { name: "test" },
b = { name: "test" };
alert(a === b); //false
So, you would need to call your function to locate the correct object in the array and set it as the value of your observable.
Not that it is way better, but in KO 1.3 you can extend .fn of observables, observableArrays, and dependentObservables to add additional functionality.
Here is a sample: http://jsfiddle.net/rniemeyer/ZP79w

Resources