exponenta event banner

Создание и анимация метеорологических слоев службы веб-карт (WMS)

В этом примере показано, как скомпоновать и анимировать данные из нескольких уровней службы веб-карт (WMS).

Базовый слой - от сервера изображений Студии научной визуализации (SVS) Центра космических полётов НАСА Годдарда. Данные в этом слое показывают спутниковые облачные данные во время урагана «Катрина» с 23 по 30 августа 2005 года. Слой состоит из данных облака, извлеченных из GOES-12 изображения и наложенных на цветное изображение юго-востока США.

Изображения радара следующего поколения (NEXRAD), собранные сервером веб-карт Iowa Environmental Mesonet (IEM) Университета штата Айова, объединяются с облачными данными через регулярные промежутки времени.

В частности, в этом примере показано, как:

  • Поиск уровней Katrina и NEXRAD с помощью базы данных WMS

  • Получение базовой карты Katrina с сервера WMS на определенном шаге времени

  • Получение карты NEXRAD с сервера WMS одновременно

  • Составьте базовую карту с картой, содержащей изображение NEXRAD

  • Просмотр составленной карты в спроецированной системе координат

  • Извлечение, компоновка и анимация нескольких временных последовательностей

  • Создание видеофайла и анимированного GIF-файла анимации

Основные сведения о терминологии WMS

Если вы новичок в WMS, несколько ключевых концепций важны для понимания и перечислены здесь.

  • Служба веб-карт - Открытый геопространственный консорциум (OGC) определяет службу веб-карт (WMS) как объект, который «формирует карты пространственно привязанных данных динамически на основе географической информации».

  • Сервер WMS --- Сервер, который следует инструкциям OGC по визуализации карт и их возврату клиентам

  • map --- Определение OGC для карты - это «изображение географической информации в виде файла цифрового изображения, пригодного для отображения на экране компьютера».

  • Слой --- Набор данных конкретного типа географической информации, такой как температура, возвышенность, погода, ортофотос, границы, демография, топография, транспорт, измерения окружающей среды и различные данные со спутников

  • capabilities document --- XML-документ, содержащий метаданные, описывающие географическое содержимое, предлагаемое сервером;

Исходная функция

Код, показанный в этом примере, можно найти в следующей функции:

function mapexwmsanimate(useInternet,datadir)

Доступ в Интернет

Поскольку серверы WMS расположены в Интернете, этот пример может быть настроен на доступ к Интернету для динамического отображения и извлечения карт с серверов WMS, или он может быть настроен на использование данных, ранее извлеченных из Интернета с использованием возможностей WMS, но теперь сохраненных в локальных файлах. Можно использовать переменную, useInternet, чтобы определить, следует ли считывать данные из локально хранимых файлов или извлекать данные из Интернета.

Если useInternet установлен флаг true, то для выполнения примера необходимо установить подключение к Интернету. Обратите внимание, что серверы WMS могут быть недоступны, и до возврата карт может пройти несколько минут. Одна из проблем работы с серверами WMS заключается в том, что иногда возникают ошибки сервера. Функция, например wmsread, может истекать время ожидания, если сервер недоступен. Часто это временная проблема, и вы сможете подключиться к серверу, если повторите попытку позже. Список общих проблем и стратегий работы с ними см. в разделе Общие проблемы с серверами WMS в Руководстве пользователя Mapping Toolbox™.

Данные можно хранить локально при первом запуске примера, а затем установить useInternet флаг false. Если useInternet флаг не определен, он имеет значение false.

if ~exist('useInternet', 'var')
    useInternet = false;
end

Настройка: Определение каталога данных и функции утилиты «Имя файла»

В этом примере данные записываются в файлы, если useInternet является true или считывает данные из файлов, если useInternet является false. Он использует переменную datadir для указания местоположения папки, содержащей файлы данных.

if ~exist('datadir','var')
    datadir = fullfile(matlabroot,'examples','map','data');
end
if ~exist(datadir,'dir')
    mkdir(datadir)
end

Определение анонимной функции для добавления datadir во входное имя файла:

datafile = @(filename) fullfile(datadir,filename);

