Building a COVID-19 map using Django, LeafletJS, Google Spreadsheets and S3 Cloud Storage

Mikhail Ageev
4 min readMar 17, 2020

--

First time I came up with an idea to build a map showing a global spreading of COVID-19 on January 24th. Even then it was clear that the story is going to be damn long.

On Friday, last week being on home-office I’ve finally launched a map (you may call it webapp) for CurrentTime TV website. Today we launched 3 localized versions of the map for language services across RFE/RL. All maps are updated every hour.

The Problem

COVID-19 is topic #1 Worldwide. People are scared (I’m scared too). Apparently you’ve already seen this great map.

Coronavirus COVID-19 Global Cases by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University (JHU)

According to the FAQ the map updates almost in real-time. The product nicely visualizes number of cases in each country. Though, map looks like a mess in high-density regions. Furthermore, it’s hard to get a regional/global overview on virus spreading.

There is another way of visualizing the spreading COVID-19 — by marking the whole countries depending of Confirmed and Death Cases. Yes, we will mark the whole country with red if even if one Death Case was confirmed.

France COVID-19 Data on CurrentTime English Website

And finally, CSSE map is only in English. Our audience is talking 20+ languages, prefers mobile phones and wants to learn more about the issue. Like millions of people who talk Farsi.

RFE/RL’s RadioFarda COVID-19 Map in Farsi Language

Design

I decided to make the whole experience with map as simple and as clear as possible. It has only two screens: Landing and Map.

  1. Landing tells a human (and a Search Engine) where she has just landed
  2. Map, well, shows the data
COVID-19 Map UX

As you may notice, all interface transitions are based on changing generic CSS opacity and border styles for a country outline.

The app layout meets branding standards for both RFE/RL (Orange, Torch, Skolar font) and CurrentTime (Plum, Playback, Roboto Condensed font). RFE/RL version also supports right-to-left Farsi language.

English version of the Map uses CARTO tiles instead of basic OpenStreetMap used in other localizations.

Restrictions may apply

It may sound weird, but I didn’t use Django to serve the map content (as it usually used). Imagine, your publishing platform restricts you to serve only static HTML. No dynamic templates, no code generators. You even has to update your HTML manually because there is no API.

However, you still may include remote JS/CSS files and execute remote XHR-calls. Here comes the magic or a kind of JAM-stack app I’ve built for this project.

Django (Python, Backend)

Main functions of Django Backend are:

  1. Synchronise COVID-19 stats from two sources: JHU CSSE on github (updated daily) and Coronavirus Monitor on RapidAPI (update more often)
  2. Localization: Fetch localized labels from Google Spreadsheets
  3. Generate map GeoJSON and upload it into S3 Cloud Storage
  4. Generate map HTML with inline JS/CSS for online publishing

Tasks 1 to 3 are performed hourly to make the map always actual. Task #4 performed by a journalist only once.

LeafletJS

Really great and flexible Javascript library that allows to build interactive maps.

Thankfully Leaflet supports various tiling/labelling providers. Instead of using OpenStreetMap you may go with CARTO or even Google Maps.

Google Spreadsheets

It’s almost impossible to find an alternative for an agile collaboration with colleagues on interface localization. We used it to manage translations into Russian, English, Farsi, Bulgarian and few other languages.

People in newsrooms are familiar with it. Spreadsheet format is easy. So you just have to share it with them and write a tiny parser to fetch labels on backend side.

S3 Cloud Storage (CDN)

The map has to be interactive and up-to-date. It may sound a bit goofy task when you have to update HTML manually. So I decided to move dynamic part in a S3-capable storage (NewsroomToolkit’s CDN on Digital Ocean Spaces). CDN plays a roles of API making Frontend almost independent of our publishing platform.

A chunk of GeoJSON generated by Django and served via CDN (Czech Republic data is highlighted)

This is how it works:

  1. Django task pushes localized and updated GeoJSON for maps into the storage
  2. Storage has a wildcard CORS setting for these files so they are available for XHR fetching from other websites
  3. A human opens a page with the Map in browser
  4. Browser fetches the latest COVID-19 data from CDN and renders localized Map.
  5. People are informed. Mission accomplished.

WHO

It’s sad to see a well-funded UN agency and a most trusted source of data does not provide an API/dataset for the COVID-19. Situation reports in PDF are great. But it’s not enough in 2020.

--

--