Ordnance Survey OpenData In QGIS 3: Part 1

Recently, I’ve been preparing my UK walking maps using the Ordnance Survey’s free OpenData products, which I’ve rendered into maps using a free, open-source Geographical Information System, QGIS. I thought I’d write a little bit about that, now that I’ve got my maps looking more or less as I’d like them. For this first part, I’m going to write about using one of the OS’s free topographic datasets. Later posts will deal with adding features like contours, rivers, lakes and roads, and with adding custom data.

First, of course, you need to install QGIS. I’ve been using version 3, which at time of writing is the latest. With that done, you then need some OS data. I downloaded both versions of their Terrain 50 dataset, which provides elevation data at 50m horizontal resolution. The “Grid” format provides raster elevation data—lots of cells in a square grid, each containing a number representing the elevation in metres above sea level for that location. The “Contours” format provides a vector dataset, full of “shape files”—properly interpreted by QGIS, they’ll draw contour lines and spot heights for you. I’ll use only the Grid data for this post, though I’ll be using the ESRI version of Contours later.

OS grid squares

These downloads need to be unzipped, at which point they each produce a folder called data, full of subfolders lettered according to the OS’s 100-km grid system. To keep the Grid and Contour data separate, I unzipped them to separate folders named OS Terrain 50 (Grid) and OS Terrain 50 (ESRI). Annoyingly, each lettered grid folder contains a multitude of zipped files—anything up to a hundred, each representing a 10-km square tile of topographic data. QGIS can actually peer inside these zipped files and load tile data directly, but I find it easier to deal with multiple tiles if I do a mass unzipping for each lettered grid square that interests me, and then clear away the zip files.

Features like rivers, lakes, woodlands and buildings are added using more datasets. I’ve been using the Open Map – Local ESRI shape files. These are downloaded in packages that cover a single grid square. For my examples here I’m going to use data from the NG square. Downloaded and unzipped, that produces a folder called OS Open Map Local (ESRI Shape File) NG. (Round about this point, I started stuffing all my data folders inside one big folder called OS Data, to make them easier to find.)

The OS also provides a variety of stylesheets—instructions that tell your GIS software how to display your data. These provide a useful starting point which can be modified to produce your own custom styles. Downloading and unzipping the Terrain 50 and Open Map – Local stylesheets from the OS’s Cartographic Stylesheets page will produce another couple of folders on your hard drive called OS-Terrain-50-stylesheets-master and OS-OpenMap-Local-stylesheets-master. Into the OS Data folder they go.

With all that in place, we can open QGIS 3 and start producing a map. QGIS opens with a load of menu items and toolbars across the top, a “Browser” window at upper left, which allows you to navigate to and load data files, and a “Layers” window at lower left, which keeps track of the various layers you’re putting together to create your map. The rest of the screen will hold the map itself. Navigating to the ng subfolder of my Terrain 50 Grid data (having first unzipped all its files), I find an eyewatering array of files with different names and extensions. I want to load all the files with extension .asc, and I can call them up using the filter tool (shaped like a little funnel) in the Browser window toolbar, and typing *.asc as my filter criterion. Then I select all the .asc files, right-click and select Add Selected Layer(s) to Canvas.

This is what appears in the map window:

OS OpenData Terrain 50 NG raster tiles
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

All the 10-km tiles containing elevation data have been loaded, and colour-coded by height, from black at the lowest to white at the highest point of each tile. The white squares are areas of no data, containing only sea. If you know your Scottish islands, it’s possible to make out the distinctive shape of the Isle of Skye, but it’s all a bit of a mess because each tile has been tinted individually.

The first thing to do is to merge all the tiles into one big square, so they can be tinted consistently. We can do that from the top menu, Raster/Miscellaneous/Merge…. For “Input Layers”, select all the tiles. Under “Merged”, save the merged data as a file with a descriptive name you can find later. I also nominate a specific “no data” value for the output, setting it to -100, so QGIS knows which areas of the merged file to make transparent.

Here’s what the merged version looks like:

OS OpenData Terrain 50 NG raster tiles merged
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

Now it could do with a bit of colour. Double-click on the name of the layer in the “Layers” window, to open the Layer Properties dialogue box. (Choose the “Symbology” view if QGIS doesn’t take you there by default.) Switch the “Render type” to Singleband pseudocolor, and QGIS will offer you a colour ramp—a series of colours that can be used to code the height data on the map. QGIS has a wide variety of built-in ramps, but they’re hidden away. Drop down the menu for “Color ramp”, choose Create New Color Ramp… and drop down the menu in the dialogue box that follows. Catalog: cpt-city contains all sorts of useful stuff.

