These instructions are for a Linux system. I used them to create a Fuengirola Printable Streetmap that you can also download via the Documents: Main section.
Problem
You want to create your own city (or map of any other area) using open data and free software. This is great because it does not cost any money except a few cents for monochrome printing on a laser printer, and once you have set up the basic system and know the process, it can also be faster than buyin a map.
Solution
Here is my procedure:
- Get TileMill running with OSM Bright. Follow the “OSM Bright Ubuntu quickstart” instructions. But note that the simplest way of installing TileMill is via its Ubuntu packages! This is a complex tutorial that finally should leave you with a functional TileMill installation including the OpenStreetMap data of the area you’re interested in, all local on your hard drive. You will also have the “OSM Bright” template in use for rendering, which already produces quite nice results.
- Edit OSM Bright to your needs. For editing, compare the CartoCSS reference. I edited the colors to have more contrast and, for zoom level 18, made the line width of streets and the font size of street and building labels ca. 2.4 times as large. Else, the font will appear way too small when printing out resp. the map would become twice as large when printing it so that the font gets readable. The map will be exported in zoom level 18 (highest) with these instructions, so we do not need to care for the other levels so far. Contact me if you want the adapted CartoCSS files – not posting them here because it’s a real messy hack to just adapt them for one zoom level.
- Set center and extent of maps to export. This can be adapted during every export, but by setting this once and for all you avoid the need to zoom in from a full world view to your map before you can export. To set these in your TileMill project, go to the project settings via the top-right button, zoom in and left click to mark the map center and Shift+drag to mark the extent. Your map’s center has to be within that extent. (And probably, by selecting the zoom level range here to include only one zoom level, you can define what zoom level (so, what styles) are used during the export, but I did not test this yet and rather tried until I got an export in the zoom level i wished for.)
- Test-export your map to PDF with TileMill. This is done in the TileMill top-right menu with “Export -> PDF”. You then zoom in until you can select the area to be covered by your map, select that area with Shift+Drag, and set the “Size” field. For exporting, this field determines the level of detail in your map; it is not influenced by the zoom level in the left-hand view, which is here only to select the boundary. You will have to experiment a bit to find the proper numbers, as the values to enter here have no apparent meaning (probably the field is just taken over from the PNG export, where it denotes the size in pixels, so has to be interpreted with some – unknown – dpi setting). So check the PDF results after a test and if necessary adapt the numbers. Too high numbers are not a good idea either, as this will make the labels appear smaller in relation to objects, thus becoming unreadable in normal printed map sizes. We rather want the labels to be quite large for map printing, and also provided for that with the adaptations to the OSM Bright map template. Example: for a 30 000 residents city, ca. 5000 x 5000 was the right setting for me.
- Export your map to SVG. This is done in analogy to the PDF export, and with the numbers for “size” that you determined by the previous tests with PDF exports. The SVG output will be pretty huge, but this is normal here (example: 20 MiB SVG, compared to a 3 MiB PDF for the same area and size settings).
- Convert the SVG to EPS. In my case, I simply opened the SVG file in Inkscape and saved it as EPS (using PostScript level 2 output, and keeping text as text). The size decreased slightly (20 MiB SVG to 16 MiB EPS). However note that for much larger files (like a full-featured map of a city of 500 000), this will probably not work as Inkscape would need way more main memory than you have … . For that case, a different way has to be found.
- Posterize the EPS to PS. This is done super-fast with the command-line program poster, available from the Ubuntu 12.04 repositories. In my case, to tile the input file with whatever page size on a grid of 4×4 A4 pages of output, I used this command:
poster -v -m A4 -p 4x4A4 -c 15% infile.eps >outfile.ps
Note that the output file will be very large (in this case 256 MiB PS file from a 15.6 MiB EPS input file, but this is not an error and will be fixed by converting it to PDF in the next step. - Distill PS to PDF. This is done by simply calling this command, which decreased the file size from a 256 MiB PS file to a 6.5 MiB PDF file:
ps2pdf infile.ps - Print and glue. The posterized PDF file is a nice vector map and ready to be printed in color or black & white. You may use it as a book-type atlas, or glue the sheets together. For glueing, the manpage of poster has good instructions.
- Create an overview page (optional). This is quite simple: export the same area as SVG but with a way lower size setting (maybe 400) to be applicable for a single page. Then open it in Inkscape and add a grid for the distribution to pages that you chose for the poster command. Maybe write grid element numbers into the elements, like the “(x, y)” style used on poster-generated output. Then create another A4 PDF page from this, and prepend it to the map’s PDF using the pdftk command-line tool.
Discussion of the Solution
- Alternatives to OSM Bright? As of 2012-09, it seems that OSM Bright is clearly the best start to create a printable map with TileMill. There are just a few CartoCSS templates available at all for download: OSM Bright and Open Streets. Of these, OSM Bright is said to be better maintained, and also the Carto wiki only mentions OSM Bright as an example style [source].
- Why go via SVG? The reason why the actual / real export is done in SVG is, there is no good way known to me to posterize a PDF file in Linux. There is the pdfposter program (available in the Ubuntu repositories), but it produced a 170 MiB output file from a 3 MiB PDF input file, and worse, the PDF output file was corrupt and could not be read. (I tried with Adobe Reader 9 and Okular.) Maybe you could try pdfposter version 0.5 to see if the bug is fixed there; I used version 0.4.4 from the Ubuntu 12.04 archives.
- Do not use tilemill-reference-layer. You may install plugins offered in TileMill, but better do not install the tilemill-reference-layer plugin. It would create, for every new project you create after installing the plugin, a base layer with Mapbox street renderings that are loaded on demand as tiles from the Internet. This is essentially also OpenStreetMap data, but you do not have the option to adapt the rendering for better printing as done above with the OSM Bright template – because this layer is downloaded as pre-generated images and not rendered on your PC. However maybe, when indeed having the local map data and the OSM bright template additionally, the tilemill-reference-layer would be hidden anyway, and you still have the advantage that you can browse the rest of the world at street level without having to download and import it all. I did not check that in detail!
- No overlaps possible with “poster”. It seems not to be possible to create more than the default 5 mm overlap between tiles with the poster command line tool. Because when using the -c option (e.g. -c 15%), it will increase the border, but leave it empty. However, such overlap would be great to have for using the maps in atlas book form rather than as a glued-together large sheet.
- Still missing: street index. It makes of course no sense to create this manually, but to create the grid and the index, some custom software has to be used. So for now, you will often have to look up a destination on Google Maps, on a desktop computer or on your mobile phone, and then mark the location on your map. You then still have the map for walking through the city, which is way better for clarity and navigation than a tiny screen of some phone where you can never have details and the big scale at once.
- Anybody wants to create a real print-optimized CartoCSS template? So more than the double-sizing mods from above. I would like to, but have no time right now. Anybody else? 😉 Here are some ideas: Outlines for areas instead of fillings, and using textures instead of colors or gray shaded in areas. I once had 100 year old maps of my own area and marvelled at the ancient ingenuity of presenting everything in black and white print: they even did not have shades of gray or rasters to emulate such shades.
- What zoom level will be used? When exporting, TileMill auto-selects the styles of one zoom level for the export. This depends on the extent of the map’s area, and the “size” setting. However note that size settings allow “intermediate” sizes, between the normal levels. The 18 or so levels in traditional OpenStreetMap and Google Maps zooming mean: the first level shows the full world in 256 x 256 pixels, and that pixel width and height is doubled for every new level. By using the size measure, you can give the size in pixels for the mapped area yourself, and use any value. However, the levels’ CartoCSS styles are not relative to these arbitrary scales, as they are given in pixels and not real-world equivalent meters. So with “size” values between the default sizes for the levels, you will get map elements like labels and street width that will appear smaller compared to a map in the level’s default size.
- What are the default sizes for levels? This should be expressed as “pixels per degree”, so that when multiplying the longitude difference spanned by your map with this “pixels per degree” value, you get the width in pixels to enter into the “size” width field for a map in a desired zoom level that also has the map elements at the maximum possible size in this zoom level, just like they would appear with this map style on OpenStreetMap. (As TileMill always uses the Mercator projection, the pixels by degree value is the same for all longitudes, and also of course for all latitudes; no need to care about this.) The following table was generated from the premise, as used in TileMill / OSM, that zoom level 1 shows the full world in a 256×256 pixel image.
- Level 1: 28 px / 360° = 0.7111 px/degree
- Level 2: 29 px / 360° = 1.422 px/degree
- Level 3: 210 px / 360° = 2.844 px/degree
- Level 4: 211 px / 360° = 5.689 px/degree
- Level 5: 212 px / 360° = 11.378 px/degree
- Level 6: 213 px / 360° = 22.756 px/degree
- Level 7: 214 px / 360° = 45.511 px/degree
- Level 8: 215 px / 360° = 91.022 px/degree
- Level 9: 216 px / 360° = 182.044 px/degree
- Level 10: 217 px / 360° = 364.089 px/degree
- Level 11: 218 px / 360° = 728.178 px/degree
- Level 12: 219 px / 360° = 1456.356 px/degree
- Level 13: 220 px / 360° = 2912.711 px/degree
- Level 14: 221 px / 360° = 5825.422 px/degree
- Level 15: 222 px / 360° = 11650.844 px/degree
- Level 16: 223 px / 360° = 23301.689 px/degree
- Level 17: 224 px / 360° = 46603.378 px/degree
- Level 18: 225 px / 360° = 93206.756 px/degree
- Level 19: 226 px / 360° = 186413.511 px/degree
- Level 20: 227 px / 360° = 372827.022 px/degree
- Level 21: 228 px / 360° = 745654.044 px/degree
Alternatives
There are a lot of other solutions, but in my case here they all had some other shortcomings so that I went with the TileMill solution above, even though it’s far from the optimum as well. All the following solutions are referenced in the OpenStreetMap OSM on Paper wiki page, but interestingly the solution proposed here using TileMill is missing there.
- MapOSMatic. This is a completely awesome web service that produces maps exactly as intended here: as PDF, with overview page, detail pages, grid, street index. And (at least most of) the data is vector-oriented in the PDF, and the PDF has a small size. Only problem: They were down when I tried, having an outage for the last week … . But when they’re up and running again, definitely use them as it’s way simpler than the procedure below.
- MapOSMatic pre-generated maps. Several thousand user generated maps are available, but there is no map index of these maps and usually no useful description as of 2012-09, you won’t find the map you are looking for.
- OpenPaperMaps. A desktop application to create paper maps as PDFs, including grid and street index. Should be tried.
- Field Papers. This is really a neat one, with a super nice interface for map selection and distribution to pages. However the output is rasterized (not vector graphics) and as of 2012-09 there was no way to get a full-detail map in the black and white rendering style for monochrome printing: even when using a zoom level and page distribution that produced all the street names and details in their OSM color map style, the black and white style had some missing.
- osmbook. Nice approach and output (creating an atlas type book), but not yet too mature it seems …
- Maperitive. A powerful tool, but seemingly configured with config files only, so not to create your city map in half an hour or so …
- OSM Export Tab. The simplest solution, usable for simple situations as described in the linked wiki page.
- OSM-Atlas. It seems to be no longer in development since 2009. But probably one should try it out still, as it promises that it will create a PDF output file with overview map, detail map pages and street index automatically. But it’s unknown if the output is in vector or rasterized form.
- bigmap. This does not work any longer – it seems to be out of maintenance for several years. The generated Perl scripts still download and mount a big image, but it will consist only of QR codes since the OSM interface to tiles seems to have changed.
- StaticMap and staticMapLite. It seems that these can only create raster images of at most 1024 x 1024 pixels. Enough for embedding in a website, but not for a city’s street plan.
Leave a Reply