[PyTopo for Linux]

PyTopo: An Open-Source Tiled Map Viewer

PyTopo is an open source tiled map viewer, written in Python and GRK. It can download and cache tiles from OpenStreetMap or other map tile servers, or you can make your own local tiled maps or use commercial datasets.

PyTopo can also show tracks and waypoints in several different formats, can save favorite places, and has some rudimentary track editing ability.

Downloaded map tiles are cached forever (or until you remove them), so you can download tiles and then use PyTopo offline if, like me, you often travel to places where there's little or no internet access.

Why does PyTopo exist? I needed a local, offline mapping program that worked on Linux.

I like to travel to remote locations with no network access, and of course I want maps once I'm there. When I first started PyTopo, smartphones didn't exist yet, bug even in the smartphone age I often want a larger map than I can show on a phone screen. I use PyTopo at home for reviewing logs from hikes, and for exploring track and waypoint data for places I plan to go. (In the field, I use OsmAnd, an excellent open-source Android offline mapping app.)

Originally PyTopo was written to use data from National Geographic's commercial Topo! data CDs. Since then, it has expanded to use tiles from OpenStreetMap and any other tile server that uses the same naming conventions. (But not Google Maps, since Google's terms of service doesn't permit other programs to use their tiles.)


PyTopo is available on PyPI:

pip install pytopo

Then run pytopo.

PyTopo's source is hosted on Github if you want the latest and greatest.

You'll need PyGTK installed. On Linux, you can get it through your distro
on Windows, with pip install pygtk
Mac is tricky since it has dependencies: the easiest way to get PyGTK may be to install GIMP, which comes with PyGTK.

Using PyTopo

