def get_box_tiles(self, box): """ Calculates for a given bounding box the U{slippy map tilenames<http://wiki.openstreetmap.org/index.php/Slippy_map_tilenames>} of the tiles that are intersected by the bounding box. The calculated tiles are given by the U{slippy map tilenames<http://wiki.openstreetmap.org/index.php/Slippy_map_tilenames>} of the top/left edge tile and the bottom/right edge tile. @type box: C{[min_lat, min_lon, max_lat, max_lon]} @param box: OSM bounding box @returns: slippy map tile names of the top/left tile and right/bottom tile of a rectangular box in the format C{[(topleft_x, topleft_y), (bottomright_x, bottomright_y)]} @rtype: C{[(int, int), (int, int)]} """ return [tileXY(box[3], box[0], self.__zoom_level), tileXY(box[1], box[2], self.__zoom_level)]
def packWay(self, id, nodes, style, tags): """Compress a way for storage""" data = '' data += struct.pack("I", id) # Nodes data += struct.pack("I", len(nodes)) for n in nodes: (id,lat,lon) = n (x,y) = tilenames.tileXY(lat,lon,31) data += struct.pack("III", x, y, id) # Styles data += struct.pack("I", self.enumIDs[style['name']]) # Layer try: layer = int(tags.get('layer',0)) except ValueError: # yeah thanks for whoever entered "=1" as a layer number... layer = 0 data += struct.pack("b", layer) # Important tags packedTags = '' packedTags += self.packTag("N", tags, 'name') packedTags += self.packTag("r", tags, 'ref') packedTags += self.packTag("r", tags, 'ncn_ref') data += struct.pack("H", len(packedTags)) + packedTags return(data)
def get_tile_coordinates(self, lat, lon): """ Gets for a point given by its geographic coordinates the geographic coordinates of the edges of the tile this point lies in. @param lat: Geographic latitude of a point @param lon: Geographic longitude of a point @returns: Geographic coordinates of the edges of the corresponding tile @rtype: (min_lat, min_lon, max_lat, max_lon) """ x, y = tileXY(lat, lon, self.__zoom_level) return tileEdges(x, y, self.__zoom_level) # S, W, N, E
def storeNode(self,id,lat,lon): """Store a node""" if(not self.nodesExist): (x,y) = tilenames.tileXY(lat,lon,z) self.db[str(id)] = "%f,%f,%d_%d"%(lat,lon,x,y) self.countNodes += 1 self.prompt -= 1 if(not self.prompt): self.prompt = self.promptFreq print "%1.3fM nodes" % (float(self.countNodes) / 1000000.0)
def getArea(self, lat, lon): """Download data in the vicinity of a lat/long""" z = tiledata.DownloadLevel() (x,y) = tilenames.tileXY(lat, lon, z) tileID = '%d,%d'%(x,y) if(self.tiles.get(tileID,False)): #print "Already got %s" % tileID return self.tiles[tileID] = True filename = tiledata.GetOsmTileData(z,x,y) #print "Loading %d,%d at z%d from %s" % (x,y,z,filename) return(self.loadOsm(filename))
def getArea(self, lat, lon): """Download data in the vicinity of a lat/long""" z = tiledata.DownloadLevel() (x, y) = tilenames.tileXY(lat, lon, z) tileID = '%d,%d' % (x, y) if self.tiles.get(tileID, False): #print("Already got %s" % tileID) return self.tiles[tileID] = True filename = tiledata.GetOsmTileData(z, x, y) #print("Loading %d,%d at z%d from %s" % (x,y,z,filename)) return self.loadOsm(filename)
def viewport_coordinates(self): """ Calculates the geographic coordinates of the edges of the MoSP-GeoTool viewport @returns: the geographic coordinates of the viewport @rtype: C{[min_lon, min_lat, max_lon, max_lat]} """ position_nw = self.get_position_in_tile(self.__selection_box[3], self.__selection_box[0]) (tile_w, tile_n) = tileXY(self.__selection_box[3], self.__selection_box[0], self.__zoom_level) tiles_x = (position_nw[0] + self.__window_width) / TILE_SIZE tiles_y = (position_nw[1] + self.__window_height) / TILE_SIZE x = TILE_SIZE - ((tiles_x + 1) * TILE_SIZE - (position_nw[0] + self.__window_width)) y = TILE_SIZE - ((tiles_y + 1) * TILE_SIZE - (position_nw[1] + self.__window_width)) tile_e = tile_w + tiles_x tile_s = tile_n + tiles_y coord_se = self.get_coord_by_position_in_tile(tile_e, tile_s, x, y) return [self.__selection_box[0], coord_se[0], coord_se[1], self.__selection_box[3]]
def getArea(self, lat, lon): """Download data in the vicinity of a lat/long. Return filename to existing or newly downloaded .osm file.""" z = tiledata.DownloadLevel() (x, y) = tilenames.tileXY(lat, lon, z) tileID = '%d,%d' % (x, y) if (self.tiles.get(tileID, False)): #print "Already got %s" % tileID return self.tiles[tileID] = True filename = tiledata.GetOsmTileData(z, x, y) #print "Loading %d,%d at z%d from %s" % (x,y,z,filename) return (self.loadOsm(filename))
def draw(self): def draw_tile_box(x, y): edges = tilenames.tileEdges(x, y, self.zoom_level) #print edges offsetlat = edges[0]-focus[0] offsetlong = edges[1]-focus[1] self.tileheight_deg = edges[2]-edges[0] self.context.rectangle( offsetlong / self.tilewidth_deg * 256, offsetlat / self.tileheight_deg * 256, 256, 256) self.context.fill() self.context.move_to( offsetlong / self.tilewidth_deg * 256 + 128, offsetlat / self.tileheight_deg * 256 + 128) self.context.set_source_rgb(0, 0, 0) self.context.set_font_size(12) self.context.show_text("%s, %s" % (x, y)) (x, y, w, h) = self.get_allocation() focus = self.focus self.context.translate(w/2, h/2) x, y = tilenames.tileXY(focus[0], focus[1], self.zoom_level) self.tilewidth_deg = 360.0/tilenames.numTiles(self.zoom_level) #tileheight_deg = 180.0/tilenames.numTiles(self.zoom_level) #print self.focus #print x, y self.context.set_source_rgb(0, 0, 1) draw_tile_box(x, y) self.context.set_source_rgb(1, 0, 1) draw_tile_box(x-1, y) self.context.set_source_rgb(1, 0, 0) draw_tile_box(x+1, y) self.context.set_source_rgb(0, 0, 0) draw_tile_box(x, y+1) self.context.set_source_rgb(0, 1, 0) draw_tile_box(x, y-1) """
def loadTileSet(self, lat, lon): size = self.tileSize + 2 * self.tileSize * self.surround img = Image.new("RGB", (size, size)) tx, ty = tilenames.tileXY(lat, lon, self.zoom) i = 0 for x in range(tx - self.surround, tx + self.surround + 1): j = 0 for y in range(ty - self.surround, ty + self.surround + 1): tile = self.loadTile(self.zoom, x, y) img.paste(tile, (i * self.tileSize, j * self.tileSize)) j += 1 i += 1 # tmp, lry = tilenames.latEdges(ty + self.surround + 1, self.zoom); # uly, tmp = tilenames.latEdges(ty - self.surround, self.zoom); # ulx, tmp = tilenames.lonEdges(tx - self.surround, self.zoom); # tmp, lrx= tilenames.lonEdges(tx + self.surround + 1, self.zoom); # self.bounds = ulx, uly, lrx, lry # print self.bounds return img
# POIs if(1): for poi in self.osm.poi: n = poi['id'] (lat,lon) = self.osm.nodes[n] (x,y) = self.proj.project(lat,lon) s = 1 ctx = self.getCtx(100000000000) ctx.set_source_rgb(0., 0., 1.) ctx.rectangle(x-s,y-s,x+s,y+s) #----------------------------------------------------------------- # Test suite - call this file from the command-line to generate a # sample image if(__name__ == '__main__'): from tilenames import tileXY a = RenderClass() filename = "sample_"+__file__+".png" #a.RenderTile(15, 16372, 10895, 'default', filename) # london #a.RenderTile(14, 8166, 5447, 'default', filename) # Z14 (x,y) = tileXY(58.409, 15.572, 9) a.RenderTile(9, x, y, 'default', filename) # i linkan #a.RenderTile(17, 65385, 43659, 'default', filename) # fran render_PIL print "------------------------------------" print "(x,y):",x,y print "Saved image to " + filename
def draw(self): (x3, y3, w, h) = self.get_allocation() def draw_tile_box(x, y): """ Draws the slippy map tile x, y on the screen """ key = (self.zoom_level,x,y) # Read tile from disk if not in memory cache if self.tiles.has_key(key): t = self.tiles[key] else: t = Tile(x, y, self.zoom_level) t.load() self.tiles[key] = t edges = tilenames.tileEdges(x, y, self.zoom_level) offsetlat = edges[2]-focus[0] # North edge offset offsetlong = edges[1]-focus[1] # West edge offset self.tileheight_deg = edges[2]-edges[0] self.tilewidth_deg = edges[3]-edges[1] px = int(offsetlong / self.tilewidth_deg * 256) py = int(-offsetlat / self.tileheight_deg * 256) self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], t.pixbuf, 0, 0, w/2 + int(px), h/2 + int(py) ) """ Adding placemark icons from the database and removing them when user is moving the map """ if (self.draw_icons == True): self.dbobjects = self.get_objects_from_db() #if (self.i % 20 == 0): for e in self.dbobjects: (f,g) = self._coord_to_pixel(e.long,e.lat) if e.__class__ == Mission: if (e.status != 3): self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.mission_pic, 0, 0, int(f), int(g)-10,19,33) if e.__class__ == Placemark: if (e.type == 1): self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.obstacle_pic, 0, 0, int(f), int(g),29,29) if (e.type == 2): self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.water_pic, 0, 0, int(f), int(g),29,29) if (e.type == 3): self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.power_pic, 0, 0, int(f), int(g),29,29) self.i = self.i-1 # Find x, y of tile in focus focus = self.focus x, y = tilenames.tileXY(focus[0], focus[1], self.zoom_level) # Cover screen with tiles by adding "safety margin" to all sides num_h = w/256+3 off_x = num_h/2 num_v = h/256+3 off_y = num_v/2 xtiles = range(x-off_x, x-off_x+num_h) ytiles = range(y-off_y, y-off_y+num_v) # Draw visible tiles for tx in xtiles: for ty in ytiles: draw_tile_box(tx,ty) # unload tiles not visible on screen from memory for key in self.tiles.keys(): if not (key[1] in xtiles and key[2] in ytiles): del self.tiles[key]
def processTileParams(prefs): tileStartX, tileStartY = tilenames.tileXY(prefs.latStart, prefs.lonStart, prefs.zoom, True) tileEndX, tileEndY = tilenames.tileXY(prefs.latEnd, prefs.lonEnd, prefs.zoom, True) # Sort the numbers low to high if tileStartY > tileEndY: tileStartY, tileEndY = tileEndY, tileStartY if tileStartX > tileEndX: tileStartX, tileEndX = tileEndX, tileStartX tileStartX, tileStartY = math.floor(tileStartX), math.floor(tileStartY) tileEndX, tileEndY = math.ceil(tileEndX), math.ceil(tileEndY) # S lat, W lon, N lat, E lon startCornerCoords = tilenames.tileEdges(tileStartX, tileStartY, prefs.zoom) endCornerCoords = tilenames.tileEdges(tileEndX, tileEndY, prefs.zoom) latStartCorner, lonStartCorner = startCornerCoords[2], startCornerCoords[1] # Get's north-west tile start lat & lon latEndCorner, lonEndCorner = endCornerCoords[0], endCornerCoords[3] # Get's south-east tile end lat & lon print("Starting at North-West corner: [" + str(latStartCorner) + ", " + str(lonStartCorner) + "]") print("Ending at South-East corner: [" + str(latEndCorner) + ", " + str(lonEndCorner) + "]") print("Downloading X tiles", tileStartX, "through", tileEndX) print("Downloading Y tiles", tileStartY, "through", tileEndY) print("Downloading a total of", abs(tileEndX - tileStartX + 1) * abs(tileEndY - tileStartY + 1), "tiles") print("Each tile at this zoom will be ~", str(tilenames.horozontalDistance(latStartCorner, prefs.zoom)), "meters wide") if prefs.dryRun: try: checkPilInstalled() except (ImportError, ModuleNotFoundError) as e: print("PIL is not installed, image stitching will not be supported") print("Dry run, exiting now...") return 0 if not os.path.exists(prefs.name): os.mkdir(prefs.name) os.chdir(prefs.name) tileCol = TileCollection(tileStartX, tileStartY, tileEndX, tileEndY, prefs.zoom, prefs.tileServer, prefs.name) if not os.path.exists("raw"): os.mkdir("raw") os.chdir("raw") downloadErr = tileCol.downloadTiles(prefs.forceDownload) if downloadErr == 0: print("Download Complete!") if not prefs.noStitch: print("Stitching images...") stitchResult = tileCol.stitchImages(prefs.stitchFormat) if stitchResult["err"] == 0: os.rename(stitchResult["imageName"], "../" + stitchResult["imageName"]) os.chdir("..") return genInfoFile(tileCol) return downloadErr
# by teh jonerer and the elofferer. # just grabs some images (like... linkoping) to populate the cache. from tiledata import GetOsmTileData from tilenames import tileXY bbox = (58.258000000000003, 15.282, 58.539000000000001, 15.976000000000001) z = 15 scalr = 1000.0 for lat in range(bbox[0]*scalr, bbox[2]*scalr): lat /= scalr for long in range(bbox[1]*scalr, bbox[3]*scalr): long /= scalr (x, y) = tileXY(lat, long, z) GetOsmTileData(z, x, y)
filename = "%s/%s.png" % (directory, y) if not os.path.exists(directory): os.makedirs(directory) (S, W, N, E) = tileEdges(x, y, z) # Download the data # URL = 'http://dev.openstreetmap.org/~ojw/api/?/map/%d/%d/%d' % (z,x,y) # URL = 'http://map02.eniro.com/geowebcache/service/tms1.0.0/map/%s/%s/%s.png' % (z,x,y) # URL = 'http://%s/api/0.6/map?bbox=%f,%f,%f,%f' % ('api.openstreetmap.org',W,S,E,N) URL = "http://c.tile.openstreetmap.org/%s/%s/%s.png" % (z, x, y) print URL if not os.path.exists(filename): # TODO: allow expiry of old data print "Downloading %d/%d/%d from network" % (z, x, y) urlretrieve(URL, filename) return filename if __name__ == "__main__": bbox = (58.258000000000003, 15.282, 58.539000000000001, 15.976000000000001) zoom_level = 10 scalr = 100.0 for lat in range(bbox[0] * scalr, bbox[2] * scalr): lat /= scalr for long in range(bbox[1] * scalr, bbox[3] * scalr): long /= scalr (x, y) = tileXY(lat, long, zoom_level) GetOsmTileData(zoom_level, x, y)
def pdfer(data, page_size=PAGE_SIZES['letter']): overlays = data.get('overlays') grid = {'zoom': data.get('zoom')} center_lon, center_lat = data['center'] center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom'])) dim_across, dim_up = data['dimensions'] if dim_across > dim_up: page_height, page_width, tiles_up, tiles_across = page_size orientation = 'landscape' else: page_width, page_height, tiles_across, tiles_up = page_size orientation = 'portrait' min_tile_x = center_tile_x - (tiles_across / 2) min_tile_y = center_tile_y - (tiles_up / 2) max_tile_x = min_tile_x + tiles_across max_tile_y = min_tile_y + tiles_up # Get base layer tiles base_pattern = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' if data.get('base_tiles'): base_pattern = data['base_tiles'] base_links = generateLinks(base_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) base_names = dl_write_all(base_links, 'base') # Get overlay tiles overlay_pattern = None if data.get('overlay_tiles'): overlay_pattern = data['overlay_tiles'] overlay_links = generateLinks(overlay_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) overlay_names = dl_write_all(overlay_links, 'overlay') now = datetime.now() date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S') outp_name = os.path.join('/tmp', '{0}.png'.format(date_string)) base_image_names = ['-'.join(l.split('/')[-3:]) for l in base_names] base_image_names = sorted([i.split('-')[-3:] for i in base_image_names], key=itemgetter(1)) arrays = [] for k, g in groupby(base_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_RGB2RGBA) array.append(i) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(outp_name, outp) if overlay_pattern: overlay_outp_name = os.path.join('/tmp', 'overlay_{0}.png'.format(date_string)) overlay_image_names = [ '-'.join(l.split('/')[-3:]) for l in overlay_names ] overlay_image_names = sorted( [i.split('-')[-3:] for i in overlay_image_names], key=itemgetter(1)) arrays = [] for k, g in groupby(overlay_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.cvtColor(cv2.imread(img, -1), cv2.COLOR_RGB2RGBA) array.append(i) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(overlay_outp_name, outp) base = cv2.imread(outp_name, -1) overlay = cv2.imread(overlay_outp_name, -1) for c in range(0, 3): zero = overlay.shape[0] one = overlay.shape[1] base[0:0+zero, 0:0+one, c] = overlay[:,:,c] * \ (overlay[:,:,3]/255.0) + base[0:0+zero, 0:0+one, c] * \ (1.0 - overlay[:,:,3]/255.0) cv2.imwrite(outp_name, base) ########################################################################### # Code below here is for drawing vector layers within the PDF # # Leaving it in just because it was a pain to come up with the first time # ########################################################################### # for parts in image_names: # parts = parts[3:] # parts[-1] = parts[-1].rstrip('.png') # key = '-'.join(parts[-3:]) # grid[key] = {'bbox': tileEdges(float(parts[1]),float(parts[2]),int(parts[0]))} # d = {} # keys = sorted(grid.keys()) # if overlays: # polys = [] # for k,v in grid.items(): # try: # one,two,three,four = grid[k]['bbox'] # polys.append(box(two, one, four, three)) # except TypeError: # pass # mpoly = MultiPolygon(polys) # bb_poly = box(*mpoly.bounds) # min_key = keys[0] # max_key = keys[-2] # bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1] # bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3] # bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy) # bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy) # bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx,bmin_my,float(grid['zoom'])) # bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx,bmax_my,float(grid['zoom'])) # bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px,bmin_py,int(grid['zoom'])) # im = cairo.ImageSurface.create_from_png(outp_name) # ctx = cairo.Context(im) # if overlays.get('shape_overlay'): # shape_overlay = overlays['shape_overlay'] # color = hex_to_rgb('#f06eaa') # coords = shape_overlay['coordinates'][0] # x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) # ctx.move_to(x,y) # ctx.set_line_width(4.0) # red, green, blue = [float(c) for c in color] # ctx.set_source_rgba(red/255, green/255, blue/255, 0.3) # for p in coords[1:]: # x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) # ctx.line_to(x,y) # ctx.close_path() # ctx.fill() # ctx.set_source_rgba(red/255, green/255, blue/255, 0.5) # for p in coords[1:]: # x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) # ctx.line_to(x,y) # ctx.close_path() # ctx.stroke() # ctx.set_line_width(2.0) # for point_overlay in overlays.get('point_overlays'): # color = hex_to_rgb(point_overlay['color']) # for p in point_overlay['points']: # if p[0] and p[1]: # pt = Point((float(p[0]), float(p[1]))) # if bb_poly.contains(pt): # nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) # red, green, blue = [float(c) for c in color] # ctx.set_source_rgba(red/255, green/255, blue/255, 0.6) # ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ? # ctx.fill() # ctx.arc(nx, ny, 5.0, 0, 50) # ctx.stroke() # im.write_to_png(outp_name) # scale = 1 pdf_name = outp_name.rstrip('.png') + '.pdf' pdf = cairo.PDFSurface(pdf_name, page_width, page_height) ctx = cairo.Context(pdf) image = cairo.ImageSurface.create_from_png(outp_name) ctx.set_source_surface(image, 0, 0) ctx.paint() pdf.finish() print pdf_name return pdf_name
def pdfer(data, page_size=PAGE_SIZES['letter']): overlays = data.get('overlays') grid = {'zoom': data.get('zoom')} center_lon, center_lat = data['center'] center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom'])) dim_across, dim_up = data['dimensions'] if dim_across > dim_up: page_height, page_width, tiles_up, tiles_across = page_size orientation = 'landscape' else: page_width, page_height, tiles_across, tiles_up = page_size orientation = 'portrait' min_tile_x = center_tile_x - (tiles_across / 2) min_tile_y = center_tile_y - (tiles_up / 2) max_tile_x = min_tile_x + tiles_across max_tile_y = min_tile_y + tiles_up links = [] for ty in range(min_tile_y, max_tile_y + 1): for tx in range(min_tile_x, max_tile_x + 1): links.append('http://a.tiles.mapbox.com/v3/datamade.hnmob3j3/{0}/{1}/{2}.png'.format(grid['zoom'], tx, ty)) names = dl_write_all(links) now = datetime.now() date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S') outp_name = os.path.join('/tmp', '{0}.png'.format(date_string)) image_names = ['-'.join(l.split('/')[-3:]) for l in names] image_names = sorted([i.split('-') for i in image_names]) arrays = [] for k,g in groupby(image_names, key=itemgetter(4)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: array.append(cv2.imread(img)) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(outp_name, outp) for parts in image_names: parts = parts[3:] parts[-1] = parts[-1].rstrip('.png') key = '-'.join(parts[-3:]) grid[key] = {'bbox': tileEdges(float(parts[1]),float(parts[2]),int(parts[0]))} d = {} keys = sorted(grid.keys()) if overlays: polys = [] for k,v in grid.items(): try: one,two,three,four = grid[k]['bbox'] polys.append(box(two, one, four, three)) except TypeError: pass mpoly = MultiPolygon(polys) bb_poly = box(*mpoly.bounds) min_key = keys[0] max_key = keys[-2] bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1] bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3] bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy) bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy) bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx,bmin_my,float(grid['zoom'])) bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx,bmax_my,float(grid['zoom'])) bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px,bmin_py,int(grid['zoom'])) im = cairo.ImageSurface.create_from_png(outp_name) ctx = cairo.Context(im) for beat_overlay in overlays.get('beat_overlays'): color = hex_to_rgb('#7B3294') boundary = requests.get('http://crimearound.us/data/beats/%s.geojson' % beat_overlay) if boundary.status_code == 200: coords = boundary.json()['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x,y) ctx.set_line_width(4.0) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red/255, green/255, blue/255, 0.7) ctx.line_to(x,y) ctx.close_path() ctx.stroke() if overlays.get('shape_overlay'): shape_overlay = overlays['shape_overlay'] color = hex_to_rgb('#f06eaa') coords = shape_overlay['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x,y) ctx.set_line_width(4.0) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red/255, green/255, blue/255, 0.3) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x,y) ctx.close_path() ctx.fill() ctx.set_source_rgba(red/255, green/255, blue/255, 0.5) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x,y) ctx.close_path() ctx.stroke() ctx.set_line_width(2.0) for point_overlay in overlays.get('point_overlays'): color = hex_to_rgb(point_overlay['color']) for p in point_overlay['points']: if p[0] and p[1]: pt = Point((float(p[0]), float(p[1]))) if bb_poly.contains(pt): nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red/255, green/255, blue/255, 0.6) ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ? ctx.fill() ctx.arc(nx, ny, 5.0, 0, 50) ctx.stroke() im.write_to_png(outp_name) scale = 1 pdf_name = outp_name.rstrip('.png') + '.pdf' pdf = cairo.PDFSurface(pdf_name, page_width, page_height) ctx = cairo.Context(pdf) image = cairo.ImageSurface.create_from_png(outp_name) ctx.set_source_surface(image, 0, 0) ctx.paint() pdf.finish() return pdf_name
def pdfer(data, page_size=PAGE_SIZES['letter'], output='pdf'): shape_overlays = data.get('shape_overlays') point_overlays = data.get('point_overlays') grid = {'zoom': data.get('zoom')} center_lon, center_lat = data['center'] center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom'])) dim_across, dim_up = data['dimensions'] if dim_across > dim_up: page_height, page_width, tiles_up, tiles_across = page_size else: page_width, page_height, tiles_across, tiles_up = page_size min_tile_x = center_tile_x - (tiles_across / 2) min_tile_y = center_tile_y - (tiles_up / 2) max_tile_x = min_tile_x + tiles_across max_tile_y = min_tile_y + tiles_up # Get base layer tiles base_pattern = 'http://d.tile.stamen.com/toner/{z}/{x}/{y}.png' if data.get('base_tiles'): base_pattern = data['base_tiles'] base_links = generateLinks(base_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) base_names = dl_write_all(base_links, 'base') # Get overlay tiles overlay_pattern = None if data.get('overlay_tiles'): overlay_pattern = data['overlay_tiles'] overlay_links = generateLinks(overlay_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) overlay_names = dl_write_all(overlay_links, 'overlay') now = datetime.now() date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S') outp_name = os.path.join('/tmp', '{0}.png'.format(date_string)) base_image_names = ['-'.join(l.split('/')[-3:]) for l in base_names] base_image_names = sorted([i.split('-')[-3:] for i in base_image_names], key=itemgetter(1)) for parts in base_image_names: z, x, y = parts y = y.rstrip('.png').rstrip('.jpg') z = z.rsplit('_', 1)[1] key = '-'.join([z, x, y]) grid[key] = {'bbox': tileEdges(float(x), float(y), int(z))} keys = sorted(grid.keys()) mercator = GlobalMercator() bb_poly = None bmin_rx = None bmin_ry = None if shape_overlays or point_overlays: polys = [] for k, v in grid.items(): try: one, two, three, four = grid[k]['bbox'] polys.append(box(two, one, four, three)) except TypeError: pass mpoly = MultiPolygon(polys) bb_poly = box(*mpoly.bounds) min_key = keys[0] max_key = keys[-2] bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1] bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3] bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy) bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy) bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx, bmin_my, float(grid['zoom'])) bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx, bmax_my, float(grid['zoom'])) bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px, bmin_py, int(grid['zoom'])) if shape_overlays: all_polys = [] for shape_overlay in shape_overlays: shape_overlay = json.loads(shape_overlay) if shape_overlay.get('geometry'): shape_overlay = shape_overlay['geometry'] coords = shape_overlay['coordinates'][0] all_polys.append(Polygon(coords)) mpoly = MultiPolygon(all_polys) one, two, three, four, five = list( box(*mpoly.bounds).exterior.coords) left, right = LineString([one, two]), LineString([three, four]) top, bottom = LineString([two, three]), LineString([four, five]) left_to_right = left.distance(right) top_to_bottom = top.distance(bottom) if left_to_right > top_to_bottom: page_height, page_width, _, _ = page_size else: page_width, page_height, _, _ = page_size center_lon, center_lat = list(mpoly.centroid.coords)[0] if point_overlays: all_points = [] for point_overlay in point_overlays: point_overlay = json.loads(point_overlay) for p in point_overlay['points']: if p[0] and p[1]: all_points.append(p) mpoint = MultiPoint(all_points) center_lon, center_lat = list(mpoint.centroid.coords)[0] one, two, three, four, five = list( box(*mpoint.bounds).exterior.coords) left, right = LineString([one, two]), LineString([three, four]) top, bottom = LineString([two, three]), LineString([four, five]) left_to_right = left.distance(right) top_to_bottom = top.distance(bottom) if left_to_right > top_to_bottom: page_height, page_width, _, _ = page_size else: page_width, page_height, _, _ = page_size center_lon, center_lat = list(mpoint.centroid.coords)[0] print(center_lon, center_lat) arrays = [] for k, g in groupby(base_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.imread(img, -1) if isinstance(i, type(None)): i = np.zeros((256, 256, 4), np.uint8) elif i.shape[2] != 4: i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA) array.append(i) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(outp_name, outp) if overlay_pattern: overlay_outp_name = os.path.join('/tmp', 'overlay_{0}.png'.format(date_string)) overlay_image_names = [ '-'.join(l.split('/')[-3:]) for l in overlay_names ] overlay_image_names = sorted( [i.split('-')[-3:] for i in overlay_image_names], key=itemgetter(1)) arrays = [] for k, g in groupby(overlay_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.imread(img, -1) if isinstance(i, type(None)): i = np.zeros((256, 256, 4), np.uint8) elif i.shape[2] != 4: i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA) array.append(i) arrays.append(np.vstack(array)) nuked = [os.remove(f) for f in fnames] outp = np.hstack(arrays) cv2.imwrite(overlay_outp_name, outp) base = cv2.imread(outp_name, -1) overlay = cv2.imread(overlay_outp_name, -1) overlay_g = cv2.cvtColor(overlay, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(overlay_g, 10, 255, cv2.THRESH_BINARY) inverted = cv2.bitwise_not(mask) overlay = cv2.bitwise_not(overlay, overlay, mask=inverted) base_alpha = 0.55 overlay_alpha = 1 for channel in range(3): x, y, d = overlay.shape base[:,:,channel] = (base[:,:,channel] * base_alpha + \ overlay[:,:,channel] * overlay_alpha * \ (1 - base_alpha)) / \ (base_alpha + overlay_alpha * (1 - base_alpha)) cv2.imwrite(outp_name, base) ########################################################################### # Code below here is for drawing vector layers within the PDF # # Leaving it in just because it was a pain to come up with the first time # ########################################################################### if shape_overlays or point_overlays: im = cairo.ImageSurface.create_from_png(outp_name) ctx = cairo.Context(im) if shape_overlays: for shape_overlay in shape_overlays: shape_overlay = json.loads(shape_overlay) if shape_overlay.get('geometry'): shape_overlay = shape_overlay['geometry'] color = hex_to_rgb('#f06eaa') coords = shape_overlay['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x, y) ctx.set_line_width(4.0) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.3) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x, y) ctx.close_path() ctx.fill() ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.5) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x, y) ctx.close_path() ctx.stroke() ctx.set_line_width(2.0) if point_overlays: for point_overlay in point_overlays: point_overlay = json.loads(point_overlay) color = hex_to_rgb(point_overlay['color']) for p in point_overlay['points']: if p[0] and p[1]: pt = Point((float(p[0]), float(p[1]))) if bb_poly.contains(pt): nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.6) ctx.arc( nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ? ctx.fill() ctx.arc(nx, ny, 5.0, 0, 50) ctx.stroke() im.write_to_png(outp_name) scale = 1 # Crop image from center center_point_x, center_point_y = latlon2xy(float(center_lat), float(center_lon), float(data['zoom'])) offset_x = (center_point_x - float(center_tile_x)) + 50 offset_y = (center_point_y - float(center_tile_y)) - 50 outp_image = cv2.imread(outp_name, -1) pixels_up, pixels_across, channels = outp_image.shape center_x, center_y = (pixels_across / 2) + offset_x, (pixels_up / 2) + offset_y start_y, end_y = center_y - (page_height / 2), center_y + (page_height / 2) start_x, end_x = center_x - (page_width / 2), center_x + (page_width / 2) cv2.imwrite(outp_name, outp_image[start_y:end_y, start_x:end_x]) if output == 'pdf': outp_file_name = outp_name.rstrip('.png') + '.pdf' pdf = cairo.PDFSurface(outp_file_name, page_width, page_height) ctx = cairo.Context(pdf) image = cairo.ImageSurface.create_from_png(outp_name) ctx.set_source_surface(image) ctx.paint() pdf.finish() elif output == 'jpeg': outp_file_name = outp_name.rstrip('.png') + '.jpg' jpeg = cv2.cvtColor(cv2.imread(outp_name, -1), cv2.COLOR_RGBA2RGB) cv2.imwrite(outp_file_name, jpeg) return outp_file_name
def pdfer(data, page_size='letter'): overlays = data.get('overlays') grid = {'zoom': data.get('zoom')} center_lon, center_lat = data['center'] center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom'])) dim_across, dim_up = data['dimensions'] if dim_across > dim_up: page_height, page_width, tiles_up, tiles_across = PAGE_SIZES[page_size] orientation = 'landscape' else: page_width, page_height, tiles_across, tiles_up = PAGE_SIZES[page_size] orientation = 'portrait' min_tile_x = center_tile_x - (tiles_across / 2) min_tile_y = center_tile_y - (tiles_up / 2) max_tile_x = min_tile_x + tiles_across max_tile_y = min_tile_y + tiles_up links = [] for ty in range(min_tile_y, max_tile_y + 1): for tx in range(min_tile_x, max_tile_x + 1): links.append( 'http://a.tiles.mapbox.com/v3/datamade.hnmob3j3/{0}/{1}/{2}.png' .format(grid['zoom'], tx, ty)) names = dl_write_all(links) now = datetime.now() date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S') outp_name = os.path.join('/tmp', '{0}.png'.format(date_string)) image_names = ['-'.join(l.split('/')[-3:]) for l in names] image_names = sorted([i.split('-') for i in image_names]) arrays = [] for k, g in groupby(image_names, key=itemgetter(4)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: array.append(cv2.imread(img)) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(outp_name, outp) for parts in image_names: parts = parts[3:] parts[-1] = parts[-1].rstrip('.png') key = '-'.join(parts[-3:]) grid[key] = { 'bbox': tileEdges(float(parts[1]), float(parts[2]), int(parts[0])) } d = {} keys = sorted(grid.keys()) if overlays: polys = [] for k, v in grid.items(): try: one, two, three, four = grid[k]['bbox'] polys.append(box(two, one, four, three)) except TypeError: pass mpoly = MultiPolygon(polys) bb_poly = box(*mpoly.bounds) min_key = keys[0] max_key = keys[-2] bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1] bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3] bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy) bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy) bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx, bmin_my, float(grid['zoom'])) bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx, bmax_my, float(grid['zoom'])) bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px, bmin_py, int(grid['zoom'])) im = cairo.ImageSurface.create_from_png(outp_name) ctx = cairo.Context(im) for beat_overlay in overlays.get('beat_overlays'): color = hex_to_rgb('#7B3294') boundary = requests.get( 'http://crimearound.us/data/beats/%s.geojson' % beat_overlay) if boundary.status_code == 200: coords = boundary.json()['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x, y) ctx.set_line_width(4.0) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.7) ctx.line_to(x, y) ctx.close_path() ctx.stroke() if overlays.get('shape_overlay'): shape_overlay = overlays['shape_overlay'] color = hex_to_rgb('#f06eaa') coords = shape_overlay['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x, y) ctx.set_line_width(4.0) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.3) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x, y) ctx.close_path() ctx.fill() ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.5) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x, y) ctx.close_path() ctx.stroke() ctx.set_line_width(2.0) for point_overlay in overlays.get('point_overlays'): color = hex_to_rgb(point_overlay['color']) for p in point_overlay['points']: if p[0] and p[1]: pt = Point((float(p[0]), float(p[1]))) if bb_poly.contains(pt): nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.6) ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ? ctx.fill() ctx.arc(nx, ny, 5.0, 0, 50) ctx.stroke() im.write_to_png(outp_name) scale = 1 pdf_name = outp_name.rstrip('.png') + '.pdf' pdf = cairo.PDFSurface(pdf_name, page_width, page_height) ctx = cairo.Context(pdf) image = cairo.ImageSurface.create_from_png(outp_name) ctx.set_source_surface(image, 0, 0) ctx.paint() pdf.finish() return pdf_name
def pdfer(data, page_size=PAGE_SIZES['letter'], output='pdf'): shape_overlays = data.get('shape_overlays') point_overlays = data.get('point_overlays') grid = {'zoom': data.get('zoom')} center_lon, center_lat = data['center'] center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom'])) dim_across, dim_up = data['dimensions'] if dim_across > dim_up: page_height, page_width, tiles_up, tiles_across = page_size else: page_width, page_height, tiles_across, tiles_up = page_size min_tile_x = center_tile_x - (tiles_across / 2) min_tile_y = center_tile_y - (tiles_up / 2) max_tile_x = min_tile_x + tiles_across max_tile_y = min_tile_y + tiles_up # Get base layer tiles base_pattern = 'http://d.tile.stamen.com/toner/{z}/{x}/{y}.png' if data.get('base_tiles'): base_pattern = data['base_tiles'] base_links = generateLinks(base_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) base_names = dl_write_all(base_links, 'base') # Get overlay tiles overlay_pattern = None if data.get('overlay_tiles'): overlay_pattern = data['overlay_tiles'] overlay_links = generateLinks(overlay_pattern, grid['zoom'], min_tile_x, min_tile_y, max_tile_x, max_tile_y) overlay_names = dl_write_all(overlay_links, 'overlay') now = datetime.now() date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S') outp_name = os.path.join('/tmp', '{0}.png'.format(date_string)) base_image_names = ['-'.join(l.split('/')[-3:]) for l in base_names] base_image_names = sorted([i.split('-')[-3:] for i in base_image_names], key=itemgetter(1)) for parts in base_image_names: z,x,y = parts y = y.rstrip('.png').rstrip('.jpg') z = z.rsplit('_', 1)[1] key = '-'.join([z,x,y]) grid[key] = {'bbox': tileEdges(float(x),float(y),int(z))} keys = sorted(grid.keys()) mercator = GlobalMercator() bb_poly = None bmin_rx = None bmin_ry = None if shape_overlays or point_overlays: polys = [] for k,v in grid.items(): try: one,two,three,four = grid[k]['bbox'] polys.append(box(two, one, four, three)) except TypeError: pass mpoly = MultiPolygon(polys) bb_poly = box(*mpoly.bounds) min_key = keys[0] max_key = keys[-2] bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1] bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3] bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy) bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy) bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx,bmin_my,float(grid['zoom'])) bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx,bmax_my,float(grid['zoom'])) bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px,bmin_py,int(grid['zoom'])) if shape_overlays: all_polys = [] for shape_overlay in shape_overlays: shape_overlay = json.loads(shape_overlay) if shape_overlay.get('geometry'): shape_overlay = shape_overlay['geometry'] coords = shape_overlay['coordinates'][0] all_polys.append(Polygon(coords)) mpoly = MultiPolygon(all_polys) one, two, three, four, five = list(box(*mpoly.bounds).exterior.coords) left, right = LineString([one, two]), LineString([three, four]) top, bottom = LineString([two, three]), LineString([four, five]) left_to_right = left.distance(right) top_to_bottom = top.distance(bottom) if left_to_right > top_to_bottom: page_height, page_width, _, _ = page_size else: page_width, page_height, _, _ = page_size center_lon, center_lat = list(mpoly.centroid.coords)[0] if point_overlays: all_points = [] for point_overlay in point_overlays: point_overlay = json.loads(point_overlay) for p in point_overlay['points']: if p[0] and p[1]: all_points.append(p) mpoint = MultiPoint(all_points) center_lon, center_lat = list(mpoint.centroid.coords)[0] one, two, three, four, five = list(box(*mpoint.bounds).exterior.coords) left, right = LineString([one, two]), LineString([three, four]) top, bottom = LineString([two, three]), LineString([four, five]) left_to_right = left.distance(right) top_to_bottom = top.distance(bottom) if left_to_right > top_to_bottom: page_height, page_width, _, _ = page_size else: page_width, page_height, _, _ = page_size center_lon, center_lat = list(mpoint.centroid.coords)[0] print(center_lon, center_lat) arrays = [] for k,g in groupby(base_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.imread(img, -1) if isinstance(i, type(None)): i = np.zeros((256,256,4), np.uint8) elif i.shape[2] != 4: i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA) array.append(i) arrays.append(np.vstack(array)) outp = np.hstack(arrays) cv2.imwrite(outp_name, outp) if overlay_pattern: overlay_outp_name = os.path.join('/tmp', 'overlay_{0}.png'.format(date_string)) overlay_image_names = ['-'.join(l.split('/')[-3:]) for l in overlay_names] overlay_image_names = sorted([i.split('-')[-3:] for i in overlay_image_names], key=itemgetter(1)) arrays = [] for k,g in groupby(overlay_image_names, key=itemgetter(1)): images = list(g) fnames = ['/tmp/%s' % ('-'.join(f)) for f in images] array = [] for img in fnames: i = cv2.imread(img, -1) if isinstance(i, type(None)): i = np.zeros((256,256,4), np.uint8) elif i.shape[2] != 4: i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA) array.append(i) arrays.append(np.vstack(array)) nuked = [os.remove(f) for f in fnames] outp = np.hstack(arrays) cv2.imwrite(overlay_outp_name, outp) base = cv2.imread(outp_name, -1) overlay = cv2.imread(overlay_outp_name, -1) overlay_g = cv2.cvtColor(overlay, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(overlay_g, 10, 255, cv2.THRESH_BINARY) inverted = cv2.bitwise_not(mask) overlay = cv2.bitwise_not(overlay, overlay, mask=inverted) base_alpha = 0.55 overlay_alpha = 1 for channel in range(3): x,y,d = overlay.shape base[:,:,channel] = (base[:,:,channel] * base_alpha + \ overlay[:,:,channel] * overlay_alpha * \ (1 - base_alpha)) / \ (base_alpha + overlay_alpha * (1 - base_alpha)) cv2.imwrite(outp_name, base) ########################################################################### # Code below here is for drawing vector layers within the PDF # # Leaving it in just because it was a pain to come up with the first time # ########################################################################### if shape_overlays or point_overlays: im = cairo.ImageSurface.create_from_png(outp_name) ctx = cairo.Context(im) if shape_overlays: for shape_overlay in shape_overlays: shape_overlay = json.loads(shape_overlay) if shape_overlay.get('geometry'): shape_overlay = shape_overlay['geometry'] color = hex_to_rgb('#f06eaa') coords = shape_overlay['coordinates'][0] x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry) ctx.move_to(x,y) ctx.set_line_width(4.0) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red/255, green/255, blue/255, 0.3) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x,y) ctx.close_path() ctx.fill() ctx.set_source_rgba(red/255, green/255, blue/255, 0.5) for p in coords[1:]: x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) ctx.line_to(x,y) ctx.close_path() ctx.stroke() ctx.set_line_width(2.0) if point_overlays: for point_overlay in point_overlays: point_overlay = json.loads(point_overlay) color = hex_to_rgb(point_overlay['color']) for p in point_overlay['points']: if p[0] and p[1]: pt = Point((float(p[0]), float(p[1]))) if bb_poly.contains(pt): nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry) red, green, blue = [float(c) for c in color] ctx.set_source_rgba(red/255, green/255, blue/255, 0.6) ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ? ctx.fill() ctx.arc(nx, ny, 5.0, 0, 50) ctx.stroke() im.write_to_png(outp_name) scale = 1 # Crop image from center center_point_x, center_point_y = latlon2xy(float(center_lat), float(center_lon), float(data['zoom'])) offset_x = (center_point_x - float(center_tile_x)) + 50 offset_y = (center_point_y - float(center_tile_y)) - 50 outp_image = cv2.imread(outp_name, -1) pixels_up, pixels_across, channels = outp_image.shape center_x, center_y = (pixels_across / 2) + offset_x, (pixels_up / 2) + offset_y start_y, end_y = center_y - (page_height / 2), center_y + (page_height / 2) start_x, end_x = center_x - (page_width / 2), center_x + (page_width / 2) cv2.imwrite(outp_name, outp_image[start_y:end_y, start_x:end_x]) if output == 'pdf': outp_file_name = outp_name.rstrip('.png') + '.pdf' pdf = cairo.PDFSurface(outp_file_name, page_width, page_height) ctx = cairo.Context(pdf) image = cairo.ImageSurface.create_from_png(outp_name) ctx.set_source_surface(image) ctx.paint() pdf.finish() elif output == 'jpeg': outp_file_name = outp_name.rstrip('.png') + '.jpg' jpeg = cv2.cvtColor(cv2.imread(outp_name, -1), cv2.COLOR_RGBA2RGB) cv2.imwrite(outp_file_name, jpeg) return outp_file_name