1 of 17

Making a hurricane .gif

I make maps!

Carl Churchill

The Wall Street Journal

Graphics Reporter

2 of 17

3 of 17

4 of 17

5 of 17

Google Earth Engine

6 of 17

7 of 17

GOES-16 MCMIPF Series ABI Level 2 Cloud and Moisture Imagery Full Disk

Geostationary Operational Environmental Satellite (16)

Advanced Baseline Imager

Specific version identifier code

Area of coverage

GOES-16

MCMIPF Series

ABI

Level 2

Cloud and Moisture Imagery

Full Disk

L2+ products contain environmental physical qualities, such as cloud top height or land surface temperature. (NOAA)

8 of 17

Code

Console

Live Map

9 of 17

var bounds = geometry

var start = ee.Date('2021-08-29')

var finish = ee.Date('2021-08-30')

var GOES = ee.ImageCollection("NOAA/GOES/16/MCMIPF")

.filterBounds(bounds)

.filterDate(start,finish)

.filter(ee.Filter.calendarRange(16,22,"hour"))

// Band aliases.

var BLUE = 'CMI_C01';

var RED = 'CMI_C02';

var VEGGIE = 'CMI_C03';

var GREEN = 'GREEN';

var NUM_BANDS = 33;

var BLUE_BAND_INDEX = (1 - 1) * 2;

var RED_BAND_INDEX = (2 - 1) * 2;

var VEGGIE_BAND_INDEX = (3 - 1) * 2;

var GREEN_BAND_INDEX = NUM_BANDS - 1;

var GOES_MIN = 0.0;

var GOES_MAX = 0.7; // Alternatively 1.0 or 1.3.

var GAMMA = 1;

var applyScaleAndOffset = function(image) {

image = ee.Image(image);

var bands = new Array(NUM_BANDS);

for (var i = 1; i < 17; i++) {

var bandName = 'CMI_C' + (100 + i + '').slice(-2);

var offset = ee.Number(image.get(bandName + '_offset'));

var scale = ee.Number(image.get(bandName + '_scale'));

bands[(i-1) * 2] = image.select(bandName).multiply(scale).add(offset);

var dqfName = 'DQF_C' + (100 + i + '').slice(-2);

bands[(i-1) * 2 + 1] = image.select(dqfName);

}

var green1 = bands[RED_BAND_INDEX].multiply(0.45);

var green2 = bands[VEGGIE_BAND_INDEX].multiply(0.10);

var green3 = bands[BLUE_BAND_INDEX].multiply(0.45);

var green = green1.add(green2).add(green3);

bands[GREEN_BAND_INDEX] = green.rename(GREEN);

return ee.Image(ee.Image(bands).copyProperties(image, image.propertyNames()));

};

var GOESscaled = GOES

.map(applyScaleAndOffset)

var crs = 'EPSG:3857'

var goesRgbViz = {

bands: [RED, GREEN, BLUE],

min: GOES_MIN,

max: GOES_MAX,

gamma: GAMMA

};

var gifParams = {

collection: GOESscaled,

description: 'GOES_gif',

dimensions: 600,

framesPerSecond: 10,

region: bounds,

crs: crs,

bands: [RED, GREEN, BLUE],

min: GOES_MIN,

max: GOES_MAX,

gamma: GAMMA

}

Map.addLayer(GOESscaled.first(), goesRgbViz);

print(ui.Thumbnail(GOESscaled,gifParams))

Ingredients

Cooking

Serving

10 of 17

var bounds = geometry� �var start = ee.Date('2021-08-29')�var finish = ee.Date('2021-08-30')��var GOES = ee.ImageCollection("NOAA/GOES/16/MCMIPF")�.filterBounds(bounds)�.filterDate(start,finish)�.filter(ee.Filter.calendarRange(16,22,"hour"))��// Band aliases.var BLUE = 'CMI_C01';�var RED = 'CMI_C02';�var VEGGIE = 'CMI_C03';�var GREEN = 'GREEN';��var NUM_BANDS = 33;�

Filter dataset

11 of 17

12 of 17

var applyScaleAndOffset = function(image) {� image = ee.Image(image);� var bands = new Array(NUM_BANDS);� for (var i = 1; i < 17; i++) {� var bandName = 'CMI_C' + (100 + i + '').slice(-2);� var offset = ee.Number(image.get(bandName + '_offset'));� var scale = ee.Number(image.get(bandName + '_scale'));� bands[(i-1) * 2] = image.select(bandName).multiply(scale).add(offset);�� var dqfName = 'DQF_C' + (100 + i + '').slice(-2);� bands[(i-1) * 2 + 1] = image.select(dqfName);� }�� var green1 = bands[RED_BAND_INDEX].multiply(0.45);� var green2 = bands[VEGGIE_BAND_INDEX].multiply(0.10);� var green3 = bands[BLUE_BAND_INDEX].multiply(0.45);� var green = green1.add(green2).add(green3);� bands[GREEN_BAND_INDEX] = green.rename(GREEN);�� return ee.Image(ee.Image(bands).copyProperties(image, image.propertyNames()));�};��var GOESscaled = GOES�.map(applyScaleAndOffset)

var crs = 'EPSG:3857'��

Define projection

Scale bands to correct values

Create green band

13 of 17

var goesRgbViz = {� bands: [RED, GREEN, BLUE],� min: GOES_MIN,� max: GOES_MAX,� gamma: GAMMA�};��var gifParams = {� collection: GOESscaled,� description: 'GOES_gif',� dimensions: 600,� framesPerSecond: 10,� region: bounds,� crs: crs,� bands: [RED, GREEN, BLUE],� min: GOES_MIN,� max: GOES_MAX,� gamma: GAMMA�}��Map.addLayer(GOESscaled.first(), goesRgbViz);��print(ui.Thumbnail(GOESscaled,gifParams))�

Projected

Unprojected

Unprojected

14 of 17

[ map is upside down ]

15 of 17

Color correction to restrain ultra-white values

Expanded area

To catch wildfires

16 of 17

EOSDIS Worldview

EO Sentinel Browser

GOES Image Viewer

From EOSDIS (NASA) Worldview

17 of 17

Carl Churchill

The Wall Street Journal

Graphics Reporter

@Cchurchili (while it lasts)

carl.churchill@wsj.com

[ Links and slide script are in the presentation notes ]