The first time you run pytopo, it will create a configuration file, typically ~/.config/pytopo/pytopo.sites (if it can't create that it will fall back to ~/.pytopo instead).

You might want to take a look at the file: this is where you can add additional map collections or sites you visit frequently. By default, pytopo will download OpenStreetMap tiles to ~/Maps. Of course, you can change that. See the PyTopo File Formats page for more details.

pytopo -p will print out a list of known sites. With the initial default configuration you'll just have a few cities like san-francisco, new-york, london, sydney; this is mostly to show you how to add your own points of interest.

Key bindings

Left, Right,
Up, Down
Scroll the map in the indicated direction.
+/=, - Zoom in or out.
s Save the current map to a file under $HOME/Topo
Space, m Jump back to the pinned location.
q Quit

Dragging and mousewheel move and scroll the map, as you'd expect. Right-clicking in the map pops up a menu of various other options.

Click on a track or waypoint to select it and see what's known about it.

Usage (commandline arguments)

Usage: pytopo
       pytopo trackfile
       pytopo known_site
       pytopo [-t trackfile] [-c collection] [-r] [site_name]
       pytopo [-t trackfile] start_lat start_long collection
       pytopo -p :     list known sites and tracks
       pytopo -r :     re-download all map tiles
       pytopo -h :     print this message

With no arguments, will display a list of known sites.

Track files may be in GPX, KML, KMZ or GeoJSON format, and may contain
track points and/or waypoints; multiple track files are allowed.

Use degrees.decimal_minutes format for coordinates.
Set up favorite site names in ~/.config/pytopo.sites,
favorite track logs in ~/Tracks


(Click to see larger image)
[San Francisco/OpenStreetMap screenshot] [White Rock DOE/OpenCycleMap screenshot] [Trails above Lexington reservoir/USGS screenshot]
San Francisco from the default setup (OpenStreetMap tiles). Trails and a waypoint in the DOE-owned lands near White Rock, NM, using OpenCycleMap tiles. Tacklogs and waypoints from a Garmin GPS above Lexington reservoir near Los Gatos, CA, using USGS/Topo! topographic maps.

Some Additional Features

Track and Waypoint Files

Pytopo can read tracks and waypoints from GPX, KML, KMZ, and GeoJSON files, and you can load multiple track files at once. It shows each track in a different color. You can toggle waypoint visibility with the right-click context menu (for when there are too many waypoints and they get in the way of reading the map).

You can select a track by clicking on it, split a track (right-click context menu again), and save a track as GPX after you've split it.


You can "Pin" a spot on the map and save it as a pinned location in your PyTopo configuration.

Switching Background Maps

Change Background Map in the context menu will list all the MapCollections you have defined, and you can switch between them interactively.

When you first run PyTopo, it will create a file called config/pytopo/pytopo.sites giving you one MapCollection, for the basic OpenStreetMap tile set, and a few major cities as Known Sites.

You'll probably want to add your own Known Sites, so you can start PyTopo by passing it names of sites near you. There are two ways to do that. You can right-click on any position on the map and choose "Pin this location", then "Save pin location" and give it a site name. Or if you're not afraid of editing files, you can edit pytopo.sites to add your own sites by their latitude or longitude.

The pytopo.sites file is also the place to add new MapCollections, and for this you do have to edit the file (see below).

Mileage and Elevation

If you need distance between two points, you can shift-click and PyTopo will print distance and bearing from there to the previous place you clicked. I know that's not an optimal user interface, but not many people seem to need that feature and I find it useful enough when I need it.

Sorry, PyTopo does not yet do anything useful with elevation or mileage on track logs. But in the meantime you may want to check out my standalone Ellie script; that's what I use.

Getting Map Data


There are lots of different types of MapCollection you can use. One useful one is to use map tiles from a different tile server. Most tile servers other than OpenStreetMap require you to sign up for an API key (which is usually free for light usage, but charges you for heavier usage). In that case your key will be encoded into the URL you set up in the MapCollection.

In the default pytopo.sites, there's an example of how to use the ThunderForest map server with an API key to retrieve OpenCycleMap tiles. It looks like this, specifying the name of the collection, the location on your local disk to cache the tiles, the size and type of the tiles, the default zoom level (your choice), the URL to use for downloading, the maximum zoom level (this is a function of the tile server), and an attribution string.

OSMMapCollection( "opencyclemap",         # collection name
                  "~/Maps/opencyclemap",  # where to cache
                  ".png", 256, 256,       # file type and size
                  13,                     # default zoom level
                  maxzoom=22,             # maximum zoom level
                  reload_if_older=90,     # reload if > 90 days
                  attribution="Maps © www.thunderforest.com, Data © www.osm.org/copyright"),

You can use the same syntax for many different tile servers to get a variety of different background map tile styles. ThunderForest has several nice styles besides OpenCycleMap: you'll see their list if you sign up for an API key. You can set up as many MapCollections as you want, either different styles from the same server or from different servers.

I don't currently know of a tile server that can serve satellite images, even with an API key. MapQuest used to offer this service but no longer does. Please tell me if you know of an alternate server. Note that the Google Maps terms of service do not allow using their tiles with non-Google mapping apps, so Google isn't an option.

Download Area

Download Area is intended to make it easy to download a collection of tiles at different zoom levels for a specified area, so you can have the tiles ready when you travel and will be offline. In practice, it doesn't work as well as intended, partly because most map tile servers will throttle connections that request too many tiles, so it takes forever to download an area. I stopped using it and therefore it isn't very well maintained.

Commercial Map Data

Aside from OpenStreetMap tile srvers, pytopo can use local map data on disk or CD; for instance, from the old Topo! local area and specific park map packages sold in camping/hiking stores, sometimes under the aegis of National Geographic.

For Topo! CD datasets, use a Topo1MapCollection for regions or a Topo2MapCollection for the park map sets:

Topo1MapCollection( "deathvalley", "~/Maps/deathvalley", 7.5, 266, 328 ),
Topo2MapCollection( "kingscanyon", "~/Maps/kingscyn", "topo", 410, 256 ),

Caution: the Topo! Back Roads Explorer and the statewide explorer collections are not in this friendly tiled format. They use large data files in a proprietary ".tpq" format. Tom Trebisky has analyzed the format and has written an extractor, and he also has a C GTK viewer for this format. I have not tried to integrate support into PyTopo; there are enough good online sources of maps now that I haven't seen the need to buy any more Topo! datasets myself.

Making Your Own Map Collections

For some areas, you can download USGS topo maps free. For instance, for California you can get maps in TIFF format from the California Spatial Information Library. You also may need to use specialized maps, such as geologic or land-use maps.

To use this sort of map, you have to split the large map into tiles. One way is to use ImageMagick, with a command like

convert in-map.jpg -rotate 90 -crop 300x300 -repage +0+0 out-map%02d.jpg

Note: previously I included -trim as part of that line, and a lot of pages you'll find googling for image splitting will tell you to use -trim. Don't: it will give you maps of inconsistent sizes, and pytopo will have no way to tell where the origin of the map should be.

Maps downloaded as PDF (such as USGS geologic maps) might work in imagemagick, but if not, try converting them to a raster format before splitting, using a program like GIMP or a command like

gs -sDEVICE=jpeg -r300 -sOutputFile=output-map.jpg input-map.pdf

API Documentation

If you want to contribute to PyTopo, or use the code for something else, you'll probably want to know more about the classes it uses, in the PyTopo API Documentation. (This is generated with epydoc --no-frames pytopo and is not guaranteed to be up to date.)

Non-interactive mapping scripts

I wrote some older commandline helper scripts, but honestly, I don't use them myself and don't vouch for them. I list them here merely on the chance that someone might find one of them a useful building block:

Is it Only For Linux?

PyTopo should run fine on any system which has Python, gtk, gdk-pixbuf, and PyGTK. I've tried to make the code as portable as I can, but I've only tested it on Linux. If it doesn't work for you, please let me know.

Bugs / Wishlist

Ellie: Plot GPS elevation profiles
More of Akkana's Software
Shallow Sky Home
mail Akkana