pytopo package

Submodules

pytopo.DownloadTileQueue module

DownloadTileQueue: maintain a list of tiles being downloaded.

class pytopo.DownloadTileQueue.DownloadTileQueue

Bases: object

static download_job(url, localpath, callback)
peek()
pop()
push(url, path)

Push details for a new tile onto the queue if not already there.

static start_job(generator)

Start a job (a coroutine that yield generic tasks).

static threaded_task(function, *args, **kwargs)

Run function inside a thread, return the result.

pytopo.GenericMapCollection module

GenericMapCollection: a tiled map collection that can use any naming scheme, suitable for home-built tiled maps or maps adapted from other data sources.

class pytopo.GenericMapCollection.GenericMapCollection(_name, _location, _prefix, _ext, _left_long, _top_lat, _img_width, _img_height, _xscale, _yscale, _numdigits, _usedash, _latfirst)

Bases: pytopo.TiledMapCollection.TiledMapCollection

A GenericMapCollection is tiled, like the Topo collections, but uses a less specific naming scheme: prefix-nn-mm.ext, with or without the dashes.

coords_to_filename(longitude, latitude)

Given coordinates in decimal degrees, map to the closest filename

get_maplet(longitude, latitude)

Get the maplet containing the specified coordinates. Returns pixbuf, x_offset, y_offset, filename where offsets are pixels from top left of the specified coords and pixbuf or (less often) filename may be None.

get_next_maplet(fullpathname, dX, dY)

Given a maplet’s pathname, get the next or previous one. Does not currently work for jumps more than 1 in any direction. Returns pixbuf, newpath (either may be None).

get_top_left()

Get the coordinates of the top left corner of the map.

pytopo.MapCollection module

MapCollection: the base class for all pytopo map collections.

class pytopo.MapCollection.MapCollection(_name, _location)

Bases: object

A MapCollection is a set of maplet tiles on disk, combined with knowledge about the geographic coordinates and scale of those tiles so they can be drawn in a map window.

Child classes implementing MapCollection must define functions __init__, get_maplet, draw_map, and get_top_left. Get_top_left() is only for debugging, when you’re trying to figure out map coordinates and need a starting place. Should probably remove it.

draw_attribution(drawwin)

Draw attribution/copyright for the map tiles used in this collection.

draw_map(center_lon, center_lat, drawwin)

Draw a map in a window, centered around the specified coordinates. drawwin is a DrawWin object.

exists()

Does the collection have its map files in place?

get_maplet(longitude, latitude)

Returns pixbuf, x_offset, y_offset:

  • the pixbuf for the maplet image (or null)
  • the offset in pixels into the image for the given coordinates, from top left.
get_top_left()

A way to display some part of a map collection even if we’re fuzzy on the coordinates – get the coordinate of the first maplet and return as longitude, latitude.

lat2y(a)
y2lat(a)
zoom(amount, latitude=45)

Zoom by the given number of steps (positive to zoom in, negative to zoom out). Pass amount=0 to recalculate/redraw. Some map collections need to know latitude to determine scale.

zoom_to(newzoom, latitude=45)

Zoom to a specific zoom level and recalculate scales. Some map collections need to know latitude to determine scale.

zoom_to_bounds(minlon, minlat, maxlon, maxlat)

pytopo.MapUtils module

MapUtils: some useful utility functions useful for mapping classes.

class pytopo.MapUtils.MapUtils

Bases: object

MapUtils really just exists to contain a bunch of utility functions useful for mapping classes.

classmethod angle_to_quadrant(angle)
static bearing(lat1, lon1, lat2, lon2)

Bearing from wp1 to wp2.

classmethod coord2str_dd(lon, lat)

Convert a longitude, latitude pair into a pretty string, in decimal degrees

classmethod dec_deg2deg_min(coord)

Convert decimal degrees to degrees.minutes

classmethod dec_deg2deg_min_str(coord)

Convert decimal degrees to a human-readable degrees/minutes string

classmethod decdeg2dms(dd)

Convert decimal degrees to (degrees, minutes, seconds)

classmethod deg_min2dec_deg(coord)

