- PVSM.RU - https://www.pvsm.ru -

А будет ли дождь?

Время от времени я езжу на работу на велосипеде. Иногда на улице идёт дождь, погода «не велосипедная», и тогда возникает дилемма: немного подождать, пока он закончится, либо вообще ехать на автомобиле. Бывает и так, что с утра погода хорошая, а вечером начинает идти дождь и хочется найти «окно» для того, чтобы вернуться домой сухим. Пару раз доходило до смешного – с утра светит солнце, я выезжаю, минут через пять начинается неслабый дождик, а ещё через несколько минут он заканчивается, снова светит солнце, а я вхожу в офис мокрый до трусов.

Таким образом нужен сервис с краткосрочным прогнозом погоды – в пределах пары часов. В основном погодные сервисы предлагают прогноз на несколько дней (при этом качество прогноза так себе), а вот удобного и простенького краткосрочного прогноза я не видел. Хотя казалось бы – что может быть проще – карты осадков в каждый момент времени имеются, и проанализировав историю за последнюю пару часов можно довольно достоверно рассчитать, что произойдет в следующие час-два.

Под катом мы сделаем следующее – программно загрузим карты дождя с одного из сервисов и посмотрим, что будет происходить в окрестностях определённой точки, сохранив результаты в dropbox. Нехитрое пятничное упражнение исполним, разумеется, в LabVIEW.

Исходные данные

Для начала посмотрим что у нас имеется. Я территориально нахожусь на севере Германии, поэтому изложение будет применительно к этой стране, но общий принцип, разумеется применим и к другим странам – нужно лишь найти подходящий источник информации. В России ситуация чуть хуже – я не видел хороших подробных карт осадков – это, кстати, идея для неплохого стартапа. Первый сервис, на который я наткнулся — www.niederschlagsradar.de [1]. Там есть практически всё, что нужно для того чтобы оценить, пойдёт дождь или нет, но нет удобного представления информации для конкретной точки. Второй сервис www.rain-alarm.com [2]. Тоже почти то, что нужно – там можно задать местонахождение, но мне нужно не столько предупреждение, сколько небольшая табличка – ведь мне не только интересно, когда дождь пойдёт, мне также важно знать когда дождь закончится, чтобы найти окно в 20-30 минут, в течение которого я доеду до работы сухим. Кроме того в бесплатной версии есть куча ограничений (например, анализ только в пределах 75 км, что очень много и реклама). На платную версию денег не то чтобы жалко, просто это не совсем то, что нужно. maps.google.com [3] может показать облака, но не осадки, и там легко получить бан за постоянный опрос данных. Есть также несколько приложений для андроид, которые показывают анимированную карту дождя, но опять-таки, анимацию приходится анализировать в голове. Что ж, засучим рукава и сделаем несложный велосипед. Попутно я покажу, как получить картинку из интернета в LabVIEW – собственно пост именно об этом.

Паразитировать будем на сайте www.niederschlagsradar.de [1]. Я не планирую выкладывать приложение в онлайн, а в написании робота «для себя» не вижу никаких проблем. Моей первой мыслью было проанализировать расположение и перемещение осадков в окрестностях интересуемой точки, затем рассчитать векторы движения облаков и построить прогноз на ближайший час. Однако велосипед изобретать не пришлось – прогноз уже есть (впрочем я лишился наиболее интересной части задачки). Сервер отдаёт картинки прогноза вот в таком формате, например для 13:00 4 января 2013 г.:

www.niederschlagsradar.de/images.aspx?j=-4&file=201301041200 [4]

Нетрудно заметить, что время в UTC.

Получение изображения из интернет в LabVIEW

Для получения картинки из интернет используем следующий незатейливый метод:

image

В данном примере грузится логотип сайта NI. Если вы читаете эту статью в Internet Explorer, и у вас есть LabVIEW версии 2010 или выше, то можете перетащить этот сниппет прямо на блок-диаграмму. Немного нетривиальная часть – добавление строки [text] в URL. Почему так – можно прочитать в документе Retrieving an Unformatted Text File via FTP or HTTP Using DataSocket [5].
Таким образом мы получили содержимое gif в строке. С файлами gif LabVIEW «из коробки» работать не умеет, поэтому воспользуемся библиотекой доброго самаритянина MikeS81 [6] для преобразования gif в picture. Я добавил туда возможность читать содержимое из строки, иначе пришлось бы сохранять полученную картинку в файл, а так можно выполнить преобразование «на лету» в памяти:

image

Формирование URL