Шаг 1: Поиск слоев Катрины из локальной базы данных

Одним из наиболее сложных аспектов использования WMS является поиск сервера WMS и затем поиск уровня, который представляет для вас интерес. Процесс поиска сервера, содержащего необходимые данные, и создания конкретного и часто сложного URL-адреса со всеми соответствующими деталями может быть очень трудным.

Mapping Toolbox™ упрощает процесс определения местоположения серверов и уровней WMS, предоставляя локальную, установленную и предварительно определенную базу данных WMS, доступную для поиска, с помощью функции wmsfind. В базе данных можно искать интересующие вас слои и серверы. Вот как вы находите слои, содержащие термин katrina в любом LayerName или LayerTitle поле базы данных:

katrina = wmsfind('katrina');
whos katrina
  Name          Size            Bytes  Class       Attributes

  katrina      34x1             16754  WMSLayer              

Поиск термина 'katrina' вернул a WMSLayer массив, содержащий несколько слоев. Для проверки информации об отдельном слое просто выведите ее на экран следующим образом:

katrina(1)
ans = 

  WMSLayer

  Properties:
           Index: 1
     ServerTitle: 'NASA SVS Image Server'
       ServerURL: 'https://svs.gsfc.nasa.gov/cgi-bin/wms?'
      LayerTitle: 'GOES-12 Imagery of Hurricane Katrina: Longwave Infrared Close-up (1024x1024 Animation)'
       LayerName: '3216_22510'
          Latlim: [15.0000 45.0000]
          Lonlim: [-100.0000 -70.0000]

Если ввести, katrina, в окне команд отображается все содержимое массива с индексным номером каждого элемента, включенным в выходные данные. Этот дисплей позволяет быстро исследовать весь массив и искать интересующий уровень. Можно отобразить только LayerTitle для каждого элемента путем выполнения команды:

disp(katrina,'Properties','layertitle','Index','off','Label','off');

Как вы обнаружили, поиск общего слова 'katrina' возвращены результаты многих слоев, и необходимо выбрать только один слой. В общем, поиск может даже возвращать тысячи слоев, которые могут быть слишком большими для просмотра по отдельности. Вместо повторного поиска в базе данных можно уточнить поиск с помощью refine способ WMSLayer класс. Использование refine метод более эффективен и возвращает результаты быстрее, чем wmsfind поскольку поиск уже был сужен до меньшего набора. Предоставление строки запроса, 'goes-12*katrina*visible*close*up*animation', в refine метод возвращает WMSLayer массив, элементы которого содержат совпадение строки запроса в LayerTitle или LayerName свойства. * символ указывает на поиск подстановочных знаков. Если возвращено несколько записей, выберите только первую из них на сервере svs.gsfc.nasa.gov.

katrina = refine(katrina,'goes-12*katrina*visible*close*up*animation');
katrina = refine(katrina,'svs.gsfc.nasa.gov','Searchfield','serverurl');
katrina = katrina(1);
whos katrina
  Name         Size            Bytes  Class       Attributes

  katrina      1x1               466  WMSLayer              

Шаг 2: Синхронизация объекта WMSLayer с сервером

База данных хранит только подмножество информации о слоях. Например, информация из абстрактного слоя, сведения об атрибутах слоя и сведения о стиле, а также система координат не возвращаются wmsfind. Чтобы вернуть всю информацию, необходимо использовать wmsupdate функция. wmsupdate синхронизирует слой из базы данных с сервером, заполняя отсутствующие свойства слоя.

Синхронизировать первый katrina слой с сервером для получения абстрактной информации. Так как это действие требует доступа к Интернету, позвоните wmsupdate только если useInternet флаг имеет значение true.

cachefile = datafile('katrina.mat');
if useInternet
    katrina = wmsupdate(katrina);
    if ~exist(cachefile,'file')
        save(cachefile,'katrina')
    end
else
    cache = load(cachefile);
    katrina = cache.katrina;
end

Отображение абстрактной информации слоя. Использовать isspace , чтобы помочь определить, где обтекать текст строкой.

