Wikipedia:WikiProject U.S. Roads/Maps task force/Tutorial/SVG maps

From Wikipedia, the free encyclopedia

This subpage of the main maps task force tutorial discusses how to create a map using the raw SVG output that Quantum GIS (QGIS) generates through its "print composer" option. This tutorial was originally written by TwinsMetsFan (talk · contribs); any questions regarding this tutorial can be left on the talk page of this page or at User talk:TwinsMetsFan. This tutorial was written using QGIS v1.1.0 (officially listed as unstable at the time of writing); the majority of what follows can also be done with v1.0.2. As with the main tutorial, no contributor to this tutorial, including but not limited to User:TwinsMetsFan, takes responsibility if downloading QGIS results in adverse effects to your computer.

Some sections were updated in December 2014 by ScottDavis (talk · contribs) for QGIS version 2 after being guided by this tutorial page to make some other maps for Wikipedia.

Pre-tutorial[edit]

You will need QGIS v1.0.2 or later (v1.1.0 preferred), Inkscape v0.46 or later, and a text editor to complete this tutorial. Some experience with dealing with (X)HTML code is recommended, but not necessary.

I set the line widths on all of my layers in QGIS to a multiple of 0.15, where anything with a 1x stroke in the MTF standards is 0.15, anything with a 2x stroke is 0.3, etc. Your desired stroke width may vary, but I don't think it makes a difference in terms of the tutorial itself.

Generating the SVG[edit]

