Составление композита и анимация Веб-картографического сервиса (WMS) метеорологические слои

Этот пример показывает, как составить и анимировать данные из нескольких слоев Web Map Service (WMS).

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

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

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

  • Используйте базу данных WMS, чтобы найти слои Катрины и NEXRAD

  • Получите базовую карту Катрины из сервера WMS в конкретный такт

  • Получите карту NEXRAD из сервера WMS в тот же такт

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

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

  • Получите, составьте и анимируйте последовательности нескольких времени

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

Понимание основной терминологии WMS

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

  • Веб-Картографический сервис---Открытый геопространственный консорциум (OGC) задает Веб-картографический сервис (WMS), чтобы быть сущностью, которая "производит карты пространственно справочных данных динамически от географической информации".

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

  • сопоставьте---, определением OGC для карты является "изображение географической информации как цифровой файл изображений, подходящий для отображения на мониторе".

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

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

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

Код, показанный в этом примере, может быть найден в этой функции:

function mapexwmsanimate(useInternet,datadir)

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

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

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

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

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

Настройка: задайте служебную функцию директории и имени файла данных

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

if ~exist('datadir','var')
    datadir = fullfile(matlabroot,'examples','map');
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' возвратил массив 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 верен.

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: получите карту Катрины из сервера

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

cachefile = datafile('katrina.tif');
if useInternet
    [katrinaMap,R] = wmsread(katrina);
    if ~exist(cachefile,'file')
        geotiffwrite(cachefile,katrinaMap,R)
    end
else
    [katrinaMap,R] = geotiffread(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;

Переменные Assign 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] = geotiffread(cachefile);
end

Отобразите nexradMap.

figure
usamap(latlim,lonlim)
geoshow(nexradMap,R)
geoshow(states,'FaceColor','none','EdgeColor','white')
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: инициализируйте переменные, чтобы анимировать карты 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;

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

Создайте объект 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 = geotiffread(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 = geotiffread(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 Центра космических полетов имени Годдарда НАСА Изображений и сохраняется Studio Аналитической визуализации.

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

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

Слой NEXRAD

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

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

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

Смотрите также

| | | | | | |