abstract = katrina.Abstract;
endOfLine = find(isstrprop(abstract,'cntrl'),1);
abstract = abstract(1:endOfLine);
numSpaces = 60;
while(~isempty(abstract))
    k = find(isspace(abstract));
    n = find(k > numSpaces,1);
    if ~isempty(n)
        fprintf('%s\n',abstract(1:k(n)))
        abstract(1:k(n)) = [];
    else
        fprintf('%s\n',abstract)
        abstract = '';
    end
end
The GOES-12 satellite sits at 75 degrees west longitude at an 
altitude of 36,000 kilometers over the equator, in geosynchronous 
orbit.  At this position its Imager instrument takes pictures 
of cloud patterns in several wavelengths for all of North and 
South America, a primary measurement used in weather forecasting. 
 The Imager takes a pattern of pictures of parts of the Earth 
in several wavelengths all day, measurements that are vital in 
weather forecasting.  This animation shows a daily sequence of 
GOES-12 images in the visible wavelengths, from 0.52 to 0.72 
microns, during the period that Hurricane Katrina passed through 
the Gulf of Mexico.  At one kilometer resolution, the visible 
band measurement is the highest resolution data from the Imager, 
which accounts for the very high level of detail in these images. 
 For this animation, the cloud data was extracted from GOES image 
and laid over a background color image of the southeast United 
States.

Обратите внимание, что эта абстрактная информация, включая любые типографские вопросы и неполные фрагменты, была получена непосредственно с сервера.

Шаг 3: Подробнее о слое Катрины

Вы можете узнать больше о katrina путем изучения Details имущества katrina слой. Details.Attributes сообщает, что слой имеет атрибуты фиксированной ширины и фиксированной высоты, поэтому размер требуемой карты изменить нельзя.

katrina.Details.Attributes
ans = 

  struct with fields:

      Queryable: 0
       Cascaded: 0
         Opaque: 1
      NoSubsets: 1
     FixedWidth: 1024
    FixedHeight: 1024

Details.Dimension сообщает, что слой имеет time измерение

katrina.Details.Dimension
ans = 

  struct with fields:

              Name: 'time'
             Units: 'ISO8601'
        UnitSymbol: ''
           Default: '2005-08-30T17:45Z'
    MultipleValues: 0
      NearestValue: 0
           Current: 0
            Extent: '2005-08-23T17:45Z/2005-08-30T17:45Z/P1D'

со степенью от 2005-08-23T17:45Z кому 2005-08-30T17:45Z с периодом P1D (один день), как показано в Details.Dimension.Extent поле.

katrina.Details.Dimension.Extent
ans =

    '2005-08-23T17:45Z/2005-08-30T17:45Z/P1D'

Шаг 4: Получение карты Katrina с сервера

Теперь, когда вы нашли интересующий слой, вы можете извлечь растровую карту с помощью функции wmsread и отобразить карту с помощью функции geoshow. С тех пор Time не указано при чтении слоя, время по умолчанию, 2005-08-30T17:45Z, извлекается, как указано в Details.Dimension.Default поле. Если useInternet устанавливается флаг true, а затем кэшируется изображение и ссылочная матрица в файле GeoTIFF.

cachefile = datafile('katrina.tif');
if useInternet
    [katrinaMap,R] = wmsread(katrina);
    if ~exist(cachefile,'file')
        geotiffwrite(cachefile,katrinaMap,R)
    end
else
    [katrinaMap,R] = readgeoraster(cachefile);
end

Отображение katrinaMap и наложить данные из usastatehi.shp файл.

states = shaperead('usastatehi.shp','UseGeoCoords',true);
figure
usamap(katrina.Latlim, katrina.Lonlim)
geoshow(katrinaMap,R)
geoshow(states,'FaceColor','none')
title({katrina.LayerTitle, katrina.Details.Dimension.Default}, ...
    'Interpreter','none')

Шаг 5: Найти уровень радара NEXRAD

