In our last outing we put together a simple map. Having reached this point, the wise cartographer asks itself (when discussing cartographers I default to non-specific, non-human pronouns): “Am I done? Does this map suffice?”
Actually, the answer to this question should have been determined before we even started. One of my favorite professors used to say “Begin every project with a proposal. It’s the easiest and best way to know when you’re done.”
Anyway, if the map you’ve already made suits your purposes, congratulations. There is no reason for you to continue reading this, so by all means go back to whatever your favorite activity happens to be. I promise I won’t take it personally. If, however, you need a less simple map – or if you’re just like me (any map worth making is worth making pretty) – then please read on.
The plan here is to avail ourselves of some of QGIS’s advanced stylizing techniques to apply a variety of better looking symbology to the map. We will work in an order the reverse of that which we used last time (top down as opposed to bottom up) because this neatly follows a least-to-most complicated trajectory (with one exception).
Our general goal here is to construct a believable illusion of three dimensions. We aren’t going to try to achieve true 3D (or – more accurately – 2.5D), instead we’ll just use a few tricks to fool the eye. In the case of the structures layer we’ll just apply a simple drop shadow. Double-click on the ‘Structures’ layer to open the Properties window. Click on ‘Style’ in the left-hand sidebar if it isn’t highlighted already. Select a lighter color for the polygons (I used a grey: #707070), then check the ‘Draw effects’ box in the main area of the window. Click on the small star that resultantly turned yellow to open up the Draw effects window. Check the ‘Drop Shadow’ box on the left, change the Offset to 4 Map Units, change the Blur Radius to 1, and change the Blend Mode to Normal. Click ‘Okay’ a couple of times and watch the map redraw itself.
Roads come in various shapes and sizes. There are many different attributes of this layer we could use to symbolize our roads, but I think the wisest (read: easiest) way to go is to symbolize them by relative size. If you right-click on the Title of the ‘Roads’ layer (in the Layers Panel), a menu appears. Click on ‘Open Attribute’ and a window opens showing you the database that’s attached to the layer (most layers have them). Feel free to have a look around, and don’t worry if much of it looks like gibberish. The first column of the attribute table is called ‘Class’ and it is the one we will be using to symbolize the layer. The road classes are single-digit codes ranging from 1 to 6 (scroll down the MassGIS ‘Roads’ page for an explanation of the classes). The short explanation is the smaller numbers represent bigger roads and vice versa. We want to symbolize thicker lines for larger roads, so we’ll just have to tweak it a bit. Double-click on the ‘Roads’ layer to open the Properties window and change the line style from ‘Single Symbol’ to ‘Graduated’. Click on the ‘ε’ symbol to the far right of the ‘Column’ selector to open up the Expression Dialog window. Enter 10-“CLASS” for the expression and click ‘okay’. Change the Method to ‘Size’ and input a range of 4 to 16. Bump the Classes up to 6 and change the Mode to ‘Quantile (Equal Count)’. Click on the word ‘Change’ in the Symbol selector to open up the Symbol Selector window. Select your line, change the Pen Width to 0.46 Map Units and set the Cap Style to ‘Round’. Add another line, move it down in the hierarchy, then change its Pen Width to 0.86 Map Units, change its color to grey (#707070) and set its Cap Style to ‘Round’ as well. Check the Draw Effects box and click on the yellow star. Select ‘Outer Glow’, change the Spread to 3 Map Units, set the Transparency to 0 and change the color to the same grey as the line itself. Click ‘okay’ a couple of times and watch the roads redraw themselves.
Almost there. If you zoom in to get a closer look at the roads you will find that they look funny. This is because each road is made up of a series of small, straight lines connected together into longer lines that more accurately represent the less-than-straight reality of roads. Each of these small lines are drawing individually, which makes random grey lines cross over our roads in annoyingly large numbers. Don’t worry. We can fix this.
Reopen the Layer Properties window to get back to the layer Styles. Click on the button labeled ‘Advanced’ and select ‘Symbol Levels’ to open the Symbol Levels dialog. You will see two columns, Layer 0 and Layer 1. Everything in the Layer 0 column should say ‘0’ and everything in the Layer 1 column should say ‘1’. Check the ‘Enable Symbol Levels’ box. This tells QGIS to draw everything in Column 0 first, then go back and draw everything in Column 1. Click ‘okay’ twice and watch the roads fix themselves.
This layer is the exception. It just needs a little tweaking to make it look differently than lines painted on. Darken the color a bit (I used #007ac9) and add an Outer Glow: Spread of 2 Map Units, Blur Radius 3, 50% Transparency, color #46f3f7.
When maps are made in 2.5D they are most commonly “lit” from the upper left corner. I don’t know where this convention came from, but it is so strongly ingrained in us that when maps are “lit” from the bottom they look backwards to us (mountains look like valleys and valleys look like mountains). Knowing this, we can take advantage of it to make objects on our maps look ‘3D’, either in a positive or negative fashion. For our bodies of water we’ll go for a negative, making them appear to be cut into the ground surface rather than just sitting upon it. We do this by applying a highlight to the lower right-hand side and a shadow on the upper left-hand side.
But first we’ll have to specify which polygons we want show and which ones we’d like to hide. When we look at the MassGIS web page for the dataset we’re using, we see two separate columns in the attribute table that describe the water features. The first is called WETCODE, and it separates the features into 28 distinct categories. These categories are also conveniently detailed in another column of the attribute table (IT_VALDESC). For our purposes, though, this is far more detail than we need. Instead, we’ll use another, similar column called POLY_CODE, which serves much the same purpose but with only 11 categories. For our symbology we’ll want to show any features that delineate open water (we’ll include marshland in this group) and hide any other features. We’ll do this by using Rules Based styling.
Open the layer style and change it from Single Symbol to Rule-based. Double-click the existing rule (No label) to open the Rule properties dialog. Click on the Expression button (…) to the right of the ‘Filter’ bar to open the Expression String Builder. We will want to separate the open water features, which are those with POLY_CODEs of 1,2,6,9 and 10 (for this map we could skip 9 and 10, but we will include them in the name of thoroughness. Sloppy work is habit forming). To do this we will build the somewhat awkward expression POLY_CODE=1 OR POLY_CODE=2 OR POLY_CODE=6 OR POLY_CODE=9 OR POLY_CODE=10. Then we add two additional Simple Fill layers to our symbol, which we will style in order from the top down. The first we color with the same color we used for Streams (#007ac9), turn off the outline and add an Inner Glow: 20 Map Unit Spread and a darker color (#005b93). The next is the shadow layer, which we color with a darker shade (#005488), turn off the outline and offset negative 8 X and 8 Y Map Units. Finally we do the highlight layer, which we color lightly (#70b5d7) and offset positive 8 X and 8 Y Map Units. Finally, we make the entire layer semi-transparent (a setting of 25 works well).
For our contours we’re going to want two discrete thicknesses (or ‘weights’) of lines. A heavier line (called an Index) occurring periodically and a lighter line (called an Interval) occurring everywhere in between. Because our data will make it easy to do so, our Index lines will occur every 30 meters (if you look at the attribute table you will see a column called ELEV_M. This is the elevation of each line in meters, and the interval of the lines is 3 meters. So every 30 meters we get a line that’s a nice round figure – 60, 90, 120, etc). Since we have hills instead of mountains here in New England, 30 meter Indices are workable without being too crowded.
Before we start, though, we should make our lives easier by combining the two contour layers we’ve been using. Because we opened zipped files, we cannot edit either of the layers as they are, so we first must convert one of them to a shapefile (a format that has more than its share of issues. But it works so we’ll just run with it). Right-click on the Greenfield Contours file and select ‘Save As’. Choose the appropriate co-ordinate system, browse to the folder you want to save it in (creating said folder if necessary. I used Maps→Data→Greenfield→Vector→Contours and called the file Greater Greenfield Contours). Then zoom to the extent of the Montague Contours layer (by right-clicking on it) and select the entirety of it with the Select Features tool. Copy the features to the clipboard and return to the previous zoom using the Zoom Last button. Select the Greater Greenfield Contours layer, toggle editing on, paste the features onto it, then save the changes and toggle editing off. Then clean up by deselecting all features and removing both the Greenfield Contours and Montague Contours layers (by right-clicking them).
Now open the Layer Properties window for Greater Greenfield Contours. Change the style from Single Symbol to Rules-based. Double-click the undefined rule and label it ‘Index’. Open the Expression String Builder and build the expression: floor( “ELEV_M”/10)=( “ELEV_M”/10). Change the color of the line to #665640, set the Pen Width to 3 Map Units, then open the Draw Effects dialog. Give it an Inner Glow (2 Map Unit Spread, 3 Blur Radius, 0% Transparency, color #f8a05c) and an Outer Glow (4 Map Unit Spread, 3 Blur Radius, 0% Transparency, color also #f8a05c).
Add a second rule labeled ‘Interval’. For this one build the following very similar but significantly different expression: floor( “ELEV_M”/10)<>( “ELEV_M”/10). Change the color to #665640 and set the Pen Width to 1.25 Map Units. Give the line an Inner Glow (0.75 Map Unit Spread, 3 Blur Radius, 50% Transparency, color#f8a05c) and an Outer Glow (4 Map Unit Spread, 3 Blur Radius, 50% Transparency, color #f8a50c). “Okay” your way out of all the dialogs and watch the map redraw itself.
And there we are. We took our basic map and made it pretty. Nice work. It should be noted that not all of this symbology works well at all zoom levels. If you zoom into and out of various areas of the map you will see what I’m referring to. Creating symbology that works well for various zoom levels is its own art form and is beyond the scope of this post. My intent here is only to introduce you to a small sample of the vast styling power of QGIS. Please continue to explore further on your own. You won’t regret it.