↑ OpenStreetmap Hacker's guide ↑↑ Net & Web  

Offline viewing (2) - rendering and viewing whole maps

Rendering a whole map -- Viewing the map -- Creating tiles

A different way – pre-render a whole map

The method described here was rather complex – render tiles, set up a tile server, adapt a viewer. It had the advantage that it is close to the most common OpenStreetmap setup, a map web-app. But it is also possible to render a whole map image (for each zoom level) that can then be viewed with a browser or image viewer.

The advantages of this approach are:

The disadvantages are:

Up to "Configuring Mapnik", the same has to be done as for the tile generation / tile server approach, only apache, mod_tile and renderd need not be installed and run. But instead of rendering tiles, we now render a larger map image. This requires a custom program, the price we have to pay for deviating more from the usual workflow. This program is easiest to write in Python 2, for which Mapnik bindings are available. (There are no bindings yet for Python 3, the current version of the language, so make sure to run python2 and associated programs if you have an up-to-date Linux distribution.) Of couse the PostgreSQL service has to be running, but renderd is not needed.

I wrote an example program that renders a rectangular map region given by two pairs of geographical latitude and longitude or an OpenStreetmap URL you can copy from your browser. (In the latter case it guesses the size of your browser window at 1600x1200, because it has no way to know that.) The other optional parameters are the output file and width / height. Mapnik infers the zoom level based on the output size, so you may have to experiment if you want a specific zoom level. Run it without arguments to read a usage message. There is a Python version and a C++ version &emdash; the latter saves you buiding the python bindings for Mapnik 3.x where they are not included in the main project any more.

Viewing a map image

Or: crash-testing image viewers

Using a standard image viewer or browser works up to a point. These programs assume that the image will fit into memory uncompressed and may crash if that is not true. This places a hard limit on system memory. But it also takes significant CPU power to decompress a large image. I have compared two viewers and two browsers with map images of three different sizes. display and gm display are the image viewers of ImageMagick and GraphicsMagick (its fork focused on code quality). Feh is a modern light-weight image viewer. links is a lightweight browser for which I have personal patches here; xombrero is a browser using the webkit engine. The results are:

Viewer Image type and size RAM usage [bytes per pixel] Time to first display [s]
display JPEG 3000x3875 24 1
display PNG 3000x3875 24 2
gm display JPEG 3000x3875 12 ≈ 0
gm display PNG 3000x3875 22 1
xombrero JPEG 3000x3875 16 2
xombrero PNG 3000x3875 16 2
links -g JPEG 3000x3875 5 1
links -g PNG 3000x3875 5 1
display JPEG 10000x12918 24 6 (+3)[1]
display PNG 10000x12918 24 11 (+2)[1]
gm display JPEG 10000x12918 12 2
gm display PNG 10000x12918 22 6
feh JPEG 10000x12918 4 1
feh PNG 10000x12918 4 1
xombrero JPEG 10000x12918 17 5
xombrero PNG 10000x12918 17 5
links -g JPEG 10000x12918 4 4
links -g PNG 10000x12918 4 4
gm display[2] JPEG 30000x38754 12 16
modified links -g[3] JPEG 30000x38754 4 24

[1] Additional time to display thumbnail for navigation in parentheses

[2] X server crash after scrolling beyond 231 pixel offset from top.

[3] See here for git branch with personal patches; see below for explanation.

(Test system details: Opteron 3380 8x2.6 GHz, 16 GB RAM, Xorg 1.17.2, NVidia driver 304.128. Compressed images were read from SSD, and results of first runs were discarded to exclude disk read time.)

Surprisingly (to me at least), the browsers are more efficient than the image viewers. The main exception is feh, which is fastest for images under 1 Gigapixel but whose libraries throw errors for larger ones. gm display is at least fast at displaying JPEG and uses less memory compared to PNG and other competitors. The browsers refuse to display the largest image. In the case of links, I have written a patch that will be available here. This involved not only removing restrictions in the browser engine, but also finding a workaround for crashes caused by the X server or NVidia driver, one of which can handle only 32-bit offsets. The same effect caused gm display to crash after scrolling down beyond the middle of the image.

So, in summary, viewing a rendered map as a single huge image works fairly well so long as it is below a Gigapixel, and the best viewer in that case is clearly feh. For larger images, gm display offers a startup speed advantage for JPEG if you have the RAM, otherwise the patched links is the ticket. Conversion to JPEG is recommended, both to save disk space and for higher speed of gm display.

Creating tiles from a large map

If you have rendered an overly large map image, you can still easily divide it up with GrahicsMagick:

gm convert <image> -crop <width>x<height> +adjoin tile%04d.jpg

<width>x<height> are the width and height of each tile. (If they do not divide the size of the original image, there will be smaller tiles at the right and bottom edge.) The +adjoin option causes multiple output images to be created, with the names generated according to the printf format string given as the output file name.

Licensed under the Creative Commons Attribution-Share Alike 4.0 Germany License

TOS / Impressum