2d81f7736bcbd68affecb637b20b79d46ba0e611
[pyrungps.git] / render_tiles.py
1 #!/usr/bin/env python
2 # coding: UTF-8
3
4 import sqlite3
5 import math
6 from pprint import pprint
7
8 def queue_render(db,filename,forced_max_zoom=None):
9
10   conn = sqlite3.connect(db)
11   cur = conn.cursor()
12         
13   cur.execute("select minlat,minlon,maxlat,maxlon from tracks where filename=?" , (filename.decode('UTF-8'),))
14   minlat,minlon,maxlat,maxlon=cur.fetchone()
15   queue_tiles(db,minlat,minlon,maxlat,maxlon,forced_max_zoom)
16
17 def deg2num(lat_deg, lon_deg, zoom):
18   lat_rad = math.radians(lat_deg)
19   n = 2.0 ** zoom
20   xtile = int((lon_deg + 180.0) / 360.0 * n)
21   ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
22   return (xtile, ytile)
23             
24 def queue_tiles(db,minlat,minlon,maxlat,maxlon,forced_max_zoom=None):
25
26   conn = sqlite3.connect(db)
27   
28   # определяем примерный стартовый зум
29
30   minzoom=8
31
32   if forced_max_zoom:
33     maxzoom=forced_max_zoom
34   else:
35     maxzoom=minzoom
36     while True:
37       minx,miny=deg2num(minlat,minlon,maxzoom)
38       maxx,maxy=deg2num(maxlat,maxlon,maxzoom)
39       
40       print maxzoom,':',minx,'-',maxx,'/',miny,'-',maxy
41       if (maxx-minx>16) or (maxy-miny>12) or (maxzoom==16):
42         break
43       else:
44         maxzoom=maxzoom+1   
45   
46   if maxzoom<minzoom:
47     minzoom=maxzoom
48   
49   ins = conn.cursor()
50   print minlat,minlon,maxlat,maxlon,minzoom,maxzoom
51   ins.execute('insert into render_queue(minlat,maxlat,minlon,maxlon,minzoom,maxzoom) values(?,?,?,?,?,?)',(minlat,maxlat,minlon,maxlon,minzoom,maxzoom))
52
53   conn.commit()        
54
55 def process_queue(db,map,force=False,backend="renderd"):
56
57   from os import system
58
59   conn = sqlite3.connect(db)
60   cur = conn.cursor()
61   cur.execute('select id,minlat,maxlat,minlon,maxlon,minzoom,maxzoom from render_queue')
62   list=cur.fetchall()
63
64   for rec in list:
65   
66     id,minlat,maxlat,minlon,maxlon,minzoom,maxzoom=rec
67     
68     if backend == "tirex" or backend == "default":    
69
70       command = 'map='+map+ \
71         ' z='+str(minzoom)+'-'+str(maxzoom)+ \
72         ' lat='+str(minlat)+','+str(maxlat)+ \
73         ' lon='+str(minlon)+','+str(maxlon)
74
75       if force:
76         command = 'tirex-batch -n 0 --prio=50 '+command
77       else:
78         command = 'tirex-batch -n 0 --prio=50 '+command+' -f not-exists'  
79
80       print command  
81       
82       if system(command)==0:
83         dcur=conn.cursor()
84         dcur.execute('delete from render_queue where id=?',(id,))
85         conn.commit()
86
87     elif backend == "renderd":
88     
89       print minlat,minlon,maxlat,maxlon
90     
91       for zoom in range(minzoom,maxzoom+1):
92         minx,miny=deg2num(minlat,minlon,zoom)
93         maxx,maxy=deg2num(maxlat,maxlon,zoom)
94
95         if minx>maxx:
96           tx=minx
97           maxx=minx
98           minx=tx
99
100         if miny>maxy:
101           ty=miny
102           maxy=miny
103           miny=ty
104
105         print zoom,minx,miny,maxx,maxy
106
107         maps = map.split(',')
108         
109         for map_name in maps:
110
111           command = 'render_list -a -m '+map+ \
112                     ' -z '+str(zoom)+' -Z '+str(zoom)+ \
113                     ' -x '+str(minx)+' -X '+str(maxx)+ \
114                     ' -y '+str(miny)+' -Y '+str(maxy)
115           if force:
116             command = command+ ' --force'
117     
118           print command  
119       
120           if system(command)<>0:
121             return
122
123       dcur=conn.cursor()
124       dcur.execute('delete from render_queue where id=?',(id,))
125       conn.commit()
126
127 def main():
128
129   from optparse import OptionParser
130   
131   parser = OptionParser()
132   parser.add_option("-d", "--data", dest="directory",
133     help="Data directory", metavar="DIR")
134   parser.add_option("-m", "--map", dest="map",
135     help="Map name", metavar="MAP")
136   parser.add_option("-z", "--zoom", dest="zoom",
137     help="Maximal zoom (forced), used with coordinates pairs (minlat minlon maxlat maxlon) or filename in arguments", metavar="MAP")
138   parser.add_option("-f", "--force", dest="force", 
139     help="Force tile regeneration (on/off), default off")
140   parser.add_option("-r", "--renderer", dest="renderer", 
141     help="Rendering backend: tirex or renderd")
142   (options, args) = parser.parse_args()  
143
144   db=options.directory+'/gpx.db'
145   map=options.map  
146   zoom=options.zoom
147   if not zoom:
148     zoom=12
149   force=(options.force=='on')
150
151   if options.renderer:
152     renderer=options.renderer
153   else:
154     print "Using default rendering backend..."
155     renderer="default"
156
157   if len(args)==1:
158     filename,=args
159     print "Rendering file: "+filename+"\n"
160     queue_render(db,filename)
161   elif len(args)==4:
162     minlat,minlon,maxlat,maxlon=args
163     print "Rendering region "+minlat+'..'+maxlat+' / '+minlon+'..'+maxlon+"\n"
164     queue_tiles(db,float(minlat),float(minlon),float(maxlat),float(maxlon),int(zoom))
165
166   if map:
167     print "Processing map(s) "+map+"\n"
168     process_queue(db,map,force,renderer)
169   
170 if __name__ == "__main__":
171
172   main()          
173