Real-time data visualization on a map

3 minute read

I have spent last couple of days working on a new live show that premieres tonight. Pre-production time (from absolute start to finish) for this entire show was only 10 days - which is super short. Final script and graphics designs were delivered on a day 5, leaving me and my colleague with just 5 days of coding. This seemed to be quite simple show at first, but things got complicated pretty quickly. Apart from many video outputs and various graphical elements, one particularly challenging task came along the way. I was asked to display visualization of covid-related data on a map of Slovakia divided into its regions.

Filling in manually all the data variations for the map (in something like Photshop) would be super tedious with high chance of error and no fun. Using some off-the-shelf web-based map visualization wasn’t possible due to specific production requirements. This map was supposed to not only visualize current data and regions names, but also have an option to specifically highlight some regions (based on either high / low data values). Custom-made procedurally generated map seemed like a best option here.

I had only about one and a half day in total for this map, so I didn’t waste time and jumped right into Houdini to prepare map geometry. Loading illustrator file with region shapes into Houdini was very straight forward - only some basic geometry adjustments were needed (such as resampling and triangulation). I assigned ‘id’ attribute to each region based on region codes (from local covid database available on github). Also centroids were generated to later provide text position per region. Finally I added second id attribute based on proximity from center of the map (which could be used for nice animations down the road). With geometry finished, I have exported everything as alembics and moved to real-time area for rendering and visualization.

Here I have setup rendering of 4 different data and packed them into single 32-bit RGBA texture. R contains ids, G contains proximity ids, B and A contain alpha masks both for regions and their edges. Channels containing ids were rendered without anti-aliasing to avoid id mismatch around edges. I have also eroded them by couple of pixels so that given id covers region nicely around the edges.

Next I loaded covid data and done some processing to isolate stuff needed for visualization. For map color mapping I wrote simple GLSL that assigns color to each pixel based on its id (in R channel). It works just by looking up data for a its region, remapping the data value based on min and max values and then coloring the pixel accordingly using given ramp (choosing U between 0-1). Shader finishes by multipling colors with masks in B / A channel - to output either whole region or just the edges. Simple and super fast!

Now its time to play with in/out animations using masking by proximity data. I also decided to use lens distortion shader for animations just so that it looks a bit more interesting.

Finally I add names of regions together with data values and map legend. I feel like it is all working together and I am happy about the result. I am closing the project hoping I can consider this part complete. Not even 10 minutes later director comes in telling me that they want to visualize also “outlier” cities… Well, it is already 12:00 and live show starts at 20:00 so I guess I just hardcode two cities into the system and call it done. :blush: There is no time to waste as there are way too many things going on apart from this map.

Problems seem to be coming literally from everywhere and we are solving them in parallel - audio signal decided to start crackling, videos for the show are not yet delivered, every 30 minutes someone walks in telling me there is yet another change in footages for LED screens, my GLSL code just stopped working and won’t compile, there are new audio effects and ambient sounds that need to be incorporated into game logic, midi signals aren’t yet mapped, we aren’t getting reference signal, some folks want to change credits, etc. My attention is taken every couple of minutes by something new that just got broken. :grin: This is how it works when there isn’t enough time to prepare a show and everything is done in a hurry. I don’t recall any other show (with this level of complexity) being done in such a short time period.

Nevertheless it is 16:00 and I have now realized we managed to solve every issue. All those bloody surprises are now fixed and we ready for live broadcast. What a crazy day.