Counting cloudless days using Google Earth Enigne - Sentinel-5p - google-earth

I perform some analysis on Sentinel-5P data using Google Earth Engine. I would like to know how many cludless days are during month for each pixel. I am using the code below and it works. The problem is that Sentinel-5P images are captured several times a day so my result is number of cloudless images instead of cloudless days.
//Poland's border
var polska = ee.FeatureCollection('users/patrykgrzybowski1991/POL_adm1');
//upload collection
var collection_january_19 = ee.ImageCollection('COPERNICUS/S5P/NRTI/L3_NO2')//('COPERNICUS/S5P/NRTI/L3_NO2')
//filters
.filterBounds(ee.FeatureCollection('users/patrykgrzybowski1991/POL_adm0'))
.filterDate('2019-01-01', '2019-02-01')
.map(function(img){return ee.Image(img.select('tropospheric_NO2_column_number_density')).updateMask(img.select('cloud_fraction').lt(0.4))})
//cludless images - count
var count_january_19 = collection_january_19.count();

Number of cloudless days is slightly ill-defined when there are multiple images, but if you mean "none of the images on a day had clouds in them", then you probably need to composite the images by day before counting:
var start = ee.Date('2019-01-01')
var daysAsList = ee.List.sequence(0, 31).map(function(n) {
n = ee.Number(n)
var begin = start.advance(n, 'day')
var end = begin.advance(1, 'day')
return collection_january_19.filterDate(begin, end).mosaic()
})
var days = ee.ImageCollection.fromImages(daysAsList).count()

Related

Problem with understanding date formats in googleScripts

I made a few functions with GoogleSheets using AppsScripts for simple task a few times in previous years. I always had problems when taking dates from cells/ranges and processing them, but somehow alwaays found a workaround, so that I did not have to deal with it. Well, this time I can not find a workaround, so I will try to explain my problems with the following code:
function getDates(){
var s = SpreadsheetApp.getActiveSpreadsheet();
var sht = s.getSheetByName('Dates');
var date = sht.getRange(2,1).getValues();
Logger.log(date[0][0]); //output is Tue Jun 08 18:00:00 GMT-04:00 2021
var datumFilter= Utilities.formatDate(date[0][0], "GMT+1", "dd/mm/yy");
Logger.log(datumFilter); //output is 08/00/21
var outrng = sht.getRange(25,1);
outrng.setValue(date);
}
The first targeted cell ('var date') has a value of "9.6.21" in the spreadsheet. The cell is formatted as a date and it opens a calendar when double-clicked. When I set the new cells values (with 'outrng.setValue(date);'), the result is OK, with the same date as in the original cell.
But I do not need to simply transfer the values, I want to implement them in some loops and I have no idea how to simply get the date in the same format or at least the same date in the script as it is in the cell. As you can see from the logger, the values there are different. A simple d/m/yy format would be sufficient.
My spreadsheet settings are set to my local time (Slovenia, GMT+1).
I am guessing that I am missing some basics here. I have spent many hours trying to understand it, so any help is highly appreciated!
Cooper already answered all your questions in the comment. I'd like to add on and show you an example on what it would like and add some modifications.
Code:
function getDates() {
var s = SpreadsheetApp.getActiveSpreadsheet();
var sht = s.getSheetByName('Dates');
// get last row of the sheet
var lastRow = sht.getLastRow();
// get your sheet's timezone
var timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var output = [];
// getValues is mostly used for multiple cells returning a 2D array
// use getValue for single cells to return its actual value
// but since function name is getDates, I assume column A is all dates
// so we fetch the whole column (A2:A[lastRow]) except the header
var dates = sht.getRange("A2:A" + lastRow).getValues();
// for each date on that column, we format the date to d/M/yy
// m/mm = minute
// M/MM = month
dates.forEach(function ([date]){
Logger.log(date);
var datumFilter= Utilities.formatDate(new Date(date), timezone, "d/M/yy");
Logger.log(datumFilter);
// collect all dates in an array
output.push([datumFilter]);
});
// assign all the dates in the array onto range B2:B
sht.getRange(2, 2, output.length, 1).setValues(output);
}
Sample data:
Logs:
Output:
Note:
The output on sheets is not equal to logs due to the formatting of my sheet.

Date logic in DAX

I am trying to compute a percentage difference between two values - market index levels separated by a period of time (the period will be determined by user input in a Power BI Slicer tool). I don't understand how I can cross reference values DAX uses by the associated date.
Value % difference from Value =
VAR __BASELINE_VALUE = SUM('Equity Markets (2)'[Value])
VAR __VALUE_TO_COMPARE = SUM('Equity Markets (2)'[Value])
RETURN
IF(
NOT ISBLANK(__VALUE_TO_COMPARE),
DIVIDE(__VALUE_TO_COMPARE - __BASELINE_VALUE, __BASELINE_VALUE)
)
"Value" is a column in a table "Equity Markets (2)" the table also includes a "Date" column.
What is the syntax for selecting a value from Value based on an associated date?
Apologies for asking such a basic question - feels like 30 sec of googling should have done it for me.
The slicer is engaging with the bar graph correctly - I know becouse I'm measuring the levels. I think all the % changes are zero because I'm evaluating x/x -1
percentage change =
VAR
__EarliestValue = CALCULATE(SUM('Equity Markets (2)'[Value]),
FIRSTDATE('Equity Markets (2)'[Date]))
VAR __LastDateValue = CALCULATE(SUM('Equity Markets (2)'[Value]),
LASTDATE('Equity Markets (2)'[Date]))
RETURN
CALCULATE(
DIVIDE(__LastDateValue,__EarliestValue)-1)