Convert degrees.minutes to decimal degrees

classmethod distance_on_unit_sphere(lat1, long1, lat2, long2)

Linear distance between two points on a globe, in km. Divide by 1.609 to get miles.

classmethod haversine_distance(latitude_1, longitude_1, latitude_2, longitude_2, metric=False)

Haversine distance between two points. From https://github.com/tkrajina/gpxpy/blob/master/gpxpy/geo.py Implemented from http://www.movable-type.co.uk/scripts/latlong.html Returns distance in miles or meters.

classmethod int_trunc(num)

Truncate to an integer, but no .999999 stuff

classmethod ohstring(num, numdigits)

Return a zero-prefixed string of the given number of digits.

classmethod truncate2frac(num, frac)

Truncate to a multiple of the given fraction

pytopo.MapViewer module

MapViewer, the main pytopo application, which controls the MapWindow.

exception pytopo.MapViewer.ArgParseException

Bases: Exception

class pytopo.MapViewer.MapViewer

Bases: object

A class to hold the mechanics of running the pytopo program, plus some important variables including Collections and KnownSites.

classmethod Usage()
append_known_site(site)
create_initial_config()

Make an initial configuration file. If the user has a ~/.config, make ~/.config/pytopo/pytopo.sites.

classmethod error_out(errstr)

Print an error and exit cleanly.

exec_config_file()

Load the user’s .pytopo config file, found either in $HOME/.config/pytopo/ or $HOME/pytopo.

find_collection(collname)

Find a collection with the given name.

static get_version()
location_select(mapwin)
main(pytopo_args)

main execution routine for pytopo.

parse_args(mapwin, args)

Parse runtime arguments.

print_sites()

Print the list of known sites.

read_saved_sites()

Read previously saved (favorite) sites.

read_tracks()
save_sites()

Write any new KnownSites to file. Should only be called from graceful exit.

track_select(mapwin)
use_site(site, mapwin)
pytopo.MapViewer.main()
pytopo.MapViewer.parse_saved_site_line(line)

Parse lines like [ “Treasure Island, zoomed”, -122.221287, 37.493330, humanitarian, 13] (enclosing brackets are optional, as are double quotes for strings that don’t include commas). Clever way of avoiding needing the CSV module

pytopo.MapViewer.strip_bracketed(s, c)

If s begins and ends with c, strip off c. c can be a single character like ‘”’, or a pair of characters like ‘[]’. Also removes trailing commas.

pytopo.MapWindow module

MapWindow: pytopo’s GTK-based window for showing tiled maps.

class pytopo.MapWindow.MapWindow(_controller)

Bases: object

The pytopo UI: the map window.

This holds the GTK specific drawing code, and is intended to be extensible into other widget libraries. To that end, it needs to implement the following methods that are expected by the MapCollection classes:

win_width, win_height = get_size(), set_color(), draw_pixbuf(pixbuf, x_off, y_off, x, y, w, h) draw_rectangle(fill, x, y, width, height) draw_line(x, y, width, height)

(That list is very incomplete and needs to be updated, sorry.)

add_waypoint_by_mouse(widget)

Set the pin at the current mouse location

cancel_download(widget, data=None)
change_collection(widget, name)
click_draw(widget, event)

Handle mouse button presses if we’re in drawing mode

context_menu(event)

Create a context menu. This is called anew on every right-click.

contrasting_color(color)

Takes a gtk.gdk.Color (RGB values 0:65535) and converts it to a similar saturation and value but different hue

coords2xy(lon, lat, win_width, win_height, xscale=None, yscale=None)

Convert lon/lat to pixels.

download_area(widget)
drag_event(widget, event)

Move the map as the user drags.

draw_circle(fill, xc, yc, r, color=None)

Draw a circle, filled or not, centered at xc, yc with radius r.

draw_label(labelstring, x, y, color=None, dropshadow=True, font=None, offsets=None)

Draw a string at the specified point. offsets is an optional tuple specifying where the string will be drawn relative to the coordinates passed in; for instance, if offsets are (-1, -1) the string will be drawn with the bottom right edge at the given x, y.

draw_line(x, y, x2, y2, color=None)

