def composite(size,im1,im2 = None, opts = None): if not im2: im2 = Image.new('RGBA', (size,size), (255, 255, 255, 255)) if opts and 'colorToAlpha' in opts: im1 = color_to_alpha.color_to_alpha(im1,opts['colorToAlpha']) alpha = im1.split()[-1] if opts and 'opacity' in opts: alpha = Image.eval(alpha,lambda a: a*opts['opacity']) im = Image.composite(im1,im2,alpha) return im.convert('RGB')
def _composite(self,im1,im2 = None, opts = None): if not im2: render_sizeX = int(self.tile_countX * self.tile_size) render_sizeY = int(self.tile_countY * self.tile_size) im2 = Image.new('RGBA', (render_sizeX,render_sizeY), (245, 245, 245, 255)) if opts and 'colorToAlpha' in opts: im1 = color_to_alpha.color_to_alpha(im1,opts['colorToAlpha']) alpha = im1.split()[-1] if opts and 'opacity' in opts: alpha = Image.eval(alpha,lambda a: a*opts['opacity']) im = Image.composite(im1,im2,alpha) return im.convert('RGB')
def render(id, mnx, mny, mxx, mxy, zoom): TILE_SIZE = 256 try: logging.info("Rendering ({},{},{},{},{}) started".format( mnx, mny, mxx, mxy, zoom)) global map_pool, P_900913 if 'map_pool' not in globals(): map_pool = {} if 'P_900913' not in globals(): P_900913 = mapnik.Projection( '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over' ) Tracer.start('render_init') mnlon, mnlat = num2deg(mnx, mxy, zoom) mxlon, mxlat = num2deg(mxx, mny, zoom) bbox = P_900913.forward(mapnik.Box2d(mnlon, mnlat, mxlon, mxlat)) sizex = int((mxx - mnx) * TILE_SIZE) sizey = int((mxy - mny) * TILE_SIZE) Tracer.end('render_init') pic = Image.new('RGBA', (sizex, sizey), (255, 255, 255, 255)) for layer_name in tqdm([ 'landcover', 'hillshade', 'contour', 'way', 'building', 'ferry', 'boundary', 'route', 'fishnet', 'symbol', 'text' ], leave=False): if layer_name != 'hillshade': while True: try: Tracer.start("render_{}_{}_map_load".format( zoom, layer_name)) layer = "/mapnik-styles/{}/~map-{}.xml".format( zoom, layer_name) if layer in map_pool: m = map_pool[layer] m.resize(sizex, sizey) else: m = mapnik.Map(sizex, sizey) mapnik.load_map(m, layer, True) m.buffer_size = 48 if layer_name != 'text' else 512 map_pool[layer] = m m.zoom_to_box(bbox) Tracer.end("render_{}_{}_map_load".format( zoom, layer_name)) Tracer.start("render_{}_{}_render".format( zoom, layer_name)) tileim = mapnik.Image(sizex, sizey) mapnik.render(m, tileim) Tracer.end("render_{}_{}_render".format( zoom, layer_name)) break except RuntimeError as e: Tracer.start("render_{}_{}_dberror_recovery".format( zoom, layer_name)) logging.error('Problem with connection.') logging.exception(e) sleep(10) Tracer.end("render_{}_{}_dberror_recovery".format( zoom, layer_name)) Tracer.start("render_{}_compositing".format(zoom)) tileim = Image.frombytes('RGBA', (sizex, sizey), tileim.tostring()) if layer_name == 'boundary': tileim = color_to_alpha(tileim, [255, 255, 255, 255]) tileim = np.array(tileim, dtype=np.uint8) tileim[:, 3] //= 2 tileim = Image.fromarray(tileim, mode='RGBA') pic = Image.alpha_composite(pic, tileim) Tracer.end("render_{}_compositing".format(zoom)) else: if zoom > 14: scale = 25 elif zoom > 13: scale = 50 elif zoom > 12: scale = 100 elif zoom > 11: scale = 200 elif zoom > 10: scale = 400 else: scale = 800 tileim = get_hillshade(mnlon, mnlat, mxlon, mxlat, scale=scale) tileim = tileim.resize( (sizex, sizey), Image.ANTIALIAS if sizex < tileim.width else Image.BILINEAR) tileim = np.array(tileim, dtype=np.float32) / 255 low_limit = 0.6 low_compression = 2 high_limit = 0.9 high_compression = 2.5 tileim **= 1 / 1.3 tileim = np.maximum( low_limit - ((low_limit - tileim) / low_compression), tileim) tileim = np.minimum( high_limit + ((tileim - high_limit) / high_compression), tileim) tileim += (1 - high_limit) * (1.0 - 1.0 / high_compression) tileim = 95 * (1 - tileim) tileim = Image.fromarray(tileim.astype(np.uint8), mode='L') Tracer.start("render_{}_compositing".format(zoom)) black = Image.new('L', (sizex, sizey), (0)) tileim = Image.merge('RGBA', (black, black, black, tileim)) pic = Image.alpha_composite(pic, tileim) Tracer.end("render_{}_compositing".format(zoom)) Tracer.start("render_{}_croping".format(zoom)) if pic: pic = pic.convert('RGB') for i in range(mxx - mnx): for j in range(mxy - mny): crop = pic.crop((TILE_SIZE * i, TILE_SIZE * j, TILE_SIZE * (i + 1), TILE_SIZE * (j + 1))) tileX = i + mnx tileY = j + mny if not os.path.isdir("/render/%s/%s" % (zoom, tileX)): os.makedirs("/render/%s/%s" % (zoom, tileX)) crop.save("/render/%s/%s/%s.jpg" % (zoom, tileX, tileY), 'JPEG', quality=85) Tracer.end("render_{}_croping".format(zoom)) logging.info("Rendering ({},{},{},{},{}) done.".format( mnx, mny, mxx, mxy, zoom)) return id, True except (KeyboardInterrupt, SystemExit): raise except Exception as e: logging.exception("Rendering of ({},{},{},{},{}) failed".format( mnx, mny, mxx, mxy, zoom)) return id, False