Having issues with pulling a date from the spreadsheet

I am working with Google Scripts and here is my problem.
I am attempting to compare today's date with a date entered into column C in the spreadsheet. The code I have seems like it should work but when I use the logger to see the date it gives me "Wed Dec 31 19:00:00 GMT-05:00 1969" instead of 2018-07-29 1:00 PM.
I know I need to use the Utilities.formatDate in order to compare them but I can't seem to understand why it is not pulling the date in column C.
Here is my code below:
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3; // First row of data to process
var numRows = sheet.getLastRow()-1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
//Logger.log(data); // give you the data you are looking at comparing
for (var i in data) {
var row = data[i];
var date = new Date();
//Logger.log(date); // sets to todays date and time.
var sheetDate = new Date(row[3]);
Logger.log(sheetDate); // date in the row you are comparing
You're not looking at the value in column C. The method getValues() returns a two-dimensional array, and arrays are 0-indexed. This means that you should be using a 2 (not a 3), when defining sheetDate.
var sheetDate = new Date(row[2]);
As mentioned in the comments, you don't need to use Utilities.formatDate(), but that's a separate issue. I would also try logging the value before converting it to a date (e.g. Logger.log(row[2])).

AutoForward labeled emails once a month using Google Scripts

I'm a complete noob.
I'd like to forward labelled emails on the 1st of every month to another email address. Using Gmail's filters, the label "forwardthis" get applied to my invoices and statements I received during the month. On the 1st of every month, I'd like Google scrips to forward all new emails with the "forwardthis" label to another email address, including attachments.
The script I found doesn't work as I hoped. Not sure what the interval options below are for, but I need to run my script only once a month, on the 1st.
function autoForward() {
var label = 'forwardthis';
var recipient = 'elvis#gmail.com';
var interval = 5; // if the script runs every 5 minutes; change otherwise
var date = new Date();
var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
var threads = GmailApp.search('label:' + label + ' after:' + timeFrom);
for (var i = 0; i < threads.length; i++) {
threads[i].getMessages()[0].forward(recipient); // only the 1st message
}
}
Hope my question is clear. I'll greatly appreciate some guidance, thanks.
Sends labeled emails created after the last time the script was run
Evidently the script was meant to run every 5 minutes so rather that keeping tracked of emailed labels already sent the script just takes the labels created after the current time minus the interval or in other words the labeled emails received since the last time the script was run.
Since you want to run the script on the first of every month you will have to figure how to get the time for the 1st of last month and put that value into the timefrom variable.
function autoForward() {
var label = 'forwardthis';
var recipient = 'elvis#gmail.com';
var interval = 5; // if the script runs every 5 minutes; change otherwise
var date = new Date();
var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;//This subtracts five minutes from the current time
var threads = GmailApp.search('label:' + label + ' after:' + timeFrom);//Emails with the correct label and created since 5 minutes ago are sent
for (var i = 0; i < threads.length; i++) {
threads[i].getMessages()[0].forward(recipient); // only the 1st message
}
}
Noob or not, you can figure this out. Most of what you need is right here. Or possibly here.
You can use triggers to run your script once a month. You can read about triggers here.

Apps Script: setting one formula for a whole column

I'm working on an Apps Script project for Sheets and I don't know if it's because I just never really worked with Sheets or Excel, but I don't know how to set a formula for a whole column through code.
var cell = sheet.getRange([i], 2);
var cell2 = sheet.getRange([i], 1);
var inhoud = cell2.getValue();
cell.setFormula("=(" + inhoud/86400000 + "DATE(1970,1,1)");
I want every B of a row to do something with the A of that same row. In the sheet self it's easy to just "drag the function down", to make it apply to every row, but I don't know how to get that to work in code as I can't use A2, for example, or A2:A30. Part of the problem may be that it's in a for loop:
var subsie = [];
for (i = 0; i < subscriptions.length; i++) {
var subscription = subscriptions[i];
creationdate = subscription.creationTime;
if (subscription.plan.planName == 'ANNUAL' && subscription.renewalSettings.renewalType == 'AUTO_RENEW') {
subsie.push([creationdate, ' ', subscription.plan.planName]);
Logger.log(subsie);
var cell = sheet.getRange([i], 2);
var cell2 = sheet.getRange([i], 1);
var inhoud = cell2.getValue();
cell.setFormula("=(A1:A100/86400000) + DATE(1970,1,1)");
} }
sheet.getRange(sheet.getLastRow()+1, 1, subsie.length, subsie[0].length).setValues(subsie);
The actual goal is to convert the epoch values of A into dates, which I tried in a lot of different ways but turned out to be more difficult than I expected. This was the only formula that seemed to work for my output, which was like this: 1433235478178. How can I make this code work? Thanks in advance!
Solved it :)
creationdate = (subscription.creationTime/86400000)+25567;