Draw a line.

draw_map()

Redraw the map, centered at center_lon, center_lat.

draw_map_scale()
draw_overlays()
draw_pixbuf(pixbuf, x_off, y_off, x, y, w, h)

Draw the pixbuf at the given position and size, starting at the specified offset. If width and height are provided, assume the offset has already been subtracted.

draw_rect_between(fill, x1, y1, x2, y2, color=None)

Draw a rectangle. between two sets of ordinates, which are not necessarily in UL, LR order.

draw_rectangle(fill, x, y, w, h, color=None)

Draw a rectangle.

draw_string_scale(x, y, s, whichfont=None)

Draw a string at the specified location. If x or y is negative, we’ll draw from the right or bottom edge. If whichfont is “waypoint” it’ll be a little bigger and italic; if “attribution” even bigger and also italic; if it’s “select” it’ll be a lot bigger.

draw_trackpoint_segment(start, linecolor, linewidth=3, linestyle=None)

Draw a trackpoint segment, starting at the given index. Stop drawing if we reach another start string, and return the index of that string. Return None if we reach the end of the list.

draw_trackpoints()
draw_zoom_control()

Draw some large zoom controls in case we’re running on a tablet or phone and have no keyboard to zoom or move around.

expose3(_unused, _ctx)
expose_event(widget, event)

Handle exposes on the canvas.

find_nearest_trackpoint(x, y)

Find the nearet track, the nearest point on that track, and the nearest waypoint (if any) to a given x, y point. Any of the three can be None if nothing is sufficiently close. Coords x, y passed in are screen coordinates; if None, we’ll assume exact center, as if we’ve already set center_lat and center_lon after a mouse click.

@return: (nearest_track, Starting point of the nearest track
nearest_point, Index of nearest point on that track nearest_waypoint) Nearest waypoint
get_size()

Return the width and height of the canvas.

gpsd_callback(gpsd)
graceful_exit(extra=None)

Clean up the window and exit. The “extra” argument is so it can be calld from GTK callbacks.

hide_traildialog(d, responseid=None)
key_press_event(widget, event)

Handle any key press.

static load_image_from_file(filename)
longpress()
mod_track_by_mouse(remove=0)

Split or modify a track at the current mouse location. If remove is negative, remove all points in the current track before the current one. If positive, remove all points after. If remove is zero, split the track into two tracks.

mousepress(widget, event)

Handle mouse button presses

mouserelease(widget, event)

Handle button releases.

move_to(x, y, widget)
mylocations(widget)
mytracks(widget)
static nop(*args)

Do nothing.

on_size_allocate(_unused, allocation)
print_location(widget=None)
prompt(prompt, comment='', default='')

Prompt the user for a string, returning the string. Returns None if the user presses CANCEL instead (as opposed to an empty string, which means the user didn’t type anything but hit OK).

remove_after_mouse(widget)
remove_before_mouse(widget)
remove_trackpoint(widget)

Remove the point nearest the mouse from its track.

save_all_tracks_as(widget)

Prompt for a filename to save all tracks and waypoints.

save_area_tracks_as(widget)

Prompt for a filename to save all tracks and waypoints, then let the user drag out an area with the mouse and save all tracks that are completely within that area.

save_as()

Save a static map. Somewhat BROKEN, needs rewriting.

save_location(widget)

Save the pinned location.

save_tracks_as(widget, select_area=False)

Prompt for a filename to save all tracks and waypoints. Then either let the user drag out an area with the mouse and save all tracks that are completely within that area, or save all tracks we know about.

scroll_event(button, event)
select_track(trackindex)

Mark a track as active.

selection_window()

Show a window that lets the user choose a known starting point. Returns True if the user chose a valid site, otherwise False.

set_bg_color()

Change to the normal background color (usually black).

set_center_to_pin(widget)

Set the center at the current pin point

set_color(color)
set_pin_by_mouse(widget)

Set the pin at the current mouse location

show_traildialog(attrstr)

Show a dialog giving information about a selected track.

show_window(init_width, init_height)

Create the initial window.

