В этом примере показано, как объединить и анимировать данные из нескольких слоев Картографический Веб-сервис (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