autopep8
This commit is contained in:
parent
846615d644
commit
c82f301853
12 changed files with 1643 additions and 1645 deletions
|
@ -27,7 +27,7 @@ from render import RasterTile
|
|||
svg = False
|
||||
|
||||
if svg:
|
||||
import cairo
|
||||
import cairo
|
||||
|
||||
|
||||
style = MapCSS(1, 19) #zoom levels
|
||||
|
@ -44,12 +44,12 @@ db = DataBackend()
|
|||
|
||||
res = RasterTile(w, h, z, db)
|
||||
if svg:
|
||||
file = open("test.svg", "wb")
|
||||
res.surface = cairo.SVGSurface(file.name, w,h)
|
||||
file = open("test.svg", "wb")
|
||||
res.surface = cairo.SVGSurface(file.name, w,h)
|
||||
res.update_surface(bbox, z, style)
|
||||
|
||||
|
||||
if not svg:
|
||||
res.surface.write_to_png("test.png")
|
||||
res.surface.write_to_png("test.png")
|
||||
else:
|
||||
res.surface.finish()
|
||||
res.surface.finish()
|
||||
|
|
152
src/gtk-app.py
152
src/gtk-app.py
|
@ -35,91 +35,91 @@ from gtk_widget import KothicWidget
|
|||
|
||||
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
import psyco
|
||||
psyco.full()
|
||||
except ImportError:
|
||||
pass
|
||||
pass
|
||||
# debug("Psyco import failed. Program may run slower. Ir you run it on i386 machine, please install Psyco to get best performance.")
|
||||
|
||||
|
||||
class KothicApp:
|
||||
def __init__(self):
|
||||
self.width, self.height = 800, 480
|
||||
|
||||
self.center_coord = (27.6549791, 53.8698)
|
||||
self.zoom = 17.
|
||||
self.data_projection = "EPSG:4326"
|
||||
self.data = DataBackend()
|
||||
self.load_style()
|
||||
|
||||
|
||||
self.request_d = (0,0)
|
||||
self.window = gtk.Window()
|
||||
|
||||
def __init__(self):
|
||||
self.width, self.height = 800, 480
|
||||
|
||||
self.center_coord = (27.6549791, 53.8698)
|
||||
self.zoom = 17.
|
||||
self.data_projection = "EPSG:4326"
|
||||
self.data = DataBackend()
|
||||
self.load_style()
|
||||
|
||||
|
||||
self.window.set_size_request(self.width, self.height)
|
||||
|
||||
self.window.connect("destroy", gtk.main_quit)
|
||||
|
||||
self.window.set_title("Kothic renderer")
|
||||
menu = gtk.MenuBar()
|
||||
|
||||
filemenu = gtk.Menu()
|
||||
filem = gtk.MenuItem("File")
|
||||
filem.set_submenu(filemenu)
|
||||
i = gtk.MenuItem("Reload style")
|
||||
i.connect("activate", self.load_style)
|
||||
filemenu.append(i)
|
||||
|
||||
stylemenu = gtk.Menu()
|
||||
stylem = gtk.MenuItem("Style")
|
||||
stylem.set_submenu(stylemenu)
|
||||
styles = [name for name in os.listdir("styles") if ".mapcss" in name]
|
||||
for style in styles:
|
||||
i = gtk.MenuItem(style)
|
||||
i.StyleName = style
|
||||
i.connect("activate", self.reload_style)
|
||||
stylemenu.append(i)
|
||||
|
||||
i = gtk.MenuItem("Exit")
|
||||
i.connect("activate", gtk.main_quit)
|
||||
filemenu.append(i)
|
||||
|
||||
menu.append(filem)
|
||||
menu.append(stylem)
|
||||
|
||||
vbox = gtk.VBox(False, 2)
|
||||
vbox.pack_start(menu,False,False,0)
|
||||
|
||||
self.KothicWidget = KothicWidget(self.data, self.style)
|
||||
self.KothicWidget.set_zoom(self.zoom)
|
||||
self.KothicWidget.jump_to(self.center_coord)
|
||||
|
||||
|
||||
|
||||
vbox.pack_end(self.KothicWidget)
|
||||
|
||||
|
||||
self.window.add(vbox)
|
||||
|
||||
def load_style(self):
|
||||
self.style = Styling(0,25)
|
||||
self.style.parse(open("styles/osmosnimki-maps.mapcss","r").read())
|
||||
def reload_style(self,w):
|
||||
self.style = Styling(0,25)
|
||||
self.style.parse(open("styles/%s"%w.StyleName,"r").read())
|
||||
self.KothicWidget.style_backend = self.style
|
||||
self.KothicWidget.redraw()
|
||||
self.request_d = (0,0)
|
||||
self.window = gtk.Window()
|
||||
|
||||
|
||||
def main(self):
|
||||
|
||||
self.window.show_all()
|
||||
gtk.main()
|
||||
exit()
|
||||
self.window.set_size_request(self.width, self.height)
|
||||
|
||||
self.window.connect("destroy", gtk.main_quit)
|
||||
|
||||
self.window.set_title("Kothic renderer")
|
||||
menu = gtk.MenuBar()
|
||||
|
||||
filemenu = gtk.Menu()
|
||||
filem = gtk.MenuItem("File")
|
||||
filem.set_submenu(filemenu)
|
||||
i = gtk.MenuItem("Reload style")
|
||||
i.connect("activate", self.load_style)
|
||||
filemenu.append(i)
|
||||
|
||||
stylemenu = gtk.Menu()
|
||||
stylem = gtk.MenuItem("Style")
|
||||
stylem.set_submenu(stylemenu)
|
||||
styles = [name for name in os.listdir("styles") if ".mapcss" in name]
|
||||
for style in styles:
|
||||
i = gtk.MenuItem(style)
|
||||
i.StyleName = style
|
||||
i.connect("activate", self.reload_style)
|
||||
stylemenu.append(i)
|
||||
|
||||
i = gtk.MenuItem("Exit")
|
||||
i.connect("activate", gtk.main_quit)
|
||||
filemenu.append(i)
|
||||
|
||||
menu.append(filem)
|
||||
menu.append(stylem)
|
||||
|
||||
vbox = gtk.VBox(False, 2)
|
||||
vbox.pack_start(menu,False,False,0)
|
||||
|
||||
self.KothicWidget = KothicWidget(self.data, self.style)
|
||||
self.KothicWidget.set_zoom(self.zoom)
|
||||
self.KothicWidget.jump_to(self.center_coord)
|
||||
|
||||
|
||||
|
||||
vbox.pack_end(self.KothicWidget)
|
||||
|
||||
|
||||
self.window.add(vbox)
|
||||
|
||||
def load_style(self):
|
||||
self.style = Styling(0,25)
|
||||
self.style.parse(open("styles/osmosnimki-maps.mapcss","r").read())
|
||||
def reload_style(self,w):
|
||||
self.style = Styling(0,25)
|
||||
self.style.parse(open("styles/%s"%w.StyleName,"r").read())
|
||||
self.KothicWidget.style_backend = self.style
|
||||
self.KothicWidget.redraw()
|
||||
|
||||
|
||||
def main(self):
|
||||
|
||||
self.window.show_all()
|
||||
gtk.main()
|
||||
exit()
|
||||
if __name__ == "__main__":
|
||||
|
||||
gtk.gdk.threads_init()
|
||||
kap = KothicApp()
|
||||
kap.main()
|
||||
gtk.gdk.threads_init()
|
||||
kap = KothicApp()
|
||||
kap.main()
|
||||
|
|
|
@ -32,256 +32,256 @@ import twms.bbox
|
|||
from twms import projections
|
||||
|
||||
class KothicWidget(gtk.DrawingArea):
|
||||
def __init__(self, data, style):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.data_backend = data
|
||||
self.style_backend = style
|
||||
self.request_d = (0,0)
|
||||
self.tiles = TileSource(data,style, callback=self.redraw)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
self.drag_x = 0
|
||||
self.drag_y = 0
|
||||
self.drag = False
|
||||
self.rastertile = None
|
||||
self.f = True
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
self.max_zoom = 25
|
||||
def __init__(self, data, style):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.data_backend = data
|
||||
self.style_backend = style
|
||||
self.request_d = (0,0)
|
||||
self.tiles = TileSource(data,style, callback=self.redraw)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
self.drag_x = 0
|
||||
self.drag_y = 0
|
||||
self.drag = False
|
||||
self.rastertile = None
|
||||
self.f = True
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
self.max_zoom = 25
|
||||
|
||||
self.zoom = 0
|
||||
self.center_coord = (0.0,0.0)
|
||||
self.old_zoom = 1
|
||||
self.old_center_coord = (0.0,0.1)
|
||||
self.tilebox = [] # bbox of currently seen tiles
|
||||
self.bbox = []
|
||||
|
||||
|
||||
self.add_events(gtk.gdk.BUTTON1_MOTION_MASK)
|
||||
self.add_events(gtk.gdk.POINTER_MOTION_MASK)
|
||||
self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
|
||||
self.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
|
||||
self.add_events(gtk.gdk.SCROLL)
|
||||
self.zoom = 0
|
||||
self.center_coord = (0.0,0.0)
|
||||
self.old_zoom = 1
|
||||
self.old_center_coord = (0.0,0.1)
|
||||
self.tilebox = [] # bbox of currently seen tiles
|
||||
self.bbox = []
|
||||
|
||||
|
||||
self.add_events(gtk.gdk.BUTTON1_MOTION_MASK)
|
||||
self.add_events(gtk.gdk.POINTER_MOTION_MASK)
|
||||
self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
|
||||
self.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
|
||||
self.add_events(gtk.gdk.SCROLL)
|
||||
# self.window.add_events(gtk.gdk.BUTTON1_MOTION_MASK)
|
||||
self.connect("expose_event",self.expose_ev)
|
||||
self.connect("motion_notify_event",self.motion_ev)
|
||||
self.connect("button_press_event",self.press_ev)
|
||||
self.connect("button_release_event",self.release_ev)
|
||||
self.connect("scroll_event",self.scroll_ev)
|
||||
|
||||
self.connect("expose_event",self.expose_ev)
|
||||
self.connect("motion_notify_event",self.motion_ev)
|
||||
self.connect("button_press_event",self.press_ev)
|
||||
self.connect("button_release_event",self.release_ev)
|
||||
self.connect("scroll_event",self.scroll_ev)
|
||||
|
||||
# self.surface = cairo.ImageSurfaceicreate(gtk.RGB24, self.width, self.height)
|
||||
|
||||
|
||||
def set_zoom(self, zoom):
|
||||
self.zoom = zoom
|
||||
self.queue_draw()
|
||||
def jump_to(self, lonlat):
|
||||
self.center_coord = lonlat
|
||||
self.queue_draw()
|
||||
def zoom_to(self, bbox):
|
||||
self.zoom = twms.bbox.zoom_for_bbox (bbox, (self.width,self.height), {"proj":"EPSG:3857","max_zoom":self.max_zoom})-1
|
||||
print "Zoom:", self.zoom
|
||||
self.center_coord = ((bbox[0]+bbox[2])/2,(bbox[1]+bbox[3])/2)
|
||||
print self.center_coord
|
||||
self.redraw()
|
||||
def set_zoom(self, zoom):
|
||||
self.zoom = zoom
|
||||
self.queue_draw()
|
||||
def jump_to(self, lonlat):
|
||||
self.center_coord = lonlat
|
||||
self.queue_draw()
|
||||
def zoom_to(self, bbox):
|
||||
self.zoom = twms.bbox.zoom_for_bbox (bbox, (self.width,self.height), {"proj":"EPSG:3857","max_zoom":self.max_zoom})-1
|
||||
print "Zoom:", self.zoom
|
||||
self.center_coord = ((bbox[0]+bbox[2])/2,(bbox[1]+bbox[3])/2)
|
||||
print self.center_coord
|
||||
self.redraw()
|
||||
|
||||
|
||||
def motion_ev(self, widget, event):
|
||||
|
||||
if self.drag:
|
||||
self.dx = event.x - self.drag_x
|
||||
self.dy = event.y - self.drag_y
|
||||
#if((abs(self.dx) > 3 or abs(self.dy) > 3) and self.f):
|
||||
if True:
|
||||
# x = event.x
|
||||
# y = event.y
|
||||
# lo1, la1, lo2, la2 = self.tilebox
|
||||
# self.center_coord = projections.coords_by_tile(self.zoom,1.*x/self.width*(lo2-lo1)+lo1, la1+(1.*y/(self.height)*(la2-la1)),"EPSG:3857")
|
||||
def motion_ev(self, widget, event):
|
||||
|
||||
if self.drag:
|
||||
self.dx = event.x - self.drag_x
|
||||
self.dy = event.y - self.drag_y
|
||||
#if((abs(self.dx) > 3 or abs(self.dy) > 3) and self.f):
|
||||
if True:
|
||||
# x = event.x
|
||||
# y = event.y
|
||||
# lo1, la1, lo2, la2 = self.tilebox
|
||||
# self.center_coord = projections.coords_by_tile(self.zoom,1.*x/self.width*(lo2-lo1)+lo1, la1+(1.*y/(self.height)*(la2-la1)),"EPSG:3857")
|
||||
widget.queue_draw()
|
||||
def press_ev(self, widget, event):
|
||||
if event.button == 1:
|
||||
#debug("Start drag")
|
||||
self.drag = True
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
self.timer = Timer("Drag")
|
||||
#elif event.button == 2:
|
||||
#debug("Button2")
|
||||
#elif event.button == 3:
|
||||
#debug("Button3")
|
||||
def release_ev(self, widget, event):
|
||||
if event.button == 1:
|
||||
#debug("Stop drag")
|
||||
self.drag = False
|
||||
self.timer.stop()
|
||||
#debug("dd: %s,%s "%(self.dx, self.dy))
|
||||
x = event.x
|
||||
y = event.y
|
||||
lo1, la1, lo2, la2 = projections.from4326(self.bbox, "EPSG:3857")
|
||||
print lo1, la1, lo2, la2
|
||||
#self.center_coord = projections.to4326((0.5*(self.width+self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+self.dy)/self.height*(la2-la1))),"EPSG:3857")
|
||||
|
||||
self.center_coord = projections.to4326((0.5*(self.width+2*self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+2*self.dy)/self.height*(la2-la1))),"EPSG:3857")
|
||||
#self.rastertile.screen2lonlat(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy);
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
self.redraw()
|
||||
|
||||
def scroll_ev(self, widget, event):
|
||||
if event.direction == gtk.gdk.SCROLL_UP:
|
||||
if self.zoom+0.5 <= self.max_zoom:
|
||||
self.zoom += 0.5
|
||||
#debug("Zoom in")
|
||||
elif event.direction == gtk.gdk.SCROLL_DOWN:
|
||||
if self.zoom >= 0: ## negative zooms are nonsense
|
||||
self.zoom -= 0.5
|
||||
# debug("Zoom out")
|
||||
#self.redraw()
|
||||
debug("new zoom: %s"%(self.zoom))
|
||||
widget.queue_draw()
|
||||
def press_ev(self, widget, event):
|
||||
if event.button == 1:
|
||||
#debug("Start drag")
|
||||
self.drag = True
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
self.timer = Timer("Drag")
|
||||
#elif event.button == 2:
|
||||
#debug("Button2")
|
||||
#elif event.button == 3:
|
||||
#debug("Button3")
|
||||
def release_ev(self, widget, event):
|
||||
if event.button == 1:
|
||||
#debug("Stop drag")
|
||||
self.drag = False
|
||||
self.timer.stop()
|
||||
#debug("dd: %s,%s "%(self.dx, self.dy))
|
||||
x = event.x
|
||||
y = event.y
|
||||
lo1, la1, lo2, la2 = projections.from4326(self.bbox, "EPSG:3857")
|
||||
print lo1, la1, lo2, la2
|
||||
#self.center_coord = projections.to4326((0.5*(self.width+self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+self.dy)/self.height*(la2-la1))),"EPSG:3857")
|
||||
|
||||
self.center_coord = projections.to4326((0.5*(self.width+2*self.dx)/self.width*(lo1-lo2)+lo2, la1+(0.5*(self.height+2*self.dy)/self.height*(la2-la1))),"EPSG:3857")
|
||||
#self.rastertile.screen2lonlat(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy);
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
self.redraw()
|
||||
|
||||
def scroll_ev(self, widget, event):
|
||||
if event.direction == gtk.gdk.SCROLL_UP:
|
||||
if self.zoom+0.5 <= self.max_zoom:
|
||||
self.zoom += 0.5
|
||||
#debug("Zoom in")
|
||||
elif event.direction == gtk.gdk.SCROLL_DOWN:
|
||||
if self.zoom >= 0: ## negative zooms are nonsense
|
||||
self.zoom -= 0.5
|
||||
# debug("Zoom out")
|
||||
#self.redraw()
|
||||
debug("new zoom: %s"%(self.zoom))
|
||||
widget.queue_draw()
|
||||
def redraw(self):
|
||||
"""
|
||||
Force screen redraw.
|
||||
"""
|
||||
#res = RasterTile(3*self.width, 3*self.height, self.zoom, self.data_backend)
|
||||
#res.update_surface_by_center(self.center_coord, self.zoom, self.style_backend)
|
||||
#self.rastertile = res
|
||||
self.queue_draw()
|
||||
def redraw(self):
|
||||
"""
|
||||
Force screen redraw.
|
||||
"""
|
||||
#res = RasterTile(3*self.width, 3*self.height, self.zoom, self.data_backend)
|
||||
#res.update_surface_by_center(self.center_coord, self.zoom, self.style_backend)
|
||||
#self.rastertile = res
|
||||
self.queue_draw()
|
||||
|
||||
|
||||
def expose_ev(self, widget, event):
|
||||
if(widget.allocation.width != self.width or widget.allocation.height != self.height ):
|
||||
#debug("Rrresize!")
|
||||
self.width = widget.allocation.width
|
||||
self.height = widget.allocation.height
|
||||
def expose_ev(self, widget, event):
|
||||
if(widget.allocation.width != self.width or widget.allocation.height != self.height ):
|
||||
#debug("Rrresize!")
|
||||
self.width = widget.allocation.width
|
||||
self.height = widget.allocation.height
|
||||
|
||||
cr = widget.window.cairo_create()
|
||||
if self.old_center_coord != self.center_coord or self.old_zoom != self.zoom:
|
||||
#print "Recentered!"
|
||||
xy = projections.from4326(self.center_coord,"EPSG:3857")
|
||||
xy1 = projections.to4326((xy[0]-40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]-40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857")
|
||||
xy2 = projections.to4326((xy[0]+40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]+40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857")
|
||||
self.bbox = (xy1[0],xy1[1],xy2[0],xy2[1])
|
||||
self.tilebox = projections.tile_by_bbox(self.bbox, self.zoom, "EPSG:3857")
|
||||
self.old_center_coord = self.center_coord
|
||||
self.old_zoom = self.zoom
|
||||
from_tile_x, from_tile_y, to_tile_x, to_tile_y = self.tilebox
|
||||
dx = 1.*(from_tile_x - int(from_tile_x))*self.tiles.tilewidth
|
||||
dy = 1.*(from_tile_y - int(from_tile_y))*self.tiles.tileheight
|
||||
print dx,dy
|
||||
#print self.dx, self.dy
|
||||
onscreen_tiles = set()
|
||||
for x in range (int(from_tile_x), int(to_tile_x)+1):
|
||||
for y in range (int(to_tile_y), int(from_tile_y)+1):
|
||||
onscreen_tiles.add((self.zoom,x,y))
|
||||
self.tiles.onscreen = onscreen_tiles
|
||||
for z,x,y in onscreen_tiles:
|
||||
tile = self.tiles[(self.zoom,x,y)]
|
||||
#print dx+(x-from_tile_x)*self.tiles.tilewidth-self.width
|
||||
#print dy+(y-from_tile_y)*self.tiles.tileheight-self.height
|
||||
#cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth-self.width), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height))
|
||||
cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height))
|
||||
cr.paint()
|
||||
#cr.set_source_surface(self.rastertile.surface, self.dx-self.width + self.rastertile.offset_x, self.dy - self.height + self.rastertile.offset_y)
|
||||
|
||||
#self.comm[3].release()
|
||||
cr = widget.window.cairo_create()
|
||||
if self.old_center_coord != self.center_coord or self.old_zoom != self.zoom:
|
||||
#print "Recentered!"
|
||||
xy = projections.from4326(self.center_coord,"EPSG:3857")
|
||||
xy1 = projections.to4326((xy[0]-40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]-40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857")
|
||||
xy2 = projections.to4326((xy[0]+40075016.*(0.5**(self.zoom))/self.tiles.tilewidth*self.width, xy[1]+40075016.*(0.5**(self.zoom))/self.tiles.tileheight*self.height), "EPSG:3857")
|
||||
self.bbox = (xy1[0],xy1[1],xy2[0],xy2[1])
|
||||
self.tilebox = projections.tile_by_bbox(self.bbox, self.zoom, "EPSG:3857")
|
||||
self.old_center_coord = self.center_coord
|
||||
self.old_zoom = self.zoom
|
||||
from_tile_x, from_tile_y, to_tile_x, to_tile_y = self.tilebox
|
||||
dx = 1.*(from_tile_x - int(from_tile_x))*self.tiles.tilewidth
|
||||
dy = 1.*(from_tile_y - int(from_tile_y))*self.tiles.tileheight
|
||||
print dx,dy
|
||||
#print self.dx, self.dy
|
||||
onscreen_tiles = set()
|
||||
for x in range (int(from_tile_x), int(to_tile_x)+1):
|
||||
for y in range (int(to_tile_y), int(from_tile_y)+1):
|
||||
onscreen_tiles.add((self.zoom,x,y))
|
||||
self.tiles.onscreen = onscreen_tiles
|
||||
for z,x,y in onscreen_tiles:
|
||||
tile = self.tiles[(self.zoom,x,y)]
|
||||
#print dx+(x-from_tile_x)*self.tiles.tilewidth-self.width
|
||||
#print dy+(y-from_tile_y)*self.tiles.tileheight-self.height
|
||||
#cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth-self.width), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height))
|
||||
cr.set_source_surface(tile, int(self.dx-dx+(x-int(from_tile_x))*self.tiles.tilewidth), int(self.dy-dy-(int(from_tile_y)-y)*self.tiles.tileheight+self.height))
|
||||
cr.paint()
|
||||
#cr.set_source_surface(self.rastertile.surface, self.dx-self.width + self.rastertile.offset_x, self.dy - self.height + self.rastertile.offset_y)
|
||||
|
||||
#self.comm[3].release()
|
||||
|
||||
|
||||
class TileSource:
|
||||
def __init__(self,data,style, callback = lambda: None):
|
||||
self.tiles = {}
|
||||
self.tilewidth = 2048
|
||||
self.tileheight = 2048
|
||||
self.max_tiles = 32
|
||||
self.data_backend = data
|
||||
self.style_backend = style
|
||||
self.callback = callback
|
||||
self.onscreen = set()
|
||||
self._singlethread = False
|
||||
self._prerender = True
|
||||
def __getitem__(self,(z,x,y),wait=False):
|
||||
def __init__(self,data,style, callback = lambda: None):
|
||||
self.tiles = {}
|
||||
self.tilewidth = 2048
|
||||
self.tileheight = 2048
|
||||
self.max_tiles = 32
|
||||
self.data_backend = data
|
||||
self.style_backend = style
|
||||
self.callback = callback
|
||||
self.onscreen = set()
|
||||
self._singlethread = False
|
||||
self._prerender = True
|
||||
def __getitem__(self,(z,x,y),wait=False):
|
||||
|
||||
try:
|
||||
#if "surface" in self.tiles[(z,x,y)] and not wait:
|
||||
# self._callback((z,x,y), True)
|
||||
print "Tiles count:", len(self.tiles)
|
||||
return self.tiles[(z,x,y)]["surface"]
|
||||
except:
|
||||
self.tiles[(z,x,y)] = {"tile": RasterTile(self.tilewidth, self.tileheight, z, self.data_backend)}
|
||||
self.tiles[(z,x,y)]["start_time"] = datetime.datetime.now()
|
||||
if self._singlethread:
|
||||
|
||||
self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface
|
||||
self.tiles[(z,x,y)]["tile"].update_surface(projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p))
|
||||
|
||||
del self.tiles[(z,x,y)]["tile"]
|
||||
else:
|
||||
self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface.create_similar(cairo.CONTENT_COLOR_ALPHA, self.tilewidth, self.tileheight)
|
||||
self.tiles[(z,x,y)]["thread"] = threading.Thread(None, self.tiles[(z,x,y)]["tile"].update_surface,None, (projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p)))
|
||||
self.tiles[(z,x,y)]["thread"].start()
|
||||
if wait:
|
||||
self.tiles[(z,x,y)]["thread"].join()
|
||||
return self.tiles[(z,x,y)]["surface"]
|
||||
def _callback (self, (z,x,y),last):
|
||||
#if last:
|
||||
# print last, "dddddddddddddddddd"
|
||||
if not self._singlethread:
|
||||
if ((z,x,y) in self.onscreen or last) and "tile" in self.tiles[(z,x,y)]:
|
||||
cr = cairo.Context(self.tiles[(z,x,y)]["surface"])
|
||||
cr.set_source_surface(self.tiles[(z,x,y)]["tile"].surface,0,0)
|
||||
cr.paint()
|
||||
|
||||
if last:
|
||||
try:
|
||||
del self.tiles[(z,x,y)]["thread"]
|
||||
del self.tiles[(z,x,y)]["tile"]
|
||||
except KeyError:
|
||||
pass
|
||||
self.tiles[(z,x,y)]["finish_time"] = datetime.datetime.now() - self.tiles[(z,x,y)]["start_time"]
|
||||
gobject.idle_add(self.callback)
|
||||
self.collect_grabage()
|
||||
if last and self._prerender:
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z-1,x/2,y/2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2,y*2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2+1,y*2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2,y*2+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2+1,y*2+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x+1,y),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x,y+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x-1,y),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x,y-1),True)
|
||||
def collect_grabage (self):
|
||||
if len(self.tiles)> self.max_tiles:
|
||||
# let's kick out the fastest rendered tiles - it's easy to rerender those
|
||||
# don't touch onscreen tiles
|
||||
cand = set(self.tiles.keys())
|
||||
cand.difference_update(self.onscreen)
|
||||
cand = [i for i in cand if "finish_time" in self.tiles[i]]
|
||||
cand.sort(lambda i,j: self.tiles[i]["finish_time"]<self.tiles[i]["finish_time"])
|
||||
while cand:
|
||||
if (len(self.tiles)> self.max_tiles):
|
||||
c = cand.pop()
|
||||
try:
|
||||
print "Killed tile ", c, " - finished in ",str(self.tiles[c]["finish_time"]), ", ago:", str(datetime.datetime.now()-self.tiles[c]["start_time"])
|
||||
del self.tiles[c]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
#if "surface" in self.tiles[(z,x,y)] and not wait:
|
||||
# self._callback((z,x,y), True)
|
||||
print "Tiles count:", len(self.tiles)
|
||||
return self.tiles[(z,x,y)]["surface"]
|
||||
except:
|
||||
self.tiles[(z,x,y)] = {"tile": RasterTile(self.tilewidth, self.tileheight, z, self.data_backend)}
|
||||
self.tiles[(z,x,y)]["start_time"] = datetime.datetime.now()
|
||||
if self._singlethread:
|
||||
|
||||
self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface
|
||||
self.tiles[(z,x,y)]["tile"].update_surface(projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p))
|
||||
|
||||
del self.tiles[(z,x,y)]["tile"]
|
||||
else:
|
||||
self.tiles[(z,x,y)]["surface"] = self.tiles[(z,x,y)]["tile"].surface.create_similar(cairo.CONTENT_COLOR_ALPHA, self.tilewidth, self.tileheight)
|
||||
self.tiles[(z,x,y)]["thread"] = threading.Thread(None, self.tiles[(z,x,y)]["tile"].update_surface,None, (projections.bbox_by_tile(z,x,y,"EPSG:3857"), z, self.style_backend, lambda p=False: self._callback((z,x,y),p)))
|
||||
self.tiles[(z,x,y)]["thread"].start()
|
||||
if wait:
|
||||
self.tiles[(z,x,y)]["thread"].join()
|
||||
return self.tiles[(z,x,y)]["surface"]
|
||||
def _callback (self, (z,x,y),last):
|
||||
#if last:
|
||||
# print last, "dddddddddddddddddd"
|
||||
if not self._singlethread:
|
||||
if ((z,x,y) in self.onscreen or last) and "tile" in self.tiles[(z,x,y)]:
|
||||
cr = cairo.Context(self.tiles[(z,x,y)]["surface"])
|
||||
cr.set_source_surface(self.tiles[(z,x,y)]["tile"].surface,0,0)
|
||||
cr.paint()
|
||||
|
||||
if last:
|
||||
try:
|
||||
del self.tiles[(z,x,y)]["thread"]
|
||||
del self.tiles[(z,x,y)]["tile"]
|
||||
except KeyError:
|
||||
pass
|
||||
self.tiles[(z,x,y)]["finish_time"] = datetime.datetime.now() - self.tiles[(z,x,y)]["start_time"]
|
||||
gobject.idle_add(self.callback)
|
||||
self.collect_grabage()
|
||||
if last and self._prerender:
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z-1,x/2,y/2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2,y*2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2+1,y*2),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2,y*2+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z+1,x*2+1,y*2+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x+1,y),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x,y+1),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x-1,y),True)
|
||||
if (z,x,y) in self.onscreen:
|
||||
a = self.__getitem__((z,x,y-1),True)
|
||||
def collect_grabage (self):
|
||||
if len(self.tiles)> self.max_tiles:
|
||||
# let's kick out the fastest rendered tiles - it's easy to rerender those
|
||||
# don't touch onscreen tiles
|
||||
cand = set(self.tiles.keys())
|
||||
cand.difference_update(self.onscreen)
|
||||
cand = [i for i in cand if "finish_time" in self.tiles[i]]
|
||||
cand.sort(lambda i,j: self.tiles[i]["finish_time"]<self.tiles[i]["finish_time"])
|
||||
while cand:
|
||||
if (len(self.tiles)> self.max_tiles):
|
||||
c = cand.pop()
|
||||
try:
|
||||
print "Killed tile ", c, " - finished in ",str(self.tiles[c]["finish_time"]), ", ago:", str(datetime.datetime.now()-self.tiles[c]["start_time"])
|
||||
del self.tiles[c]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
gtk.gdk.threads_init()
|
||||
kap = KothicApp()
|
||||
kap.main()
|
||||
gtk.gdk.threads_init()
|
||||
kap = KothicApp()
|
||||
kap.main()
|
||||
|
|
|
@ -11,189 +11,189 @@ reload(sys)
|
|||
sys.setdefaultencoding("utf-8") # a hack to support UTF-8
|
||||
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
import psyco
|
||||
psyco.full()
|
||||
except ImportError:
|
||||
pass
|
||||
#print >>sys.stderr, "Psyco import failed. Program may run slower. If you run it on i386 machine, please install Psyco to get best performance."
|
||||
pass
|
||||
#print >>sys.stderr, "Psyco import failed. Program may run slower. If you run it on i386 machine, please install Psyco to get best performance."
|
||||
|
||||
def get_vectors(bbox, zoom, style, vec = "polygon"):
|
||||
bbox_p = projections.from4326(bbox, "EPSG:3857")
|
||||
geomcolumn = "way"
|
||||
bbox_p = projections.from4326(bbox, "EPSG:3857")
|
||||
geomcolumn = "way"
|
||||
|
||||
database = "dbname=gis user=gis"
|
||||
pxtolerance = 1.8
|
||||
intscalefactor = 10000
|
||||
ignore_columns = set(["way_area", "osm_id", geomcolumn, "tags", "z_order"])
|
||||
table = {"polygon":"planet_osm_polygon", "line":"planet_osm_line","point":"planet_osm_point", "coastline": "coastlines"}
|
||||
database = "dbname=gis user=gis"
|
||||
pxtolerance = 1.8
|
||||
intscalefactor = 10000
|
||||
ignore_columns = set(["way_area", "osm_id", geomcolumn, "tags", "z_order"])
|
||||
table = {"polygon":"planet_osm_polygon", "line":"planet_osm_line","point":"planet_osm_point", "coastline": "coastlines"}
|
||||
|
||||
a = psycopg2.connect(database)
|
||||
b = a.cursor()
|
||||
if vec != "coastline":
|
||||
b.execute("SELECT * FROM %s LIMIT 1;" % table[vec])
|
||||
a = psycopg2.connect(database)
|
||||
b = a.cursor()
|
||||
if vec != "coastline":
|
||||
b.execute("SELECT * FROM %s LIMIT 1;" % table[vec])
|
||||
names = [q[0] for q in b.description]
|
||||
for i in ignore_columns:
|
||||
if i in names:
|
||||
names.remove(i)
|
||||
names = ",".join(['"'+i+'"' for i in names])
|
||||
|
||||
|
||||
taghint = "*"
|
||||
types = {"line":"line","polygon":"area", "point":"node"}
|
||||
adp = ""
|
||||
if "get_sql_hints" in dir(style):
|
||||
sql_hint = style.get_sql_hints(types[vec], zoom)
|
||||
adp = []
|
||||
for tp in sql_hint:
|
||||
add = []
|
||||
for j in tp[0]:
|
||||
if j not in names:
|
||||
break
|
||||
else:
|
||||
add.append(tp[1])
|
||||
if add:
|
||||
add = " OR ".join(add)
|
||||
add = "("+add+")"
|
||||
adp.append(add)
|
||||
adp = " OR ".join(adp)
|
||||
if adp:
|
||||
adp = adp.replace("<", "<")
|
||||
adp = adp.replace(">", ">")
|
||||
|
||||
|
||||
if vec == "polygon":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s,
|
||||
ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_PointOnSurface(way)),%s,%s,%s,%s),0) as reprpoint, %s from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_Buffer(way,-%s),%s)))).geom as %s, %s from
|
||||
(select ST_Union(way) as %s, %s from
|
||||
(select ST_Buffer(way, %s) as %s, %s from
|
||||
%s
|
||||
where (%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
and way_area > %s
|
||||
) p
|
||||
group by %s
|
||||
) p
|
||||
where ST_Area(way) > %s
|
||||
order by ST_Area(way)
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn,
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
geomcolumn, names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
(pixel_size_at_zoom(zoom, pxtolerance)**2)/pxtolerance,
|
||||
names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance)**2
|
||||
)
|
||||
elif vec == "line":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)),%s,%s,%s,%s),0) as %s, %s from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_LineMerge(way),%s)))).geom as %s, %s from
|
||||
(select ST_Union(way) as %s, %s from
|
||||
%s
|
||||
where (%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
|
||||
group by %s
|
||||
) p
|
||||
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn, names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
|
||||
names,
|
||||
|
||||
)
|
||||
elif vec == "point":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(way,%s,%s,%s,%s),0) as %s, %s
|
||||
from %s where
|
||||
(%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
limit 10000
|
||||
"""%(
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
|
||||
)
|
||||
elif vec == "coastline":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s, 'coastline' as "natural" from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_Buffer(way,-%s),%s)))).geom as %s from
|
||||
(select ST_Union(way) as %s from
|
||||
(select ST_Buffer(SetSRID(the_geom,900913), %s) as %s from
|
||||
%s
|
||||
where
|
||||
SetSRID(the_geom,900913) && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
) p
|
||||
) p
|
||||
where ST_Area(way) > %s
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn,
|
||||
geomcolumn,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn,
|
||||
table[vec],
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
pixel_size_at_zoom(zoom, pxtolerance)**2
|
||||
)
|
||||
#print query
|
||||
a = psycopg2.connect(database)
|
||||
b = a.cursor()
|
||||
b.execute(query)
|
||||
names = [q[0] for q in b.description]
|
||||
for i in ignore_columns:
|
||||
if i in names:
|
||||
names.remove(i)
|
||||
names = ",".join(['"'+i+'"' for i in names])
|
||||
|
||||
ROWS_FETCHED = 0
|
||||
polygons = []
|
||||
|
||||
taghint = "*"
|
||||
types = {"line":"line","polygon":"area", "point":"node"}
|
||||
adp = ""
|
||||
if "get_sql_hints" in dir(style):
|
||||
sql_hint = style.get_sql_hints(types[vec], zoom)
|
||||
adp = []
|
||||
for tp in sql_hint:
|
||||
add = []
|
||||
for j in tp[0]:
|
||||
if j not in names:
|
||||
break
|
||||
else:
|
||||
add.append(tp[1])
|
||||
if add:
|
||||
add = " OR ".join(add)
|
||||
add = "("+add+")"
|
||||
adp.append(add)
|
||||
adp = " OR ".join(adp)
|
||||
if adp:
|
||||
adp = adp.replace("<", "<")
|
||||
adp = adp.replace(">", ">")
|
||||
|
||||
|
||||
if vec == "polygon":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s,
|
||||
ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_PointOnSurface(way)),%s,%s,%s,%s),0) as reprpoint, %s from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_Buffer(way,-%s),%s)))).geom as %s, %s from
|
||||
(select ST_Union(way) as %s, %s from
|
||||
(select ST_Buffer(way, %s) as %s, %s from
|
||||
%s
|
||||
where (%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
and way_area > %s
|
||||
) p
|
||||
group by %s
|
||||
) p
|
||||
where ST_Area(way) > %s
|
||||
order by ST_Area(way)
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn,
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
geomcolumn, names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
(pixel_size_at_zoom(zoom, pxtolerance)**2)/pxtolerance,
|
||||
names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance)**2
|
||||
)
|
||||
elif vec == "line":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)),%s,%s,%s,%s),0) as %s, %s from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_LineMerge(way),%s)))).geom as %s, %s from
|
||||
(select ST_Union(way) as %s, %s from
|
||||
%s
|
||||
where (%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
|
||||
group by %s
|
||||
) p
|
||||
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn, names,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn, names,
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
|
||||
names,
|
||||
|
||||
)
|
||||
elif vec == "point":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(way,%s,%s,%s,%s),0) as %s, %s
|
||||
from %s where
|
||||
(%s)
|
||||
and way && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
limit 10000
|
||||
"""%(
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn, names,
|
||||
table[vec],
|
||||
adp,
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
|
||||
)
|
||||
elif vec == "coastline":
|
||||
query = """select ST_AsGeoJSON(ST_TransScale(ST_ForceRHR(ST_Intersection(way,SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913))),%s,%s,%s,%s),0) as %s, 'coastline' as "natural" from
|
||||
(select (ST_Dump(ST_Multi(ST_SimplifyPreserveTopology(ST_Buffer(way,-%s),%s)))).geom as %s from
|
||||
(select ST_Union(way) as %s from
|
||||
(select ST_Buffer(SetSRID(the_geom,900913), %s) as %s from
|
||||
%s
|
||||
where
|
||||
SetSRID(the_geom,900913) && SetSRID('BOX3D(%s %s,%s %s)'::box3d,900913)
|
||||
) p
|
||||
) p
|
||||
where ST_Area(way) > %s
|
||||
) p
|
||||
"""%(bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
-bbox_p[0],-bbox_p[1],intscalefactor/(bbox_p[2]-bbox_p[0]),intscalefactor/(bbox_p[3]-bbox_p[1]),
|
||||
geomcolumn,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn,
|
||||
geomcolumn,
|
||||
pixel_size_at_zoom(zoom, pxtolerance),
|
||||
geomcolumn,
|
||||
table[vec],
|
||||
bbox_p[0],bbox_p[1],bbox_p[2],bbox_p[3],
|
||||
pixel_size_at_zoom(zoom, pxtolerance)**2
|
||||
)
|
||||
#print query
|
||||
a = psycopg2.connect(database)
|
||||
b = a.cursor()
|
||||
b.execute(query)
|
||||
names = [q[0] for q in b.description]
|
||||
|
||||
ROWS_FETCHED = 0
|
||||
polygons = []
|
||||
|
||||
for row in b.fetchall():
|
||||
ROWS_FETCHED += 1
|
||||
geom = dict(map(None,names,row))
|
||||
for t in geom.keys():
|
||||
if not geom[t]:
|
||||
del geom[t]
|
||||
geojson = json.loads(geom[geomcolumn])
|
||||
del geom[geomcolumn]
|
||||
if geojson["type"] == "GeometryCollection":
|
||||
continue
|
||||
if "reprpoint" in geom:
|
||||
geojson["reprpoint"] = json.loads(geom["reprpoint"])["coordinates"]
|
||||
del geom["reprpoint"]
|
||||
prop = {}
|
||||
for k,v in geom.iteritems():
|
||||
prop[k] = v
|
||||
try:
|
||||
if int(v) == float(v):
|
||||
prop[k] = int(v)
|
||||
else:
|
||||
prop[k] = float(v)
|
||||
if str(prop[k]) != v: # leading zeros etc.. should be saved
|
||||
prop[k] = v
|
||||
except:
|
||||
pass
|
||||
geojson["properties"] = prop
|
||||
polygons.append(geojson)
|
||||
return {"bbox": bbox, "granularity":intscalefactor, "features":polygons}
|
||||
for row in b.fetchall():
|
||||
ROWS_FETCHED += 1
|
||||
geom = dict(map(None,names,row))
|
||||
for t in geom.keys():
|
||||
if not geom[t]:
|
||||
del geom[t]
|
||||
geojson = json.loads(geom[geomcolumn])
|
||||
del geom[geomcolumn]
|
||||
if geojson["type"] == "GeometryCollection":
|
||||
continue
|
||||
if "reprpoint" in geom:
|
||||
geojson["reprpoint"] = json.loads(geom["reprpoint"])["coordinates"]
|
||||
del geom["reprpoint"]
|
||||
prop = {}
|
||||
for k,v in geom.iteritems():
|
||||
prop[k] = v
|
||||
try:
|
||||
if int(v) == float(v):
|
||||
prop[k] = int(v)
|
||||
else:
|
||||
prop[k] = float(v)
|
||||
if str(prop[k]) != v: # leading zeros etc.. should be saved
|
||||
prop[k] = v
|
||||
except:
|
||||
pass
|
||||
geojson["properties"] = prop
|
||||
polygons.append(geojson)
|
||||
return {"bbox": bbox, "granularity":intscalefactor, "features":polygons}
|
||||
|
||||
|
||||
|
||||
|
@ -203,19 +203,19 @@ print
|
|||
|
||||
form = cgi.FieldStorage()
|
||||
if "z" not in form:
|
||||
print "need z"
|
||||
exit()
|
||||
print "need z"
|
||||
exit()
|
||||
if "x" not in form:
|
||||
print "need x"
|
||||
exit()
|
||||
print "need x"
|
||||
exit()
|
||||
if "y" not in form:
|
||||
print "need y"
|
||||
exit()
|
||||
print "need y"
|
||||
exit()
|
||||
z = int(form["z"].value)
|
||||
x = int(form["x"].value)
|
||||
y = int(form["y"].value)
|
||||
if z>22:
|
||||
exit()
|
||||
exit()
|
||||
callback = "onKothicDataResponse"
|
||||
|
||||
bbox = projections.bbox_by_tile(z+1,x,y,"EPSG:3857")
|
||||
|
@ -235,13 +235,12 @@ dir = "/var/www/vtile/%s/%s/"%(z,x)
|
|||
file = "%s.js"%y
|
||||
|
||||
try:
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
except:
|
||||
pass
|
||||
pass
|
||||
|
||||
file = open(dir+file,"w")
|
||||
file.write(aaaa)
|
||||
file.flush()
|
||||
file.close()
|
||||
|
||||
|
|
|
@ -43,349 +43,349 @@ substyles = []
|
|||
last_id = 0
|
||||
|
||||
def get_id(i = 0):
|
||||
global last_id
|
||||
last_id += i
|
||||
return last_id
|
||||
global last_id
|
||||
last_id += i
|
||||
return last_id
|
||||
|
||||
|
||||
def zoom_to_scaledenom(z1,z2=False):
|
||||
"""
|
||||
Converts zoom level to mapnik's scaledenominator pair for EPSG:3857
|
||||
"""
|
||||
if not z2:
|
||||
z2 = z1
|
||||
s = 279541132.014
|
||||
z1 = (s/(2**(z1-1))+s/(2**(z1-2)))/2
|
||||
z2 = (s/(2**(z2-1))+s/(2**z2))/2
|
||||
#return 100000000000000, 1
|
||||
return z1, z2
|
||||
"""
|
||||
Converts zoom level to mapnik's scaledenominator pair for EPSG:3857
|
||||
"""
|
||||
if not z2:
|
||||
z2 = z1
|
||||
s = 279541132.014
|
||||
z1 = (s/(2**(z1-1))+s/(2**(z1-2)))/2
|
||||
z2 = (s/(2**(z2-1))+s/(2**z2))/2
|
||||
#return 100000000000000, 1
|
||||
return z1, z2
|
||||
|
||||
def pixel_size_at_zoom(z, l=1):
|
||||
"""
|
||||
Converts l pixels on tiles into length on zoom z
|
||||
"""
|
||||
return int(math.ceil(l* 20037508.342789244 / 256 * 2 / (2**z)))
|
||||
"""
|
||||
Converts l pixels on tiles into length on zoom z
|
||||
"""
|
||||
return int(math.ceil(l* 20037508.342789244 / 256 * 2 / (2**z)))
|
||||
|
||||
|
||||
def xml_fontset(name, unicode=True):
|
||||
if unicode:
|
||||
unicode = '<Font face-name="unifont Medium" />'
|
||||
return """
|
||||
<FontSet name="%s">
|
||||
<Font face-name="%s" />
|
||||
%s
|
||||
</FontSet>"""%(name, name, unicode)
|
||||
|
||||
if unicode:
|
||||
unicode = '<Font face-name="unifont Medium" />'
|
||||
return """
|
||||
<FontSet name="%s">
|
||||
<Font face-name="%s" />
|
||||
%s
|
||||
</FontSet>"""%(name, name, unicode)
|
||||
|
||||
|
||||
def xml_pointsymbolizer(path="", width="", height="", opacity=1, overlap="false"):
|
||||
if width:
|
||||
width =' width="%s" '%width
|
||||
if height:
|
||||
height =' height="%s" '%height
|
||||
return """
|
||||
<PointSymbolizer file="%s" %s %s opacity="%s" allow-overlap="%s" />"""\
|
||||
%(os.path.join(icons_path, path), width, height, opacity, overlap)
|
||||
if width:
|
||||
width =' width="%s" '%width
|
||||
if height:
|
||||
height =' height="%s" '%height
|
||||
return """
|
||||
<PointSymbolizer file="%s" %s %s opacity="%s" allow-overlap="%s" />"""\
|
||||
%(os.path.join(icons_path, path), width, height, opacity, overlap)
|
||||
|
||||
|
||||
def xml_linesymbolizer(color="#000000", width="1", opacity="1", linecap="butt", linejoin="round", dashes="", smooth=0, zoom=200):
|
||||
color = nicecolor(color)
|
||||
linecap = {"none":"butt",}.get(linecap.lower(), linecap)
|
||||
color = nicecolor(color)
|
||||
linecap = {"none":"butt",}.get(linecap.lower(), linecap)
|
||||
|
||||
if dashes:
|
||||
dashes = 'stroke-dasharray="%s"'%(dashes)
|
||||
else:
|
||||
dashes = ""
|
||||
if dashes:
|
||||
dashes = 'stroke-dasharray="%s"'%(dashes)
|
||||
else:
|
||||
dashes = ""
|
||||
|
||||
if smooth:
|
||||
smooth = 'smooth="%s"'%(smooth)
|
||||
else:
|
||||
smooth = ""
|
||||
if smooth:
|
||||
smooth = 'smooth="%s"'%(smooth)
|
||||
else:
|
||||
smooth = ""
|
||||
|
||||
rasterizer = ""
|
||||
rasterizer = ""
|
||||
# if float(width) < 4 and not dashes and zoom < 6:
|
||||
# rasterizer = ' rasterizer="fast"'
|
||||
|
||||
return """
|
||||
<LineSymbolizer %s %s stroke="%s" stroke-width="%s" stroke-opacity="%s" stroke-linejoin="%s" stroke-linecap="%s" %s/>"""%(rasterizer, smooth, color, float(width), float(opacity), linejoin, linecap, dashes)
|
||||
return """
|
||||
<LineSymbolizer %s %s stroke="%s" stroke-width="%s" stroke-opacity="%s" stroke-linejoin="%s" stroke-linecap="%s" %s/>"""%(rasterizer, smooth, color, float(width), float(opacity), linejoin, linecap, dashes)
|
||||
|
||||
|
||||
def xml_polygonsymbolizer(color="#000000", opacity="1", smooth='0'):
|
||||
color = nicecolor(color)
|
||||
if smooth:
|
||||
smooth = 'smooth="%s"'%(smooth)
|
||||
else:
|
||||
smooth = ""
|
||||
return """
|
||||
<PolygonSymbolizer fill="%s" fill-opacity="%s" gamma="0.73" %s />"""%(color, float(opacity), smooth)
|
||||
color = nicecolor(color)
|
||||
if smooth:
|
||||
smooth = 'smooth="%s"'%(smooth)
|
||||
else:
|
||||
smooth = ""
|
||||
return """
|
||||
<PolygonSymbolizer fill="%s" fill-opacity="%s" gamma="0.73" %s />"""%(color, float(opacity), smooth)
|
||||
|
||||
def xml_polygonpatternsymbolizer(file=""):
|
||||
return """
|
||||
<PolygonPatternSymbolizer file="%s"/>"""%(os.path.join(icons_path,file))
|
||||
return """
|
||||
<PolygonPatternSymbolizer file="%s"/>"""%(os.path.join(icons_path,file))
|
||||
|
||||
|
||||
def xml_linepatternsymbolizer(file=""):
|
||||
return """
|
||||
<LinePatternSymbolizer file="%s"/>"""%(os.path.join(icons_path,file))
|
||||
return """
|
||||
<LinePatternSymbolizer file="%s"/>"""%(os.path.join(icons_path,file))
|
||||
|
||||
|
||||
def xml_textsymbolizer(
|
||||
text="name",face="DejaVu Sans Book",size="10",color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", pos="X", transform = "none", spacing="4096"):
|
||||
color = nicecolor(color)
|
||||
halo_color = nicecolor(halo_color)
|
||||
pos = pos.replace("exact", "X").replace("any","S, E, X, N, W, NE, SE, NW, SW").split(",")
|
||||
pos.extend([str(int(float(x)*text_scale)) for x in size.split(",")])
|
||||
pos = ",".join(pos)
|
||||
size = str(int(float(size.split(",")[0])*text_scale))
|
||||
|
||||
|
||||
placement = {"center": "interior"}.get(placement.lower(), placement)
|
||||
align = {"center": "middle"}.get(align.lower(), align)
|
||||
dy = int(float(offset))
|
||||
dx = 0
|
||||
if align in ("right",'left'):
|
||||
dx = dy
|
||||
dy = 0
|
||||
|
||||
return """
|
||||
<TextSymbolizer fontset-name="%s" size="%s" fill="%s" halo-fill= "%s" halo-radius="%s" placement="%s" dx="%s" dy="%s" max-char-angle-delta="17" allow-overlap="%s" wrap-width="%s" minimum-distance="%s" vertical-alignment="middle" horizontal-alignment="%s" opacity="%s" placement-type="simple" placements="%s" text-transform="%s" minimum-path-length="5" spacing="%s">[%s]</TextSymbolizer>
|
||||
"""%(face,int(float(size)),color,halo_color,halo_radius,placement,dx,dy,overlap,wrap_width,distance,align,opacity,pos, transform, spacing,text)
|
||||
color = nicecolor(color)
|
||||
halo_color = nicecolor(halo_color)
|
||||
pos = pos.replace("exact", "X").replace("any","S, E, X, N, W, NE, SE, NW, SW").split(",")
|
||||
pos.extend([str(int(float(x)*text_scale)) for x in size.split(",")])
|
||||
pos = ",".join(pos)
|
||||
size = str(int(float(size.split(",")[0])*text_scale))
|
||||
|
||||
|
||||
placement = {"center": "interior"}.get(placement.lower(), placement)
|
||||
align = {"center": "middle"}.get(align.lower(), align)
|
||||
dy = int(float(offset))
|
||||
dx = 0
|
||||
if align in ("right",'left'):
|
||||
dx = dy
|
||||
dy = 0
|
||||
|
||||
return """
|
||||
<TextSymbolizer fontset-name="%s" size="%s" fill="%s" halo-fill= "%s" halo-radius="%s" placement="%s" dx="%s" dy="%s" max-char-angle-delta="17" allow-overlap="%s" wrap-width="%s" minimum-distance="%s" vertical-alignment="middle" horizontal-alignment="%s" opacity="%s" placement-type="simple" placements="%s" text-transform="%s" minimum-path-length="5" spacing="%s">[%s]</TextSymbolizer>
|
||||
"""%(face,int(float(size)),color,halo_color,halo_radius,placement,dx,dy,overlap,wrap_width,distance,align,opacity,pos, transform, spacing,text)
|
||||
|
||||
def xml_shieldsymbolizer(path="", width="", height="",
|
||||
text="name",face="DejaVu Sans Book",size="10",color="#000000", halo_color="#ffffff", halo_radius="0", placement="line", offset="0", overlap="false", distance="26", wrap_width=256, align="center", opacity="1", transform="none", unlock_image='true', spacing='500'):
|
||||
color = nicecolor(color)
|
||||
halo_color = nicecolor(halo_color)
|
||||
placement = {"center": "point"}.get(placement.lower(), placement)
|
||||
align = {"center": "middle"}.get(align.lower(), align)
|
||||
size = size.split(",")[0]
|
||||
if width:
|
||||
width =' width="%s" '%width
|
||||
if height:
|
||||
height =' height="%s" '%height
|
||||
return """
|
||||
<ShieldSymbolizer file="%s%s" %s %s fontset-name="%s" size="%s" fill="%s" halo-fill= "%s" halo-radius="%s" placement="%s" dy="%s" allow-overlap="%s" wrap-width="%s" minimum-distance="%s" horizontal-alignment="%s" opacity="%s" text-transform="%s" unlock-image="%s" spacing="%s">[%s]</ShieldSymbolizer>
|
||||
"""%(icons_path, \
|
||||
path, width, height,face,int(float(size)*text_scale),color,halo_color,halo_radius,placement,offset,overlap,wrap_width,distance,align,opacity, transform, unlock_image, spacing,text )
|
||||
color = nicecolor(color)
|
||||
halo_color = nicecolor(halo_color)
|
||||
placement = {"center": "point"}.get(placement.lower(), placement)
|
||||
align = {"center": "middle"}.get(align.lower(), align)
|
||||
size = size.split(",")[0]
|
||||
if width:
|
||||
width =' width="%s" '%width
|
||||
if height:
|
||||
height =' height="%s" '%height
|
||||
return """
|
||||
<ShieldSymbolizer file="%s%s" %s %s fontset-name="%s" size="%s" fill="%s" halo-fill= "%s" halo-radius="%s" placement="%s" dy="%s" allow-overlap="%s" wrap-width="%s" minimum-distance="%s" horizontal-alignment="%s" opacity="%s" text-transform="%s" unlock-image="%s" spacing="%s">[%s]</ShieldSymbolizer>
|
||||
"""%(icons_path, \
|
||||
path, width, height,face,int(float(size)*text_scale),color,halo_color,halo_radius,placement,offset,overlap,wrap_width,distance,align,opacity, transform, unlock_image, spacing,text )
|
||||
|
||||
def xml_filter(string):
|
||||
return """
|
||||
<Filter>%s</Filter>"""%string
|
||||
return """
|
||||
<Filter>%s</Filter>"""%string
|
||||
|
||||
def xml_scaledenominator(z1, z2=False):
|
||||
zz1, zz2 = zoom_to_scaledenom(z1,z2)
|
||||
return """
|
||||
<MaxScaleDenominator>%s</MaxScaleDenominator>
|
||||
<MinScaleDenominator>%s</MinScaleDenominator><!-- z%s-%s -->"""%(zz1,zz2,z1,z2)
|
||||
zz1, zz2 = zoom_to_scaledenom(z1,z2)
|
||||
return """
|
||||
<MaxScaleDenominator>%s</MaxScaleDenominator>
|
||||
<MinScaleDenominator>%s</MinScaleDenominator><!-- z%s-%s -->"""%(zz1,zz2,z1,z2)
|
||||
|
||||
def xml_start(bgcolor="transparent"):
|
||||
if bgcolor != "transparent":
|
||||
bgcolor = nicecolor(bgcolor)
|
||||
return """<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="%s" srs="%s" minimum-version="0.7.1" buffer-size="512" maximum-extent="-20037508.342789244,-20037508.342780735,20037508.342789244,20037508.342780709" >
|
||||
"""%(bgcolor, map_proj)
|
||||
if bgcolor != "transparent":
|
||||
bgcolor = nicecolor(bgcolor)
|
||||
return """<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="%s" srs="%s" minimum-version="0.7.1" buffer-size="512" maximum-extent="-20037508.342789244,-20037508.342780735,20037508.342789244,20037508.342780709" >
|
||||
"""%(bgcolor, map_proj)
|
||||
|
||||
def xml_end():
|
||||
return """
|
||||
</Map>"""
|
||||
return """
|
||||
</Map>"""
|
||||
|
||||
|
||||
def xml_style_start():
|
||||
global substyles
|
||||
layer_id = get_id(1)
|
||||
substyles.append(layer_id)
|
||||
return """
|
||||
<Style name="s%s">"""%(layer_id)
|
||||
global substyles
|
||||
layer_id = get_id(1)
|
||||
substyles.append(layer_id)
|
||||
return """
|
||||
<Style name="s%s">"""%(layer_id)
|
||||
|
||||
def xml_style_end():
|
||||
return """
|
||||
</Style>"""
|
||||
return """
|
||||
</Style>"""
|
||||
|
||||
def xml_rule_start():
|
||||
return """
|
||||
<Rule>"""
|
||||
return """
|
||||
<Rule>"""
|
||||
|
||||
def xml_rule_end():
|
||||
return """
|
||||
</Rule>"""
|
||||
return """
|
||||
</Rule>"""
|
||||
|
||||
def xml_cleantopo(zoom, x_scale, demramp):
|
||||
return """
|
||||
<Style name="elevation1z%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer mesh-size="1">
|
||||
<RasterColorizer default-mode="linear" epsilon="0.001">
|
||||
%s
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
return """
|
||||
<Style name="elevation1z%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer mesh-size="1">
|
||||
<RasterColorizer default-mode="linear" epsilon="0.001">
|
||||
%s
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="ele-raster1z%s">
|
||||
<StyleName>elevation1z%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, demramp, zoom, zoom, cleantopo_dem_path)
|
||||
<Layer name="ele-raster1z%s">
|
||||
<StyleName>elevation1z%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, demramp, zoom, zoom, cleantopo_dem_path)
|
||||
|
||||
def xml_srtm(zoom, x_scale, demramp):
|
||||
return """
|
||||
<Style name="elevationz%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer mesh-size="1">
|
||||
<RasterColorizer default-mode="linear" epsilon="0.001">
|
||||
%s
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
return """
|
||||
<Style name="elevationz%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer mesh-size="1">
|
||||
<RasterColorizer default-mode="linear" epsilon="0.001">
|
||||
%s
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="ele-rasterz%s">
|
||||
<StyleName>elevationz%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, demramp, zoom, zoom, srtm_dem_path)
|
||||
|
||||
<Layer name="ele-rasterz%s">
|
||||
<StyleName>elevationz%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, demramp, zoom, zoom, srtm_dem_path)
|
||||
|
||||
|
||||
def xml_hillshade(zoom, x_scale):
|
||||
hs_path = cleantopo_hs_path
|
||||
if zoom>6:
|
||||
hs_path = srtm_hs_path
|
||||
return """
|
||||
<Style name="hillshade%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer opacity="0.3" mesh-size="1">
|
||||
<RasterColorizer default-mode="linear">
|
||||
<stop value="0" color="rgba(0,0,0,1)" />
|
||||
<stop value="128" color="rgba(128,128,128,0.4)" />
|
||||
<stop value="255" color="rgba(255,255,255,1)" />
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
hs_path = cleantopo_hs_path
|
||||
if zoom>6:
|
||||
hs_path = srtm_hs_path
|
||||
return """
|
||||
<Style name="hillshade%s">
|
||||
<Rule>%s
|
||||
<RasterSymbolizer opacity="0.3" mesh-size="1">
|
||||
<RasterColorizer default-mode="linear">
|
||||
<stop value="0" color="rgba(0,0,0,1)" />
|
||||
<stop value="128" color="rgba(128,128,128,0.4)" />
|
||||
<stop value="255" color="rgba(255,255,255,1)" />
|
||||
</RasterColorizer>
|
||||
</RasterSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="ele-hsz%s">
|
||||
<StyleName>hillshade%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, zoom, zoom, hs_path)
|
||||
|
||||
|
||||
<Layer name="ele-hsz%s">
|
||||
<StyleName>hillshade%s</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="file">%s</Parameter>
|
||||
<Parameter name="type">gdal</Parameter>
|
||||
<Parameter name="band">1</Parameter>
|
||||
<Parameter name="srid">3857</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
""" % (zoom, x_scale, zoom, zoom, hs_path)
|
||||
|
||||
|
||||
def xml_hardcoded_arrows():
|
||||
return """
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="1" stroke-linejoin="bevel" stroke-dasharray="0,12,10,152" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="2" stroke-linejoin="bevel" stroke-dasharray="0,12,9,153" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="3" stroke-linejoin="bevel" stroke-dasharray="0,18,2,154" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="4" stroke-linejoin="bevel" stroke-dasharray="0,18,1,155" />
|
||||
"""
|
||||
return """
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="1" stroke-linejoin="bevel" stroke-dasharray="0,12,10,152" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="2" stroke-linejoin="bevel" stroke-dasharray="0,12,9,153" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="3" stroke-linejoin="bevel" stroke-dasharray="0,18,2,154" />
|
||||
<LineSymbolizer stroke="#6c70d5" stroke-width="4" stroke-linejoin="bevel" stroke-dasharray="0,18,1,155" />
|
||||
"""
|
||||
|
||||
def xml_layer(type="postgis", geom="point", interesting_tags = "*", sql = "true", zoom=0 ):
|
||||
layer_id = get_id(1)
|
||||
global substyles
|
||||
subs = "\n".join(["<StyleName>s%s</StyleName>"%i for i in substyles])
|
||||
substyles = []
|
||||
intersection_SQL = ""
|
||||
if zoom < 5:
|
||||
intersection_SQL = '<Parameter name="intersect_max_scale">1</Parameter>'
|
||||
elif zoom > 16:
|
||||
intersection_SQL = '<Parameter name="intersect_min_scale">500000000000</Parameter>'
|
||||
|
||||
|
||||
if type == "postgis":
|
||||
waystring = 'way'
|
||||
if zoom < 10:
|
||||
waystring = "ST_Simplify(way, %s) as way"%(pixel_size_at_zoom(zoom,0.6))
|
||||
if zoom >= 5:
|
||||
sql = 'way && !bbox! and '+ sql
|
||||
if geom == "polygon":
|
||||
sql = 'way_area > %s and '%(pixel_size_at_zoom(zoom,0.1)**2)+ sql
|
||||
interesting_tags = list(interesting_tags)
|
||||
if '"' not in "".join(interesting_tags) and "->" not in "".join(interesting_tags):
|
||||
interesting_tags = "\", \"".join(interesting_tags)
|
||||
interesting_tags = "\""+ interesting_tags+"\""
|
||||
else:
|
||||
interesting_tags = ", ".join(interesting_tags)
|
||||
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="table">
|
||||
( -- zoom %s
|
||||
select %s, %s
|
||||
from %s%s
|
||||
where %s
|
||||
) as k_layer
|
||||
</Parameter>
|
||||
%s
|
||||
<Parameter name="type">postgis</Parameter>
|
||||
<Parameter name="st_prefix">true</Parameter>
|
||||
<Parameter name="user">%s</Parameter>
|
||||
<Parameter name="dbname">%s</Parameter>
|
||||
<Parameter name="srid">%s</Parameter>
|
||||
<Parameter name="geometry_field">way</Parameter>
|
||||
<Parameter name="geometry_table">%s%s</Parameter>
|
||||
<Parameter name="estimate_extent">false</Parameter>
|
||||
<Parameter name="extent">-20037508.342789244, -20037508.342780735, 20037508.342789244, 20037508.342780709</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, zoom, interesting_tags, waystring, table_prefix, geom, sql, intersection_SQL, db_user, db_name, db_srid, table_prefix, geom)
|
||||
elif type == "postgis-process":
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="table">
|
||||
( -- zoom %s
|
||||
%s
|
||||
) as k_layer
|
||||
</Parameter>
|
||||
%s
|
||||
<Parameter name="type">postgis</Parameter>
|
||||
<Parameter name="st_prefix">true</Parameter>
|
||||
<Parameter name="user">%s</Parameter>
|
||||
<Parameter name="dbname">%s</Parameter>
|
||||
<Parameter name="srid">%s</Parameter>
|
||||
<Parameter name="geometry_field">way</Parameter>
|
||||
<Parameter name="geometry_table">%s%s</Parameter>
|
||||
<Parameter name="estimate_extent">false</Parameter>
|
||||
<Parameter name="extent">-20037508.342789244, -20037508.342780735, 20037508.342789244, 20037508.342780709</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, zoom, sql, intersection_SQL, db_user, db_name, db_srid, table_prefix, geom)
|
||||
elif type == "coast":
|
||||
if zoom < 9:
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="type">shape</Parameter>
|
||||
<Parameter name="file">%sshoreline_300</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, world_bnd_path)
|
||||
else:
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="type">shape</Parameter>
|
||||
<Parameter name="file">%sprocessed_p</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, world_bnd_path)
|
||||
layer_id = get_id(1)
|
||||
global substyles
|
||||
subs = "\n".join(["<StyleName>s%s</StyleName>"%i for i in substyles])
|
||||
substyles = []
|
||||
intersection_SQL = ""
|
||||
if zoom < 5:
|
||||
intersection_SQL = '<Parameter name="intersect_max_scale">1</Parameter>'
|
||||
elif zoom > 16:
|
||||
intersection_SQL = '<Parameter name="intersect_min_scale">500000000000</Parameter>'
|
||||
|
||||
|
||||
if type == "postgis":
|
||||
waystring = 'way'
|
||||
if zoom < 10:
|
||||
waystring = "ST_Simplify(way, %s) as way"%(pixel_size_at_zoom(zoom,0.6))
|
||||
if zoom >= 5:
|
||||
sql = 'way && !bbox! and '+ sql
|
||||
if geom == "polygon":
|
||||
sql = 'way_area > %s and '%(pixel_size_at_zoom(zoom,0.1)**2)+ sql
|
||||
interesting_tags = list(interesting_tags)
|
||||
if '"' not in "".join(interesting_tags) and "->" not in "".join(interesting_tags):
|
||||
interesting_tags = "\", \"".join(interesting_tags)
|
||||
interesting_tags = "\""+ interesting_tags+"\""
|
||||
else:
|
||||
interesting_tags = ", ".join(interesting_tags)
|
||||
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="table">
|
||||
( -- zoom %s
|
||||
select %s, %s
|
||||
from %s%s
|
||||
where %s
|
||||
) as k_layer
|
||||
</Parameter>
|
||||
%s
|
||||
<Parameter name="type">postgis</Parameter>
|
||||
<Parameter name="st_prefix">true</Parameter>
|
||||
<Parameter name="user">%s</Parameter>
|
||||
<Parameter name="dbname">%s</Parameter>
|
||||
<Parameter name="srid">%s</Parameter>
|
||||
<Parameter name="geometry_field">way</Parameter>
|
||||
<Parameter name="geometry_table">%s%s</Parameter>
|
||||
<Parameter name="estimate_extent">false</Parameter>
|
||||
<Parameter name="extent">-20037508.342789244, -20037508.342780735, 20037508.342789244, 20037508.342780709</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, zoom, interesting_tags, waystring, table_prefix, geom, sql, intersection_SQL, db_user, db_name, db_srid, table_prefix, geom)
|
||||
elif type == "postgis-process":
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="table">
|
||||
( -- zoom %s
|
||||
%s
|
||||
) as k_layer
|
||||
</Parameter>
|
||||
%s
|
||||
<Parameter name="type">postgis</Parameter>
|
||||
<Parameter name="st_prefix">true</Parameter>
|
||||
<Parameter name="user">%s</Parameter>
|
||||
<Parameter name="dbname">%s</Parameter>
|
||||
<Parameter name="srid">%s</Parameter>
|
||||
<Parameter name="geometry_field">way</Parameter>
|
||||
<Parameter name="geometry_table">%s%s</Parameter>
|
||||
<Parameter name="estimate_extent">false</Parameter>
|
||||
<Parameter name="extent">-20037508.342789244, -20037508.342780735, 20037508.342789244, 20037508.342780709</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, zoom, sql, intersection_SQL, db_user, db_name, db_srid, table_prefix, geom)
|
||||
elif type == "coast":
|
||||
if zoom < 9:
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="type">shape</Parameter>
|
||||
<Parameter name="file">%sshoreline_300</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, world_bnd_path)
|
||||
else:
|
||||
return """
|
||||
<Layer name="l%s" status="on" srs="%s">
|
||||
%s
|
||||
<Datasource>
|
||||
<Parameter name="type">shape</Parameter>
|
||||
<Parameter name="file">%sprocessed_p</Parameter>
|
||||
</Datasource>
|
||||
</Layer>"""%(layer_id, db_proj, subs, world_bnd_path)
|
||||
def xml_nolayer():
|
||||
global substyles
|
||||
substyles = []
|
||||
global substyles
|
||||
substyles = []
|
||||
def xml_nosubstyle():
|
||||
global substyles
|
||||
substyles = substyles[:-1]
|
||||
global substyles
|
||||
substyles = substyles[:-1]
|
||||
|
|
|
@ -24,8 +24,8 @@ from mapcss import MapCSS
|
|||
langs = ['int_name', 'name:af', 'name:am', 'name:ar', 'name:be', 'name:bg', 'name:br', 'name:ca', 'name:cs', 'name:cy', 'name:de', 'name:el', 'name:en', 'name:eo', 'name:es', 'name:et', 'name:eu', 'name:fa', 'name:fi', 'name:fr', 'name:fur', 'name:fy', 'name:ga', 'name:gd', 'name:gsw', 'name:he', 'name:hi', 'name:hr', 'name:hsb', 'name:hu', 'name:hy', 'name:it', 'name:ja', 'name:ja_kana', 'name:ja_rm', 'name:ka', 'name:kk', 'name:kn', 'name:ko', 'name:ko_rm', 'name:ku', 'name:la', 'name:lb', 'name:lt', 'name:lv', 'name:mk', 'name:mn', 'name:nl', 'name:pl', 'name:pt', 'name:ro', 'name:ru', 'name:sk', 'name:sl', 'name:sq', 'name:sr', 'name:sv', 'name:th', 'name:tr', 'name:uk', 'name:vi', 'name:zh', 'name:zh_pinyin']
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: make_postgis_style.py [stylesheet] [additional_tag,tag2,tag3]"
|
||||
exit()
|
||||
print "Usage: make_postgis_style.py [stylesheet] [additional_tag,tag2,tag3]"
|
||||
exit()
|
||||
|
||||
style = MapCSS(1, 19) #zoom levels
|
||||
style.parse(open(sys.argv[1],"r").read())
|
||||
|
@ -33,33 +33,33 @@ style.parse(open(sys.argv[1],"r").read())
|
|||
dct = {}
|
||||
|
||||
if len(sys.argv) >= 3:
|
||||
langs.extend(sys.argv[2].split(","))
|
||||
dct = dict([(k,set([("node", "linear"), ('way', 'linear')])) for k in langs])
|
||||
langs.extend(sys.argv[2].split(","))
|
||||
dct = dict([(k,set([("node", "linear"), ('way', 'linear')])) for k in langs])
|
||||
|
||||
t = {"node":("node", "linear"), "line":("way", "linear"), "area":("way", "polygon")}
|
||||
|
||||
for a in t:
|
||||
for tag in style.get_interesting_tags(type=a):
|
||||
if tag not in dct:
|
||||
dct[tag] = set()
|
||||
dct[tag].add(t[a])
|
||||
for tag in style.get_interesting_tags(type=a):
|
||||
if tag not in dct:
|
||||
dct[tag] = set()
|
||||
dct[tag].add(t[a])
|
||||
|
||||
print """
|
||||
# OsmType Tag DataType Flags"""
|
||||
for t in ("z_order","way_area",":area"):
|
||||
if t in dct:
|
||||
del dct[t]
|
||||
if t in dct:
|
||||
del dct[t]
|
||||
|
||||
keys = dct.keys()
|
||||
keys.sort()
|
||||
|
||||
for k in keys:
|
||||
v = dct[k]
|
||||
s = ",".join(set([i[0] for i in v]))
|
||||
pol = "linear"
|
||||
if "polygon" in set([i[1] for i in v]):
|
||||
pol = "polygon"
|
||||
print "%-10s %-20s %-13s %s"%(s, k, "text", pol)
|
||||
v = dct[k]
|
||||
s = ",".join(set([i[0] for i in v]))
|
||||
pol = "linear"
|
||||
if "polygon" in set([i[1] for i in v]):
|
||||
pol = "polygon"
|
||||
print "%-10s %-20s %-13s %s"%(s, k, "text", pol)
|
||||
print """
|
||||
node,way z_order int4 linear # This is calculated during import
|
||||
way way_area real # This is calculated during import"""
|
||||
|
|
286
src/osm2tiles.py
286
src/osm2tiles.py
|
@ -23,13 +23,13 @@ from twms import projections
|
|||
from style import Styling
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding("utf-8") # a hack to support UTF-8
|
||||
sys.setdefaultencoding("utf-8") # a hack to support UTF-8
|
||||
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
import psyco
|
||||
psyco.full()
|
||||
except ImportError:
|
||||
pass
|
||||
pass
|
||||
|
||||
MAXZOOM = 16
|
||||
TEMPORARY_FILE_PATH = 'temp_file.bin'
|
||||
|
@ -41,179 +41,179 @@ style = Styling()
|
|||
# elsif($k eq 'highway' and $v eq 'footway' or $v eq 'path' or $v eq 'track'){
|
||||
|
||||
def tilelist_by_geometry(way, start_zoom = 0, ispoly = False):
|
||||
"""
|
||||
Gives a number of (z,x,y) tile numbers that geometry crosses.
|
||||
"""
|
||||
ret = set([])
|
||||
tiles_by_zooms = {} # zoom: set(tile,tile,tile...)
|
||||
for t in xrange(0,MAXZOOM+1):
|
||||
tiles_by_zooms[t] = set([])
|
||||
for point in way:
|
||||
tile = projections.tile_by_coords(point, MAXZOOM, proj)
|
||||
tile = (MAXZOOM, int(tile[0]),int(tile[1]))
|
||||
tiles_by_zooms[MAXZOOM].add(tile)
|
||||
for t in xrange(MAXZOOM-1,start_zoom-1,-1):
|
||||
for tt in tiles_by_zooms[t+1]:
|
||||
tiles_by_zooms[t].add((t, int(tt[1]/2), int(tt[2]/2)))
|
||||
for z in tiles_by_zooms.values():
|
||||
ret.update(z)
|
||||
return ret
|
||||
"""
|
||||
Gives a number of (z,x,y) tile numbers that geometry crosses.
|
||||
"""
|
||||
ret = set([])
|
||||
tiles_by_zooms = {} # zoom: set(tile,tile,tile...)
|
||||
for t in xrange(0,MAXZOOM+1):
|
||||
tiles_by_zooms[t] = set([])
|
||||
for point in way:
|
||||
tile = projections.tile_by_coords(point, MAXZOOM, proj)
|
||||
tile = (MAXZOOM, int(tile[0]),int(tile[1]))
|
||||
tiles_by_zooms[MAXZOOM].add(tile)
|
||||
for t in xrange(MAXZOOM-1,start_zoom-1,-1):
|
||||
for tt in tiles_by_zooms[t+1]:
|
||||
tiles_by_zooms[t].add((t, int(tt[1]/2), int(tt[2]/2)))
|
||||
for z in tiles_by_zooms.values():
|
||||
ret.update(z)
|
||||
return ret
|
||||
|
||||
def pix_distance(a,b,z):
|
||||
"""
|
||||
Calculates onscreen distance between 2 points on given zoom.
|
||||
"""
|
||||
return 2**z*256*(((a[0]-b[0])/360.)**2+((a[1]-b[1])/180.)**2)**0.5
|
||||
"""
|
||||
Calculates onscreen distance between 2 points on given zoom.
|
||||
"""
|
||||
return 2**z*256*(((a[0]-b[0])/360.)**2+((a[1]-b[1])/180.)**2)**0.5
|
||||
|
||||
def sanitize(string):
|
||||
string=string.replace(" ", "_")
|
||||
string=string.replace(";", ",")
|
||||
string=string.replace("=", "###")
|
||||
return string
|
||||
string=string.replace(" ", "_")
|
||||
string=string.replace(";", ",")
|
||||
string=string.replace("=", "###")
|
||||
return string
|
||||
|
||||
print sanitize (" ;=")
|
||||
|
||||
def initDB(filename):
|
||||
conn = sqlite3.connect(filename)
|
||||
c = conn.cursor()
|
||||
# create table
|
||||
c.execute('''CREATE TABLE nodes (id integer, lat real, lon real)''')
|
||||
# create index in the id column
|
||||
# - this makes node id lookup MUCH faster
|
||||
c.execute('''CREATE INDEX id_idx ON nodes(id)''')
|
||||
return conn
|
||||
conn = sqlite3.connect(filename)
|
||||
c = conn.cursor()
|
||||
# create table
|
||||
c.execute('''CREATE TABLE nodes (id integer, lat real, lon real)''')
|
||||
# create index in the id column
|
||||
# - this makes node id lookup MUCH faster
|
||||
c.execute('''CREATE INDEX id_idx ON nodes(id)''')
|
||||
return conn
|
||||
|
||||
def storeNode(conn, id, lat, lon):
|
||||
# conn.execute("INSERT INTO nodes VALUES ('%d', %f, %f)" % (id, lat, lon))
|
||||
conn.execute("INSERT INTO nodes(id, lat, lon) values (?, ?, ?)", (id, lat, lon))
|
||||
conn.execute("INSERT INTO nodes(id, lat, lon) values (?, ?, ?)", (id, lat, lon))
|
||||
|
||||
def getNode(conn, id):
|
||||
# conn.execute("SELECT * FROM nodes WHERE id = '%s'" % id)
|
||||
return conn.execute("SELECT lat, lon FROM nodes WHERE id = '%s'" % id).fetchone()
|
||||
return conn.execute("SELECT lat, lon FROM nodes WHERE id = '%s'" % id).fetchone()
|
||||
|
||||
def main ():
|
||||
DROPPED_POINTS = 0
|
||||
WAYS_WRITTEN = 0
|
||||
NODES_READ = 0
|
||||
WAYS_READ = 0
|
||||
tilefiles = {}
|
||||
tilefiles_hist = []
|
||||
#osm_infile = open("minsk.osm", "rb")
|
||||
osm_infile = sys.stdin
|
||||
DROPPED_POINTS = 0
|
||||
WAYS_WRITTEN = 0
|
||||
NODES_READ = 0
|
||||
WAYS_READ = 0
|
||||
tilefiles = {}
|
||||
tilefiles_hist = []
|
||||
#osm_infile = open("minsk.osm", "rb")
|
||||
osm_infile = sys.stdin
|
||||
|
||||
# remove any stale temporary files
|
||||
if os.path.exists(TEMPORARY_FILE_PATH):
|
||||
os.remove(TEMPORARY_FILE_PATH)
|
||||
conn = initDB(TEMPORARY_FILE_PATH)
|
||||
# remove any stale temporary files
|
||||
if os.path.exists(TEMPORARY_FILE_PATH):
|
||||
os.remove(TEMPORARY_FILE_PATH)
|
||||
conn = initDB(TEMPORARY_FILE_PATH)
|
||||
|
||||
# nodes = {}
|
||||
curway = []
|
||||
tags = {}
|
||||
context = etree.iterparse(osm_infile)
|
||||
for action, elem in context:
|
||||
items = dict(elem.items())
|
||||
if elem.tag == "node":
|
||||
NODES_READ += 1
|
||||
if NODES_READ % 10000 == 0:
|
||||
print "Nodes read:", NODES_READ
|
||||
print len(curway), len(tags), len(tilefiles), len(tilefiles_hist)
|
||||
if NODES_READ % 100000 == 0:
|
||||
conn.commit()
|
||||
print "flushing to temporary storage"
|
||||
curway = []
|
||||
tags = {}
|
||||
context = etree.iterparse(osm_infile)
|
||||
for action, elem in context:
|
||||
items = dict(elem.items())
|
||||
if elem.tag == "node":
|
||||
NODES_READ += 1
|
||||
if NODES_READ % 10000 == 0:
|
||||
print "Nodes read:", NODES_READ
|
||||
print len(curway), len(tags), len(tilefiles), len(tilefiles_hist)
|
||||
if NODES_READ % 100000 == 0:
|
||||
conn.commit()
|
||||
print "flushing to temporary storage"
|
||||
|
||||
# nodes[str(items["id"])] = (float(items["lon"]), float(items["lat"]))
|
||||
storeNode(conn, int(items["id"]), float(items["lon"]), float(items["lat"]))
|
||||
tags = {}
|
||||
elif elem.tag == "nd":
|
||||
result = getNode(conn, int(items["ref"]))
|
||||
if result:
|
||||
curway.append(result)
|
||||
storeNode(conn, int(items["id"]), float(items["lon"]), float(items["lat"]))
|
||||
tags = {}
|
||||
elif elem.tag == "nd":
|
||||
result = getNode(conn, int(items["ref"]))
|
||||
if result:
|
||||
curway.append(result)
|
||||
# try:
|
||||
# curway.append(nodes[str(items["ref"])])
|
||||
# except KeyError:
|
||||
# pass
|
||||
elif elem.tag == "tag":
|
||||
tags[sanitize(items["k"])] = sanitize(items["v"])
|
||||
elif elem.tag == "way":
|
||||
WAYS_READ += 1
|
||||
if WAYS_READ % 1000 == 0:
|
||||
print "Ways read:", WAYS_READ
|
||||
|
||||
mzoom = 1
|
||||
#tags = style.filter_tags(tags)
|
||||
if tags:
|
||||
if True:#style.get_style("way", tags, True): # if way is stylized
|
||||
towrite = ";".join(["%s=%s"%x for x in tags.iteritems()]) ### TODO: sanitize keys and values
|
||||
#print towrite
|
||||
way_simplified = {MAXZOOM: curway}
|
||||
elif elem.tag == "tag":
|
||||
tags[sanitize(items["k"])] = sanitize(items["v"])
|
||||
elif elem.tag == "way":
|
||||
WAYS_READ += 1
|
||||
if WAYS_READ % 1000 == 0:
|
||||
print "Ways read:", WAYS_READ
|
||||
|
||||
for zoom in xrange(MAXZOOM-1,-1,-1): ######## generalize a bit
|
||||
# TODO: Douglas-Peucker
|
||||
prev_point = curway[0]
|
||||
way = [prev_point]
|
||||
for point in way_simplified[zoom+1]:
|
||||
if pix_distance(point, prev_point, zoom) > 1.5:
|
||||
way.append(point)
|
||||
prev_point = point
|
||||
else:
|
||||
DROPPED_POINTS += 1
|
||||
mzoom = 1
|
||||
#tags = style.filter_tags(tags)
|
||||
if tags:
|
||||
if True:#style.get_style("way", tags, True): # if way is stylized
|
||||
towrite = ";".join(["%s=%s"%x for x in tags.iteritems()]) ### TODO: sanitize keys and values
|
||||
#print towrite
|
||||
way_simplified = {MAXZOOM: curway}
|
||||
|
||||
if len(way) == 1:
|
||||
mzoom = zoom
|
||||
#print zoom
|
||||
break
|
||||
if len(way) > 1:
|
||||
way_simplified[zoom] = way
|
||||
#print way
|
||||
for tile in tilelist_by_geometry(curway, mzoom+1):
|
||||
z, x, y = tile
|
||||
path = "tiles/z%s/%s/x%s/%s/"%(z, x/1024, x, y/1024)
|
||||
if tile not in tilefiles:
|
||||
for zoom in xrange(MAXZOOM-1,-1,-1): ######## generalize a bit
|
||||
# TODO: Douglas-Peucker
|
||||
prev_point = curway[0]
|
||||
way = [prev_point]
|
||||
for point in way_simplified[zoom+1]:
|
||||
if pix_distance(point, prev_point, zoom) > 1.5:
|
||||
way.append(point)
|
||||
prev_point = point
|
||||
else:
|
||||
DROPPED_POINTS += 1
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
tilefiles[tile] = open(path+"y"+str(y)+".vtile","wb")
|
||||
tilefiles_hist.append(tile)
|
||||
else:
|
||||
if not tilefiles[tile]:
|
||||
tilefiles[tile] = open(path+"y"+str(y)+".vtile","a")
|
||||
tilefiles_hist.append(tile)
|
||||
tilefiles_hist.remove(tile)
|
||||
tilefiles_hist.append(tile)
|
||||
print >>tilefiles[tile], "%s %s" % (towrite, items["id"]), " ".join([str(x[0])+" "+str(x[1]) for x in way_simplified[tile[0]]])
|
||||
if len(tilefiles_hist) > 400:
|
||||
print "Cleaned up tiles. Wrote by now:", len(tilefiles),"active:",len(tilefiles_hist)
|
||||
for tile in tilefiles_hist[0:len(tilefiles_hist)-100]:
|
||||
if len(way) == 1:
|
||||
mzoom = zoom
|
||||
#print zoom
|
||||
break
|
||||
if len(way) > 1:
|
||||
way_simplified[zoom] = way
|
||||
#print way
|
||||
for tile in tilelist_by_geometry(curway, mzoom+1):
|
||||
z, x, y = tile
|
||||
path = "tiles/z%s/%s/x%s/%s/"%(z, x/1024, x, y/1024)
|
||||
if tile not in tilefiles:
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
tilefiles[tile] = open(path+"y"+str(y)+".vtile","wb")
|
||||
tilefiles_hist.append(tile)
|
||||
else:
|
||||
if not tilefiles[tile]:
|
||||
tilefiles[tile] = open(path+"y"+str(y)+".vtile","a")
|
||||
tilefiles_hist.append(tile)
|
||||
tilefiles_hist.remove(tile)
|
||||
tilefiles_hist.append(tile)
|
||||
print >>tilefiles[tile], "%s %s" % (towrite, items["id"]), " ".join([str(x[0])+" "+str(x[1]) for x in way_simplified[tile[0]]])
|
||||
if len(tilefiles_hist) > 400:
|
||||
print "Cleaned up tiles. Wrote by now:", len(tilefiles),"active:",len(tilefiles_hist)
|
||||
for tile in tilefiles_hist[0:len(tilefiles_hist)-100]:
|
||||
|
||||
|
||||
tilefiles_hist.remove(tile)
|
||||
tilefiles[tile].flush()
|
||||
tilefiles[tile].close()
|
||||
tilefiles[tile] = None
|
||||
tilefiles_hist.remove(tile)
|
||||
tilefiles[tile].flush()
|
||||
tilefiles[tile].close()
|
||||
tilefiles[tile] = None
|
||||
|
||||
|
||||
#print >>corr, "%s %s %s %s %s %s"% (curway[0][0],curway[0][1],curway[1][0],curway[1][1], user, ts )
|
||||
WAYS_WRITTEN += 1
|
||||
if WAYS_WRITTEN % 10000 == 0:
|
||||
print WAYS_WRITTEN
|
||||
curway = []
|
||||
tags = {}
|
||||
elem.clear()
|
||||
# extra insurance
|
||||
del elem
|
||||
#user = default_user
|
||||
#ts = ""
|
||||
print "Tiles generated:",len(tilefiles)
|
||||
print "Nodes dropped when generalizing:", DROPPED_POINTS
|
||||
#print >>corr, "%s %s %s %s %s %s"% (curway[0][0],curway[0][1],curway[1][0],curway[1][1], user, ts )
|
||||
WAYS_WRITTEN += 1
|
||||
if WAYS_WRITTEN % 10000 == 0:
|
||||
print WAYS_WRITTEN
|
||||
curway = []
|
||||
tags = {}
|
||||
elem.clear()
|
||||
# extra insurance
|
||||
del elem
|
||||
#user = default_user
|
||||
#ts = ""
|
||||
print "Tiles generated:",len(tilefiles)
|
||||
print "Nodes dropped when generalizing:", DROPPED_POINTS
|
||||
# print "Nodes in memory:", len(nodes)
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * from nodes')
|
||||
print "Nodes in memory:", len(c.fetchall())
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT * from nodes')
|
||||
print "Nodes in memory:", len(c.fetchall())
|
||||
|
||||
# report temporary file size
|
||||
print "Temporary file size:", os.path.getsize(TEMPORARY_FILE_PATH)
|
||||
# report temporary file size
|
||||
print "Temporary file size:", os.path.getsize(TEMPORARY_FILE_PATH)
|
||||
|
||||
# remove temporary files
|
||||
os.remove(TEMPORARY_FILE_PATH)
|
||||
# remove temporary files
|
||||
os.remove(TEMPORARY_FILE_PATH)
|
||||
|
||||
main()
|
||||
|
|
|
@ -23,7 +23,7 @@ This is a module to substitute debug.py in porduction mode.
|
|||
|
||||
debug = lambda st: None
|
||||
class Timer:
|
||||
def __init__(self, comment):
|
||||
pass
|
||||
def stop(self):
|
||||
pass
|
||||
def __init__(self, comment):
|
||||
pass
|
||||
def stop(self):
|
||||
pass
|
||||
|
|
976
src/render.py
976
src/render.py
File diff suppressed because it is too large
Load diff
|
@ -40,10 +40,10 @@ db = DataBackend()
|
|||
|
||||
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
import psyco
|
||||
psyco.full()
|
||||
except ImportError:
|
||||
pass
|
||||
pass
|
||||
|
||||
OK = 200
|
||||
ERROR = 500
|
||||
|
@ -63,8 +63,8 @@ urls = (
|
|||
'/(.*)', 'mainhandler'
|
||||
)
|
||||
class mainhandler:
|
||||
def GET(self, crap):
|
||||
return handler()
|
||||
def GET(self, crap):
|
||||
return handler()
|
||||
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@ def twms_main(req):
|
|||
height=0
|
||||
req_bbox = ()
|
||||
if data.get("bbox",data.get("BBOX",None)):
|
||||
req_bbox = tuple(map(float,data.get("bbox",data.get("BBOX",req_bbox)).split(",")))
|
||||
req_bbox = tuple(map(float,data.get("bbox",data.get("BBOX",req_bbox)).split(",")))
|
||||
|
||||
req_bbox = projections.to4326(req_bbox, srs)
|
||||
|
||||
|
@ -102,11 +102,10 @@ def twms_main(req):
|
|||
image_content = StringIO.StringIO()
|
||||
|
||||
|
||||
|
||||
|
||||
res.surface.write_to_png(image_content)
|
||||
|
||||
|
||||
|
||||
|
||||
resp = image_content.getvalue()
|
||||
return (OK, content_type, resp)
|
||||
|
||||
|
|
256
src/style.py
256
src/style.py
|
@ -23,136 +23,136 @@ from debug import debug
|
|||
from mapcss.webcolors.webcolors import whatever_to_cairo as colorparser
|
||||
|
||||
class Styling():
|
||||
"""
|
||||
Class used to choose the right way of rendering an object.
|
||||
"""
|
||||
def __init__(self, stylefile = None):
|
||||
self.Selectors = {}
|
||||
self.Selectors["way"] = []
|
||||
self.Selectors["node"] = []
|
||||
self.Selectors["relation"] = []
|
||||
if not stylefile:
|
||||
# self.Selectors["way"].append(StyleSelector( ( [ ( ("building",),(None) ) ] ),{"fill-color": "#00f"} ))
|
||||
|
||||
#if stylefile=="zzzz":
|
||||
### using "builtin" styling
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("area",),("yes") ) ] ),{"fill-color": "#ff0000"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),(None) ) ] ),{"width":1,"color":"#ff0000","text": "name", "text-position":"line","text-halo-radius":2,} ))
|
||||
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("barrier",),(None) ) ] ),{"casing-width":1,} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("residential", "tertiary", "living_street")) ] ),{"width": 3, "color":"#ffffff", "casing-width": 5, "z-index":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("service", "unclassified")) ] ),{"width": 2.5, "color":"#ccc", "casing-width": 4, "z-index":9} ))
|
||||
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("primary", "motorway", "trunk")) ] ),{"width": 4, "color":"#ff0", "casing-width": 6, "z-index":11} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("primary_link", "motorway_link", "trunk_link")) ] ),{"width": 3.5, "color":"#ff0", "casing-width": 6, "z-index":11} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("secondary", )) ] ),{"width": 4, "color":"orange", "casing-width": 6, "z-index":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("living_street",),("yes")) ] ),{"width": 2, "casing-width": 3, "z-index": 0} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse","natural"),("forest", "wood") ) ] ),{"fill-color": "#020"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse",),("industrial",) ) ] ),{"fill-color": "#855"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse",),("military",) ) ] ),{"fill-color": "pink"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("waterway","natural"),("riverbank", "water") ) ] ),{"fill-color": "#002"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("waterway","natural"),("river", "stream") ) ] ),{"color": "#002"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse","natural"),("grass",) ) ] ),{"fill-color": "#050",} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("footway","pedestrian","path" )) ] ),{"width":2.5, "color":"#655", "dashes": [3,1],"z-index":3} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("bridge",),("yes") ) ] ),{"casing-width":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("power",),("line",)) ] ),{"width": 1, "color":"#ccc",} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("building",),(None) ) ] ),{"fill-color": "#522","text": "addr:housenumber","text-halo-radius":2,"z-index":100} ))#"extrude":10,
|
||||
|
||||
self.stylefile = stylefile
|
||||
self.useful_keys = set(["layer"])
|
||||
for objtype in self.Selectors.values(): # getting useful keys
|
||||
for selector in objtype:
|
||||
#debug(selector)
|
||||
for tag in selector.tags:
|
||||
self.useful_keys.update(set(tag[0]))
|
||||
if "text" in selector.style:
|
||||
self.useful_keys.update(set((selector.style["text"],)))
|
||||
debug(self.useful_keys)
|
||||
|
||||
|
||||
|
||||
def get_style(self, objtype, tags, nodata = False):
|
||||
"""
|
||||
objtype is "node", "way" or "relation"
|
||||
tags - object tags
|
||||
nodata - we won't render that now, don't need exact styling
|
||||
Class used to choose the right way of rendering an object.
|
||||
"""
|
||||
resp = {}
|
||||
for selector in self.Selectors[objtype]:
|
||||
resp.update(selector.get_style(tags))
|
||||
if nodata:
|
||||
if resp:
|
||||
return True
|
||||
if not nodata and resp:
|
||||
#debug((tags, tags.get("layer",0)), )
|
||||
try:
|
||||
resp["layer"] = int(tags.get("layer",0))*100+resp.get("z-index",0)+1000
|
||||
except ValueError:
|
||||
resp["layer"] = 1000000
|
||||
|
||||
if "text" in resp: # unpacking text
|
||||
if resp["text"] in tags:
|
||||
resp["text"] = tags[resp["text"]]
|
||||
#debug("text: %s"%resp["text"])
|
||||
else:
|
||||
del resp["text"]
|
||||
return resp
|
||||
def filter_tags(self, tags):
|
||||
"""
|
||||
Returns only tags that are useful for rendering
|
||||
"""
|
||||
#resp = {}
|
||||
#for k,v in tags.iteritems():
|
||||
# if k in self.useful_keys:
|
||||
# resp[k] = v
|
||||
return tags
|
||||
def __init__(self, stylefile = None):
|
||||
self.Selectors = {}
|
||||
self.Selectors["way"] = []
|
||||
self.Selectors["node"] = []
|
||||
self.Selectors["relation"] = []
|
||||
if not stylefile:
|
||||
# self.Selectors["way"].append(StyleSelector( ( [ ( ("building",),(None) ) ] ),{"fill-color": "#00f"} ))
|
||||
|
||||
#if stylefile=="zzzz":
|
||||
### using "builtin" styling
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("area",),("yes") ) ] ),{"fill-color": "#ff0000"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),(None) ) ] ),{"width":1,"color":"#ff0000","text": "name", "text-position":"line","text-halo-radius":2,} ))
|
||||
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("barrier",),(None) ) ] ),{"casing-width":1,} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("residential", "tertiary", "living_street")) ] ),{"width": 3, "color":"#ffffff", "casing-width": 5, "z-index":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("service", "unclassified")) ] ),{"width": 2.5, "color":"#ccc", "casing-width": 4, "z-index":9} ))
|
||||
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("primary", "motorway", "trunk")) ] ),{"width": 4, "color":"#ff0", "casing-width": 6, "z-index":11} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("primary_link", "motorway_link", "trunk_link")) ] ),{"width": 3.5, "color":"#ff0", "casing-width": 6, "z-index":11} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("secondary", )) ] ),{"width": 4, "color":"orange", "casing-width": 6, "z-index":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("living_street",),("yes")) ] ),{"width": 2, "casing-width": 3, "z-index": 0} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse","natural"),("forest", "wood") ) ] ),{"fill-color": "#020"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse",),("industrial",) ) ] ),{"fill-color": "#855"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse",),("military",) ) ] ),{"fill-color": "pink"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("waterway","natural"),("riverbank", "water") ) ] ),{"fill-color": "#002"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("waterway","natural"),("river", "stream") ) ] ),{"color": "#002"} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("landuse","natural"),("grass",) ) ] ),{"fill-color": "#050",} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("highway",),("footway","pedestrian","path" )) ] ),{"width":2.5, "color":"#655", "dashes": [3,1],"z-index":3} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("bridge",),("yes") ) ] ),{"casing-width":10} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("power",),("line",)) ] ),{"width": 1, "color":"#ccc",} ))
|
||||
self.Selectors["way"].append(StyleSelector( ( [ ( ("building",),(None) ) ] ),{"fill-color": "#522","text": "addr:housenumber","text-halo-radius":2,"z-index":100} ))#"extrude":10,
|
||||
|
||||
self.stylefile = stylefile
|
||||
self.useful_keys = set(["layer"])
|
||||
for objtype in self.Selectors.values(): # getting useful keys
|
||||
for selector in objtype:
|
||||
#debug(selector)
|
||||
for tag in selector.tags:
|
||||
self.useful_keys.update(set(tag[0]))
|
||||
if "text" in selector.style:
|
||||
self.useful_keys.update(set((selector.style["text"],)))
|
||||
debug(self.useful_keys)
|
||||
|
||||
|
||||
|
||||
def get_style(self, objtype, tags, nodata = False):
|
||||
"""
|
||||
objtype is "node", "way" or "relation"
|
||||
tags - object tags
|
||||
nodata - we won't render that now, don't need exact styling
|
||||
"""
|
||||
resp = {}
|
||||
for selector in self.Selectors[objtype]:
|
||||
resp.update(selector.get_style(tags))
|
||||
if nodata:
|
||||
if resp:
|
||||
return True
|
||||
if not nodata and resp:
|
||||
#debug((tags, tags.get("layer",0)), )
|
||||
try:
|
||||
resp["layer"] = int(tags.get("layer",0))*100+resp.get("z-index",0)+1000
|
||||
except ValueError:
|
||||
resp["layer"] = 1000000
|
||||
|
||||
if "text" in resp: # unpacking text
|
||||
if resp["text"] in tags:
|
||||
resp["text"] = tags[resp["text"]]
|
||||
#debug("text: %s"%resp["text"])
|
||||
else:
|
||||
del resp["text"]
|
||||
return resp
|
||||
def filter_tags(self, tags):
|
||||
"""
|
||||
Returns only tags that are useful for rendering
|
||||
"""
|
||||
#resp = {}
|
||||
#for k,v in tags.iteritems():
|
||||
# if k in self.useful_keys:
|
||||
# resp[k] = v
|
||||
return tags
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class StyleSelector():
|
||||
def __init__(self, tags, style):
|
||||
"""
|
||||
Selector that decides if that style is right for the object
|
||||
tags - list of tags [(("key","key"..), ("value", "value"...)), (("key","key"..), ("value", "value"...))]
|
||||
style - MapCSS rules to apply
|
||||
"""
|
||||
self.tags = tags
|
||||
self.style = {}
|
||||
for key in style:
|
||||
|
||||
keyz = key.lower()
|
||||
|
||||
if "color" in keyz:
|
||||
self.style[keyz] = colorparser(style[key])
|
||||
debug((colorparser(style[key]),style[key]))
|
||||
else:
|
||||
self.style[keyz] = style[key]
|
||||
|
||||
def get_style(self, tags):
|
||||
"""
|
||||
Get actual styling for object.
|
||||
"""
|
||||
styled = False
|
||||
#debug(self.tags)
|
||||
for k,v in self.tags:
|
||||
for j in k:
|
||||
if j in tags:
|
||||
if v:
|
||||
if tags[j] in v:
|
||||
styled = True
|
||||
else:
|
||||
styled = True
|
||||
if styled:
|
||||
return self.style
|
||||
return {}
|
||||
|
||||
def __init__(self, tags, style):
|
||||
"""
|
||||
Selector that decides if that style is right for the object
|
||||
tags - list of tags [(("key","key"..), ("value", "value"...)), (("key","key"..), ("value", "value"...))]
|
||||
style - MapCSS rules to apply
|
||||
"""
|
||||
self.tags = tags
|
||||
self.style = {}
|
||||
for key in style:
|
||||
|
||||
keyz = key.lower()
|
||||
|
||||
if "color" in keyz:
|
||||
self.style[keyz] = colorparser(style[key])
|
||||
debug((colorparser(style[key]),style[key]))
|
||||
else:
|
||||
self.style[keyz] = style[key]
|
||||
|
||||
def get_style(self, tags):
|
||||
"""
|
||||
Get actual styling for object.
|
||||
"""
|
||||
styled = False
|
||||
#debug(self.tags)
|
||||
for k,v in self.tags:
|
||||
for j in k:
|
||||
if j in tags:
|
||||
if v:
|
||||
if tags[j] in v:
|
||||
styled = True
|
||||
else:
|
||||
styled = True
|
||||
if styled:
|
||||
return self.style
|
||||
return {}
|
||||
|
||||
if __name__ == "__main__":
|
||||
c = Styling()
|
||||
print c.get_style("way", {"building":"yes"})
|
||||
print c.get_style("way", {"highway":"residential"})
|
||||
print c.get_style("way", {"highway":"road"})
|
||||
print c.get_style("way", {"highway":"residential", "building": "yes"})
|
||||
print c.get_style("way", {"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs"})
|
||||
print c.get_style("way", {"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs"}, True)
|
||||
print c.get_style("way", {"highway":"residential", "building": "yes"}, True)
|
||||
print c.filter_tags({"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs", "building": "residential"})
|
||||
c = Styling()
|
||||
print c.get_style("way", {"building":"yes"})
|
||||
print c.get_style("way", {"highway":"residential"})
|
||||
print c.get_style("way", {"highway":"road"})
|
||||
print c.get_style("way", {"highway":"residential", "building": "yes"})
|
||||
print c.get_style("way", {"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs"})
|
||||
print c.get_style("way", {"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs"}, True)
|
||||
print c.get_style("way", {"highway":"residential", "building": "yes"}, True)
|
||||
print c.filter_tags({"highwadfgaay":"resifdgsdential", "builafgding": "yedfgs", "building": "residential"})
|
||||
|
|
|
@ -37,87 +37,87 @@ metatiles_in_progress = {}
|
|||
renderlock = threading.Lock()
|
||||
|
||||
def kothic_fetcher (z, x, y, this_layer):
|
||||
if "max_zoom" in this_layer:
|
||||
if z >= this_layer["max_zoom"]:
|
||||
return None
|
||||
bbox = projections.bbox_by_tile(z,x,y,"EPSG:3857")
|
||||
db = DataBackend(path="/home/kom/osm/kothic/src/tiles")
|
||||
res = RasterTile(256, 256, 1, db, "EPSG:3857")
|
||||
res.update_surface(bbox, z, style)
|
||||
f = NamedTemporaryFile()
|
||||
f.close()
|
||||
res.surface.write_to_png(f.name)
|
||||
del res
|
||||
del db
|
||||
im = Image.open(f.name)
|
||||
os.unlink(f.name)
|
||||
im = im.convert("RGBA")
|
||||
if "max_zoom" in this_layer:
|
||||
if z >= this_layer["max_zoom"]:
|
||||
return None
|
||||
bbox = projections.bbox_by_tile(z,x,y,"EPSG:3857")
|
||||
db = DataBackend(path="/home/kom/osm/kothic/src/tiles")
|
||||
res = RasterTile(256, 256, 1, db, "EPSG:3857")
|
||||
res.update_surface(bbox, z, style)
|
||||
f = NamedTemporaryFile()
|
||||
f.close()
|
||||
res.surface.write_to_png(f.name)
|
||||
del res
|
||||
del db
|
||||
im = Image.open(f.name)
|
||||
os.unlink(f.name)
|
||||
im = im.convert("RGBA")
|
||||
|
||||
return im
|
||||
|
||||
return im
|
||||
|
||||
|
||||
def kothic_metatile(z, x, y, this_layer):
|
||||
|
||||
print z, x, y
|
||||
global metatiles_in_progress
|
||||
if "max_zoom" in this_layer:
|
||||
if z >= this_layer["max_zoom"]:
|
||||
return None
|
||||
if z<5:
|
||||
return None
|
||||
|
||||
metatile_id = (z,int(x/8), int(y/8))
|
||||
|
||||
try:
|
||||
metatiles_in_progress[metatile_id].join()
|
||||
except KeyError:
|
||||
metatiles_in_progress[metatile_id] = threading.Thread(None, gen_metatile, None, (metatile_id, this_layer))
|
||||
metatiles_in_progress[metatile_id].start()
|
||||
metatiles_in_progress[metatile_id].join()
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
|
||||
local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y)
|
||||
ext = this_layer["ext"]
|
||||
if os.path.exists(local+ext): # First, look for tile in cache
|
||||
print z, x, y
|
||||
global metatiles_in_progress
|
||||
if "max_zoom" in this_layer:
|
||||
if z >= this_layer["max_zoom"]:
|
||||
return None
|
||||
if z<5:
|
||||
return None
|
||||
|
||||
metatile_id = (z,int(x/8), int(y/8))
|
||||
|
||||
try:
|
||||
im1 = Image.open(local+ext)
|
||||
del metatiles_in_progress[metatile_id]
|
||||
return im1
|
||||
except IOError:
|
||||
os.remove(local+ext)
|
||||
metatiles_in_progress[metatile_id].join()
|
||||
except KeyError:
|
||||
metatiles_in_progress[metatile_id] = threading.Thread(None, gen_metatile, None, (metatile_id, this_layer))
|
||||
metatiles_in_progress[metatile_id].start()
|
||||
metatiles_in_progress[metatile_id].join()
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
|
||||
local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y)
|
||||
ext = this_layer["ext"]
|
||||
if os.path.exists(local+ext): # First, look for tile in cache
|
||||
try:
|
||||
im1 = Image.open(local+ext)
|
||||
del metatiles_in_progress[metatile_id]
|
||||
return im1
|
||||
except IOError:
|
||||
os.remove(local+ext)
|
||||
|
||||
def gen_metatile(metatile_id, this_layer):
|
||||
#renderlock.acquire()
|
||||
z, x, y = metatile_id
|
||||
z -= 3
|
||||
wh = 2560
|
||||
bb1 = projections.coords_by_tile(z, x-0.125, y-0.125, "EPSG:3857")
|
||||
bb2 = projections.coords_by_tile(z, x+1.125, y+1.125, "EPSG:3857")
|
||||
bbox = (bb1[0],bb2[1],bb2[0],bb1[1])
|
||||
db = DataBackend()
|
||||
res = RasterTile(wh, wh, 1, db, "EPSG:3857")
|
||||
res.update_surface(bbox, z+3, style)
|
||||
f = NamedTemporaryFile()
|
||||
f.close()
|
||||
res.surface.write_to_png(f.name)
|
||||
del res
|
||||
del db
|
||||
im = Image.open(f.name)
|
||||
os.unlink(f.name)
|
||||
im = im.convert("RGBA")
|
||||
x*=8
|
||||
y*=8
|
||||
z+=3
|
||||
ext = this_layer["ext"]
|
||||
for i in range(x,x+9):
|
||||
for j in range(y,y+9):
|
||||
local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, i/1024, i, j/1024,j)
|
||||
box = (256*(i-x+1),256*(j-y+1),256*(i-x+2),256*(j-y+2))
|
||||
im1 = im.crop(box)
|
||||
if not os.path.exists("/".join(local.split("/")[:-1])):
|
||||
os.makedirs("/".join(local.split("/")[:-1]))
|
||||
im1.save(local+ext)
|
||||
del im1
|
||||
#renderlock.release()
|
||||
#renderlock.acquire()
|
||||
z, x, y = metatile_id
|
||||
z -= 3
|
||||
wh = 2560
|
||||
bb1 = projections.coords_by_tile(z, x-0.125, y-0.125, "EPSG:3857")
|
||||
bb2 = projections.coords_by_tile(z, x+1.125, y+1.125, "EPSG:3857")
|
||||
bbox = (bb1[0],bb2[1],bb2[0],bb1[1])
|
||||
db = DataBackend()
|
||||
res = RasterTile(wh, wh, 1, db, "EPSG:3857")
|
||||
res.update_surface(bbox, z+3, style)
|
||||
f = NamedTemporaryFile()
|
||||
f.close()
|
||||
res.surface.write_to_png(f.name)
|
||||
del res
|
||||
del db
|
||||
im = Image.open(f.name)
|
||||
os.unlink(f.name)
|
||||
im = im.convert("RGBA")
|
||||
x*=8
|
||||
y*=8
|
||||
z+=3
|
||||
ext = this_layer["ext"]
|
||||
for i in range(x,x+9):
|
||||
for j in range(y,y+9):
|
||||
local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, i/1024, i, j/1024,j)
|
||||
box = (256*(i-x+1),256*(j-y+1),256*(i-x+2),256*(j-y+2))
|
||||
im1 = im.crop(box)
|
||||
if not os.path.exists("/".join(local.split("/")[:-1])):
|
||||
os.makedirs("/".join(local.split("/")[:-1]))
|
||||
im1.save(local+ext)
|
||||
del im1
|
||||
#renderlock.release()
|
||||
|
|
Loading…
Add table
Reference in a new issue