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 ]