Finding the cpt-city catalogue in QGIS 3
Click to enlarge

I made my own ramp, based on the height tints of the classic OS tourist maps of the 1970s, and saved it (using the Style button at lower left) so I could reuse it. Here’s the set-up for the ramp:

Custom colour ramp in QGIS 3
Click to enlarge

And here’s what the map looks like with my colour ramp applied:

OS OpenData Terrain 50 NG height pseudocolour
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

No sea colour, but that’s deliberate. Zero height in the topographic data doesn’t correspond precisely to the coastline, and the OS provides a set of tiles in Open Map – Local that will lay a precise coastline on to my topo map. From the QGIS menu, Layer/Add Layer…/Add Vector Layer… brings up a dialogue box that lets you browse to the directory in which the ESRI shape files are stored—in my case, OS Open Map Local (ESRI Shape File) NG/data. The file I’m after is NG_TidalWater.shp. Adding that as a layer on top of the topographic data produces this:

OS OpenData Terrain 50 NG tidal water
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

Lovely coastline, shame about the colour, which has been assigned at random by QGIS. Time to use an OS stylesheet. Double-click on the new TidalWater layer to open its Layer Properties dialogue, go to “Symbology”, and use the button at lower left to open Style/Load Style. Navigate to the Open Map – Local stylesheets—in my case exhaustingly named OS-OpenMap-Local-stylesheets-master/ESRI Shapefile stylesheets/QGIS stylesheets (QML)/Full colour style. Load TidalWater.qml. Presto! Now the sea is sea-coloured, and all those tile margins have disappeared:

OS OpenData Terrain 50 NG tidal water blue
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

The awkward white boxes can be eliminated by setting the background colour of the project to the same shade as the OS’s tidal water. Project/Properties… takes you to the dialogue box. Drop down the menu for “Background colour”—Pick Color will give you a little paint-dropper pointer that you can use to copy the tidal water colour off the map by clicking on it. The result looks like this:

OS OpenData Terrain 50 NG tidal water blue + background
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

Starting to look pretty good, isn’t it? *

Adding a little shading will produce a more three-dimensional effect. Choose Raster/Analysis/Hillshade…. In the dialogue box, choose your topographic layer as the “Input layer”, and assign a filename to save the Hillshade result. The default settings work fine for everything else. Here’s what the hillshade layer looks like when it’s loaded on top of the topographic layer, but below the TidalWater tiles:

OS OpenData Terrain 50 NG hillshade
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

Very pretty, but it would be nice to see the topo colours, too. Double-click on the hillshade layer to bring up its Layer Properties dialogue, choose “Transparency”, and fiddle with the “Global opacity” slider. I find an opacity of 20% looks nice:

OS OpenData Terrain 50 NG topo + hillshade + water
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

There’s a problem, though. If you want to use these maps at large scale, you come up against the limited horizontal resolution of 50m imposed by the Ordnance Survey on its free products. Here’s what the mountain Blaven, on the Isle of Skye, looks like if we zoom in on the map above:

Blaven, Skye, tinted and shaded at 50m horizontal resolution
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

Click or tap to enlarge the above view, and it’s glaringly obvious that the 50m squares are showing up intrusively in the map tint and shading.

Since I’m not particularly concerned with the accuracy of the height data, only in using them to generate a nice tint and shade to demonstrate the general topography, I’m happy to run an interpolation to increase the horizontal resolution and produce a smoother effect. I do that from Raster/Projections/Warp (Reproject)…. Here’s the dialogue box completed and ready to start rendering:

QGIS Warp (Reproject) settings for 10m interpolation
Click to enlarge

I’m not interested in changing the Coordinate Reference System (CRS) of my map—it stays the same (OSGB36). All I’m doing is changing the horizontal resolution to 10m. A bit of experimentation has shown me that using the Cubic spline resampling method produces the most pleasant-looking results. Here’s what I end up with, after producing the 10m-resolution layer and repeating the production of the hillshade layer, as described above:

Blaven, Skye, tinted and shaded at 10m horizontal resolution
Click to enlarge
Contains OS OpenData © Crown copyright and database right 2018

That’s better! In my next post on this topic, I’ll add some contours and other features.


* The sea colour cover isn’t perfect—depending on your graphics card, you may see occasional seams around tile margins when the view is zoomed out. I have some solutions to this, which I may write about another time.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.