Main Content

Animate Data Layers

Create Movie of Terra/MODIS Maps

You can create maps of the same geographic region at different times and view them as a movie. For a period of seven days, read and display a daily composite of visual images from NASA's Moderate Resolution Imaging Spectroradiometer (MODIS) scenes captured during the month of December 2010.

Search the WMS Database for a MODIS layer from the NASA Earth Observations (NEO) server.

neo = wmsfind("neo*nasa","SearchFields","serverurl");
modis = refine(neo,"true*color*terra*modis"); 
modis = wmsupdate(modis);

Create a WebMapServer object and a WMSMapRequest object.

server = WebMapServer(modis.ServerURL);
mapRequest = WMSMapRequest(modis,server);

The Extent field provides information about how to retrieve individual frames. For this extent, you can request a single day because the extent is defined by day ('/P1D'). Because this layer updates periodically, the value of your Extent field might be different.

modis.Details.Dimension.Extent
ans = 
'2006-09-01/2006-09-14/P1D,2006-09-17/2006-10-10/P1D,2006-10-12/2006-11-18/P1D,2006-11-21/2007-08-16/P1D,2007-08-18,2007-08-20/2007-09-11/P1D,2007-09-15/2007-12-30/P1D,2008-01-01/2008-06-12/P1D,2008-06-14,2008-06-16/2008-07-12/P1D,2008-07-14/2008-09-17/P1D,2008-09-19,2008-09-22/2008-10-17/P1D,2008-10-19/2008-10-22/P1D,2008-10-28/2008-12-02/P1D,2008-12-04/2008-12-20/P1D,2008-12-23/2008-12-30/P1D,2009-01-01/2009-01-20/P1D,2009-01-22/2009-04-19/P1D,2009-04-23/2009-07-05/P1D,2009-07-08/2009-12-30/P1D,2010-01-01/2010-07-16/P1D,2010-07-18/2010-12-07/P1D,2010-12-09/2010-12-30/P1D,2011-01-01/2011-01-25/P1D,2011-01-27/2011-03-19/P1D,2011-03-21/2011-07-23/P1D,2011-07-27/2011-08-27/P1D,2011-08-30/2011-12-13/P1D,2011-12-15/2012-02-19/P1D,2012-02-21/2013-12-01/P1D,2013-12-04/2018-03-12/P1D,2018-03-14/2018-05-16/P1D,2018-05-18/2018-09-17/P1D,2018-09-19/2022-05-04/P1D,2022-05-06/2022-12-21/P1D,2022-12-23/2023-01-04/P1D'

Create an array indicating the first seven days. Set the start time to December 10, 2022 and use a serial date number.

days = 1:7;
time = "2022-12-10";
startTime = datenum(time);

Open a figure window with axes appropriate for the region specified by the MODIS layer.

hFig = figure;
worldmap(mapRequest.Latlim,mapRequest.Lonlim);

Save each frame to a video file.

videoFilename = "modis_dec.avi";
writer = VideoWriter(videoFilename);
writer.FrameRate = 1;
writer.Quality = 100;
writer.open;

Set the Visible property of the figure to 'off' to hide the figure while populating the frames. For each day, read a map of the MODIS layer. Set the Time property to the day number. Ignore data not found on the server or errors issued by the server by using a try/catch statement. For correct indexing, set the start time to one day less.

hFig.Visible = "off";
startTime = startTime - 1;
for k = days
    try
        mapRequest.Time = startTime + k;
        timeStr = datestr(mapRequest.Time);
        dailyImage = getMap(server,mapRequest.RequestURL);
        geoshow(dailyImage,mapRequest.RasterReference);
        title({mapRequest.Layer.LayerTitle,timeStr}, ...
            "Interpreter","none","FontWeight","bold")
        frame = getframe(hFig);
        writer.writeVideo(frame);
    catch e
        fprintf(['Server error: %s.\n', ...
            'Ignoring frame number %d on day %s.\n'], ...
            e.message,k,timeStr)
    end
end
writer.close

Read in all video frames.

v = VideoReader(videoFilename);
vidFrames = read(v);
numFrames = get(v,"NumFrames");

Create a movie structure from the video frames.

frames = struct("cdata",[],"colormap",[]);
frames(numFrames) = frames(1);
for k = 1 : numFrames
    frames(k).cdata = vidFrames(:,:,:,k);
    frames(k).colormap = [];
end

Set the Visible property of the figure to 'on' and play the movie once at the frame rate of the video.

hFig.Visible = "on";
movie(hFig,frames,1,v.FrameRate)

Create Animated GIF of WMS Maps

Read and display an animation of the Larsen Ice Shelf experiencing a dramatic collapse between January 31, 2002 and March 7, 2002.

Search the WMS Database for the phrase 'Larsen Ice Shelf'.

iceLayer = wmsfind('Larsen Ice Shelf');

