Tidying up leaflet maps created with qgis2web

Food poverty risk in different parts of Herefordshire

Food poverty risk in different parts of Herefordshire

This is a bit of a detailed (read geeky) post. It’s largely notes for myself to make it easy to remember what I did next time someone asks me to fiddle about with a web map milled out from QGIS but It might be helpful to others in the future.

If you understand what I’m talking about then please do read on. Otherwise, this post may not be for you…

A quick bit of background

QGIS and leaflet

QGIS is a widely used open source Geographic Information System. It helps you create and analyse mapping data. Sometimes you might want to share a version of your map with others on a webpage. A nice plugin helps you to do this… called qgis2web. This converts your mapping files into a bundle of HTML, CSS and JavaScript based on the OpenLayers or Leaflet libraries. I favour Leaflet only because I’m a bit more familiar with it.

Food Poverty risk mapping

We’ve been working with the Herefordshire Food Poverty Alliance to help them understand food poverty risk. Herefordshire is a sparsely population rural county and the risk factors here may be different to more densely populated area.

We developed a set of indicators to identify food poverty risk factors using data at ‘lower super output area’ geographies. You can read more about the data we used and see the results on our project page.

The obvious way to share this data, given that our clients aren’t GIS specialists, is on a web map. And the Alliance also wanted to share the map with others wanting to understand this issue. Our GIS associate used qgis2web to create the bundle of files for leaflet and I published them to our Github repository. You can view the food poverty web map here. We then wanted to perform a few tweaks.

The tweaks

None of these were dramatic. We wanted to:

  • Apply a colour-blindness friendly colour range

  • Add a little branding

  • Change the indicator layers display control to radio buttons rather than check boxes

  • Add a circle to the legend (because we had a layer showing the location of support services)

This is what I need to remember for next time.

The nice thing is that almost all of these changes can be performed in the index.html file. With a few of them requiring CSS changes. However we don’t have to mess about with the JavaScript files.

Apply a colour-blindness friendly colour range

Actually we could have done this in QGIS and these colours would have been exported into the leaflet files. But we forgot to specify this. Our preferred colour range is based on a colorbrewer palette. The deepest red colour is almost the same as our brand red. So we actually use that instead.

It’s simple to update the colours in the map…

 case '1':
					return {
 						weight: '1.3',
 						fillColor: '#fef0d9',
 						color: '#000000',
 						weight: '1',
 						dashArray: '',
 						opacity: '1.0',
 						fillOpacity: '1.0',
 					};
 

For each case in each layer there is a fillColor key. With the judicious application of Find/Replace we quickly apply the new palette.

Apply a little branding

We’ve dropped reference to Data Orchard into two places. Into the attribution section:

var basemap_0 = L.tileLayer('https://.png', {  
			attribution: additional_attrib + '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>. A project by <a href=\https://dataorchard.org.uk/\">Data Orchard CIC</a>.'
	});	

It’s worth noting that because this isn’t raw HTML, it’s a string which will be used later to generate some HTML, we need to escape some characters (in particular “ by putting \ immediately before it. This basically says “I know this looks like a but of code but ignore it, it’s just text”.

We’ve also dropped our logo into the title section.

		title.update = function () {
			this._div.innerHTML = '<a href="https://www.dataorchard.org.uk/case-studies/food-poverty-mapping-project"><img class="titleimage" src="https://data-orchard.github.io/pages/assets/Burgundy-leaf-icon.png"></a> <h2>Food Poverty risk in Herefordshire</h2><p>Risk Factors of food poverty</p>'
		};

And we then need to add a little CSS to tell the browser what to do with the image. We include this in the helpfully named “own_style.css” file.

 .titleimage {
  border: 1px;
  border-radius: 4px;
  padding: 5px;
  width: 100px;
  float:right;
  opacity: 0.5;
}

Change the indicator layers display control to radio buttons rather than check boxes

As we’ve designed the map there is no advantage to displaying 2 of the risk score layers at the same time. By default they appear with checkboxes so you can choose to display as many as you like and this is potentially confusing.

The solution is to declare that each of the risk score maps is a basemap. Slightly counterintuitively if we include the actual basemap as a basemap it won’t be able to be displayed when any of the risk score layers are shown. Which rather ruins the point.

So we declare that the basemap and the location of support services layer as overlays and the other layers as basemaps.

 var baseMaps = {
"OverallDeprivation": exp_OverallDeprivationJSON,"BenefitClaimants": exp_BenefitClaimantsJSON,"FuelPoverty": exp_FuelPovertyJSON,"NoCarHouseholds": exp_NoCarHouseholdsJSON,"Year6Obesity": exp_Year6ObesityJSON,"LoneParentHouseholds": exp_LoneParentHouseholdsJSON,"LonePensionerHouseholds": exp_LonePensionerHouseholdsJSON,"OverallMedianScore": exp_OverallMedianScoreJSON
};
var overlayMaps = {"Locationsofplacesthathelp": exp_LocationsofplacesthathelpJSON,'OSM Standard': basemap_0};

It feels weird but it works.

Add a circle to the legend for the layer showing the location of support services

The legend is actually a table with the relevant cells coloured in for each risk score (again we have to escape characters that might be interpreted as code rather than text).

 legend.onAdd = function (map) {
			var div = L.DomUtil.create('div', 'info legend');
			div.innerHTML = "<h3>Legend</h3> <table style=\"width:100%\"><tr><th>Colour</th><th style=\"text-align:right\">Risk level</th></tr><tr><td style=\"background-color:\#fef0d9\"></td><td style=\"text-align:right\">1</td></tr><tr><td style=\"background-color:\#fdcc8a\"></td><td style=\"text-align:right\">2</td></tr><tr><td style=\"background-color:\#fc8d59\"></td><td style=\"text-align:right\">3</td></tr><tr><td style=\"background-color:\#e34a33\"></td><td style=\"text-align:right\">4</td></tr><tr><td style=\"background-color:\#b11e33\"></td><td style=\"text-align:right\">5</td></tr><tr><td colspan=\"2\">Bigger is higher risk</td></tr><tr><td><span class=\"dot\"></span></td><td style=\"text-align:right\">Places that help</td></tr><table>";
    		return div;
		};

We also show grey circles on the map. To render those on the legend we have to use a little CSS too. The circle is going to appear where we have written

<span class="dot"></span>

The CSS (also in own_style.css) is

 
.dot{
    height: 10px;
  width: 10px;
  background-color: #808285;
    border-radius: 50%;
    border-style: solid;
    border-width: 1px;
    border-color: #000000;
  display: inline-block;
}

That’s it

Hopefully next time I need to do this I can refer to these notes.

And maybe it will help someone else down the line wrestling with qgis2web.

Here it is in all its glory…

Ben Proctor