Радиолокационные изображения NEXRAD для США хранятся на сервере веб-карт IEM университета штата Айова. Сервер удобно хранит изображения NEXRAD с шагом в пять минут от 1995-01-01 по настоящее время. Для поиска слоя сначала выполните поиск термина. IEM WMS Service в ServerTitle поле базы данных WMS, затем уточнение поиска путем запроса интересующего уровня, nexrad-n0r-wmst.

iemLayers = wmsfind('IEM WMS Service','SearchField','servertitle');
nexrad = refine(iemLayers,'nexrad-n0r-wmst');

Синхронизируйте слой с сервером.

cachefile = datafile('nexrad.mat');
if useInternet
    nexrad = wmsupdate(nexrad);
    if ~exist(cachefile,'file')
        save(cachefile,'nexrad')
    end
else
    cache = load(cachefile);
    nexrad = cache.nexrad;
end

Шаг 6: Получение параметров экстента

Чтобы скомпоновать nexrad слой с katrina слой, вы должны получить nexrad слой в совпадающие периоды времени и параллельные географические границы и границы изображения. Details.Dimension поле сообщает, что слой имеет измерение времени,

nexrad.Details.Dimension
ans = 

  struct with fields:

              Name: 'time'
             Units: 'ISO8601'
        UnitSymbol: ''
           Default: '2006-06-23T03:10:00Z'
    MultipleValues: 0
      NearestValue: 0
           Current: 0
            Extent: '1995-01-01/2011-12-31/PT5M'

и Details.Dimension.Default сообщает, что интервал времени слоя включает секунды.

nexrad.Details.Dimension.Default
ans =

    '2006-06-23T03:10:00Z'

Получение значения времени, совпадающего с katrina и добавьте секунды к спецификации времени.

nexradTime = [katrina.Details.Dimension.Default(1:end-1) ':00Z'];

Назначить latlim и lonlim переменные для задания пределов для nexrad слой. Установите значения в пределы katrina слой, чтобы географические области совпадали. Обратите внимание, что nexrad южный предел широты слоя не простирается так далеко на юг, как katrina южный предел широты слоя. Значения, лежащие вне географического ограничивающего четырехугольника nexrad для слоя устанавливается цвет фона.

fprintf('%s%d\n','Southern latitude limit of NEXRAD  layer: ',nexrad.Latlim(1))
fprintf('%s%d\n','Southern latitude limit of Katrina layer: ',katrina.Latlim(1))
Southern latitude limit of NEXRAD  layer: 24
Southern latitude limit of Katrina layer: 10
latlim = katrina.Latlim;
lonlim = katrina.Lonlim;

Назначить imageHeight и imageWidth переменные.

imageHeight = katrina.Details.Attributes.FixedHeight;
imageWidth  = katrina.Details.Attributes.FixedWidth;

Шаг 7: Получение радиолокационной карты NEXRAD с сервера

Вы можете получить nexradMap с сервера, указанного одновременно с katrinaMap и для одинаковых географических границ и границ изображения, путем предоставления пар параметр/значение wmsread функция. Для точного извлечения радиолокационного сигнала с карты установите ImageFormat к параметру image/png формат. Чтобы легко извлечь сигнал из фона, установите цвет фона на черный ([0 0 0]).

Получить nexradMap.

black = [0 0 0];
cachefile = datafile('nexrad.tif');
if useInternet
    [nexradMap,R] = wmsread(nexrad, ...
        'Latlim',latlim,'Lonlim',lonlim,'Time',nexradTime, ...
        'BackgroundColor',black,'ImageFormat','image/png', ...
        'ImageHeight',imageHeight,'ImageWidth',imageWidth);
    if ~exist(cachefile, 'file')
        geotiffwrite(cachefile,nexradMap,R)
    end
else
    [nexradMap,R] = readgeoraster(cachefile);
end

Отображение nexradMap.

figure
usamap(latlim,lonlim)
geoshow(nexradMap,R)
geoshow(states,'FaceColor','none','EdgeColor',[0.9 0.9 0.9])
title({nexrad.LayerTitle, nexradTime},'Interpreter','none');

Шаг 8: Составная радиолокационная карта NEXRAD с картой Катрина

