Part of a series of posts to cover some small projects that I did whilst not being able to work. They cover things from the role of familiar strangers on the internet and anti-social networks, through to meteorological hacks, funny memes to twitter bots. This post is about a meteorological hack.
DataPoint is a way of accessing freely available Met Office data feeds in a format that is suitable for application developers. It is aimed at professionals, the scientific community and student or amateur developers, in fact anyone looking to re-use Met Office data within their own innovative applications.
The year before this, in Denver, USA, I was shown by a couple of awesome mapping and weather geeks a mobile app that showed when it was going to rain, and more importantly when it wasn’t going to rain in very high temporal resolution. You can use the app and know whether to get a swift half and then leave to get the bus, or whether to stay in for an hour until the showers end. It was very detailed and highly useful. This app Dark Sky App
was freaking awesome. And I want here in the UK, so when the Met Office announced their API I was interested.
You cannot do what DarkSkyApp does with the Met Office DataPoint API though – what you can do is do some interpolations though. The API for precipitation forecasts only gives access to a 3 hourly map tile.
Although further poking around shows that they do have an undocumented 1 hourly image.
These map tiles then could be used. http://rain-graph.herokuapp.com is the resulting application with the code here: https://github.com/timwaters/rain_graph
It’s a Ruby Sinatra application which for a location, grabs the precipitation tile for a defined location for each hour from now. It looks at the pixel value for the given location and determines the amount predicted. It shows when the heaviest rain is predicted and when it would stop. Interpolation is given by the graph engine itself – no fancy meteorological modelling is done (at this stage). It uses Chunky_png to get the pixel values.
All requests are cached to avoid hitting the MetOffice API and because an image won’t change for an hour. Additionally it uses another API method to get a human readable upcoming forecast text for that location, and displays it under the graph. Contrary to popular global belief it’s not always raining in the UK, and so most of the time you will never see a a graph showing something!
Pixels to Lat Lon:
Since a lat/lon location is quite specific, it could map to one pixel in a tile, and that pixel could have a lower or higher value than the ones surrounding it. I could use a kernel average – do a 6×6 pass over the pixel and get the average value. But since there are tiles are lower zoom levels, by zooming out, the spatial extent of the pixel would equal that larger area – it would do the work for us.
Interpolation between forecasts:
It wasn’t clear if the forecast images showed the predicted situation over the whole hour, or whether it showed the situation at that moment. Should a user look at an animation to see how rain cloud moves across from A->B and guess that in between that there would be rain, or should they think that that there would be no rain if there is no rain shown?
It looks a bit bland – we should show the image tiles underneath - perhaps shown when hovering over a point.
I haven’t tested the accuracy of this.
Location hard coding:
The text forecasts are hardcoded to a set number of regions, but we could do a closest point and get the correct forecast for the given lat and lon.
Use Yr.No API
Yr.no has detailed hour by hour forecasts API for a place giving the amount of precipitation.
<time from="2013-12-06T19:00:00" to="2013-12-06T20:00:00"> <!-- Valid from 2013-12-06T19:00:00 to 2013-12-06T20:00:00 --> <symbol number="3" name="Partly cloudy" var="mf/03n.11" /> <precipitation value="0" /><!-- Valid at 2013-12-06T19:00:00 --> <windDirection deg="294.2" code="WNW" name="West-northwest" /> <windSpeed mps="4.3" name="Gentle breeze" /> <temperature unit="celsius" value="1" /> <pressure unit="hPa" value="1004.9" /> </time>