Pull to refresh

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

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

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

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


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


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

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

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

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

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


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

image

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

image

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


Теперь нам надо сформировать строку вида
www.niederschlagsradar.de/images.aspx?j=-4&file=201301041200
Время тут используется с шагом в пять минут – 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
Tags:
Hubs:
+40
Comments 30
Comments Comments 30

Articles