Теперь нам надо сформировать строку вида
www.niederschlagsradar.de/images.aspx?j=-4&file=201301041200 [4]
Время тут используется с шагом в пять минут – 12:00, 12:05 и т.д. Так что получим текущее время, округлим его до пяти минут, (потом в цикле будем прибавлять по 300 секунд, чтобы получить все файлы прогноза):

image

Генерация строки примитивна:

image

Анализ

Теперь приступим к анализу. Анализ — это, конечно, громко сказано, но тем не менее. Сервер отдаёт нам GIF картинки размером 550x512 пикселей c прозрачным фоном. Синяя компонента всегда равна 255, а красная и зелёная уменьшаются на дождевых участках. Скажем R=100; G=100; B=255 – это довольно сильный дождь. Синим цветом показаны участки с дождём:

image

Сделаем нехитрый анализ: возьмём точку с заданными координатами (мой город находится примерно в точке с координатами x=302,y=79), из массива изображения вырежем квадрат (я взял 13х13 пикселей – это примерно 10 км) и посчитаем минимум. Теоретически правильнее считать среднее, но с минимумом я получил лучшие результаты (бывает, что туча лишь цепляет край квадрата, но при этом за окном довольно сильный дождь, так что минимум даёт более реалистичный результат):

image

Технически RGB картинка (picture) в LabVIEW это одномерный массив байтов, в котором каждые три байта это цветовые компоненты RGBRGBRGB и т.д. Соответственно Decimate 1D Array c тремя выходами разложит нам массив по компонентам. Чтобы не морочиться с высчитыванием индексов, одномерный массив перегоняется в двумерный, а затем оттуда вырезается квадратный кусочек.

Сохраняем

Осталось лишь сохранить отчёт в HTML файл:

image

На вход у нас приходит двумерный массив с результатами. Первая колонка – время прогноза, а вторая – результат. Результат будем сохранять в %USERPROFILE%Dropbox (хороший тон — не использовать жёстко закодированных путей):

image

Вот практически и всё. Осталось лишь подложить карту Германии под облака, чтобы проконтролировать положение и размер региона интереса. Для этого используем MaskColor – этот SubVI создаст маску, через которую будет просвечивать карта. Карта грузится из той же папки, в которой лежит основной VI. Соберём всё вместе и запустим в цикле:

image

Здесь While цикл срабатывает каждые 5 минут (пауза в 300000 мс – это некошерно, но мне не хочется усложнять диаграмму), а for цикл грузит данные за два часа (22 итерации – именно столько картинок с прогнозом доступно на сервере). Я намеренно не стал прятать логику под SubVI, чтобы было нагляднее. На передней панели у нас будет вот такая картинка:

image

Вот такая вот гамбурская зима. Ну а в дропбоксе будет лежать вот такой файл, вот к примеру сегодня утром (прочерки означают отсутсвие дождя, а плюсики — наличие и силу):

image

Сразу хорошо видно, что в восемь утра лучше из дома не выезжать, а дождаться половины девятого.
Поскольку у меня клиент дропбокса есть и на планшете и на телефоне – я могу всегда перед выходом из дома посмотреть – стоит ли мне ехать на велосипеде, или имеет смысл взять машину.
Конечно, программу можно обвешивать свистелками до бесконечности (сворачивание в трей, выгрузка данных на ftp, добавление температуры, сообщения на e-mail/SMS и т.п.), но и в таком простом виде меня это приложение устраивает более чем полностью. И само собой разумеется, подобную штуку можно собрать на любом языке программирования, эта статья является лишь примером – как небольшую прикладную задачку можно решить средствами LabVIEW.

Исходный код в LabVIEW 2010 [7]

Автор: AndreyDmitriev

Источник [8]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/data-mining/24062

Ссылки в тексте:

[1] www.niederschlagsradar.de: http://www.niederschlagsradar.de

[2] www.rain-alarm.com: http://www.rain-alarm.com

[3] maps.google.com: http://maps.google.com

[4] www.niederschlagsradar.de/images.aspx?j=-4&file=201301041200: http://www.niederschlagsradar.de/images.aspx?j=-4&file=201301041200

[5] Retrieving an Unformatted Text File via FTP or HTTP Using DataSocket: http://digital.ni.com/public.nsf/3efedde4322fef19862567740067f3cc/f3cc5f7e60a75cb2862567e700696abf?OpenDocument

[6] библиотекой доброго самаритянина MikeS81: https://decibel.ni.com/content/docs/DOC-3293

[7] Исходный код в LabVIEW 2010: http://vi-lib.com/forForum/rain/IsRain.zip

[8] Источник: http://habrahabr.ru/post/164735/