Packaged at last...
[pyrungps.git] / pyrungps / render_tiles.py
diff --git a/pyrungps/render_tiles.py b/pyrungps/render_tiles.py
new file mode 100755 (executable)
index 0000000..ea342e8
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+# coding: UTF-8
+
+import sqlite3
+import math
+from pprint import pprint
+
+def queue_render(db,filename,forced_max_zoom=None):
+
+  conn = sqlite3.connect(db)
+  conn.text_factory = str
+  cur = conn.cursor()
+        
+  cur.execute("select minlat,minlon,maxlat,maxlon from tracks where filename=?" , (filename,))
+  minlat,minlon,maxlat,maxlon=cur.fetchone()
+  queue_tiles(db,minlat,minlon,maxlat,maxlon,forced_max_zoom)
+
+def deg2num(lat_deg, lon_deg, zoom):
+  lat_rad = math.radians(lat_deg)
+  n = 2.0 ** zoom
+  xtile = int((lon_deg + 180.0) / 360.0 * n)
+  ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
+  return (xtile, ytile)
+            
+def queue_tiles(db,minlat,minlon,maxlat,maxlon,forced_max_zoom=None):
+
+  conn = sqlite3.connect(db)
+  
+  # определяем примерный стартовый зум
+
+  minzoom=8
+
+  if forced_max_zoom:
+    maxzoom=forced_max_zoom
+  else:
+    maxzoom=minzoom
+    while True:
+      minx,miny=deg2num(minlat,minlon,maxzoom)
+      maxx,maxy=deg2num(maxlat,maxlon,maxzoom)
+      
+      print(maxzoom,':',minx,'-',maxx,'/',miny,'-',maxy)
+      if (maxx-minx>16) or (maxy-miny>12) or (maxzoom==16):
+        break
+      else:
+        maxzoom=maxzoom+1   
+  
+  if maxzoom<minzoom:
+    minzoom=maxzoom
+  
+  ins = conn.cursor()
+  print(minlat,minlon,maxlat,maxlon,minzoom,maxzoom)
+  ins.execute('insert into render_queue(minlat,maxlat,minlon,maxlon,minzoom,maxzoom) values(?,?,?,?,?,?)',(minlat,maxlat,minlon,maxlon,minzoom,maxzoom))
+
+  conn.commit()        
+
+def process_queue(db,map,force=False,backend="renderd"):
+
+  from os import system
+
+  conn = sqlite3.connect(db)
+  cur = conn.cursor()
+  cur.execute('select id,minlat,maxlat,minlon,maxlon,minzoom,maxzoom from render_queue')
+  list=cur.fetchall()
+
+  for rec in list:
+  
+    id,minlat,maxlat,minlon,maxlon,minzoom,maxzoom=rec
+    
+    if backend == "tirex" or backend == "default":    
+
+      command = 'map='+map+ \
+        ' z='+str(minzoom)+'-'+str(maxzoom)+ \
+        ' lat='+str(minlat)+','+str(maxlat)+ \
+        ' lon='+str(minlon)+','+str(maxlon)
+
+      if force:
+        command = 'tirex-batch -n 0 --prio=50 '+command
+      else:
+        command = 'tirex-batch -n 0 --prio=50 '+command+' -f not-exists'  
+
+      print(command  )
+      
+      if system(command)==0:
+        dcur=conn.cursor()
+        dcur.execute('delete from render_queue where id=?',(id,))
+        conn.commit()
+
+    elif backend == "renderd":
+    
+      print(minlat,minlon,maxlat,maxlon)
+    
+      for zoom in range(minzoom,maxzoom+1):
+        minx,miny=deg2num(minlat,minlon,zoom)
+        maxx,maxy=deg2num(maxlat,maxlon,zoom)
+
+        if minx>maxx:
+          tx=minx
+          maxx=minx
+          minx=tx
+
+        if miny>maxy:
+          ty=miny
+          maxy=miny
+          miny=ty
+
+        print(zoom,minx,miny,maxx,maxy)
+
+        maps = map.split(',')
+        
+        for map_name in maps:
+
+          command = 'render_list -a -m '+map+ \
+                    ' -z '+str(zoom)+' -Z '+str(zoom)+ \
+                    ' -x '+str(minx)+' -X '+str(maxx)+ \
+                    ' -y '+str(miny)+' -Y '+str(maxy)
+          if force:
+            command = command+ ' --force'
+    
+          print(command  )
+      
+          if not system(command) == 0:
+            return
+
+      dcur=conn.cursor()
+      dcur.execute('delete from render_queue where id=?',(id,))
+      conn.commit()
+
+def main():
+
+  from optparse import OptionParser
+  
+  parser = OptionParser()
+  parser.add_option("-d", "--data", dest="directory",
+    help="Data directory", metavar="DIR")
+  parser.add_option("-m", "--map", dest="map",
+    help="Map name", metavar="MAP")
+  parser.add_option("-z", "--zoom", dest="zoom",
+    help="Maximal zoom (forced), used with coordinates pairs (minlat minlon maxlat maxlon) or filename in arguments", metavar="MAP")
+  parser.add_option("-f", "--force", dest="force", 
+    help="Force tile regeneration (on/off), default off")
+  parser.add_option("-r", "--renderer", dest="renderer", 
+    help="Rendering backend: tirex or renderd")
+  (options, args) = parser.parse_args()  
+
+  db=options.directory+'/gpx.db'
+  map=options.map  
+  zoom=options.zoom
+  if not zoom:
+    zoom=12
+  force=(options.force=='on')
+
+  if options.renderer:
+    renderer=options.renderer
+  else:
+    print("Using default rendering backend...")
+    renderer="default"
+
+  if len(args)==1:
+    filename,=args
+    print("Rendering file: "+filename+"\n")
+    queue_render(db,filename)
+  elif len(args)==4:
+    minlat,minlon,maxlat,maxlon=args
+    print("Rendering region "+minlat+'..'+maxlat+' / '+minlon+'..'+maxlon+"\n")
+    queue_tiles(db,float(minlat),float(minlon),float(maxlat),float(maxlon),int(zoom))
+
+  if map:
+    print("Processing map(s) "+map+"\n")
+    process_queue(db,map,force,renderer)
+  
+if __name__ == "__main__":
+
+  main()          
+  
\ No newline at end of file