Чтобы скомпоновать nexradMap с копией katrinaMap, необходимо определить не фоновые пикселы в nexradMap. nexradMap данные возвращаются в виде изображения с двойным классом из-за того, как этот сервер веб-карт обрабатывает PNG формат, поэтому необходимо преобразовать его в uint8 перед объединением.

Определение пикселов nexradMap изображения, не содержащие цвета фона.

threshold = 0;
index = any(nexradMap > threshold, 3);
index = repmat(index,[1 1 3]);

Составные nexradMap с katrinaMap.

combination = katrinaMap;
combination(index) = uint8(nexradMap(index)*255);

Отображение составленной карты.

figure
usamap(latlim,lonlim)
geoshow(combination,R)
geoshow(states,'FaceColor','none')
title({'GOES 12 Imagery of Hurricane Katrina', ...
    'Composited with NEXRAD Radar',nexradTime})

Шаг 9: Инициализация переменных для анимации карт Katrina и NEXRAD

Следующий шаг - инициализация переменных для анимации составленного katrina и nexrad карты.

Создание переменных, которые содержат временные рамки katrina слой.

extent = katrina.Details.Dimension.Extent;
slash = '/';
slashIndex = strfind(extent,slash);
startTime = extent(1:slashIndex(1)-1);
endTime = extent(slashIndex(1)+1:slashIndex(2)-1);

Вычислите числовые значения для дней начала и окончания. Обратите внимание, что интервал времени находится в yyyy-mm-dd формат.

hyphen = '-';
hyphenIndex = strfind(startTime,hyphen);
dayIndex = [hyphenIndex(2) + 1, hyphenIndex(2) + 2];
startDay = str2double(startTime(dayIndex));
endDay = str2double(endTime(dayIndex));

Назначение начального katrinaTime.

katrinaTime = startTime;

Поскольку для анимации требуется несколько запросов к серверу, более эффективно использовать WebMapServer и WMSMapRequest классы.

Построить WebMapServer объект для сервера каждого слоя.

nasaServer = WebMapServer(katrina.ServerURL);
iemServer  = WebMapServer(nexrad.ServerURL);

Создать WMSMapRequest объекты.

katrinaRequest = WMSMapRequest(katrina, nasaServer);
nexradRequest  = WMSMapRequest(nexrad, iemServer);

Назначить свойства.

nexradRequest.Latlim = latlim;
nexradRequest.Lonlim = lonlim;
nexradRequest.BackgroundColor = black;
nexradRequest.ImageFormat = 'image/png';
nexradRequest.ImageHeight = imageHeight;
nexradRequest.ImageWidth  = imageWidth;

Шаг 10: Создание файлов анимации

Анимацию можно просмотреть в браузере, когда браузер открывает анимированный GIF-файл или видеофайл AVI. Чтобы создать кадры анимации базовой карты WMS и векторных наложений, создайте цикл каждый день из startDay кому endDayи получить katrinaMap и nexradMap на тот день. Составьте карты в одно изображение, отобразите изображение, извлеките кадр и сохраните результаты в кадр AVI-файла и кадр анимированного GIF-файла.

Чтобы поделиться с другими или опубликовать в веб-видеосервисах, создайте AVI видеофайл, содержащий все кадры с помощью VideoWriter класс.

videoFilename = fullfile(pwd,'wmsanimated.avi');
if exist(videoFilename,'file')
    delete(videoFilename)
end
writer = VideoWriter(videoFilename);
writer.FrameRate = 1;
writer.Quality = 100;
open(writer)

Анимация просматривается в одном отображении карты. Вне цикла анимации создайте отображение карты. Инициализировать hmap, используется в цикле в качестве дескриптора возврата из функции geoshow, так что его можно удалить при первом прохождении через цикл. Закольцовывайте каждый день, извлекайте и отображайте карту WMS и сохраняйте кадр.

fig = figure;
usamap(latlim,lonlim)
hstates = geoshow(states,'FaceColor','none');
hmap = [];

