I finish my last post about using Ordnance Survey OpenData in QGIS having produced this map of the area around Blaven, on the Isle of Skye:
It’s tinted for height, shaded and marked up with contours to emphasize landforms, and has features such as surface water, coastline, roads and buildings added.
Now it needs some labels. If you’ve been following along with the previous posts, you’ve already downloaded the relevant ESRI vector data for OS grid square NG. The relevant shape file is NG_NamedPlace.shp, which is sitting in the directory OS OpenMap Local (ESRI Shape File) NG/data. Add it to the map by going through the top menu bar in QGIS, Layer/Add Layer/Add Vector Layer….
When the shape file is first loaded, you’ll just see an array of dots marking named locations, but with no names, which is a little disappointing. The Ordnance Survey actually provides a NamedPlace.qml stylesheet which will do some basic formatting for you (I discussed the use of OS stylesheets in my previous post), but I think it’s more useful to build the formatting a step at a time on this occasion, to introduce some of the more complicated things you can do with QGIS.
So before we do anything else, we need to turn on the names. To see how to do this, double-click on the NamedPlace layer in the Layers window to bring up its Layer Properties dialogue window. At left, choose “Source Fields” to see a list of all the attributes associated with NamedPlace entities. It looks like this:
Checking the OS OpenMap – Local Product Guide (1.7MB pdf)* we can find out what these attribute names mean:
ID is a unique identifier we don’t need to worry about
DISTNAME is the distinctive name of the place
HTMLNAME repeats the distinctive name, but using html control characters to deliver any accented letters—you might need to use this to display Welsh place names properly
CLASSIFICA is the classification of the named place—the rather limited options are Populated Place, Landform, Woodland Or Forest, Hydrography or Landcover
FONTHEIGHT gives a recommendation (Small, Medium or Large) for the size of label to be used, according to the size of the named feature
ORIENTATIO is the orientation of the label, measured in degrees from the horizontal, to align it with a linear feature
FEATCODE is a feature code number—in the case of named places, it simply provides one of five numerical codes according to the feature’s classification, so adds no new information
So we can use either DISTNAME or HTMLNAME to label our features, and CLASSIFICA, FONTHEIGHT and ORIENTATIO to determine what the label looks like.
So now click on “Labels” at the left of the Layer Properties dialogue window. Choose Single Labels from the drop-down dialogue box, and choose DISTNAME in the “Label with” dialogue that now appears. The “Text Sample” box shows you the size your labels will appear on the map. Provided that is a reasonable size (it should be, the default is 10-point lettering), leave everything else alone at present, and click Apply at lower right to see the result.
My display comes up looking like this, with lots of question marks where special characters should be:
I can fix this by selecting “Source” at the left of the Layer Properties dialogue window, and then changing “Data source encoding” to System.
Now it would be nice to label the five different classifications in five different ways. To do this, go the “Labels” section of the Layer Properties dialogue, and switch the drop-down menu at top to Rule-based Labeling. It comes up with a single unnamed default rule, which is to label everything with DISTNAME. Double-click on this rule to bring up the Edit Rule dialogue.
I want to label hydrographic features in blue. I type Hydrography into the “Description” box, to give my rule a name, and then set the “Filter” rule like this:
“CLASSIFICA” = ‘Hydrography’
It’s important to type the double quotes around the attribute name, the single quotes around the value you want to filter on, and get all the spelling and capitalization correct. The Test button to the right is useful, because it lets you check that your filter is actually working—I pick up 1916 hydrographic features with this filter, so all is well. I need to type DISTNAME into the “Label with” field, and then the whole lower half of the dialogue lets me configure my text, with multiple additional options available by clicking the various headings at left (“Text”, “Formatting”, “Buffer”, and so on). It’s informative to just play with these settings to see what happens, but at present I’ve just changed the “Color” option to blue.
I click on OK at bottom right when I’ve finished setting the text formatting, and that returns me to the rule-based labelling, with the Hydrography rule in place. Now I can add another rule by clicking the green plus sign at bottom left, and filling in a new filter and new text formatting, always remembering to fill the “Label with” field, too. (When my labels don’t appear, it’s usually because I’ve become so preoccupied with setting the rules and formatting, I’ve forgotten to specify the attribute to use for the label.)
Working my way through all five classifications, I end up with a set of rules that look like this:
Within those rules, I’ve set woodland labels to green, landcover to brown, water to blue, and used a different typeface to distinguish populated places and landforms. Only the last three of those actually show up in the area of my Blaven map:
You can do exactly the same thing under “Symbology”, by selecting Ruled-based from the drop-down menu at the top of the window, and then stipulating different markers for different classifications. But for now, I’m just going to make all the markers disappear, by moving the “Opacity” slider to 0% in “Symbology”.
Now I’d like to use FONTHEIGHT to specify larger labels on larger features. Here’s the Edit Rule window for Landforms:
Although it seems to allow only one size of typeface for each rule, the slightly mysterious icons arrayed down the right-hand side of this dialogue window allow me to define more attribute rules to determine each font setting. I Click on the icon next to “Size” (ringed in red above), select Edit…, and I’m presented with the Expression String Builder dialogue window.
it looks a bit daunting, but if I click on “Fields and Values”, I’m presented with a familiar list of the names of all the attributes associated with NamedPlace. Clicking on FONTHEIGHT brings up a window that can be used to display the values of that attribute. A click on the all unique button shows me all the different values that FONTHEIGHT contains:
I’d like to enter a set of conditions using the CASE … WHEN … THEN format. If I know the syntax, I can just type the code into the left-hand window. But if I need guidance, I can click on the “Conditional” option, select “CASE”, and see the syntax spelled out for me in the right-hand window.
Here’s what the window looks like after I’ve entered the necessary code to associate ‘Large’, ‘Medium’ and ‘Small’ features with 30, 20 and 10-point labels, respectively. The text below the left window will let you know if you’ve used the wrong syntax.
(Again, be sure to use double quotes on the attribute names and single quotes on the values, and to get all the capitalization correct.)
When I click on OK, QGIS lets me know that I’ve set up rules for font size by placing a little yellow icon containing an ε next to the “Size” text box. Any value in that box will now be overruled by the conditions I’ve programmed. While I’m in the Edit Rule window, I also set up some conditions for “Style”, by entering the following code in the Expression String Builder:
CASE
WHEN “FONTHEIGHT”=’Large’ THEN ‘Bold’
ELSE ‘Regular’
END
This should make my largest Landform labels appear in bold.
Finally, I centre the label over the Landform by calling up “Placement” in Edit Rule, clicking on the “Offset from point” radio button, and selecting the central placement from the grid of options presented. Like this:
And here’s the result when I apply that set of rules to my map labels:
It’s a bit shouty and needs some fine tuning, but you get the idea. Then it’s just a matter of going through the other four classifications, and tweaking them to achieve the effect you want—I’ve used some very simple rules, but a little experimentation will show you the wealth of configuration options you have at your fingertips.
Here’s what it looks like with a little more formatting:
For Hydrography I’ve used the “Formatting” options to set “Wrap on character” to a space, so that those long Gaelic names are stacked one word above the other.
Finally, we need to use the ORIENTATIO attribute to align the text labelling linear features. Going back to the Edit Rule window we can enter a rule for “Rotation” (down near the bottom of the “Placement” window). In the Expression String Builder I just type “ORIENTATIO” to set the text rotation to equal the Ordnance Survey’s orientation attribute. It seems to have no effect on any feature except Landforms, so that’s the only rule worth changing. But when I make the change, I get a disappointing result:
You can see that the names of the two corries below Blaven are orientated almost crosswise to the features they label. The problem is that QGIS changed the expected direction of its rotation angles in the transition from QGIS 2 to QGIS 3, and the OS’s dataset hasn’t changed to match that, at time of writing. But it’s easily fixed, once you understand the problem. Just put a minus sign in front of “ORIENTATIO” in the Expression String Builder for “Rotation”, and order is restored:
That’s it for this time. In my next post on this topic, I’ll add in some data from sources outside the Ordnance Survey.
* Pages 52-57 provide information specific to the NamedPlace shape files.
or