The QGIS print composer (Project -> Print composer) offers options to export to a range of image formats (including PNG), SVG or PDF. The export to PNG option is essentially identical to the File -> Save as image option, except that it allows for the creation of higher resolution images. Here's how to use the print composer:

  1. After you've made your map using steps 1 through 21 of the main tutorial, click Project -> Print Composer.
  2. Give the new composer a name.
  3. To the right of the white box that appears is a panel. Under the "Composition" tab in the "Paper and Quality" section, select "custom" for the paper size and enter the values width 290, height 172 to produce a map that meets the MTF standard for length to width ratio.
  4. Click the icon on the toolbar named "Add new map" (it looks like curled paper with a green Plus sign).
  5. Click on the white box and drag to create a rectangle of any size. Once you've made a rectangle, release the mouse button. A box containing your map will appear.
  6. Click the "Item Properties" tab in the panel to the right. In the panel, click "Set to map canvas extent" to set the extents (geographic coordinates) top match the main GIS window or manually type in the values you prefer.
  7. Change the Position and Size values to 0,0,290, 172 to make the map cover the entire virtual paper. Also, decheck the "frame" option if it is selected.
  8. Click the "Export as SVG" icon (a document with an orange symbol and an export sign in the corner). Pick a place to save the image (preferably one where you'll remember where you saved it), name your image and save.
  9. Exit Quantum GIS.

Pre-Inkscape tweaks[edit]

QGIS inserts a couple lines of code that makes it difficult to jump right into Inkscape and refine the SVG. Thus, we must first edit the SVG in a text editor. I use ConTEXT; however, something as simple as Notepad will work as long as it can edit XML files. At the moment, we are only interested in the first three lines, which should look something like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="294.64mm" height="174.752mm"
 viewBox="0 0 290 172"

Change the width to 290 (no mm) and the height to 172, and remove the third line entirely. Save the file and exit the text editor. We are now ready to edit our SVG in Inkscape.

Refining the SVG in Inkscape[edit]

If you're not concerned with file size or with adding labels, you could upload the map to Commons right now. However, this tutorial will cover every way to reduce the file size of the SVG and also cover adding labels. If you're not interested in one section, feel free to skip it as every tweak from this point out is purely optional.

Preliminary tweaks[edit]

What I do as soon as I open the SVG in Inkscape is I select everything, ungroup everything (hit Ctrl+Alt+G twice or until the bottom of the screen says "no groups to ungroup in selection") and convert everything to paths (Path -> Object to Path). All of the road lines are "polylines", which are purely coordinate-based and require something called a "matrix" in XML circles to preserve their shape. Paths, meanwhile, are made up of nodes that essentially function independently - when the path is moved or resized, no matrix is necessary.

Next, I resize everything so that when I specify sizes for labels and such, I don't have to deal with decimals (as right now the image is only 290x172 pixels, quite small). The quickest way I know of is to click the padlock next to the width entry box into the toolbar at the top (this will lock the aspect ratio in place), select "%" in the drop down box to the right of it (at first it says "px"), and specify a percentage (50 will halve the size, 200 will double it, and so on). I personally use 500. The tweaks below will assume that 500 was entered; to find the right sizes for other percentages, perform some calculations to determine what percentage you will need to enlarge or reduce the size by.

Lastly, open the XML editor in Inkscape (Edit -> XML Editor) and click on the top-most "<svg:path" item. A rectangle made of dotted lines should appear on the map. Next, close the XML Editor and open the document properties (File -> Document Properties). Click "fit page to selection"; this will alter the size of the SVG document's "paper" to be the right size for the map. After this is done, close the document properties window.

Trimming the excess[edit]

Due to the process that QGIS uses to generate the SVG, there's a lot of excess code that gets thrown into the SVG - which can more than triple the size of the SVG file. Here's how to trim off the excess:

Part I: in Inkscape[edit]

QGIS does not trim off the parts of the map layers that fall outside of the map area; instead, it simply includes all parts of the polygons and lines that enter the map area, even if no or small portions of such are actually within the area. This is due to a flaw with the Qt4 SVG code that QGIS uses to export a map to SVG. A bug ticket for this exists (see here); however, it has been open for years and the milestone for it has been pushed back many times, so it's anyone's guess as to whether or not it will ever be resolved. So, until it is we need to do it ourselves. The main things that need to be cut are water and urban areas (if used); to do so, follow these steps for each polygon that sticks out beyond the map area:

  1. Make a rectangle 1450x860 in width (NOTE: if you used a different scaling above, change these values to match the actual size of your map).
  2. Select the new rectangle and the polygon that you want to cut.
  3. Select Path -> Intersection.

Two other things you can do:

  1. Trim the lines that stick out past the map area by deleting any extra nodes; that is, all nodes outside the map area but the first node that is outside of the map area.
  2. Delete all of the polygons and lines that do not enter the map area.

Once everything is to your satisfaction, save the SVG (save as a plain SVG to reduce the file size even more) and close Inkscape.

Part II: in the code[edit]

It may be a good idea to make a copy of your SVG file before performing this step, so if you make a mistake you won't have to start from scratch.

The process that QGIS uses to generate the SVG adds a ton of unnecessary code, such as font specifications for the road lines, which obviously have no text. You can remove this excess code, as well as others by performing these find and replaces in a text editor:

replace "font-size:10px;font-style:normal;font-weight:400;" with ""
replace ";font-family:MS Shell Dlg 2" with ""
replace "fill:none;fill-opacity:1;fill-rule:evenodd;" with "fill:none;fill-rule:evenodd;"

Save and close the text editor when done.

Adding labels[edit]

This is the easiest of the tweaks listed here and probably the one that will be performed the most. In Inkscape, simply click on the map and type to add labels. I usually make the text about 8-13 "points" high (the number you see next to the font name in the toolbar when editing text); see one of my maps (such as File:NY Route 259 map.svg) for size and text color examples. For best shield results, download the shields from Commons and use the aforementioned width/height toolbar entry areas to resize the shields (making sure the padlock is still "locked"). I make the shields about 34 pixels high. It sounds small, but when there's ~20 shields on a map it looks good and it doesn't overwhelm the map itself.

Upload[edit]

When you're satisfied with your map, upload it to Commons.

That concludes this tutorial.