Tomorrow's Weather on Yesterday's Computers
For most of the last month, I've been working on a retro-friendly weather forecast website for
#CGHMN. I decided to develop the site itself using a modern LAMP stack due to the need to call modern APIs for weather data, although the output is pure HTML 3.2 without a single line of JavaScript.
Before I wrote any code, I commissioned my friend
@[email protected] to make a logo for the site. Someone on Fedi suggested a retro computer with an umbrella, so we went with that. I used the Google color emoji set for placeholder art to represent various weather conditions with the expectation of replacing them with original work later. (as I write this,
@[email protected] has offered to make some)
I decided to use the
Open-Meteo API for forecast data. They don't provide local observation data though; their current conditions are model estimates. I wanted to provide accurate info, so I figured my best bet would be to pull and parse METAR reports from the US's NOAA. I set up a MariaDB database to hold a list of all the available weather stations with their coordinates (from
OurAirports ) and most recent report, and made a cronjob to update them all every hour. I used
Safran Cassiopée's php-metar-decoder to handle decoding, and wrote a little function to convert the current conditions reported to a generally-equivalent WMO 4677 code.
Since Open-Meteo needs a set of geographic coordinates to get local forecasts, I needed a geocoding solution. They offer a geocoding API based on
GeoNames data, but I wasn't entirely happy with it. I ended up loading the GeoNames datasets directly into my MariaDB server and setting up the code to query that. This was the first time I'd dealt with a ~5 million-line database, so I had to learn a bit about indexing and optimization to get it to perform decently.
Next, I wanted to have a list of current weather conditions for major world cities on the landing page. I decided to include six cities from each continent, though it was a bit tricky to determine which ones to pick. I asked Fedi for some recommendations. The end goal was to give an at-a-glance summary of weather around the globe. Of course, in addition to picking which cities to use, in most cases I also had to figure out which airport to take a representative report from. I generally went with whatever was closest to the city center, rather than the largest or busiest.
With current and future weather settled, the next thing I wanted to add was radar. The need to work worldwide complicated things but some of the folks in the CGHMN IRC chat pointed me to
Rain Viewer, which offers a free API. It's a bit slow but it did what I needed. They only provide the radar data itself though, so I was still on my own to come up with a base map. For that I chose
Thunderforest, who provide an API based on
OpenStreetMap data. Thankfully both APIs used the same arguments for location and scale factor so they meshed together well.
I experimented with a few different layouts for the forecast info, first trying a table with days as rows and hours as columns, then a format suggested by Loganius on CGHMN with days as columns, before ultimately settling on a simple row of daily summaries. To provide detail, I set up a separate page with a set of graphs showing hourly forecast data for a three-day period. I used
PHPlot to draw the graphs server-side. The library hasn't been updated since 2015 but it still works with PHP 8.4, surprisingly enough. I based the layout of the graphs on the ones on
the US National Weather Service's site. Most of the plotting was handled automatically by PHPlot but I had to write a few custom callbacks for the wind barbs and nighttime indicators.
At this point the site is essentially done, though I've been thinking about other meteorological information I could provide. It all depends on what I'm able to find free or reasonably-priced APIs for. I'm a bit inspired by the
NCAR Research Applications Laboratory site, though that's strongly US-centric and I'm aiming for world coverage.
#blog