split_track_by_mouse(widget)
toggle_show_waypoints(widget)
toggle_track_drawing(mode)
trackpoints_center()
undo(widget=None)
update_position_from_GPS()
was_click_in_gps(event_x, event_y)

Was the click over the blue GPS circle? True or False.

was_click_in_zoom(x, y)

Do the coordinates fall within the zoom in or out buttons?

xy2coords(x, y, xscale=None, yscale=None)

Convert pixels to longitude/latitude.

zoom(widget=None)

pytopo.OSMMapCollection module

OSMMapCollection: tiles downloaded from the OpenStreetMap project, one of its renderers, or any other source that uses a similar tile naming and zoom scheme.

class pytopo.OSMMapCollection.OSMMapCollection(_name, _location, _ext, _img_width, _img_height, _init_zoom, _download_url=None, maxzoom=19, reload_if_older=None, attribution=None)

Bases: pytopo.TiledMapCollection.TiledMapCollection

A collection of tiles downloaded from the OpenStreetMap project or one of its renderers, using the OSM naming scheme. See also http://tfischernet.wordpress.com/2009/05/04/drawing-gps-traces-on-map-tiles-from-openstreetmap/

@ivar: zoomlevel The current zoom level. @ivar: location Where on disk the map tiles reside. @ivar: download_url Where to download new tiles.

coords_to_filename(longitude, latitude)

Given coordinates in decimal degrees, map to the closest filename

deg2num(lat_deg, lon_deg, zoom=None)

Map coordinates to tile numbers and offsets. @return: (xtile, ytile, x_off, y_off)

draw_attribution(mapwin)

Draw attribution/copyright for the map tiles used in this collection.

draw_map(center_lon, center_lat, mapwin)

Draw maplets at the specified coordinates, to fill the mapwin.

fetch_or_download_maplet(path)

Return a pixbuf if the file is on disk, else download

get_maplet(longitude, latitude)

Fetch or queue download for the maplet containing the specified coordinates. Input coordinates are in decimal degrees. Returns pixbuf, x_offset, y_offset, filename where offsets are pixels from top left of the specified coords and pixbuf or (less often) filename may be None.

get_next_maplet(fullpathname, dX, dY)

Given a maplet’s pathname, get the next or previous one. May not work for jumps more than 1 in any direction. Returns pixbuf, newpath (either may be None).

get_next_maplet_name(fullpathname, dX, dY)

Starting from a maplet name, get the one a set distance away.

get_top_left()

Get the coordinates of the top left corner of the map.

num2deg(xtile, ytile)

Map OSM tile file numbers to coordinates. @return: (lat_deg, lon_deg)

url_from_path(path, zoomlevel=None)

URL we need to get the given tile file. URLs can be specified like “http://a.tile.openstreetmap.org”, and we will append /zoom/x/y.ext or they can be specified like “https://tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=X” and we will substitute {z}, {x} and {y}.

zoom(amount, latitude=45)

Zoom in or out by the specified amount, updating the scales appropriately. Call zoom(0) to update x/y scales without changing zoom level. Pass latitude for map collections (e.g. OSM) that cover large areas so scale will tend to vary with latitude.

zoom_to(newzoom, latitude=45)

Zoom to a specific zoom level, updating scales accordingly. Pass latitude for map collections (e.g. OSM) that cover large areas so scale will tend to vary with latitude.

pytopo.TiledMapCollection module

TiledMapCollection: a pytopo map collection that can download tiles.

A base class for more specific downloaders.

class pytopo.TiledMapCollection.TiledMapCollection(_name, _location, _tile_w, _tile_h)

Bases: pytopo.MapCollection.MapCollection

Code common to map collections that have raster tiles of a fixed size. TiledMapCollection classes must implement:

(pixbuf, x_off, y_off, pathname) = get_maplet(curlon, curlat) (pixbuf, newpath) = get_next_maplet(oldpath, dX, dY) deg2num(self, lat_deg, lon_deg, zoom=None) num2deg(self, xtile, ytile) deg2num
deg2num(lat_deg, lon_deg, zoom=None)
download_finished(path)

Callback when a tile finishes downloading. The path argument is either the local file path just downloaded, or an exception, e.g. IOError.

