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 the ASCII grid and ESRI contours from 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 used to be readily accessible on the OS’s own website, but now (as reported in the Comments section below) they’re rather obscurely located on the GitHub developers’ site. Here are direct links to the two stylesheets required: Open Map – Local and Terrain50. Clicking on these links will download a couple of zipped files, and unzipping those will generate 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 is the file I’m after . 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.

6 thoughts on “Ordnance Survey OpenData In QGIS 3: Part 1”

  1. This series was quite interesting and a useful aid for my first dive into QGIS. I have found the seams between the sea tiles to be rather frustrating. I can get rid of them at a certain zoom level by fiddling with the style, but there doesn’t seem to be one value which is good at any zoom. Have you found a general solution to that issue?

    1. I got a partial solution by merging all the tidal water tiles I needed into one big tile. That got rid of all the seams except around the edges. I was working on a way of inverting a vector shoreline map so as to produce a huge sea tile with edges beyond the visible boundaries of any likely map, but ended up replacing my computer during that process–at which point I discovered my new machine didn’t seem to produce the tile edge artefacts, so moved on to other projects.
      I do however notice that the Project Properties/General dialogue now (in QGIS 3.4.15) contains an option of “Avoid artifacts when project is rendered as map tiles (degrades performance)” which I’m pretty sure wasn’t there when I was trying to fix the problem. Given that I now can’t produce the tile seam artefacts, I can’t test it. Have you tried?

  2. Very clear tutorial, thank you. I have a problem though – I can’t find “OS-OpenMap-Local-stylesheets_master” anywhere in GitHub, which is where the link takes me. Have OS moved it?

    1. The Ordnance Survey used to host these stylesheets on a page on their own website, with the URL https://www.ordnancesurvey.co.uk/resources/carto-design/cartographic-stylesheets.html, which is what my tutorial currently links to. Unfortunately, that URL now redirects to the fairly unhelpful GitHub page you’ve discovered—thanks for pointing that out.

      I’ll fix the tutorial in due course, but the relevant files are now downloadable from GitHub, rather than the OS.
      After a bit of poking around, here are direct links to the Open Map – Local and Terrain50 zipped stylesheets mentioned in the text. The internal file structure of these zip files looks the same as the ones originally downloadable from the OS, as described in the tutorial, so the rest of the tutorial should continue to work as before.

  3. I discovered how to find OS-OpenMap-Local-stylesheets-master. In GitHub, Go to

    “https://github.com/OrdnanceSurvey/OS-OpenMap-Local-stylesheets/blob/3ccf2fc64ee926bf79f7aaccbba998455196b998/Geopackage%20stylesheets/QGIS%20Stylesheets%20(QML)/Backdrop%20style/README.md”

    and click on the download option in the text.

    Then, to get the road styling to work, for my (new, 3.26.0) version of QGIS I had to change the categorised value from “classification” to “CLASSIFICA” to match the name of the column in the attribute table. you do this in the Layer Properties Symbology window. Hope this is useful to somebody, it’s taken me all day to work it out!

    1. I’ve now updated the text of my tutorial to reflect the new location of the files, and have embedded direct links to the two necessary stylesheets. Thanks for pointing out the problem.

Leave a Reply

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