+#!/usr/bin/env python
+
+try:
+ import mapnik2 as mapnik
+except:
+ import mapnik
+
+import sys, os
+
+from lxml import html,etree
+from optparse import OptionParser
+
+from pprint import pprint
+
+import pygpx
+
+# Set up projections
+# spherical mercator (most common target map projection of osm data imported with osm2pgsql)
+merc = mapnik.Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
+
+# long/lat in degrees, aka ESPG:4326 and "WGS 84"
+longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
+# can also be constructed as:
+#longlat = mapnik.Projection('+init=epsg:4326')
+
+# ensure minimum mapnik version
+if not hasattr(mapnik,'mapnik_version') and not mapnik.mapnik_version() >= 600:
+ raise SystemExit('This script requires Mapnik >=0.6.0)')
+
+
+def render_map(mapfile,map_uri,gpx_file,imgx,imgy):
+
+ xml = etree.parse(gpx_file)
+ gpx = pygpx.GPX()
+ gpx.ReadTree(xml)
+
+ bbox = gpx.bound_box()
+ pprint(bbox)
+ cx=(bbox[0][1]+bbox[1][1])/2
+ cy=(bbox[0][0]+bbox[1][0])/2
+ print cx,cy
+ w=(bbox[1][1]-bbox[0][1])*1.2
+ h=(bbox[1][0]-bbox[0][0])*1.2
+ print w,h
+ bounds = (cx-w/2,cy-h/2,cx+w/2,cy+h/2)
+ print bounds
+
+ m = mapnik.Map(imgx,imgy)
+ mapnik.load_map(m,mapfile)
+
+ m.background = mapnik.Color('rgb(255,255,255)')
+
+ # ensure the target map projection is mercator
+ m.srs = merc.params()
+
+ bbox = mapnik.Box2d(*bounds)
+
+ pprint(bbox)
+
+ transform = mapnik.ProjTransform(longlat,merc)
+ merc_bbox = transform.forward(bbox)
+ m.zoom_to_box(merc_bbox)
+
+ style = mapnik.Style()
+ rule = mapnik.Rule()
+
+ point_symbolizer = mapnik.MarkersSymbolizer()
+ point_symbolizer.allow_overlap = True
+ point_symbolizer.opacity = 0.8 # semi-transparent
+ rule.symbols.append(point_symbolizer)
+
+ style.rules.append(rule)
+ m.append_style('GPS_tracking_points', style)
+
+ layer = mapnik.Layer('GPS_tracking_points')
+ layer.datasource = mapnik.Ogr(file=gpx_file, layer='track_points')
+ layer.styles.append('GPS_tracking_points')
+ m.layers.append(layer)
+
+ im = mapnik.Image(imgx,imgy)
+ mapnik.render(m, im)
+ im.save(map_uri,'png')
+ sys.stdout.write('output image to %s!\n' % map_uri)
+
+
+def render_all(db,mapfile,imgx,imgy):
+
+ import sqlite3
+ from os.path import dirname
+
+ conn = sqlite3.connect(db)
+ cur = conn.cursor()
+ updcur = conn.cursor()
+
+ cur.execute ("select id,filename from tracks where preview_name is null")
+
+ list=cur.fetchall()
+
+ for rec in list:
+
+ id = rec[0]
+ filename = rec[1]
+ preview_name = dirname(filename) + '/' + str(id) + '.png'
+
+ print id,filename,preview_name
+
+ try:
+ render_map(mapfile,preview_name.encode('utf8'),filename,imgx,imgy)
+ updcur.execute("update tracks set preview_name=? where id=?", (preview_name,id))
+ conn.commit()
+ except:
+ raise
+
+
+def main():
+
+ parser = OptionParser()
+ parser.add_option("-m", "--map", dest="mapfile",
+ help="use map file", metavar="MAP")
+ parser.add_option("-o", "--output", dest="outfile",
+ help="output image to file", metavar="OUT")
+ parser.add_option("-g", "--gpx", dest="gpxfile",
+ help="track to render", metavar="GPX")
+ parser.add_option("-x", "--x-size", dest="x",
+ help="image width", metavar="X")
+ parser.add_option("-y", "--y-size", dest="y",
+ help="image height", metavar="Y")
+ parser.add_option("-d", "--db", dest="db",
+ help="render all not process files in database", metavar="DB")
+ (options, args) = parser.parse_args()
+
+ if options.mapfile:
+ mapfile = options.mapfile
+ else:
+ mapfile = "/etc/mapnik-osm-carto-data/veloroad-transparent.xml"
+
+ if options.outfile:
+ map_uri = options.outfile
+ else:
+ map_uri = "image.png"
+
+ if options.x:
+ imgx = int(options.x)
+ else:
+ imgx= 400
+ if options.y:
+ imgy = int(options.y)
+ else:
+ imgy= 400
+
+ if options.db:
+ render_all(options.db,mapfile,imgx,imgy)
+ else:
+ if options.gpxfile:
+ gpx_file = options.gpxfile
+ render_map(mapfile,map_uri,gpx_file,imgx,imgy)
+ else:
+ print "No input file"
+ exit(1)
+
+if __name__ == "__main__":
+
+ main()