Create a WebMapServer by specifying the server URL of the first layer. Synchronize the layer with the server by using the updateLayers function.

server = WebMapServer(iceLayer(1).ServerURL);
iceLayer = updateLayers(server,iceLayer(1));

Create a WMSMapRequest object.

request = WMSMapRequest(iceLayer(1),server);

The Extent field provides the available values for a dimension, in this case time. Set the value of the extent to a variable. Calculate the number of required frames.

extent = string(iceLayer.Details.Dimension.Extent);
extent = split(extent,",");
numFrames = numel(extent);

Create a figure and set up a map with appropriate geographic limits. Customize the appearance of the parallels and meridians.

f = figure;
worldmap(request.Latlim,request.Lonlim)
setm(gca,'MLineLocation',1,'MLabelLocation',1, ...
   'MLabelParallel',-67.5,'LabelRotation','off');

Initialize the value of animated to 0.

animated(1,1,1,numFrames) = 0;

Set the Visible property of the figure to 'off' to hide the map while populating the frames. Read the image of the Larsen Ice Shelf on different days.

f.Visible = 'off';
for k=1:numFrames
   request.Time = extent(k);
   iceImage = getMap(server,request.RequestURL);
   geoshow(iceImage,request.RasterReference)
   title(request.Time,'Interpreter','none')
   frame = getframe(f);
   if k == 1
      [animated, cmap] = rgb2ind(frame.cdata,256,'nodither');
   else
      animated(:,:,1,k) = rgb2ind(frame.cdata,cmap,'nodither');
   end
   pause(2)
end

Save the frames as an animated GIF and view the GIF in a browser.

filename = 'wmsanimated.gif';
imwrite(animated,cmap,filename,'DelayTime',1.5, ...
   'LoopCount',inf);
web(filename) 

Create Animation of Time-Lapse Radar Observations

Display Next-Generation Radar (NEXRAD) images for the United States using data from the Iowa Environmental Mesonet (IEM) web map server. The server stores layers covering the past 50 minutes up to the present time in increments of 5 minutes. Read and display the merged layers.

Find layers in the WMS Database that include 'mesonet' and 'nexrad' in their ServerURL fields.

mesonet = wmsfind('mesonet*nexrad','SearchField','serverurl');

NEXRAD Base Reflect Current ('nexrad-n0r') measures the intensity of precipitation. Refine your search to include only layers with this phrase in one of the search fields.

nexrad = refine(mesonet,'nexrad-n0r','SearchField','any');

Remove the 900913 layers because they are intended for Google Maps™ overlay. Remove the WMST layer because it contains data for different times.

layers_900913 = refine(nexrad,'900913','SearchField', ...
   'layername'); 
layer_wmst = refine(nexrad,'wmst', 'SearchField', 'layername'); 
rmLayerNames = {layers_900913.LayerName layer_wmst.LayerName}; 
index = ismember({nexrad.LayerName}, rmLayerNames); 
nexrad = nexrad(~index); 

Update the nexrad layer to fill in all fields and obtain the most recent data.

nexrad = wmsupdate(nexrad,'AllowMultipleServers',true); 

Create a map of the conterminous United States. Get the latitude and longitude limits of the map.

figure
usamap('conus')
mstruct = gcm;
latlim = mstruct.maplatlimit;
lonlim = mstruct.maplonlimit;

Read and display the merged layers.

[A,R] = wmsread(nexrad,'Latlim',latlim,'Lonlim',lonlim);
geoshow(A,R)
geoshow('usastatehi.shp','FaceColor','none')
title({'NEXRAD Radar Map', 'Merged Layers'})

Loop through the sequence of time-lapse radar observations. Set the Visible property of the figure to 'off' to hide the figure while populating the frames.

hfig = figure('Visible','off');
usamap('conus')
hstates = geoshow('usastatehi.shp','FaceColor','none');
numFrames = numel(nexrad);
frames = struct('cdata',[],'colormap',[]);
frames(numFrames) = frames;
hmap = [];
frameIndex = 0;
for k = numFrames:-1:1
   frameIndex = frameIndex + 1;
   delete(hmap)
   [A, R] = wmsread(nexrad(k),'Latlim',latlim,'Lonlim',lonlim);
   hmap = geoshow(A,R);
   uistack(hstates,'top')
   title(nexrad(k).LayerName)
   frames(frameIndex) = getframe(hfig);
end

Create an array to write out as an animated GIF.

animated(1,1,1,numFrames) = 0;
for k=1:numFrames
   if k == 1
      [animated,cmap] = rgb2ind(frames(k).cdata,256,'nodither');
   else
      animated(:,:,1,k) = ...
         rgb2ind(frames(k).cdata,cmap,'nodither');
   end     
end

Save the animated GIF and view it in a browser.

filename = 'wmsnexrad.gif';
imwrite(animated,cmap,filename,'DelayTime',1.5, ...
   'LoopCount',inf);
web(filename)

See Also

| |

Related Topics