From: Roman Bazalevskiy Date: Mon, 16 Apr 2018 11:03:06 +0000 (+0300) Subject: Генерация превью карты. X-Git-Url: https://git.rvb.name/pyrungps.git/commitdiff_plain/8031e085646c31a307fe8ec64bf8993991a302ce?ds=inline Генерация превью карты. --- diff --git a/generate_image.py b/generate_image.py new file mode 100644 index 0000000..a4deaac --- /dev/null +++ b/generate_image.py @@ -0,0 +1,163 @@ +#!/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() diff --git a/pyrungps.py b/pyrungps.py index db24972..8d13b8d 100644 --- a/pyrungps.py +++ b/pyrungps.py @@ -13,6 +13,8 @@ import pygpx import render_tiles +import generate_image + def get_page(uname,year,month): trainings = [] @@ -251,6 +253,8 @@ def main(): elif osmname: sync_osm(osmname,osmpwd,current_year,current_month,outdir,options.verbose,options.force) + generate_image.render_all(db,'/etc/mapnik-osm-carto-data/veloroad-transparent.xml',400,400) + if __name__ == "__main__": main()