В этом примере показано, как объединить и анимировать данные из нескольких слоев Картографический Веб-сервис (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, несколько ключевых концепций важно понять и перечислены здесь.
Картографический Веб-сервис --- Открытый геопространственный консорциум (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
Этот пример записывает данные в файлы, если 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);
Одним из наиболее сложных аспектов использования 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
База данных хранит только подмножество информации о слое. Например, информация из абстрактных данных слоя, подробные сведения об атрибутах слоя и информации о стиле, а также система координат-ссылок слоя не возвращаются 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.
Обратите внимание, что эта абстрактная информация, включая любые типографские проблемы и неполные фрагменты, была получена непосредственно с сервера.
Вы можете узнать больше информации о 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'
Теперь, когда вы нашли интересующий слой, можно извлечь растровую карту с помощью функции 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')

Радиолокационные изображения 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
Составление 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;
Можно извлечь 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');

Составление 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})

Следующим шагом является инициализация переменных в порядок для анимации составной 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;
Анимацию можно просмотреть в браузере, когда браузер открывает анимированный 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);
Анимацию можно просмотреть в браузере, когда браузер открывает анимированный 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?')
geoshow | refine | usamap | WebMapServer | wmsfind | WMSMapRequest | wmsread | wmsupdate