/**
* @license
* Copyright 2020 Google LLC.
* SPDX-License-Identifier: Apache-2.0
*
* Makes a GOES MCMIPC animation that tracks an event. Set a region of interest
* and two points that define the path to track along the duration of the
* animation.
*/
// #############################################################################
// ### INPUTS ###
// #############################################################################
var COLLECTION = 'NOAA/GOES/16/MCMIPC'; // or 'NOAA/GOES/17/MCMIPC'
// Observation start and end time of interest.
var START_TIME = '2020-12-23T11:00:00';
var END_TIME = '2020-12-23T15:30:00';
var TIME_ZONE = 'America/North_Dakota/Center';
// Video parameters.
var VID_PARAMS = {
dimensions: 512, // Max dim.
region: window, // Edit geometry import using Code Editor drawing tools.
framesPerSecond: 18,
crs: 'EPSG:5070',
};
// Visualization params.
var GOES_RGB_VIS = {
min: 0,
max: 0.3,
gamma: 1.3,
};
/* GEOMETRY IMPORTS
var window =
ee.Geometry.Polygon(
[[[-106.21025959225202, 39.76736868283722],
[-106.21025959225202, 35.578020596544334],
[-98.16826740475202, 35.578020596544334],
[-98.16826740475202, 39.76736868283722]]], null, false),
endpoints = ee.Geometry.MultiPoint(
[[-102.03545490475202, 37.24015600167216],
[-100.76104084225202, 33.898903754557274]]);
*/
// #############################################################################
// Band names.
var BLUE = 'CMI_C01';
var RED = 'CMI_C02';
var VEGGIE = 'CMI_C03';
var GREEN = 'GREEN';
GOES_RGB_VIS['bands'] = [RED, GREEN, BLUE];
// Create a states outline layer.
var states = ee.FeatureCollection('FAO/GAUL/2015/level1');
var statesOutline = ee.Image().byte()
.paint({featureCollection: states, color: 1, width: 1})
.visualize({palette: '000000', opacity: 0.6});
/**
* Properly scales an MCMIPM image.
*
* @param {ee.Image} image An unaltered MCMIPM image.
* @return {ee.Image}
*/
var applyScaleAndOffset = function(image) {
var names = image.select('CMI_C..').bandNames();
// Scale the radiance bands using the image's metadata.
var scales = names.map(function(name) {
return image.getNumber(ee.String(name).cat('_scale'));
});
var offsets = names.map(function(name) {
return image.getNumber(ee.String(name).cat('_offset'));
});
var scaled = image.select('CMI_C..')
.multiply(ee.Image.constant(scales))
.add(ee.Image.constant(offsets));
return image.addBands({srcImg: scaled, overwrite: true});
};
/**
* Computes and adds a green radiance band to a MCMIPM image.
*
* The image must already have been properly scaled via applyScaleAndOffset.
*
* For more information on computing the green band, see:
* https://doi.org/10.1029/2018EA000379
*
* @param {ee.Image} image An image to add a green radiance band to. It
* must be the result of the applyScaleAndOffset function.
* @return {ee.Image}
*/
var addGreenBand = function(image) {
function toBandExpression(bandName) { return 'b(\'' + bandName + '\')'; }
var B_BLUE = toBandExpression(BLUE);
var B_RED = toBandExpression(RED);
var B_VEGGIE = toBandExpression(VEGGIE);
// Green = 0.45 * Red + 0.10 * NIR + 0.45 * Blue
var GREEN_EXPR = GREEN + ' = 0.45 * ' + B_RED + ' + 0.10 * ' + B_VEGGIE +
' + 0.45 * ' + B_BLUE;
var green = image.expression(GREEN_EXPR).select(GREEN);
return image.addBands(green);
};
/**
* Creates GOES visualization layer.
*
* The image must already have been properly scaled via applyScaleAndOffset
* and had the green band added via addGreenBand.
*
* @param {ee.Image} image An image to visualize.
* @return {ee.Image}
*/
var visualizeGoes = function(image) {
return image.visualize(GOES_RGB_VIS)
.resample('bicubic')
.reproject({crs: VID_PARAMS.crs, scale: 1500})
.blend(statesOutline)
.set('system:time_start', image.get('system:time_start'));
};
// Build the base collection.
var start = ee.Date(START_TIME, TIME_ZONE);
var end = ee.Date(END_TIME, TIME_ZONE);
var col = ee.ImageCollection(COLLECTION)
.filterDate(start, end)
.map(applyScaleAndOffset)
.map(addGreenBand)
.map(visualizeGoes);
// Figure out the transform distance interval x, y
var coords = ee.List(endpoints.coordinates());
var startLoc = ee.List(coords.get(0));
var endLoc = ee.List(coords.get(1));
var xDelta = ee.Number(endLoc.get(0)).subtract(ee.Number(startLoc.get(0)));
var yDelta = ee.Number(endLoc.get(1)).subtract(ee.Number(startLoc.get(1)));
var xMove = ee.Number(xDelta.divide(col.size()).multiply(-111000)); // Degrees to meters
var yMove = ee.Number(yDelta.divide(col.size()).multiply(111000)); // Degrees to meters
// Shift each image in the collection.
var seq = ee.List.sequence(0, ee.Number(col.size()).subtract(1));
var colList = col.toList(col.size());
var colTracking = ee.ImageCollection.fromImages(seq.map(function(i) {
var img = ee.Image(colList.get(i));
return img.translate({
x: xMove.multiply(ee.Number(i)),
y: yMove.multiply(ee.Number(i)),
units: 'meters'
}).set('system:time_start', img.get('system:time_start'));
}));
// Figure out where to place the start and end locations
Map.addLayer(col.first()); // First frame
Map.addLayer(col.sort('system:time_start', false).first()); // Last frame
// Uncomment this line after the start and end points are placed.
print(ui.Thumbnail(colTracking, VID_PARAMS));
Last active
January 6, 2021 22:26
-
-
Save jdbcode/369c16d781c39385852f50cdc25f2873 to your computer and use it in GitHub Desktop.
Earth Engine GOES event tracking animation.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment