Qiusheng Wu
Geospatial Data Science

Follow

Geospatial Data Science

Follow
GEE Tutorial #39 - How to create Landsat timelapse animations without coding

GEE Tutorial #39 - How to create Landsat timelapse animations without coding

Qiusheng Wu's photo
Qiusheng Wu
·Oct 13, 2020·

7 min read

This tutorial shows you how to create timelapse animations of Landsat imagery and normalized difference indices (e.g., NDVI, NDWI) using Earth Engine and geemap.

Steps to create a Landsat timelapse:

  1. Pan and zoom to your area of interest, or click the globe icon at the upper left corner to search for a location.
  2. Use the drawing tool to draw a rectangle anywhere on the map.
  3. Adjust the parameters (e.g., start year, end year, title) if needed.
  4. Click the Create timelapse button to create a timelapse.
  5. Once the timelapse has been added to the map, click the hyperlink at the end if you want to download the GIF.

Web Apps: gishub.org/timelapse, gishub.org/gee-ngrok

Notebook: github.com/giswqs/geemap/blob/master/exampl..

Demo:

YouTube:

Source Code:

import os
import ee
import geemap
import ipywidgets as widgets
Map = geemap.Map()
Map.add_basemap('HYBRID')
Map
style = {'description_width': 'initial'}
title = widgets.Text(
    description='Title:',
    value='Landsat Timelapse',
    width=200,
    style=style
)

bands = widgets.Dropdown(
    description='Select RGB Combo:',
    options=['Red/Green/Blue', 'NIR/Red/Green',  'SWIR2/SWIR1/NIR', 'NIR/SWIR1/Red','SWIR2/NIR/Red', 
             'SWIR2/SWIR1/Red', 'SWIR1/NIR/Blue', 'NIR/SWIR1/Blue', 'SWIR2/NIR/Green', 'SWIR1/NIR/Red'],
    value='NIR/Red/Green',
    style=style
)

hbox1 = widgets.HBox([title, bands])
hbox1
speed = widgets.IntSlider(
    description='  Frames per second:',
    tooltip='Frames per second:',
    value=10,
    min=1, 
    max = 30,
    style=style
)

cloud = widgets.Checkbox(
    value=True,
    description='Apply fmask (remove clouds, shadows, snow)',
    style=style
)

hbox2 = widgets.HBox([speed, cloud])
hbox2
start_year = widgets.IntSlider(description='Start Year:', value=1984, min=1984, max=2020, style=style)
end_year = widgets.IntSlider(description='End Year:', value=2020, min=1984, max=2020, style=style)
start_month = widgets.IntSlider(description='Start Month:', value=5, min=1, max=12, style=style)
end_month = widgets.IntSlider(description='End Month:', value=10, min=1, max=12, style=style)
hbox3 = widgets.HBox([start_year, end_year, start_month, end_month])
hbox3
font_size = widgets.IntSlider(description='Font size:', value=30, min=10, max=50, style=style)

font_color = widgets.ColorPicker(
    concise=False,
    description='Font color:',
    value='white',
    style=style
)

progress_bar_color = widgets.ColorPicker(
    concise=False,
    description='Progress bar color:',
    value='blue',
    style=style
)

hbox4 = widgets.HBox([font_size, font_color, progress_bar_color])
hbox4
# Normalized Satellite Indices: https://www.usna.edu/Users/oceano/pguth/md_help/html/norm_sat.htm

nd_options = ['Vegetation Index (NDVI)', 
              'Water Index (NDWI)',
              'Modified Water Index (MNDWI)',
              'Snow Index (NDSI)',
              'Soil Index (NDSI)',
              'Burn Ratio (NBR)',
              'Customized']
nd_indices = widgets.Dropdown(options=nd_options, value=None, description='Normalized Difference Index:', style=style)

first_band = widgets.Dropdown(
    description='1st band:',
    options=['Blue', 'Green','Red','NIR', 'SWIR1', 'SWIR2'],
    value=None,
    style=style
)

second_band = widgets.Dropdown(
    description='2nd band:',
    options=['Blue', 'Green','Red','NIR', 'SWIR1', 'SWIR2'],
    value=None,
    style=style
)

nd_threshold = widgets.FloatSlider(
    value=0,
    min=-1,
    max=1,
    step=0.01,
    description='Threshold:',
    orientation='horizontal',
)

nd_color = widgets.ColorPicker(
    concise=False,
    description='Color:',
    value='blue',
    style=style
)

def nd_index_change(change):
    if nd_indices.value == 'Vegetation Index (NDVI)':
        first_band.value = 'NIR'
        second_band.value = 'Red'
    elif nd_indices.value == 'Water Index (NDWI)':
        first_band.value = 'NIR'
        second_band.value = 'SWIR1'   
    elif nd_indices.value == 'Modified Water Index (MNDWI)':
        first_band.value = 'Green'
        second_band.value = 'SWIR1'   
    elif nd_indices.value == 'Snow Index (NDSI)':
        first_band.value = 'Green'
        second_band.value = 'SWIR1'
    elif nd_indices.value == 'Soil Index (NDSI)':
        first_band.value = 'SWIR1'
        second_band.value = 'NIR'        
    elif nd_indices.value == 'Burn Ratio (NBR)':
        first_band.value = 'NIR'
        second_band.value = 'SWIR2'
    elif nd_indices.value == 'Customized':
        first_band.value = None
        second_band.value = None

nd_indices.observe(nd_index_change, names='value')

hbox5 = widgets.HBox([nd_indices, first_band, second_band, nd_threshold, nd_color])
hbox5
create_gif = widgets.Button(
    description='Create timelapse',
    button_style='primary',
    tooltip='Click to create timelapse',
    style=style
)

download_gif = widgets.Button(
    description='Download GIF',
    button_style='primary',
    tooltip='Click to download timelapse',
    disabled=False,
    style=style
)

output = widgets.Output()

hbox5 = widgets.HBox([create_gif])
hbox5
def submit_clicked(b):

    with output:
        output.clear_output()
        if start_year.value > end_year.value:
            print('The end year must be great than the start year.')
            return
        if start_month.value > end_month.value:
            print('The end month must be great than the start month.')
            return        
        if start_year.value == end_year.value:
            add_progress_bar = False
        else:
            add_progress_bar = True

        start_date = str(start_month.value).zfill(2) + '-01'
        end_date = str(end_month.value).zfill(2) + '-30'

        print('Computing...')

        nd_bands = None    
        if (first_band.value is not None) and (second_band.value is not None):
            nd_bands = [first_band.value, second_band.value]

        Map.add_landsat_ts_gif(roi=Map.user_roi, label=title.value, start_year=start_year.value, 
                               end_year=end_year.value, start_date=start_date, end_date=end_date, 
                               bands=bands.value.split('/'), font_color=font_color.value, 
                               frames_per_second=speed.value, font_size=font_size.value, 
                               add_progress_bar= add_progress_bar, progress_bar_color=progress_bar_color.value, 
                               download=True, apply_fmask=cloud.value, nd_bands=nd_bands, 
                               nd_threshold=nd_threshold.value, nd_palette=['black', nd_color.value]) 

create_gif.on_click(submit_clicked)
output
 
Share this