download_more()

Idle/timeout proc to download any pending tiles. Should always return False so it won’t get rescheduled. Eventually this should download in a separate thread.

draw_map(center_lon, center_lat, mapwin)

Draw maplets at the specified coordinates, to fill the mapwin.

draw_single_tile(path, mapwin)

After a new tile is downloaded, fetch its pixbuf and draw it in the right place for our currently displayed map.

draw_tile_at_position(pixbuf, mapwin, x, y, x_off, y_off)

Draw a single tile, perhaps after downloading it, at a specified location.

get_next_maplet(fullpathname, dX, dY)

Given a maplet’s pathname, get the next or previous one. May not work for jumps more than 1 in any direction. Returns pixbuf, newpath (either may be None).

get_next_maplet_name(fullpathname, dX, dY)

Starting from a maplet name, get the one a set distance away.

num2deg(xtile, ytile)
set_reload_tiles(p)

pytopo.TopoMapCollection module

TopoMapCollection: a pytopo map collection using Topo! commercial map datasets.

class pytopo.TopoMapCollection.Topo1MapCollection(_name, _location, _series, _tile_w, _tile_h)

Bases: pytopo.TopoMapCollection.TopoMapCollection

Topo1MapCollection: data from local-area Topo! packages,
the kind that have 7.5 minute and 15 minute varieties included.
(self, _name, _location, _series, tile_w, tile_h):
zoom(amount, latitude=45)

Zoom by the given number of steps (positive to zoom in, negative to zoom out). Pass amount=0 to recalculate/redraw. Some map collections need to know latitude to determine scale.

class pytopo.TopoMapCollection.Topo2MapCollection(_name, _location, _prefix, _tile_w, _tile_h)

Bases: pytopo.TopoMapCollection.TopoMapCollection

Topo2MapCollection: data from local-area Topo! packages that
have only the 7.5-minute series and use jpg instead of gif.
(collection_name, directory_path, file_prefix, tile_w, tile_h):
class pytopo.TopoMapCollection.TopoMapCollection(_name, _location, _series, _tile_w, _tile_h, _ser7prefix='012t', _ser15prefix='024t', _img_ext='.gif')

Bases: pytopo.TiledMapCollection.TiledMapCollection

TiledMapCollections using the Topo! map datasets. Filenames are named according to a fairly strict convention. Some variants can toggle between more than one scale (series).

coords_to_filename(longitude, latitude)

Given a pair of coordinates in deg.mmss, map to the containing filename, e.g. q37122c2/012t0501.gif.

dir_to_latlong(qdir)

Given a directory, figure out the corresponding coords.

get_maplet(longitude, latitude)

Get the maplet containing the specified coordinates. Returns pixbuf, x_offset, y_offset, filename where offsets are pixels from top left of the specified coords and pixbuf or (less often) filename may be None.

get_next_maplet(fullpathname, dX, dY)

Given a maplet’s pathname, get the next or previous one. Does not currently work for jumps more than 1 in any direction. Returns pixbuf, newpath (either may be None).

get_top_left()

Get the coordinates of the top left corner of the map.

set_series(_series)

Set the series to either 7.5 or 15 minutes.

pytopo.TrackPoints module

Parsing and handling of GPS track files in pytopo.

class pytopo.TrackPoints.GeoPoint(lat, lon, ele=None, name=False, timestamp=None, attrs=None)

Bases: object

A single track point or waypoint.

class pytopo.TrackPoints.TrackPoints

Bases: object

Parsing and handling of GPS track files. Supports GPX, KML, KMZ and GeoJSON. A TrackPoints object can include a track (points[]) and a list of waypoints (waypoints[]).

Each point in a track can be either a trackpoint or the beginning of a new track segment.

Beginnings of segments are represented by the name of the segment as a string or unicode, but use is_start() to test for that in case of future changes.

A trackpoint is an array where the first two elements are longitude and latitude, as floatings. Following longitude there may be an optional elevation, a float, or waypoint name, a string or unicode. Finally, a dictionary may be present, containing additional elements like time (timestamp).

