I have ve always loved maps. I guess it goes well with liking drawing and maths,
there’s a deep connection (the pun is
intended) between the
subjects. As a map lover, when we decided to relocate to a somewhat more
countryside town, I wanted better-looking maps to wander around the area. I
checked government-issued maps, but they were either too large (scale 1:25000)
or didn’t show the area I was interested (for the 1:10000 maps.) Thus I did what
any other nerd would do: roll my own map as I wanted it.
The end result looks like this (downscaled to 20%)
The real map is 1.4 × 1.2 metres
Getting the data
My first idea was to follow the steps of Dominik
Schwarz in his quest for
printing a huge map of the world, and harvest images from Google Maps and get
away with it. But one of the fundamental parts of my map was supposed to be
having all walking routes visible and available. Google Maps won’t show that, or
at least not everything. Specially among vines or forests. What’s the point of
living close to the Pantà de
Foix (the Foix Dam) and not
being able to walk there?
Hence, I turned to our trusty government, and in particular to the Catalan
Cartographic and Geologic
Institute (from now on the ICC,
which is the Catalan acronym.) They have a powerful online map application, with
good quality satellite imagery, elevation data, toponymy… All is available
online. And a free download. You only need to register, and seem to be limited
to one download at a time. No big issue, although I needed to get 16 satellite
There is a huge amount of data available for download. Since my knowledge of
technical map stuff ended at knowing that the technical term for what I wanted
to do is GIS , I
wasn’t really sure what files I needed and what I could do with them on a Mac
without having to pay for a dedicated app.
The first step was finding a free app that could “do maps.” After some Googling
it was pretty clear it had to be QGIS (formerly
known as Quantum GIS) which is free, open-source and available cross-platform.
It was quite straightforward to install on Mac, just needing some extra
libraries to work with the satellite image files I was using. Once I had it, the
real “nightmare” started, where I had to decide what kind of files I needed and
what they were good for. This is where ICC helped, since they have documentation
for all their file types, not only explaining what they have but also what they
are useful for.
For a starter I downloaded all satellite imagery with a scale of 1:2500,
generated on 2014. Recent enough. This was the easy one:
Download each file
In QGIS, Layer→AddLayer→Add Raster Layer (or Shift-Cmd-R)
Since the files are already geolocated data (the format is SID, which is why I
needed a special plugin to handle it) in just a few minutes I had a satellite
view of the area, automatically placed and multi-scale. Not bad for a few
minutes of downloading and goofing around.
Then the real work started: I wanted street names, road names and features. How?
I’m pretty sure there are many ways, but the one I found most straightforward
Download Topography-base maps, with a scale of 1:2500 in SHP (Shapefile)
In QGIS, Layer→Add Layer→Add Vector Layer (or Shift-Cmd-V)
Select full folder, Arc/Info binary format and browse to it
Select the files you really want
ICC provides a lot of files for each map tile at that resolution. Lots of stuff
I didn’t really want. I chose only toponymy, elevation lines, hydrography and
I needed toponymy layers to set labels to features
Elevation looks cool (even if I disabled it for the final generated
With hydrography I could change the colour from the satellite imagery to a
more bluish tone in water areas (since the Foix dam is quite greenish)
Roads was the main reason I was doing this
Adding some text
Once I had everything in place I wondered: Where are the labels?
Double-click a toponymy layer
Labels→Label this layer with…
Here some of the huge power of QGIS started to appear. Most “variables” in the
map can be controlled via either fields in the data layer OR functions applied
to these fields. So, I could easily label by a data column, like TEXT_TOP
(which had the common name of the feature, like Pantà de Foix.) But I also
could set the size of the font to the one defined in the datafile. And I could
even choose the font according to the feature type (or in my case, the font
defined in the data file: the data provided by the ICC had font size and font
family for the features) with a function.
CASEWHEN"FONTNAME"LIKE'Times New Roman'THEN'Georgia'WHEN"FONTNAME"LIKE'Arial'THEN'Futura'WHEN"FONTNAME"LIKE'Arial Narrow'THEN'Futura'WHEN"FONTNAME"LIKE'Courier New'THEN'Inconsolata'END
The language seems to be QGIS specific, but has SQL-like LIKE. Single quotes
denote strings, double quotes denote fields, just like in SQL. Important to
remember, since it’s very easy to mix one with the other without realising. I
set all labels to show, even colliding labels. I didn’t want to miss a castle or
church because it was too close to a large street. I’d rather have overlapping
labels in this case.
Then I decided I wanted something more: I wanted icons to show what each feature
was. Icons like what you have in a normal map, where churches are indicated by a
cross and castles by a tower. The layer I was working with (the toponymy layer)
only had type codes for its features, so I couldn’t really tell what a 23 was.
Church? Castle? Farm?
To do this, I needed to download an auxiliary file (which the ICC already told
me about when I clicked ShapeFile as type of download) having the list of code
together with human-readable definitions. It is loaded as a single-file
ShapeFile layer, but has no “visible data.” Instead you need some magic.
Open a toponymy layer
Add a join layer with codis_topo (the source, in this case the layer I
just added) and selecting as join field the type code (in this case,
I disabled caching and added a custom name to the newly created column, the
With this at least I’d know, since the type was now human-readable. I still
didn’t know how to add icons, but I could edit the name and add a letter to
denote what it is (or I could even add some text.) The labelling function is
This, basically adds a weird symbol to the text, so, for instance, bridges have
a π symbol in front. Not great, but I actually printed it like this for a
starter and it looks pretty decent. Here you can see a zoom in and the general
In the zoom you can see the glyphs for a fountain (Font d’Horta and Font de Mas Carlús), a church (Sant Pere) an aqueduct (de les Aigües de Vilanova i la Geltrú) and a bridge (de la font d’Horta.) This was nice but non-optimal. I wanted symbols! So, how do you get symbols if you have a toponymy layer with lines, not feature points?
First, duplicate the layers holding the labels. It can be done without
duplicating, but it introduces a layer of complication for the human… So, if
your computer doesn’t mind the extra layers, it is easier for you as human to
have a separate layer for the labels and a layer for the icons.
Once you have duplicated the layer, change its style to rule-based, and add
marks following rules with the add sign. For instance, this is the rule I use
for Castell (castle):
NOTE: if you are using only one condition, for rule-based markers you can just keep it at
since it will just return 0 or 1 as needed. You’ll only need CASE when you have
several types going to the same marker. Since I just copy-pasted most of my code
I didn’t mind the extra cruft. Thanks to Nathan
Woodrow, one of QGIS' developers for pointing it
out on twitter.
To add this as image you need to select Marker, then SVG marker. I found
very nice SVG icons here, so I use this opportunity
as credit (since the printed map is just for my personal use.) And indeed, you
need to add as many rules as icons you have. That’s life. A GIS professional
probably knows other ways, I’m just a newbie. Once you have all the rules you
want, you can copy-paste them in all the layers. Actually, I think all this map
business would have been easier merging all vector layers before doing anything
else, but since I didn’t do it from the beginning it was hard to do it now. You
can find how to merge vector layers in this StackOverflow
After adding markers you’ll need to tweak them. I did one part in SVG (adding
stroke to the shapes and changing colours directy in the file so I didn’t need
to bother in QGIS) and some others relating to placement (middle point and then
changing size and baseline of the icon.) I also did some changes editing the
file directly in Emacs, since QGIS files are just XML and replacing is much
faster without clicking anything, once you know how the fields are named. The
end result? Here you can see the same area as above with icons.
Nice, don’t you think?
So, how do you print it?
This is actually very very easy. To print you need a New print composer from
the Project menu. This is a set of rules to print some map. So, you choose the
paper size and then add pieces to the layout. The basics are a map, a scale and
some text, or at least this is the bare minimum I wanted.
Once you have the map area you can change scale, drag around and change many
things, it’s awesome. I decided to use 1:10000 since fitting the whole map in
the map area I chose was 1:9556 and I’d rather have a round number and lose some
map around the borders. Ready to export to PDF and bring to a printing place.
You can also generate a JPG file, but beware of trying to open a 176 Mb with an
iPad (even if it is an Air.) It won’t zoom. On the other hand, for my Mac it was
much easier to open and zoom/navigate a huge JPG rather than a huge PDF file.
Also keep in mind large maps take a long time to export: if you are making tests
disable as many layers as you can really manage.
Since I wanted a portable version of the map to have on my iPad Air, I decided to split it using ImageMagick in 9 tiles I could easily zoom in any app. IM has the nice “crop” feature that can generate tiles, like:
The problem is that this takes way, way longer than expected, because the image
is too big. The fastest way is instead to use the stream command to generate
raw RGB data and convert that to JPG. So, repeating 9 times stuff like:
Since I only needed to do it this time I didn’t bother to code it as a bash for
loop or anything. Whereas convert was taking more than 12 hours to do
anything, stream took 3 minutes, counting the time I needed to compute the pixel
shifts and the conversions. And probably even the time it took me to create a
index.html with the pieces to zoom.
What’s the takeaway of this post? Doing maps is fun, and using
QGIS is not that hard as it may seem. And yes, I
have an awesome big map now.