def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): """ """ if self.mapnik is None: self.mapnik = mapnik.Map(0, 0) if exists(self.mapfile): mapnik.load_map(self.mapnik, str(self.mapfile)) else: handle, filename = mkstemp() os.write(handle, urlopen(self.mapfile).read()) os.close(handle) mapnik.load_map(self.mapnik, filename) os.unlink(filename) self.mapnik.width = width self.mapnik.height = height self.mapnik.zoom_to_box(mapnik.Envelope(xmin, ymin, xmax, ymax)) img = mapnik.Image(width, height) mapnik.render(self.mapnik, img) img = Image.fromstring('RGBA', (width, height), img.tostring()) return img
def rendertiles(self, bounds, data, item, label, lat, layer, lon, num_items, projec): z = 1 imgx = 128 * z imgy = 128 * z mapfile = "/map_data/styles/bs_" + layer + ".xml" m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) # ensure the target map projection is mercator m.srs = projec.params() if hasattr(mapnik, 'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat, projec) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx, imgy) mapnik.render(m, im) img = im.tostring('png256') data[(item, layer)] = img
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right p0 = (x * 256, (y + 1) * 256) p1 = ((x + 1) * 256, y * 256) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) render_size = 256 self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) if (self.m.buffer_size < 128): self.m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri, 'png256')
def render_location(self): # spherical mercator (most common target map projection of osm data imported with osm2pgsql) merc = 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') longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') mapfile = "renderer/map_data/styles/bs_complete.xml" bounds = (self.lon-self.size, self.lat-self.size, self.lon+self.size,self.lat+self.size) z = 1 imgx = 224 * z imgy = 224 * z m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) m.srs = merc.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat,merc) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) #render the map to an image im = mapnik.Image(imgx,imgy) mapnik.render(m, im) img = im.tostring('png256') img = cv2.imdecode(np.fromstring(img, dtype=np.uint8), 1) img =np.asarray(img) window_name = "Location" cv2.imshow(window_name, img) cv2.waitKey(0)
def render_legend(mapfile, tile_uri): m = mapnik.Map(1024, 2048) # Load style XML mapnik.load_map(m, mapfile, True) # Obtain <Map> projection prj = mapnik.Projection(m.srs) # Projects between tile pixel co-ordinates and LatLong (EPSG:4326) tileproj = GoogleProjection(20) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = prj.forward(mapnik.Coord(14.4503,50.0673)) c1 = prj.forward(mapnik.Coord(14.457,50.0678)) # Bounding box for the tile if hasattr(mapnik,'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x,c0.y, c1.x,c1.y) else: bbox = mapnik.Envelope(c0.x,c0.y, c1.x,c1.y) render_size_x = 1024 render_size_y = 1500 m.resize(render_size_x, render_size_y) m.zoom_to_box(bbox) m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size_x, render_size_y) mapnik.render(m, im) im.save(tile_uri, 'png256') surface = cairo.SVGSurface('legend.svg', render_size_x, render_size_y) mapnik.render(m, surface) surface.finish()
def render_dynamic(self, painter): if self.mapnik_map: w = painter.device().width() h = painter.device().height() # using canvas dims leads to shift in QGIS < 1.3... #w = self.canvas.width() #h = self.canvas.height() try: self.mapnik_map.resize(w, h) except: self.mapnik_map.width = w self.mapnik_map.height = h if self.qCanvas: can = self.qCanvas else: can = self.canvas try: e = can.extent() except: can = self.canvas e = can.extent() bbox = mapnik.Envelope(e.xMinimum(), e.yMinimum(), e.xMaximum(), e.yMaximum()) self.mapnik_map.zoom_to_box(bbox) im = mapnik.Image(w, h) mapnik.render(self.mapnik_map, im) if os.name == 'nt': qim = QImage() qim.loadFromData(QByteArray(im.tostring('png'))) painter.drawImage(0, 0, qim) else: qim = QImage(im.tostring(), w, h, QImage.Format_ARGB32) painter.drawImage(0, 0, qim.rgbSwapped()) can.refresh()
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right p0 = (x * 256, (y + 1) * 256) p1 = ((x + 1) * 256, y * 256) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) render_size = 256 self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri, 'png256') grid_uri = tile_uri.replace('.png', '.grid.json') # new mapnik.Grid api, works like mapnik.Image # with the exception that you can only render one # layer to it with the mapnik.render_layer function # create grid as same size as map/image grid = mapnik.Grid(render_size, render_size) # render a layer to that grid array mapnik.render_layer(self.m, grid, layer=0, fields=['POP2005', 'NAME']) # then encode the grid array as utf, resample to 1/4 the size, and dump features grid_utf = grid.encode('utf', resolution=4, add_features=True) # below is the old grid api - will be removed soon, don't use #grid_utf = mapnik.render_grid(self.m,0,key='__id__',resolution=4,fields=['POP2005','NAME']) # client code uses jsonp, so fake by wrapping in grid() callback open(grid_uri, 'wb').write('grid(' + json.dumps(grid_utf) + ')')
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right p0 = (x * TILES_SIZE, (y + 1) * TILES_SIZE) p1 = ((x + 1) * TILES_SIZE, y * TILES_SIZE) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) render_size = TILES_SIZE self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 if FORMAT == 'grid': grid = mapnik.Grid(render_size, render_size) # mapnik.render_layer(self.m, grid, layer=64, fields=['name']) for n, l in enumerate(self.m.layers): if l.name != 'admin-012345678': if 'name' in l.datasource.fields(): mapnik.render_layer(self.m, grid, layer=n, fields=['name']) utfgrid = grid.encode('utf', resolution=4) f = open(tile_uri + '.' + FILE_EXTENSION, 'w') f.write(json.dumps(utfgrid)) f.close() else: # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri + '.' + FILE_EXTENSION, FORMAT)
def complexRun(image, stylesheet, extent, size): mapfile = stylesheet map_uri = image imgx = size[0] imgy = size[1] m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(extent[0], extent[2], extent[1], extent[3]) else: bbox = mapnik.Envelope(extent[0], extent[2], extent[1], extent[3]) m.zoom_to_box(bbox) im = mapnik.Image(imgx, imgy) mapnik.render(m, im) view = im.view(0, 0, imgx, imgy) # x,y,width,height view.save(map_uri, 'png')
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right # start=time.time() # p0 = (x * TILESIZE, (y + 1) * TILESIZE) # p1 = ((x + 1) * TILESIZE, y * TILESIZE) # # # Convert to LatLong (EPSG:4326) # l0 = self.tileproj.fromPixelToLL(p0, z); # l1 = self.tileproj.fromPixelToLL(p1, z); # # # Convert to map projection (e.g. mercator co-ords EPSG:900913) # c0 = self.prj.forward(mapnik2.Coord(l0[0],l0[1])) # c1 = self.prj.forward(mapnik2.Coord(l1[0],l1[1])) l0y, l0x = num2deg(x, y + 1, z) l1y, l1x = num2deg(x + 1, y, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik2.Coord(l0x, l0y)) c1 = self.prj.forward(mapnik2.Coord(l1x, l1y)) # Bounding box for the tile if hasattr(mapnik2, 'mapnik_version') and mapnik2.mapnik_version() >= 800: bbox = mapnik2.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik2.Envelope(c0.x, c0.y, c1.x, c1.y) render_size = TILESIZE self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 # Render image with default Agg renderer im = mapnik2.Image(render_size, render_size) # print("%f"%(time.time()-start)) # start=time.time() mapnik2.render(self.m, im) # print("%f"%(time.time()-start)) # start=time.time() im.save(tile_uri, 'png256')
def generate_map_tile(self, m, filename, z, x, y): # Code taken from OSM generate_tiles.py proj = GoogleProjection() mprj = mapnik.Projection(m.srs) p0 = (x * 256, (y + 1) * 256) p1 = ((x + 1) * 256, y * 256) l0 = proj.fromPixelToLL(p0, z); l1 = proj.fromPixelToLL(p1, z); c0 = mprj.forward(mapnik.Coord(l0[0], l0[1])) c1 = mprj.forward(mapnik.Coord(l1[0], l1[1])) if hasattr(mapnik,'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) m.resize(256, 256) m.zoom_to_box(bbox) im = mapnik.Image(256, 256) mapnik.render(m, im) im.save(str(filename), "png256")
def rendertiles( bounds, item, label, lat, layers, lon, projec, writer): z = 1 imgx = 128 * z imgy = 128 * z for layer in layers: index = layers.index(layer) mapfile = "/map_data/styles/bs_" + layer + ".xml" m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) # ensure the target map projection is mercator m.srs = projec.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat,projec) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx,imgy) mapnik.render(m, im) img = im.tostring('png256') if index == 0: data=[img] #data = np.expand_dims(data, 0) else: data.append(img) save_data(data, layers, item, label, lat, lon, writer)
m = mapnik2.Map(pic_output_width, pic_output_height) # Load osm-xml-stylesheet for rendering the views # DB has to have the same name as cmd user mapnik2.load_map(m, path_to_osm_xml) # Define projection prj = mapnik2.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" ) # Map bounds. Bound values come from SQL-query if hasattr(mapnik2, 'Box2d'): bbox = mapnik2.Box2d(xmin, ymin, xmax, ymax) else: bbox = mapnik2.Envelope(xmin, ymin, xmax, ymax) # Project bounds to map projection e = mapnik2.forward_(bbox, prj) # Zoom map to bounding box m.zoom_to_box(e) ### ### START Layer 1 ### # style object to hold rules s = mapnik2.Style() s2 = mapnik2.Style()
# This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # import mapnik2 mapfile = 'tutorial2.xml' map_output = '~/geodata/raster/world/hello_world_using_xml_config.png' map_output = 'hello_world_using_xml_config.png' # Instantiate a map object with given width, height and spatial reference system #m = mapnik.Map(600,300,"+proj=latlong +datum=WGS84") m = mapnik2.Map(600, 300) mapnik2.load_map(m, mapfile) bbox = mapnik2.Envelope(mapnik2.Coord(-180.0, -90.0), mapnik2.Coord(180.0, 90.0)) m.zoom_to_box(bbox) # Write the data to a png image called world.png in the base directory of your user mapnik2.render_to_file(m, map_output) # Exit the python interpreter exit()
def render_map(mapfile): #A4 #filename = 'export_A4' #render_size_x = 842 #render_size_y = 595 #A3 #filename = 'export_A3' #render_size_x = 1191 #render_size_y = 842 #A2 #filename = 'export_A2' #render_size_x = 1684 #render_size_y = 1191 #A1 #filename = 'export_A1' #render_size_x = 2384 #render_size_y = 1684 #A0 filename = 'export_A0' render_size_x = 3370 render_size_y = 2384 #A-1 #filename = 'export_A-1' #render_size_x = 4768 #render_size_y = 3370 #A-2 #filename = 'export_A-2' #render_size_x = 6740 #render_size_y = 4768 m = mapnik.Map(render_size_x, render_size_y) # Load style XML mapnik.load_map(m, mapfile, True) # Obtain <Map> projection prj = mapnik.Projection(m.srs) # Projects between tile pixel co-ordinates and LatLong (EPSG:4326) tileproj = GoogleProjection(20) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = prj.forward(mapnik.Coord(14.33, 50.05)) c1 = prj.forward(mapnik.Coord(14.53, 50.14)) #filename = filename + '_BIG' #c0 = prj.forward(mapnik.Coord(14.25,49.95)) #c1 = prj.forward(mapnik.Coord(14.68,50.16)) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) m.resize(render_size_x, render_size_y) m.zoom_to_box(bbox) m.buffer_size = 128 # Render image with default Agg renderer #im = mapnik.Image(render_size_x, render_size_y) #mapnik.render(m, im) #im.save('export.png', 'png256') #surface = cairo.PDFSurface(filename + '.pdf', render_size_x, render_size_y) #mapnik.render(m, surface) surface = cairo.PSSurface(filename + '.ps', render_size_x, render_size_y) surface.dsc_comment("%%Title: Cyklisticka mapa prahy") surface.dsc_comment("%%Copyright: CC-BY-SA") mapnik.render(m, surface) #surface = cairo.SVGSurface(filename + '.svg', render_size_x, render_size_y) #mapnik.render(m, surface) surface.finish()
#--------------------------------------------------- z = 10 imgx = 120 * z imgy = 80 * z m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) # ensure the target map projection is mercator m.srs = merc.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) # Our bounds above are in long/lat, but our map # is in spherical mercator, so we need to transform # the bounding box to mercator to properly position # the Map when we call `zoom_to_box()` transform = mapnik.ProjTransform(longlat,merc) merc_bbox = transform.forward(bbox) # Mapnik internally will fix the aspect ratio of the bounding box # to match the aspect ratio of the target image width and height # This behavior is controlled by setting the `m.aspect_fix_mode` # and defaults to GROW_BBOX, but you can also change it to alter # the target image size by setting aspect_fix_mode to GROW_CANVAS #m.aspect_fix_mode = mapnik.GROW_CANVAS # Note: aspect_fix_mode is only available in Mapnik >= 0.6.0
def metadata_image(bboxes, mapfile): """Create a metadata image""" from json import dumps as tojson import mapnik2 as mapnik features = [] for bbox in bboxes: minx, miny, maxx, maxy = bbox # create the bounding box as a json string width, height = (maxx - minx, maxy - miny) min_dim = 0.0125 # minimum dimension for display as a rectangle (in degrees) if width < min_dim or height < min_dim: # it should be a point feature = { "type": "Feature", "geometry": { "type": "Point", "coordinates": [minx, miny] }, "properties": { "type": "point" } } width, height = (9, 9) else: feature = { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[minx, miny], [maxx, miny], [maxx, maxy], [minx, maxy], [minx, miny]]] }, "properties": { "type": "bbox" } } features.append(feature) json = tojson({ "type": "FeatureCollection", "features": features }) # instantiate the map m = mapnik.Map(250, 250) mapnik.load_map_from_string(m, mapfile) # set the datasource for the last layer to show the bounding box datasource = mapnik.Ogr(file=json, layer='OGRGeoJSON') m.layers[-1].datasource = datasource # create an image of the area of interest with a border border = 80.0 # percentage border dx = width * (border / 100) minx2 = minx - dx; maxx2 = maxx + dx dy = height * (border / 100) miny2 = miny - dy; maxy2 = maxy + dy # don't create a border larger than the globe's extent if minx2 < -180.0 or maxx2 > 180.0 or miny2 < -90.0 or maxy2 > 90.0: minx2 = minx; maxx2 = maxx; miny2 = miny; maxy2 = maxy bbox = mapnik.Envelope(mapnik.Coord(minx2, miny2), mapnik.Coord(maxx2, maxy2)) m.zoom_to_box(bbox) image = mapnik.Image(m.width, m.height) mapnik.render(m, image) return image
def render_metatile(self, metatile): z = metatile.z x = metatile.x y = metatile.y # TODO: move all this somewhere else # Calculate pixel positions of bottom-left & top-right p0 = (x * self.tile_size, (y + self.metatile_size) * self.tile_size) p1 = ((x + self.metatile_size) * self.tile_size, y * self.tile_size) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) self.m.resize(self.image_size, self.image_size) self.m.zoom_to_box(bbox) if self.m.buffer_size < 128: self.m.buffer_size = 128 # we must decide wether to render the subtiles/children of this tile render_children = {child: False for child in metatile.children()} if not self.opts.dry_run: # Render image with default Agg renderer start = time.perf_counter() im = mapnik.Image(self.image_size, self.image_size) try: mapnik.render(self.m, im) except RuntimeError as e: exception("%r: %s", metatile, e) else: mid = time.perf_counter() # save the image, splitting it in the right amount of tiles for tile in metatile.tiles: i, j = tile.meta_index # TODO: Tile.meta_pixel_coords img = im.view(i * self.tile_size, j * self.tile_size, self.tile_size, self.tile_size) tile.data = img.tostring('png256') # TODO: move to Tile is_empty = map_utils.is_empty(tile.data) if not is_empty or self.opts.empty == 'write': self.backend.store(tile) # at least something to render. note that if we're # rendering only one tile (either metatile_size == 1 # or z == 0), i, j can only be == 0. this matches # the situation further down render_children[metatile.child(tile)] = True else: if self.opts.empty == 'skip': # empty tile, skip debug("%r: empty" % tile) continue # TODO: else? self.backend.commit() end = time.perf_counter() info("%r: %f, %f" % (metatile, mid - start, end - mid)) else: # simulate some work time.sleep(randint(0, 30) / 10) for child in metatile.children(): if random() <= 0.75 or 2**metatile.z < self.opts.metatile_size: render_children[child] = True return render_children
#--------------------------------------------------- # Change this to the bounding box you want # #ll = (-5.2, 41.4, 10.16, 46.2) #ll = (1.393547058105469, 43.56610697474913, 1.429810523986817, 43.58131079720606) #reynerie #ll = (1.406988241528325, 43.56730920511517, 1.461919882153325, 43.60237411394007) #ponts #ll = (1.359014509180042, 43.59232959871322, 1.404848096826527, 43.62626162214223) #tournefeuille (rocades) ll = args.bbox #--------------------------------------------------- z = args.zoom imgx = 500 * z imgy = 1000 * z m = mapnik2.Map(imgx, imgy) mapnik2.load_map(m, args.mapfile) prj = mapnik2.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" ) c0 = prj.forward(mapnik2.Coord(ll[0], ll[1])) c1 = prj.forward(mapnik2.Coord(ll[2], ll[3])) if hasattr(mapnik2, 'mapnik_version') and mapnik2.mapnik_version() >= 800: bbox = mapnik2.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik2.Envelope(c0.x, c0.y, c1.x, c1.y) m.zoom_to_box(bbox) im = mapnik2.Image(imgx, imgy) mapnik2.render(m, im) view = im.view(0, 0, imgx, imgy) # x,y,width,height view.save(map_uri, 'png')
def render_metatile( self, metatile: map_utils.MetaTile) -> Dict[map_utils.Tile, bool]: # get LatLong (EPSG:4326) l0 = metatile.coords[0] l1 = metatile.coords[1] # this is the only time where we convert manually into WebMerc # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) image_size = self.opts.tile_size * min(self.metatile_size, 2** metatile.z) self.m.resize(image_size, image_size) self.m.zoom_to_box(bbox) if self.m.buffer_size < 128: self.m.buffer_size = 128 bail_out = True start = time.perf_counter() if not self.opts.dry_run: im = mapnik.Image(image_size, image_size) # Render image with default Agg renderer debug('[%s] rende...', self.name) # TODO: handle exception, send back into queue mapnik.render(self.m, im) debug('[%s] ...ring!', self.name) mid = time.perf_counter() # TODO: all this is on a single tile, not a metatile # converting to png256 is the fastest I have found so far: # python3.6 -m timeit -s 'import mapnik; im = mapnik.Image.fromstring(open("Attic/tmp/369.png", "br").read())' 'data = im.tostring("png256")' # 100 loops, best of 3: 7.72 msec per loop # tostring() looks nice, but I can't rebuild a mapnik.Image from it :( # python3.6 -m timeit -s 'import mapnik; im = mapnik.Image.fromstring(open("Attic/tmp/369.png", "br").read())' 'data = im.tostring()' # 100000 loops, best of 3: 13.8 usec per loop # python3.6 -m timeit -s 'import mapnik, bz2; im = mapnik.Image.fromstring(open("Attic/tmp/369.png", "br").read())' 'c = bz2.BZ2Compressor(); c.compress(im.tostring()); data = c.flush()' # 10 loops, best of 3: 20.3 msec per loop # python3.6 -m timeit -s 'import mapnik, gzip; im = mapnik.Image.fromstring(open("Attic/tmp/369.png", "br").read())' 'data = gzip.compress(im.tostring())' # 10 loops, best of 3: 27.7 msec per loop # python3.6 -s -m timeit -s 'import mapnik, lzma; im = mapnik.Image.fromstring(open("Attic/tmp/369.png", "br").read())' "c = lzma.LZMACompressor(); c.compress(im.tostring()); data = c.flush()" # 10 loops, best of 3: 92 msec per loop # TODO: # but bz2 compresses the best, 52714 png vs 49876 bzip vs 70828 gzip vs 53032 lzma if not self.opts.store_thread: # metatile will go in a non-marshaling queue, no need tostring() it metatile.im = im else: metatile.im = im.tostring('png256') end = time.perf_counter() else: debug('[%s] thumbtumbling', self.name) time.sleep(randint(0, 30) / 10) mid = time.perf_counter() end = time.perf_counter() metatile.render_time = mid - start metatile.serializing_time = end - mid bail_out = False debug("[%s] putting %r", self.name, metatile) self.output.put(metatile) debug("[%s] put! (%d)", self.name, self.output.qsize()) if not self.opts.store_thread and self.output.qsize() > 0: # NOTE: mypy complains here that Item "Process" of "Union[Process, StormBringer]" has no attribute "single_step" # the solutions are ugly, so I'm leaving it as that self.store_thread.single_step() return bail_out
def render(self, item, zoom, size, dest): """ Compile a Cascadenik MML file, returning a cascadenik.output.Map object. Parameters: src: Path to .mml file, or raw .mml file content. dirs: Object with directory names in 'cache', 'output', and 'source' attributes. dirs.source is expected to be fully-qualified, e.g. "http://example.com" or "file:///home/example". Keyword Parameters: verbose: If True, debugging information will be printed to stderr. srs: Target spatiral reference system for the compiled stylesheet. If provided, overrides default map srs in the .mml file. datasources_cfg: If a file or URL, uses the config to override datasources or parameters (i.e. postgis_dbname) defined in the map's canonical <DataSourcesConfig> entities. This is most useful in development, whereby one redefines individual datasources, connection parameters, and/or local paths. """ mmap = mapnik.Map(*size) mmap.srs = '+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' resolution = 20037508.34 / 128 / (pow(2, zoom)) extent = [ -resolution / 2 * size[0], -resolution / 2 * size[1], resolution / 2 * size[0], resolution / 2 * size[1] ] classes = set(item.get('class', '').split()) layers = [] for layer in self.layers: # check if this layers classes are in class list if not need_layer(layer.classes, item, classes): continue datasource = create_datasource() if layer.classes <= classes: datasource.addFeatures(item, extent) for bg_el in item.findall('background'): bg_classes = set(bg_el.get('class', '').split()) if layer.classes <= bg_classes: datasource.addFeatures(bg_el, extent) layer.datasource = datasource layers.append(layer) output.Map(self.map_el.attrib.get('srs', None), layers, self.fontsets, **self.map_attrs).to_mapnik(mmap, self.dirs) bbox = mapnik.Envelope(*extent) mmap.zoom_to_box(bbox) mmap.background = mapnik.Color(0, 0, 0, 0) im = mapnik.Image(*size) mapnik.render(mmap, im) im.save(dest, 'png256') return im.tostring()