for k = startDay:endDay

    % Update the time values and assign the Time property for each server.
    currentDay = num2str(k);
    katrinaTime(dayIndex) = currentDay;
    nexradTime = [katrinaTime(1:end-1) ':00Z'];
    katrinaRequest.Time = katrinaTime;
    nexradRequest.Time = nexradTime;

    % Retrieve the WMS map of Katrina from the server (or file)
    % for this time period.
    cachefile = datafile(['katrina_' num2str(currentDay) '.tif']);
    if useInternet
        katrinaMap = getMap(nasaServer, katrinaRequest.RequestURL);
        if ~exist(cachefile, 'file')
            geotiffwrite(cachefile, katrinaMap, katrinaRequest.RasterRef)
        end
    else
        katrinaMap = readgeoraster(cachefile);
    end

    % Retrieve the WMS map of the NEXRAD imagery from the server (or file)
    % for this time period.
    cachefile = datafile(['nexrad_' num2str(currentDay) '.tif']);
    if useInternet
        nexradMap = getMap(iemServer, nexradRequest.RequestURL);
        if ~exist(cachefile, 'file')
            geotiffwrite(cachefile, nexradMap, nexradRequest.RasterRef)
        end
    else
        nexradMap = readgeoraster(cachefile);
    end

    % Identify the pixels of the nexradMap image that do not contain the
    % background color.
    index = any(nexradMap > threshold, 3);
    index = repmat(index,[1 1 3]);

    % Composite nexradMap with katrinaMap.
    combination = katrinaMap;
    combination(index) = uint8(nexradMap(index)*255);

    % Delete the old map and display the new composited map.
    delete(hmap)
    hmap = geoshow(combination, katrinaRequest.RasterRef);
    uistack(hstates,'top')
    title({'GOES 12 Imagery of Hurricane Katrina', ...
        'Composited with NEXRAD Radar',nexradTime})
    drawnow

    % Save the current frame as an RGB image.
    currentFrame = getframe(fig);
    RGB = currentFrame.cdata;

    % Create an indexed image for each RGB frame in order to display an
    % animated GIF.
    if k == startDay
        % The first time through the loop, convert the RGB image to
        % an indexed image and save the colormap into the
        % variable, cmap. Use cmap to convert later frames.
        [frame,cmap] = rgb2ind(RGB,256,'nodither');

        % Use the size of the first frame and the total
        % number of frames to initialize animated with
        % a size large enough to contain all the frames.
        frameSize = size(frame);
        numFrames = endDay - startDay + 1;
        animated = zeros([frameSize 1 numFrames],'like',frame);
    else
        % Use the colormap from the first frame conversion and
        % convert this frame to an indexed image.
        frame = rgb2ind(RGB,cmap,'nodither');
    end

    % Store the frame into the animated array for the GIF file.
    frameCount = k - startDay + 1;
    animated(:,:,1,frameCount) = frame;

    % Write the RGB frame to the AVI file.
    writeVideo(writer,RGB);
end

Закройте окно «Рисунок» и файл AVI.

close(fig)
close(writer)

Запишите анимированный GIF-файл.

filename = fullfile(pwd,'wmsanimated.gif');
if exist(filename,'file')
    delete(filename)
end
delayTime = 2.0;
loopCount = inf;
imwrite(animated,cmap,filename, ...
    'DelayTime',delayTime,'LoopCount',loopCount);

Шаг 11: Просмотр анимированного GIF-файла

Анимацию можно просмотреть в браузере, когда браузер открывает анимированный GIF-файл.

Кредиты

Слой Катрины

Слой Катрины, используемый в примере, находится в SVS Image Server Центра космических полётов НАСА Годдарда и поддерживается Scientific Visualization Studio.

Для получения дополнительных сведений об этом сервере запустите:

  >> wmsinfo('http://svs.gsfc.nasa.gov/cgi-bin/wms?')

Уровень NEXRAD

Слой NEXRAD, используемый в примере, получен от сервера IEM WMS Университета штата Айова и представляет собой сформированный композит CONUS Национальной службы погоды (NWS) WSR-88D базовой отражательной способностью уровня III.

Для получения дополнительных сведений об этом сервере запустите:

>> wmsinfo('http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?')

См. также

| | | | | | |