GPX_point_coords(pointnode)

Parse a new trackpoint or waypoint from a GPX node. Returns lat (float), lon (float), ele (string or NOne), time (string or None), attrs (dict or None).

add_bogus_timestamps()

Add made-up timestamps to every track point.

attributes(trackindex)

Does the indicated track have attributes? Then return them.

get_DOM_text(node, childname=None)

Get the text out of a DOM node. Or, if childname is specified, get the text out of a child node with node name childname.

get_KML_coordinates(el)

Get the contents of the first <coordinates> triple inside the given element (which is inside a KML file). Inside a LineString, coordinate pairs or triples are separated by whitespace, which may include newlines. Return a list of triples [[lat, lon, ele], [lat, lon, ele] …] Not all KMLs have elevation, so use None in that case.

get_bounds()

Get bounds encompassing all contained tracks and waypoints.

get_segment_name(seg)

See if this trkseg or trk has a <name> child. If so, return the text out of it, else None.

static get_version()
handle_track_point(lat, lon, ele=None, timestamp=None, waypoint_name=False, attrs=None)

Add a new trackpoint or waypoint after some basic sanity checks. If waypoint_name, we assume this is a waypoint, otherwise assume it’s a track point. attrs is an optional dict of other attributes, like hdop or speed.

inside_box(pt, bb)

Is the point inside the given bounding box? Bounding box is (min_lon, min_lat, max_lon, max_lat).

is_attributes(point)

Is this point actually a set of attributes?

is_start(point)

Is this the start of a new track segment? If so, it’s a string (or unicode), the name of the track section.

classmethod is_track_file(filename)

Is the file a type PyTopo recognizes as a track file? But it’s more efficient to call read_track_file() wrapped in a try to avoid checking the extension twice.

classmethod lowerext(filename)
mappers = ((('gpx',), <function TrackPoints.read_track_file_GPX>), (('kml', 'kmz'), <function TrackPoints.read_track_file_KML>), (('json', 'geojson'), <function TrackPoints.read_track_file_GeoJSON>))
print_tracks()
read_track_file(filename)

Read a track file. Raise FileNotFoundError if the file doesn’t exist, RuntimeError if it’s not a track file, IOError or other exceptions as needed.

read_track_file_GPX(filename)

Read a GPX track file into the current TrackPoints object. Raise FileNotFoundError if the file doesn’t exist, RuntimeError if it’s not a track file, IOError or other exceptions as needed.

read_track_file_GeoJSON(filename)

Read a GeoJSON track file. Raise FileNotFoundError if the file doesn’t exist, RuntimeError if it’s not a track file, IOError or other exceptions as needed.

read_track_file_KML(filename)

Read a KML or KMZ track file. Just read Placemarks (which cover both paths and points); ignore all styles. Raise FileNotFoundError if the file doesn’t exist, RuntimeError if it’s not a track file, IOError or other exceptions as needed.

remove_after(pointidx)

Remove all points after index pointidx.

remove_before(pointidx)

Remove all points before index pointidx.

save_GPX(filename, boundingbox=None)

Save all known tracks and waypoints as a GPX file. XXX We don’t have valid <time> saved for these points.

save_GPX_in_region(start_lon, start_lat, end_lon, end_lat, filename)
save_for_undo()
undo()

pytopo.trackstats module

Statistics on track logs, such as total distance, average speed, and total climb.

pytopo.trackstats.main()
pytopo.trackstats.smooth(vals, halfwin, beta)

Kaiser window smoothing.

pytopo.trackstats.statistics(trackpoints, halfwin, beta, metric, startpt=0, onetrack=False)

Accumulate statistics like mileage and total climb. Return a dictionary of stats collected. If startpt is provided, start from a sub-track. If onetrack is True, only analyze one track segment.

pytopo.trackstats.tot_climb(arr)

Module contents

pytopo module: display tiled maps from a variety of sources, along with trackpoints, waypoints and other useful information.

Copyright 2005-2019 by Akkana Peck. Please use, distribute or modify this program under the terms of the GPL v2 or, at your option, a later GPL version. I’d appreciate hearing about it if you make any changes.