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

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

Базовый слой выполнен с сервера изображений NASA Goddard Space Flight Center (SVS) Scientific Visualization Studio (SVS). Данные этого слоя показывают данные облака спутника во время урагана Катрина с 23 августа по 30 августа 2005 года. Слой состоит из облачных данных, извлеченных из GOES-12 изображений и наложенных на цветное изображение юго-востока США.

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

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

  • Используйте базу данных WMS для поиска слоев Katrina и NEXRAD

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

  • Извлечение карты NEXRAD с сервера WMS в то же время

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

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

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

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

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

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

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

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

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

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

  • документ возможностей --- 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

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

Этот пример записывает данные в файлы, если 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' возвращено 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 свойства. The * символ указывает на поиск по подстановочной карте. Если возвращается несколько записей, выберите только первый элемент на сервере 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 слой. The Details.Attributes поле сообщает вам, что слой имеет атрибуты фиксированной ширины и фиксированной высоты, поэтому размер запрашиваемой карты не может быть изменен.

katrina.Details.Attributes
ans = 

  struct with fields:

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

The 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 слой в совпадающие периоды времени и параллельные географические и графические границы. The 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. The nexradMap данные возвращаются как изображение с классом double из-за того, как этот сервер веб-карты обрабатывает 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;

Поскольку для анимации требуется несколько запросов к серверу, более эффективно использовать 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 Пространства рейсов НАСА Годдарда и поддерживается Научной студией визуализации.

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

  >> 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?')

См. также

| | | | | | |