def test_render_mvt_merc_nested_layers(): m = mapnik.Map(512, 512) mapnik.load_map(m, '../data-visual/styles/nested-layers-1.xml') mvt = mapnik.VectorTileMerc(0, 0, 0) im2 = mapnik.Image(m.width, m.height) m.zoom_to_box(mvt.extent) mapnik.render(m, im2) actual2 = 'images/mvt/nested_layers.classic.actual.png' expected2 = 'images/mvt/nested_layers.classic.expected.png' im2.save(actual2, 'png32') eq_(compare_file_size(actual2, expected2, 100), True) mvt_buffer = mapnik.create_mvt_merc(m, mvt.x, mvt.y, mvt.z) # Check number of layers of the MVT vti = mapnik.VectorTileInfo() vti.parse_from_string(mvt_buffer) eq_(vti.layers_size(), 2); mapnik.merge_compressed_buffer(mvt, mvt_buffer) m = mapnik.Map(512, 512) # Load a version of the style with no datasources mapnik.load_map(m, 'styles/nested-layers-1.xml') im = mapnik.Image(m.width, m.height) mapnik.render_mvt_merc(mvt, m, im) actual = 'images/mvt/nested_layers.mvt.actual.png' im.save(actual, 'png32') expected = 'images/mvt/nested_layers.mvt.expected.png' eq_(compare_file_size(actual, expected, 100), True)
def serve_geotiff(self, path, width, height, bbox, srs, opacity): # Create a map mapnik_map = mapnik.Map(width, height) # Setup coordinate system and background mapnik_map.srs = netcdf.GOOGLEMERCATOR.ExportToProj4() mapnik_map.background = mapnik.Color('transparent') # Create a layer from the geotiff raster = mapnik.Gdal(file=str(path), shared=True) layer = mapnik.Layer( 'Tiff Layer', netcdf.GOOGLEMERCATOR.ExportToProj4()) layer.datasource = raster s = mapnik.Style() r = mapnik.Rule() rs = mapnik.RasterSymbolizer() rs.opacity = opacity r.symbols.append(rs) s.rules.append(r) layer.styles.append('geotiff') # Add the layer mapnik_map.layers.append(layer) mapnik_map.append_style('geotiff', s) # Zoom to bbox and create the PNG image mapnik_map.zoom_to_box(mapnik.Envelope(*bbox)) img = mapnik.Image(width, height) mapnik.render(mapnik_map, img) img_data = img.tostring('png') # Return the HttpResponse response = HttpResponse(img_data, content_type='image/png') return response
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')
def render_tile(self, z, x, y): """ :param z: Zoom level :param x: Tile horizontal position :param y: Tile vertical position """ topleft = num2deg(x, y, z) bottomright = num2deg(x + 1, y + 1, z) # Bounding box for the tile bbox = mapnik.Box2d(topleft, bottomright) bbox = DATA_PROJECTION.forward(bbox) print("Bouding box: ", bbox) # self.m.resize(TILE_WIDTH, TILE_WIDTH) self.m.zoom_to_box(bbox) MIN_BUFFER = 256 self.m.buffer_size = max(self.m.buffer_size, MIN_BUFFER) # Render image with default Agg renderer im = mapnik.Image(TILE_WIDTH, TILE_WIDTH) mapnik.render(self.m, im) return im
def test_style_level_comp_op(): m = mapnik.Map(256, 256) mapnik.load_map(m, '../data/good_maps/style_level_comp_op.xml') m.zoom_all() successes = [] fails = [] for name in mapnik.CompositeOp.names: # find_style returns a copy of the style object style_markers = m.find_style("markers") style_markers.comp_op = getattr(mapnik.CompositeOp, name) # replace the original style with the modified one replace_style(m, "markers", style_markers) im = mapnik.Image(m.width, m.height) mapnik.render(m, im) actual = '/tmp/mapnik-style-comp-op-' + name + '.png' expected = 'images/style-comp-op/' + name + '.png' im.save(actual) if not os.path.exists(expected): print 'generating expected test image: %s' % expected im.save(expected) expected_im = mapnik.Image.open(expected) # compare them if im.tostring() == expected_im.tostring(): successes.append(name) else: fails.append('failed comparing actual (%s) and expected(%s)' % (actual,'tests/python_tests/'+ expected)) fail_im = side_by_side_image(expected_im, im) fail_im.save('/tmp/mapnik-style-comp-op-' + name + '.fail.png') eq_(len(fails), 0, '\n'+'\n'.join(fails))
def test_background_image_with_alpha_and_background_color(): m = mapnik.Map(10,10) m.background = mapnik.Color('rgba(255,255,255,.5)') m.background_image = '../data/images/yellow_half_trans.png' im = mapnik.Image(m.width,m.height) mapnik.render(m,im) eq_(get_unique_colors(im),['rgba(255,255,85,191)'])
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, coord, tile_scale): """ """ start_time = time() if self.mapnik is None: self.mapnik = get_mapnikMap(self.mapfile) logging.debug('TileStache.Mapnik.ImageProvider.renderArea() %.3f to load %s', time() - start_time, self.mapfile) # # Mapnik can behave strangely when run in threads, so place a lock on the instance. # if global_mapnik_lock.acquire(): self.mapnik.width = width self.mapnik.height = height self.mapnik.zoom_to_box(Box2d(xmin, ymin, xmax, ymax)) img = mapnik.Image(width, height) mapnik.render(self.mapnik, img) global_mapnik_lock.release() img = Image.fromstring('RGBA', (width, height), img.tostring()) logging.error('Mapnik.renderArea: {"ts":%.0f,"mapfile":"%s","z":%d,"x":%d,"y":%d,"time":%f}', start_time, self.mapfile, coord.zoom, coord.column, coord.row, time() - start_time) logging.debug('TileStache.Mapnik.ImageProvider.renderArea() %dx%d in %.3f from %s', width, height, time() - start_time, self.mapfile) return img
def test_pre_multiply_status_of_map2(): m = mapnik.Map(256,256) m.background = mapnik.Color(1,1,1,255) im = mapnik.Image(m.width,m.height) eq_(validate_pixels_are_not_premultiplied(im),True) mapnik.render(m,im) eq_(validate_pixels_are_not_premultiplied(im),True)
def test_raster_with_alpha_blends_correctly_with_background(): WIDTH = 500 HEIGHT = 500 map = mapnik.Map(WIDTH, HEIGHT) WHITE = mapnik.Color(255, 255, 255) map.background = WHITE style = mapnik.Style() rule = mapnik.Rule() symbolizer = mapnik.RasterSymbolizer() symbolizer.scaling = mapnik.scaling_method.BILINEAR rule.symbols.append(symbolizer) style.rules.append(rule) map.append_style('raster_style', style) map_layer = mapnik.Layer('test_layer') filepath = '../data/raster/white-alpha.png' if 'gdal' in mapnik.DatasourceCache.plugin_names(): map_layer.datasource = mapnik.Gdal(file=filepath) map_layer.styles.append('raster_style') map.layers.append(map_layer) map.zoom_all() mim = mapnik.Image(WIDTH, HEIGHT) mapnik.render(map, mim) mim.tostring() # All white is expected eq_(get_unique_colors(mim), ['rgba(254,254,254,255)'])
def _render_mapfile(self, mapfile, query): start_time = time.time() m = self.map_obj(mapfile) m.resize(query.size[0], query.size[1]) m.srs = '+init=%s' % str(query.srs.srs_code.lower()) envelope = mapnik.Box2d(*query.bbox) m.zoom_to_box(envelope) data = None try: if self.layers: i = 0 for layer in m.layers[:]: if layer.name != 'Unkown' and layer.name not in self.layers: del m.layers[i] else: i += 1 img = mapnik.Image(query.size[0], query.size[1]) if self.scale_factor: mapnik.render(m, img, self.scale_factor) else: mapnik.render(m, img) data = img.tostring(str(query.format)) finally: size = None if data: size = len(data) log_request('%s:%s:%s:%s' % (mapfile, query.bbox, query.srs.srs_code, query.size), status='200' if data else '500', size=size, method='API', duration=time.time()-start_time) return ImageSource(BytesIO(data), size=query.size, image_opts=ImageOptions(format=query.format))
def test_raster_warping_does_not_overclip_source(): lyrSrs = "+init=epsg:32630" mapSrs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' lyr = mapnik.Layer('dataraster', lyrSrs) if 'gdal' in mapnik.DatasourceCache.instance().plugin_names(): lyr.datasource = mapnik.Gdal( file = '../data/raster/dataraster.tif', band = 1, ) sym = mapnik.RasterSymbolizer() sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255,255,0)) rule = mapnik.Rule() rule.symbols.append(sym) style = mapnik.Style() style.rules.append(rule) _map = mapnik.Map(256,256, mapSrs) _map.background=mapnik.Color('white') _map.append_style('foo', style) lyr.styles.append('foo') _map.layers.append(lyr) _map.zoom_to_box(mapnik.Box2d(3,42,4,43)) im = mapnik.Image(_map.width,_map.height) mapnik.render(_map, im) # save a png somewhere so we can see it save_data('test_raster_warping_does_not_overclip_source.png', im.tostring('png')) assert im.view(0,200,1,1).tostring()=='\xff\xff\x00\xff'
def test_background_image_and_background_color(): m = mapnik.Map(8,8) m.background = mapnik.Color('rgba(255,255,255,.5)') m.background_image = '../data/images/stripes_pattern.png' im = mapnik.Image(m.width,m.height) mapnik.render(m,im) eq_(get_unique_colors(im),['rgba(255,255,255,128)', 'rgba(74,74,74,255)'])
def test_raster_with_alpha_blends_correctly_with_background(): WIDTH = 500 HEIGHT = 500 map = mapnik.Map(WIDTH, HEIGHT) WHITE = mapnik.Color(255, 255, 255) map.background = WHITE style = mapnik.Style() rule = mapnik.Rule() symbolizer = mapnik.RasterSymbolizer() symbolizer.scaling = mapnik.scaling_method.BILINEAR rule.symbols.append(symbolizer) style.rules.append(rule) map.append_style('raster_style', style) map_layer = mapnik.Layer('test_layer') filepath = '../data/raster/white-alpha.png' if 'gdal' in mapnik.DatasourceCache.instance().plugin_names(): map_layer.datasource = mapnik.Gdal(file=filepath) map_layer.styles.append('raster_style') map.layers.append(map_layer) map.zoom_all() mim = mapnik.Image(WIDTH, HEIGHT) mapnik.render(map, mim) save_data('test_raster_with_alpha_blends_correctly_with_background.png', mim.tostring('png')) imdata = mim.tostring() # All white is expected assert contains_word('\xff\xff\xff\xff', imdata)
def test_raster_warping(): lyrSrs = "+init=epsg:32630" mapSrs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' lyr = mapnik.Layer('dataraster', lyrSrs) if 'gdal' in mapnik.DatasourceCache.instance().plugin_names(): lyr.datasource = mapnik.Gdal( file = '../data/raster/dataraster.tif', band = 1, ) sym = mapnik.RasterSymbolizer() sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255,255,0)) rule = mapnik.Rule() rule.symbols.append(sym) style = mapnik.Style() style.rules.append(rule) _map = mapnik.Map(256,256, mapSrs) _map.append_style('foo', style) lyr.styles.append('foo') _map.layers.append(lyr) prj_trans = mapnik.ProjTransform(mapnik.Projection(mapSrs), mapnik.Projection(lyrSrs)) _map.zoom_to_box(prj_trans.backward(lyr.envelope())) im = mapnik.Image(_map.width,_map.height) mapnik.render(_map, im) # save a png somewhere so we can see it save_data('test_raster_warping.png', im.tostring('png')) imdata = im.tostring() assert contains_word('\xff\xff\x00\xff', imdata)
def render_map(map, bbox, width, height): """Render a map within a given bounding box and size""" map.resize(width, height) map.zoom_to_box(bbox) image = Image(width, height) render(map, image) return image.tostring('png')
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): """ """ start_time = time() # # Mapnik can behave strangely when run in threads, so place a lock on the instance. # if global_mapnik_lock.acquire(): try: if self.mapnik is None: self.mapnik = get_mapnikMap(self.mapfile) logging.debug('TileStache.Mapnik.ImageProvider.renderArea() %.3f to load %s', time() - start_time, self.mapfile) self.mapnik.width = width self.mapnik.height = height self.mapnik.zoom_to_box(Box2d(xmin, ymin, xmax, ymax)) img = mapnik.Image(width, height) mapnik.render(self.mapnik, img) except: self.mapnik = None raise finally: # always release the lock global_mapnik_lock.release() img = Image.frombytes('RGBA', (width, height), img.tostring()) logging.debug('bbox:%lf,%lf,%lf,%lf', xmin, ymin, xmax, ymax) logging.debug('TileStache.Mapnik.ImageProvider.renderArea() %dx%d in %.3f from %s', width, height, time() - start_time, self.mapfile) return img
def render_tile(self, x, y, z, utf_grid): # 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 if utf_grid is True: grid = mapnik.Grid(self.m.width,self.m.height) mapnik.render_layer(self.m, grid, layer=0, fields=['html_exp']) utfgrid = grid.encode('utf', resolution=4) return json.dumps(utfgrid); else: im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) return im.tostring('png');
def test_raster_warping_does_not_overclip_source(): lyrSrs = "+init=epsg:32630" mapSrs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' lyr = mapnik.Layer('dataraster', lyrSrs) if 'gdal' in mapnik.DatasourceCache.plugin_names(): lyr.datasource = mapnik.Gdal( file = '../data/raster/dataraster.tif', band = 1, ) sym = mapnik.RasterSymbolizer() sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255,255,0)) rule = mapnik.Rule() rule.symbols.append(sym) style = mapnik.Style() style.rules.append(rule) _map = mapnik.Map(256,256, mapSrs) _map.background=mapnik.Color('white') _map.append_style('foo', style) lyr.styles.append('foo') _map.layers.append(lyr) _map.zoom_to_box(mapnik.Box2d(3,42,4,43)) im = mapnik.Image(_map.width,_map.height) mapnik.render(_map, im) expected_file = './images/support/raster_warping_does_not_overclip_source.png' actual_file = '/tmp/' + os.path.basename(expected_file) im.save(actual_file,'png32') if not os.path.exists(expected_file) or os.environ.get('UPDATE'): im.save(expected_file,'png32') actual = mapnik.Image.open(actual_file) expected = mapnik.Image.open(expected_file) eq_(actual.tostring('png32'),expected.tostring('png32'), 'failed comparing actual (%s) and expected (%s)' % (actual_file,expected_file))
def newGetMap(self, params): # HACK: check if the image should be strechted bbox_ratio = float(params['bbox'][2] - params['bbox'][0]) / float(params['bbox'][3] - params['bbox'][1]) image_ratio = float(params['width']) / float(params['height']) img_height = params['height'] resize = False if int(bbox_ratio * 100) != int(image_ratio * 100): params['height'] = int(params['height'] / bbox_ratio) resize = True m = self._buildMap(params) im = Image(params['width'], params['height']) render(m, im) format = PIL_TYPE_MAPPING[params['format']] if resize: import Image as PILImage size = params['width'], params['height'] im = PILImage.open(StringIO(im.tostring(format))) size = params['width'], img_height im = im.resize(size) output = StringIO() im.save(output, format=format) return Response(params['format'].replace('8',''), output.getvalue()) return Response(params['format'].replace('8',''), im.tostring(format))
def test_passing_pycairo_context_png(): m = make_tmp_map() m.zoom_to_box(mapnik.Box2d(-180,-90,180,90)) test_cairo_file = '/tmp/mapnik-cairo-context-test.png' surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, m.width, m.height) expected_cairo_file = './images/pycairo/cairo-cairo-expected.png' expected_cairo_file2 = './images/pycairo/cairo-cairo-expected-reduced.png' context = cairo.Context(surface) mapnik.render(m,context) draw_title(m,context,"Hello Map",size=20) draw_neatline(m,context) surface.write_to_png(test_cairo_file) reduced_color_image = test_cairo_file.replace('png','-mapnik.png') im = mapnik.Image.from_cairo(surface) im.save(reduced_color_image,'png8') surface.finish() if not os.path.exists(expected_cairo_file): print 'generated expected cairo surface file %s' % expected_cairo_file shutil.copy(test_cairo_file,expected_cairo_file) diff = abs(os.stat(expected_cairo_file).st_size-os.stat(test_cairo_file).st_size) msg = 'diff in size (%s) between actual (%s) and expected(%s)' % (diff,test_cairo_file,'tests/python_tests/'+ expected_cairo_file) eq_( diff < 500, True, msg) os.remove(test_cairo_file) if not os.path.exists(expected_cairo_file2): print 'generated expected cairo surface file %s' % expected_cairo_file2 shutil.copy(reduced_color_image,expected_cairo_file2) diff = abs(os.stat(expected_cairo_file2).st_size-os.stat(reduced_color_image).st_size) msg = 'diff in size (%s) between actual (%s) and expected(%s)' % (diff,reduced_color_image,'tests/python_tests/'+ expected_cairo_file2) eq_( diff < 500, True, msg) os.remove(reduced_color_image)
def test_that_coordinates_do_not_overflow_and_polygon_is_rendered_csv(): expected_color = mapnik.Color('white') projection = '+init=epsg:4326' ds = mapnik.MemoryDatasource() context = mapnik.Context() feat = mapnik.Feature.from_geojson(json.dumps(geojson), context) ds.add_feature(feat) geojson_string = "geojson\n'%s'" % json.dumps(geojson['geometry']) ds = mapnik.Datasource(**{'type': 'csv', 'inline': geojson_string}) s = mapnik.Style() r = mapnik.Rule() sym = mapnik.PolygonSymbolizer() sym.fill = expected_color r.symbols.append(sym) s.rules.append(r) lyr = mapnik.Layer('Layer', projection) lyr.datasource = ds lyr.styles.append('style') m = mapnik.Map(256, 256, projection) m.background_color = mapnik.Color('green') m.append_style('style', s) m.layers.append(lyr) # 17/20864/45265.png m.zoom_to_box(mapnik.Box2d(-13658379.710221574, 6197514.253362091, -13657768.213995293, 6198125.749588372)) # works 15/5216/11316.png # m.zoom_to_box(mapnik.Box2d(-13658379.710221574,6195679.764683247,-13655933.72531645,6198125.749588372)) im = mapnik.Image(256, 256) mapnik.render(m, im) eq_(im.get_pixel(128, 128), expected_color.packed())
def stream(self): """ Routine to render the an image to a string """ im = mapnik.Image(self.m.width, self.m.height) mapnik.render(self.m, im) return im.tostring(self.format)
def render_to_file(self,*args): """ Routine to render the requested AGG format. """ format = args[2] if format in ('tif','tiff'): self.timer() (handle, png_tmp) = tempfile.mkstemp('.png', 'nik2img-tmp') os.close(handle) self.world_file_ext = 'wld' self.write_wld(png_tmp) im = mapnik.Image(args[0].width,self.m.height) if self.scale_factor: mapnik.render(args[0],im,self.scale_factor) else: mapnik.render(args[0],im) im.save(png_tmp,'png') # todo - figure out more reasonable defaults opts = ' -ot Byte -co COMPRESS=JPEG -co JPEG_QUALITY=100' base_cmd = 'gdal_translate %s %s -a_srs "%s" %s' cmd = base_cmd % (png_tmp,args[1],args[0].srs,opts) #print call(cmd,fail=True) os.system(cmd) self.stop() else: self.timer() if self.scale_factor: args = args + (self.scale_factor,) mapnik.render_to_file(*args) if self.world_file_ext: self.write_wld(args[1]) self.stop() if self.zip_compress: self.zip_up(args[1])
def render(self, filename, tile_x, tile_y, zoom): """ Render a single tile to a given filename. """ print 'Rendering %s' % (filename) # Calculate pixel positions of bottom-left & top-right half_width = self.width / 2 half_height = self.height / 2 px0 = (tile_x * self.width, (tile_y + 1) * self.height) px1 = ((tile_x + 1) * self.width, tile_y * self.height) # Convert tile coords to LatLng ll0 = self.tile_projection.fromPixelToLL(px0, zoom); ll1 = self.tile_projection.fromPixelToLL(px1, zoom); # Convert LatLng to map coords c0 = self.map_projection.forward(mapnik.Coord(ll0[0], ll0[1])) c1 = self.map_projection.forward(mapnik.Coord(ll1[0], ll1[1])) # Create bounding box for the render bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) self.mapnik_map.zoom_to_box(bbox) self.mapnik_map.buffer_size = self.buffer_size # Render image with default renderer image = mapnik.Image(self.width, self.height) mapnik.render(self.mapnik_map, image) image.save(filename, self.filetype)
def renderPage(ll,file): z = 2 #imgx = 987 * z #imgy = 801 * z imgx = int(987 * z ) imgy = int(987 * z *0.77 ) m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) prj = 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") c0 = prj.forward(mapnik.Coord(ll[0],ll[1])) c1 = prj.forward(mapnik.Coord(ll[2],ll[3])) 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.zoom_to_box(bbox) im = mapnik.Image(imgx,imgy) mapnik.render(m, im) view = im.view(0,0,imgx,imgy) # x,y,width,height map_uri=file + '.png' view.save(map_uri,'png') file=open(file+'.svg' ,'w') surface=cairo.SVGSurface(file.name,imgx,imgy) mapnik.render(m,surface) #c = cairo.Context(surface) #c.move_to(50,50) #c.show_text('testing') surface.finish();
def test_raster_warping(): lyrSrs = "+init=epsg:32630" mapSrs = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" lyr = mapnik.Layer("dataraster", lyrSrs) if "gdal" in mapnik.DatasourceCache.plugin_names(): lyr.datasource = mapnik.Gdal(file="../data/raster/dataraster.tif", band=1) sym = mapnik.RasterSymbolizer() sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255, 255, 0)) rule = mapnik.Rule() rule.symbols.append(sym) style = mapnik.Style() style.rules.append(rule) _map = mapnik.Map(256, 256, mapSrs) _map.append_style("foo", style) lyr.styles.append("foo") _map.layers.append(lyr) map_proj = mapnik.Projection(mapSrs) layer_proj = mapnik.Projection(lyrSrs) prj_trans = mapnik.ProjTransform(map_proj, layer_proj) _map.zoom_to_box(prj_trans.backward(lyr.envelope())) im = mapnik.Image(_map.width, _map.height) mapnik.render(_map, im) imdata = im.tostring() assert contains_word("\xff\xff\x00\xff", imdata)
def render_tile(mapfile, tile_uri, x, y, z): m = mapnik.Map(256, 256) # 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(z+1) # 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 = tileproj.fromPixelToLL(p0, z); l1 = tileproj.fromPixelToLL(p1, z); # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = prj.forward(mapnik.Coord(l0[0],l0[1])) c1 = prj.forward(mapnik.Coord(l1[0],l1[1])) # Bounding box for the tile bbox = mapnik.Envelope(c0.x,c0.y, c1.x,c1.y) render_size = 256 m.resize(render_size, render_size) m.zoom_to_box(bbox) m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(m, im) im.save(tile_uri, 'png256')
def GetMap(self, params): if params["bbox"][0] >= params["bbox"][2]: raise OGCException("BBOX values don't make sense. minx is greater than maxx.") if params["bbox"][1] >= params["bbox"][3]: raise OGCException("BBOX values don't make sense. miny is greater than maxy.") if params.has_key("styles") and len(params["styles"]) != len(params["layers"]): raise OGCException("STYLES length does not match LAYERS length.") m = Map(params["width"], params["height"]) if params.has_key("transparent") and params["transparent"] == "FALSE": m.background = params["bgcolor"] else: m.background = Color(0, 0, 0, 0) maplayers = self.mapfactory.layers mapstyles = self.mapfactory.styles for layername in params["layers"]: try: layer = maplayers[layername] except KeyError: raise OGCException('Layer "%s" not defined.' % layername, "LayerNotDefined") for stylename in layer.styles: if stylename in mapstyles.keys(): m.append_style(stylename, mapstyles[stylename]) else: raise ServerConfigurationError( 'Layer "%s" refers to non-existent style "%s".' % (layername, stylename) ) m.layers.append(layer) m.zoom_to_box(Envelope(params["bbox"][0], params["bbox"][1], params["bbox"][2], params["bbox"][3])) im = Image(params["width"], params["height"]) render(m, im) im = fromstring("RGBA", (params["width"], params["height"]), rawdata(im)) fh = StringIO() im.save(fh, PIL_TYPE_MAPPING[params["format"]], quality=100) fh.seek(0) return Response(params["format"], fh.read())
def test_that_coordinates_do_not_overflow_and_polygon_is_rendered(): expected_color = mapnik.Color('white') ds = mapnik.MemoryDatasource() context = mapnik.Context() ds.add_feature(mapnik.Feature.from_geojson(json.dumps(geojson),context)) s = mapnik.Style() r = mapnik.Rule() sym = mapnik.PolygonSymbolizer() sym.fill = expected_color sym.clip = False r.symbols.append(sym) s.rules.append(r) lyr = mapnik.Layer('Layer') lyr.datasource = ds lyr.styles.append('style') m = mapnik.Map(256,256) m.background_color = mapnik.Color('black') m.append_style('style',s) m.layers.append(lyr) # 17/20864/45265.png m.zoom_to_box(mapnik.Box2d(-13658379.710221574,6197514.253362091,-13657768.213995293,6198125.749588372)) # works 15/5216/11316.png #m.zoom_to_box(mapnik.Box2d(-13658379.710221574,6195679.764683247,-13655933.72531645,6198125.749588372)) im = mapnik.Image(256,256) mapnik.render(m,im) eq_(im.get_pixel(128,128),expected_color.packed())
def wms(request): global map_cache w,h = int(request.GET['WIDTH']), int(request.GET['HEIGHT']) mime = request.GET['FORMAT'] p = mapnik.Projection('%s' % str("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") ) mapfile = settings.MAPNIK_MAPFILE if not map_cache: map_cache = MapCache(mapfile,p.params()) env = map(float,request.GET['BBOX'].split(',')) # note: must be run without threading until #345 is closed # http://trac.mapnik.org/ticket/345 # tile = deepcopy(map_cache.map) tile = map_cache.map tile.buffer_size = 128 try: tile.resize(w,h) except: tile.width = w tile.height = h tile.zoom_to_box(mapnik.Envelope(*env)) draw = mapnik.Image(tile.width, tile.height) mapnik.render(tile,draw) image = draw.tostring(str(mime.split('/')[1])) response = HttpResponse() response['Content-length'] = len(image) response['Content-Type'] = mime response.write(image) return response
def _test_rgba_8bui_rendering(lbl, overview, rescale, clip): if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table='(select * from "River") foo', use_overviews=1 if overview else 0, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['rid'], 1) lyr = mapnik.Layer('rgba_8bui') lyr.datasource = ds expenv = mapnik.Box2d(0, -210, 256, 0) env = lyr.envelope() # As the input size is a prime number both horizontally # and vertically, we expect the extent of the overview # tables to be a pixel wider than the original, whereas # the pixel size in geographical units depends on the # overview factor. So we start with the original pixel size # as base scale and multiply by the overview factor. # NOTE: the overview table extent only grows north and east pixsize = 1 # see gdalinfo river.tif tol = pixsize * max(overview.split(',')) if overview else 0 assert_almost_equal(env.minx, expenv.minx) assert_almost_equal(env.miny, expenv.miny, delta=tol) assert_almost_equal(env.maxx, expenv.maxx, delta=tol) assert_almost_equal(env.maxy, expenv.maxy) mm = mapnik.Map(256, 256) style = mapnik.Style() sym = mapnik.RasterSymbolizer() rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') #im.save('/tmp/xfull.png') # for debugging # no data eq_(hexlify(im.view(3, 3, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(250, 250, 1, 1).tostring()), '00000000') # full opaque river color eq_(hexlify(im.view(175, 118, 1, 1).tostring()), 'b9d8f8ff') # half-transparent pixel pxstr = hexlify(im.view(122, 138, 1, 1).tostring()) apat = ".*(..)$" match = re.match(apat, pxstr) assert match, 'pixel ' + pxstr + ' does not match pattern ' + apat alpha = match.group(1) assert alpha != 'ff' and alpha != '00', \ 'unexpected full transparent/opaque pixel: ' + alpha # Now zoom over a portion of the env (1/10) newenv = mapnik.Box2d(166, -105, 191, -77) mm.zoom_to_box(newenv) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:1/10') #im.save('/tmp/xtenth.png') # for debugging # no data eq_(hexlify(im.view(255, 255, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(200, 40, 1, 1).tostring()), '00000000') # full opaque river color eq_(hexlify(im.view(100, 168, 1, 1).tostring()), 'b9d8f8ff') # half-transparent pixel pxstr = hexlify(im.view(122, 138, 1, 1).tostring()) apat = ".*(..)$" match = re.match(apat, pxstr) assert match, 'pixel ' + pxstr + ' does not match pattern ' + apat alpha = match.group(1) assert alpha != 'ff' and alpha != '00', \ 'unexpected full transparent/opaque pixel: ' + alpha
def _test_data_subquery(lbl, pixtype, value): # # 3 8 13 # +---+---+---+ # 3 | v | v | v | NOTE: writes different values # +---+---+---+ in 13,8 and 8,13 # 8 | v | v | a | # +---+---+---+ # 13 | v | b | v | # +---+---+---+ # val_a = value / 3 val_b = val_a * 2 sql = "(select 3 as i, " \ " ST_SetValues(" \ " ST_SetValues(" \ " ST_AsRaster(" \ " ST_MakeEnvelope(0,0,14,14), " \ " 1.0, -1.0, '%s', %s" \ " ), " \ " 11, 6, 5, 5, %s::float8" \ " )," \ " 6, 11, 5, 5, %s::float8" \ " ) as \"R\"" \ ") as foo" % (pixtype,value, val_a, val_b) overview = '' rescale = 0 clip = 0 if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table=sql, raster_field='R', use_overviews=0 if overview else 0, band=1, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['i'], 3) lyr = mapnik.Layer('data_subquery') lyr.datasource = ds expenv = mapnik.Box2d(0, 0, 14, 14) env = lyr.envelope() assert_almost_equal(env.minx, expenv.minx, places=0) assert_almost_equal(env.miny, expenv.miny, places=0) assert_almost_equal(env.maxx, expenv.maxx, places=0) assert_almost_equal(env.maxy, expenv.maxy, places=0) mm = mapnik.Map(15, 15) style = mapnik.Style() col = mapnik.RasterColorizer() col.default_mode = mapnik.COLORIZER_DISCRETE col.add_stop(val_a, mapnik.Color(0xff, 0x00, 0x00, 255)) col.add_stop(val_b, mapnik.Color(0x00, 0xff, 0x00, 255)) col.add_stop(value, mapnik.Color(0x00, 0x00, 0xff, 255)) sym = mapnik.RasterSymbolizer() sym.colorizer = col rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') #im.save('/tmp/xfull.png') # for debugging h = format(value, '02x') hex_v = '0000ffff' hex_a = 'ff0000ff' hex_b = '00ff00ff' eq_(hexlify(im.view(3, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(3, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 8, 1, 1).tostring()), hex_a) eq_(hexlify(im.view(3, 13, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 13, 1, 1).tostring()), hex_b) eq_(hexlify(im.view(13, 13, 1, 1).tostring()), hex_v)
def getTile(self, x, y, z, **kwargs): if self.projection: mapSrs = self.projection layerSrs = self.getProj4String() extent = None overscan = 0 if not hasattr(self, '_repeatLongitude'): # If the original dataset is in a latitude/longitude # projection, and does cover more than 360 degrees in longitude # (with some slop), and is outside of the bounds of # [-180, 180], we want to render it twice, once at the # specified longitude and once offset to ensure that we cover # [-180, 180]. This is done by altering the projection's # prime meridian by 360 degrees. If none of the dataset is in # the range of [-180, 180], this does't apply the shift either. self._repeatLongitude = None if self._proj4Proj(layerSrs).crs.is_geographic: bounds = self.getBounds() if bounds['xmax'] - bounds['xmin'] < 361: if bounds['xmin'] < -180 and bounds['xmax'] > -180: self._repeatLongitude = layerSrs + ' +pm=+360' elif bounds['xmax'] > 180 and bounds['xmin'] < 180: self._repeatLongitude = layerSrs + ' +pm=-360' else: mapSrs = '+proj=longlat +axis=enu' layerSrs = '+proj=longlat +axis=enu' # There appears to be a bug in some versions of mapnik/gdal when # requesting a tile with a bounding box that has a corner exactly # at (0, extentMaxY), so make a slightly larger image and crop it. extent = '0 0 %d %d' % (self.sourceSizeX, self.sourceSizeY) overscan = 1 xmin, ymin, xmax, ymax = self.getTileCorners(z, x, y) if self.projection: # If we are using a projection, the tile could contain no data. # Don't bother having mapnik render the blank tile -- just output # it. bounds = self.getBounds(self.projection) if (xmin >= bounds['xmax'] or xmax <= bounds['xmin'] or ymin >= bounds['ymax'] or ymax <= bounds['ymin']): pilimg = PIL.Image.new('RGBA', (self.tileWidth, self.tileHeight)) return self._outputTile(pilimg, TILE_FORMAT_PIL, x, y, z, applyStyle=False, **kwargs) if overscan: pw = (xmax - xmin) / self.tileWidth py = (ymax - ymin) / self.tileHeight xmin, xmax = xmin - pw * overscan, xmax + pw * overscan ymin, ymax = ymin - py * overscan, ymax + py * overscan with self._getTileLock: if not hasattr(self, '_mapnikMap'): mapnik.logger.set_severity(mapnik.severity_type.Debug) m = mapnik.Map(self.tileWidth + overscan * 2, self.tileHeight + overscan * 2, mapSrs) self.addStyle(m, layerSrs, extent) if getattr(self, '_repeatLongitude', None): self.addStyle(m, self._repeatLongitude, extent) self._mapnikMap = m else: m = self._mapnikMap m.zoom_to_box(mapnik.Box2d(xmin, ymin, xmax, ymax)) img = mapnik.Image(self.tileWidth + overscan * 2, self.tileHeight + overscan * 2) mapnik.render(m, img) pilimg = PIL.Image.frombytes('RGBA', (img.width(), img.height()), img.tostring()) if overscan: pilimg = pilimg.crop( (1, 1, pilimg.width - overscan, pilimg.height - overscan)) return self._outputTile(pilimg, TILE_FORMAT_PIL, x, y, z, applyStyle=False, **kwargs)
def tile(request, version, rasterlayer_id, zoom, x, y): try: rasterlayer = RasterLayer.objects.get(id=rasterlayer_id) if version != "1.0": raise Http404 zoom = int(zoom) x = int(x) y = int(y) if zoom < 0 or zoom > MAX_ZOOM_LEVEL: raise Http404 xExtent = _unitsPerPixel(zoom) * TILE_WIDTH yExtent = _unitsPerPixel(zoom) * TILE_HEIGHT minLong = x * xExtent - 20026376.39 minLat = y * yExtent - 20026376.39 maxLong = minLong + xExtent maxLat = minLat + yExtent map = mapnik.Map( TILE_WIDTH, TILE_HEIGHT, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +units=m +k=1.0 +nadgrids=@null +no_defs" ) map.background = mapnik.Color("#00000000") raster = mapnik.Layer("raster") raster.srs = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +no_defs +over" # se carga el archivo file_path = rasterlayer.file_path file_name = rasterlayer.file_name file_format = rasterlayer.file_format ext = file_format file_name = file_name.replace(ext, "-proj" + ext) fullName = join(file_path, file_name) numBands = rasterlayer.numBands # se obtiene el estilo layer_styles = Style.objects.filter(layers__id=rasterlayer.id) if numBands == 1 and layer_styles.count() == 1: raster.datasource = mapnik.Gdal(file=fullName, band=1) else: raster.datasource = mapnik.Gdal(file=fullName) style = mapnik.Style() rule = mapnik.Rule() symbol = mapnik.RasterSymbolizer() # agregar estilo si existe if layer_styles.count() == 1: layer_style = layer_styles[0] colorMap = getColorMap(layer_style) c = mapnik.RasterColorizer(mapnik.COLORIZER_LINEAR, mapnik.Color(0, 0, 0, 0)) for entry in colorMap: color = entry["color"] quantity = entry["quantity"] c.add_stop(quantity, mapnik.Color(color)) symbol.colorizer = c rule.symbols.append(symbol) style.rules.append(rule) map.append_style("estilo", style) raster.styles.append("estilo") map.layers.append(raster) map.zoom_to_box(mapnik.Box2d(minLong, minLat, maxLong, maxLat)) image = mapnik.Image(TILE_WIDTH, TILE_HEIGHT) mapnik.render(map, image) imageData = image.tostring('png') return HttpResponse(imageData, content_type="image/png") except: traceback.print_exc() return HttpResponse("Error")
def test_render_with_scale_factor_zero_throws(): m = mapnik.Map(256, 256) im = mapnik.Image(256, 256) mapnik.render(m, im, 0.0)
def renderLegendElement(sourceFile, elementType, tagList, zoom, imageWidth, map_uri): """ # 'Fake' load a map to use mapnik libxml2 support for large xml files mSource = mapnik.Map(1,1) mapnik.load_map(mSource,sourceFile) inputstylesheet=mapnik.save_map_to_string(mSource) """ # serialize map file with external entities included inputstylesheet = etree.tostring(etree.parse(sourceFile)) # the mapfile (stylesheet made only for legend element rendering # is returned as a string, no file is written on disk # then use mapnik.load_map_from_string mapfile = create_legend_stylesheet(inputstylesheet) # create a new element, which return its bbox and an osm file as # a string osmStr, bound = createOsmElement(elementType, tagList, zoom) # create a named temporary file, mapnik needs a real file # we cannot pass a StringIO nor a string, nor a unnammed # temporary file osmFile = tempfile.NamedTemporaryFile(mode='w+t') osmFile.write(osmStr) #write the osm file osmFile.seek(0) #rewind #--------------------------------------------------- # Set up projection # long/lat in degrees, aka ESPG:4326 and "WGS 84" lonlat = mapnik.Projection('+proj=longlat +datum=WGS84') #bbbox =(lon,lat,maxlon,maxlat) ratio = abs((bound[2] - bound[0]) / (bound[3] - bound[1])) width = imageWidth height = int(width / ratio * 1) # add +1 if highway=path looks blurry FIXME m = mapnik.Map(width, height) mapnik.load_map_from_string(m, mapfile) m.srs = lonlat.params() for l in m.layers: l.datasource = Osm(file=osmFile.name) l.srs = lonlat.params() # uncomment this line to save the mapfile on disk, remember to # NEVER show this file to a stylesheet maintainer: #save_map(m,'mapfile.xml') # render the element and save to disk bbox =lonlat.forward(mapnik.Envelope(mapnik.Coord(bound[0],bound[1]),\ mapnik.Coord(bound[2],bound[3]))) m.zoom_to_box(bbox) im = mapnik.Image(width, height) mapnik.render(m, im) osmFile.close() # closing the datasource view = im.view(0, 0, width, height) # x,y,width,height #print "saving ", map_uri #view.save(map_uri,'png') #'save' the image in a string imgStr = view.tostring('png') # reopen the saved image with PIL to count the color # if 1, the pic is empty #img = Image.open(map_uri) # kind of StringIO() for images instead: imgParser = ImageFile.Parser() imgParser.feed(imgStr) img = imgParser.close() if len(img.getcolors()) == 1: print "empty file not saved", map_uri #delete the pic file if empty #os.remove(map_uri) else: # Crop the file to its smaller extent # Cropping the pic allow a much concise html page formatting, # use CSS for the rest img256 = img.convert('L') imgbg = ImageChops.constant(img256, img256.getpixel((0, 0))) box = ImageChops.difference(img256, imgbg).getbbox() out = img.crop(box) print "saving ", map_uri out.save(map_uri) return True
map = mapnik.Map(width, height) # Load map configuration mapnik.load_map(map, "/openstreetmap-carto/mapnik.xml") # Zoom the map to the bounding box map.zoom_to_box(bbox) # Fork so that we can handle crashes rendering the map pid = os.fork() # Render the map if pid == 0: if form.getvalue("format") == "png": image = mapnik.Image(map.width, map.height) mapnik.render(map, image) png = image.tostring("png") output_headers("image/png", "map.png", len(png)) sys.stdout.write(png) elif form.getvalue("format") == "jpeg": image = mapnik.Image(map.width, map.height) mapnik.render(map, image) jpeg = image.tostring("jpeg") output_headers("image/jpeg", "map.jpg", len(jpeg)) sys.stdout.write(jpeg) elif form.getvalue("format") == "svg": file = tempfile.NamedTemporaryFile(prefix = "export") surface = cairo.SVGSurface(file.name, map.width, map.height) mapnik.render(map, surface) surface.finish() output_headers("image/svg+xml", "map.svg", file_size(file))
tileim = Image.eval(tileim,lambda x: highCompress(lowCompress(gamma(x,1.3)))) sys.stdout.write("done. (%gs/%gs)\n" % (time.clock() - t0,time.time() - t0_)) sys.stdout.flush() else: t0 = time.clock() t0_ = time.time() sys.stdout.write("\tRendering '%s'..." % (mapfile)) sys.stdout.flush() m = mapnik.Map(mtileSize,mtileSize) mapnik.load_map(m, "%s/~map-%s.xml" % (mappath,mapfile), True) m.buffer_size = 512 if mapfile == "text" else 48 m.resize(mtileSize, mtileSize) m.zoom_to_box(bbox) tileim = mapnik.Image(mtileSize, mtileSize) mapnik.render(m, tileim) tileim = Image.fromstring('RGBA',(mtileSize, mtileSize),tileim.tostring()) sys.stdout.write("done. (%gs/%gs)\n" % (time.clock() - t0,time.time() - t0_)) sys.stdout.flush() im = composite(mtileSize,tileim,im,opts) k += 1 t0 = time.clock() t0_ = time.time() sys.stdout.write("\tCroping tiles...") sys.stdout.flush() im.convert('RGB') for i in range(mtileSize/TILE_SIZE): for j in range(mtileSize/TILE_SIZE):
def _test_rgba_subquery(lbl, pixtype, r, g, b, a, g1, b1): # # 3 8 13 # +---+---+---+ # 3 | v | v | h | NOTE: writes different alpha # +---+---+---+ in 13,8 and 8,13 # 8 | v | v | a | # +---+---+---+ # 13 | v | b | v | # +---+---+---+ # sql = "(select 3 as i, " \ " ST_SetValues(" \ " ST_SetValues(" \ " ST_AddBand(" \ " ST_AddBand(" \ " ST_AddBand(" \ " ST_AsRaster(" \ " ST_MakeEnvelope(0,0,14,14), " \ " 1.0, -1.0, '%s', %s" \ " )," \ " '%s', %d::float" \ " ), " \ " '%s', %d::float" \ " ), " \ " '%s', %d::float" \ " ), " \ " 2, 11, 6, 4, 5, %s::float8" \ " )," \ " 3, 6, 11, 5, 4, %s::float8" \ " ) as r" \ ") as foo" % (pixtype, r, pixtype, g, pixtype, b, pixtype, a, g1, b1) overview = '' rescale = 0 clip = 0 if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table=sql, raster_field='r', use_overviews=0 if overview else 0, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['i'], 3) lyr = mapnik.Layer('rgba_subquery') lyr.datasource = ds expenv = mapnik.Box2d(0, 0, 14, 14) env = lyr.envelope() assert_almost_equal(env.minx, expenv.minx, places=0) assert_almost_equal(env.miny, expenv.miny, places=0) assert_almost_equal(env.maxx, expenv.maxx, places=0) assert_almost_equal(env.maxy, expenv.maxy, places=0) mm = mapnik.Map(15, 15) style = mapnik.Style() sym = mapnik.RasterSymbolizer() rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') im.save('/tmp/xfull.png') # for debugging hex_v = format(r << 24 | g << 16 | b << 8 | a, '08x') hex_a = format(r << 24 | g1 << 16 | b << 8 | a, '08x') hex_b = format(r << 24 | g << 16 | b1 << 8 | a, '08x') eq_(hexlify(im.view(3, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(3, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 8, 1, 1).tostring()), hex_a) eq_(hexlify(im.view(3, 13, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 13, 1, 1).tostring()), hex_b) eq_(hexlify(im.view(13, 13, 1, 1).tostring()), hex_v)
# 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 m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx, imgy) mapnik.render(m, im) im.save(map_uri, 'png') sys.stdout.write('output image to %s!\n' % map_uri) # Note: instead of creating an image, rendering to it, and then # saving, we can also do this in one step like: # mapnik.render_to_file(m, map_uri,'png') # And in Mapnik >= 0.7.0 you can also use `render_to_file()` to output # to Cairo supported formats if you have Mapnik built with Cairo support # For example, to render to pdf or svg do: # mapnik.render_to_file(m, "image.pdf") #mapnik.render_to_file(m, "image.svg")
def _test_rgb_8bui_rendering(lbl, tnam, overview, rescale, clip): if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table=tnam, use_overviews=1 if overview else 0, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['rid'], 1) lyr = mapnik.Layer('rgba_8bui') lyr.datasource = ds expenv = mapnik.Box2d(-12329035.7652168,4508650.39854396, \ -12328653.0279471,4508957.34625536) env = lyr.envelope() # As the input size is a prime number both horizontally # and vertically, we expect the extent of the overview # tables to be a pixel wider than the original, whereas # the pixel size in geographical units depends on the # overview factor. So we start with the original pixel size # as base scale and multiply by the overview factor. # NOTE: the overview table extent only grows north and east pixsize = 2 # see gdalinfo nodata-edge.tif tol = pixsize * max(overview.split(',')) if overview else 0 assert_almost_equal(env.minx, expenv.minx, places=0) assert_almost_equal(env.miny, expenv.miny, delta=tol) assert_almost_equal(env.maxx, expenv.maxx, delta=tol) assert_almost_equal(env.maxy, expenv.maxy, places=0) mm = mapnik.Map(256, 256) style = mapnik.Style() sym = mapnik.RasterSymbolizer() rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') #im.save('/tmp/xfull.png') # for debugging # no data eq_(hexlify(im.view(3, 16, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(128, 16, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(250, 16, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(3, 240, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(128, 240, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(250, 240, 1, 1).tostring()), '00000000') # dark brown eq_(hexlify(im.view(174, 39, 1, 1).tostring()), 'c3a698ff') # dark gray eq_(hexlify(im.view(195, 132, 1, 1).tostring()), '575f62ff') # Now zoom over a portion of the env (1/10) newenv = mapnik.Box2d(-12329035.7652168, 4508926.651484220, \ -12328997.49148983,4508957.34625536) mm.zoom_to_box(newenv) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:1/10') #im.save('/tmp/xtenth.png') # for debugging # no data eq_(hexlify(im.view(3, 16, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(128, 16, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(250, 16, 1, 1).tostring()), '00000000') # black eq_(hexlify(im.view(3, 42, 1, 1).tostring()), '000000ff') eq_(hexlify(im.view(3, 134, 1, 1).tostring()), '000000ff') eq_(hexlify(im.view(3, 244, 1, 1).tostring()), '000000ff') # gray eq_(hexlify(im.view(135, 157, 1, 1).tostring()), '4e555bff') # brown eq_(hexlify(im.view(195, 223, 1, 1).tostring()), 'f2cdbaff')
def map_image(zoom, left, bottom, right, top, line, orientation='n', highres=True): mapfile = settings.MAPNIK_STYLES + "mapnik2normal.xml" if orientation != 'n': mapfile = settings.MAPNIK_STYLES + "mapnik2orlice_%s.xml" % str(orientation) imgx, imgy = get_image_size(zoom, top, left, bottom, right) if orientation in ('w', 'e'): imgx, imgy = imgy, imgx if highres: mapfile = settings.MAPNIK_STYLES + "mapnik2print.xml" if orientation != 'n': mapfile = settings.MAPNIK_STYLES + "mapnik2print_orlice_%s.xml" % str(orientation) imgx = 2*imgx imgy = 2*imgy m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) prj = 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') # North on top n0 = prj.forward(mapnik.Coord(left, bottom)) n1 = prj.forward(mapnik.Coord(right, top)) # East on top e0 = mapnik.Coord(-n0.y, n0.x) e1 = mapnik.Coord(-n1.y, n1.x) # South on top s0 = mapnik.Coord(-n1.x, -n1.y) s1 = mapnik.Coord(-n0.x, -n0.y) # West on top w0 = mapnik.Coord(-e1.x, -e1.y) w1 = mapnik.Coord(-e0.x, -e0.y) # bottom_left = prj.forward(mapnik.Coord(left, bottom)) # top_right = prj.forward(mapnik.Coord(right, top)) boxes = {'n': mapnik.Box2d(n0.x, n0.y, n1.x, n1.y), 'e': mapnik.Box2d(e0.x, e0.y, e1.x, e1.y), 's': mapnik.Box2d(s0.x, s0.y, s1.x, s1.y), 'w': mapnik.Box2d(w0.x, w0.y, w1.x, w1.y) } if line: gpxstyle = mapnik.Style() gpxrule = mapnik.Rule() lns = mapnik.LineSymbolizer() stroke = mapnik.Stroke() stroke.color = mapnik.Color('#FF6600') if highres: stroke.width = 10 else: stroke.width = 5 stroke.opacity = 0.9 stroke.line_join = mapnik.line_join.names['round'] stroke.line_cap = mapnik.line_cap.names['round'] lns.stroke = stroke gpxrule.symbols.append(lns) gpxstyle.rules.append(gpxrule) m.append_style('gpxstyle', gpxstyle) gpxlayer = mapnik.Layer('gpx') gpxlayer.datasource = mapnik.Ogr(file=line, layer='OGRGeoJSON') gpxlayer.styles.append('gpxstyle') m.layers.append(gpxlayer) bbox = boxes[orientation] m.zoom_to_box(bbox) im = mapnik.Image(imgx, imgy) mapnik.render(m, im) return Image.open(StringIO(im.tostring('png')))
def _test_dataraster_16bsi_rendering(lbl, overview, rescale, clip): if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table='"dataRaster"', band=1, use_overviews=1 if overview else 0, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['rid'], 1) lyr = mapnik.Layer('dataraster_16bsi') lyr.datasource = ds expenv = mapnik.Box2d(-14637, 3903178, 1126863, 4859678) env = lyr.envelope() # As the input size is a prime number both horizontally # and vertically, we expect the extent of the overview # tables to be a pixel wider than the original, whereas # the pixel size in geographical units depends on the # overview factor. So we start with the original pixel size # as base scale and multiply by the overview factor. # NOTE: the overview table extent only grows north and east pixsize = 500 # see gdalinfo dataraster.tif tol = pixsize * max(overview.split(',')) if overview else 0 assert_almost_equal(env.minx, expenv.minx) assert_almost_equal(env.miny, expenv.miny, delta=tol) assert_almost_equal(env.maxx, expenv.maxx, delta=tol) assert_almost_equal(env.maxy, expenv.maxy) mm = mapnik.Map(256, 256) style = mapnik.Style() col = mapnik.RasterColorizer() col.default_mode = mapnik.COLORIZER_DISCRETE col.add_stop(0, mapnik.Color(0x40, 0x40, 0x40, 255)) col.add_stop(10, mapnik.Color(0x80, 0x80, 0x80, 255)) col.add_stop(20, mapnik.Color(0xa0, 0xa0, 0xa0, 255)) sym = mapnik.RasterSymbolizer() sym.colorizer = col rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') # no data eq_(im.view(1, 1, 1, 1).tostring(), '\x00\x00\x00\x00') eq_(im.view(255, 255, 1, 1).tostring(), '\x00\x00\x00\x00') eq_(im.view(195, 116, 1, 1).tostring(), '\x00\x00\x00\x00') # A0A0A0 eq_(im.view(100, 120, 1, 1).tostring(), '\xa0\xa0\xa0\xff') eq_(im.view(75, 80, 1, 1).tostring(), '\xa0\xa0\xa0\xff') # 808080 eq_(im.view(74, 170, 1, 1).tostring(), '\x80\x80\x80\xff') eq_(im.view(30, 50, 1, 1).tostring(), '\x80\x80\x80\xff') # 404040 eq_(im.view(190, 70, 1, 1).tostring(), '\x40\x40\x40\xff') eq_(im.view(140, 170, 1, 1).tostring(), '\x40\x40\x40\xff') # Now zoom over a portion of the env (1/10) newenv = mapnik.Box2d(273663, 4024478, 330738, 4072303) mm.zoom_to_box(newenv) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:1/10') # nodata eq_(hexlify(im.view(255, 255, 1, 1).tostring()), '00000000') eq_(hexlify(im.view(200, 254, 1, 1).tostring()), '00000000') # A0A0A0 eq_(hexlify(im.view(90, 232, 1, 1).tostring()), 'a0a0a0ff') eq_(hexlify(im.view(96, 245, 1, 1).tostring()), 'a0a0a0ff') # 808080 eq_(hexlify(im.view(1, 1, 1, 1).tostring()), '808080ff') eq_(hexlify(im.view(128, 128, 1, 1).tostring()), '808080ff') # 404040 eq_(hexlify(im.view(255, 0, 1, 1).tostring()), '404040ff')
y = int(args.zxy[2]) if args.time: start = time.time() import mapnik custom_fonts_dir = '/etc/mapnik-osm-data/fonts/' mapnik.register_fonts(custom_fonts_dir) scale = 3 m = mapnik.Map(256 * scale, 256 * scale) mapnik.load_map(m, mapfile) bba = TileToBBox(x, y, z) bbox = mapnik.Box2d(bba[0], bba[1], bba[2], bba[3]) m.zoom_to_box(bbox) im = mapnik.Image(256 * scale, 256 * scale) mapnik.render(m, im, scale) if args.outputfile: ofile = args.outputfile else: ofile = args.prefix + '-' + str(z) + '-' + str(x) + '-' + str( y) + '.png' if ofile != '-': f = open(ofile, 'w') f.write(im.tostring('png')) f.close() else: sys.stdout.write(im.tostring('png')) if args.time: end = time.time() print("rendering time: %d seconds" % (end - start))
def _test_grayscale_subquery(lbl, pixtype, value): # # 3 8 13 # +---+---+---+ # 3 | v | v | v | NOTE: writes different color # +---+---+---+ in 13,8 and 8,13 # 8 | v | v | a | # +---+---+---+ # 13 | v | b | v | # +---+---+---+ # val_a = int(value / 3) val_b = val_a * 2 sql = "(select 3 as i, " \ " ST_SetValues(" \ " ST_SetValues(" \ " ST_AsRaster(" \ " ST_MakeEnvelope(0,0,14,14), " \ " 1.0, -1.0, '%s', %s" \ " ), " \ " 11, 6, 4, 5, %s::float8" \ " )," \ " 6, 11, 5, 4, %s::float8" \ " ) as \"R\"" \ ") as foo" % (pixtype, value, val_a, val_b) rescale = 0 clip = 0 if rescale: lbl += ' Sc' if clip: lbl += ' Cl' ds = mapnik.PgRaster(dbname=MAPNIK_TEST_DBNAME, table=sql, raster_field='"R"', use_overviews=1, prescale_rasters=rescale, clip_rasters=clip) fs = ds.featureset() feature = fs.next() eq_(feature['i'], 3) lyr = mapnik.Layer('grayscale_subquery') lyr.datasource = ds expenv = mapnik.Box2d(0, 0, 14, 14) env = lyr.envelope() assert_almost_equal(env.minx, expenv.minx, places=0) assert_almost_equal(env.miny, expenv.miny, places=0) assert_almost_equal(env.maxx, expenv.maxx, places=0) assert_almost_equal(env.maxy, expenv.maxy, places=0) mm = mapnik.Map(15, 15) style = mapnik.Style() sym = mapnik.RasterSymbolizer() rule = mapnik.Rule() rule.symbols.append(sym) style.rules.append(rule) mm.append_style('foo', style) lyr.styles.append('foo') mm.layers.append(lyr) mm.zoom_to_box(expenv) im = mapnik.Image(mm.width, mm.height) t0 = time.time() # we want wall time to include IO waits mapnik.render(mm, im) lap = time.time() - t0 log('T ' + str(lap) + ' -- ' + lbl + ' E:full') expected = 'images/support/pgraster/%s-%s-%s-%s.png' % ( lyr.name, lbl, pixtype, value) compare_images(expected, im) h = format(value, '02x') hex_v = h + h + h + 'ff' hex_v = hex_v.encode() h = format(val_a, '02x') hex_a = h + h + h + 'ff' hex_a = hex_a.encode() h = format(val_b, '02x') hex_b = h + h + h + 'ff' hex_b = hex_b.encode() eq_(hexlify(im.view(3, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 3, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(3, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 8, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(13, 8, 1, 1).tostring()), hex_a) eq_(hexlify(im.view(3, 13, 1, 1).tostring()), hex_v) eq_(hexlify(im.view(8, 13, 1, 1).tostring()), hex_b) eq_(hexlify(im.view(13, 13, 1, 1).tostring()), hex_v)
def tile(request, version, shapefile_id, zoom, x, y): try: if version != "1.0": raise Http404 try: shapefile = Shapefile.objects.get(id=shapefile_id) except Shapefile.DoesNotExist: raise Http404 zoom = int(zoom) x = int(x) y = int(y) if zoom < 0 or zoom > MAX_ZOOM_LEVEL: raise Http404 xExtent = _unitsPerPixel(zoom) * TILE_WIDTH yExtent = _unitsPerPixel(zoom) * TILE_HEIGHT minLong = x * xExtent - 180.0 minLat = y * yExtent - 90.0 maxLong = minLong + xExtent maxLat = minLat + yExtent if (minLong < -180 or maxLong > 180 or minLat < -90 or maxLat > 90): print "Map extent out of bounds:",minLong,minLat,maxLong,maxLat raise Http404 ####################################################### map = mapnik.Map(TILE_WIDTH, TILE_HEIGHT, str("+proj=longlat +datum=WGS84")) map.background = mapnik.Color(str("#7391ad")) dbSettings = settings.DATABASES['default'] datasource = mapnik.PostGIS(user=str(dbSettings['USER']),password=str(dbSettings['PASSWORD']), dbname=str(dbSettings['NAME']),table='tms_basemap', srid=4326, geometry_field="geometry", geometry_table='tms_basemap', port=5433) baseLayer = mapnik.Layer(str("baseLayer")) baseLayer.datasource = datasource baseLayer.styles.append(str("baseLayerStyle")) rule = mapnik.Rule() rule.symbols.append( mapnik.PolygonSymbolizer(mapnik.Color(str("#b5d19c")))) rule.symbols.append( mapnik.LineSymbolizer(mapnik.Color(str("#404040")), 0.2)) style = mapnik.Style() style.rules.append(rule) map.append_style(str("baseLayerStyle"), style) #### map.layers.append(baseLayer) geometry_field = \ utils.calc_geometry_field(shapefile.geom_type) query = '(SELECT ' + geometry_field \ + ' FROM "shared_feature" WHERE' \ + ' shapefile_id = ' + str(shapefile.id) + ') as geom' print query print dbSettings['USER'],dbSettings['PASSWORD'],dbSettings['NAME'],query,geometry_field datasource = \ mapnik.PostGIS(user=dbSettings['USER'], password=dbSettings['PASSWORD'], dbname=dbSettings['NAME'], port=dbSettings['PORT'], srid=4326, table=query, geometry_field=geometry_field, geometry_table='shared_feature', ) featureLayer = mapnik.Layer(str("featureLayer")) featureLayer.datasource = datasource featureLayer.styles.append(str("featureLayerStyle")) rule = mapnik.Rule() if shapefile.geom_type in ["Point", "MultiPoint"]: rule.symbols.append(mapnik.PointSymbolizer()) elif shapefile.geom_type in ["LineString", "MultiLineString"]: rule.symbols.append( mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.5)) elif shapefile.geom_type in ["Polygon", "MultiPolygon"]: rule.symbols.append( mapnik.PolygonSymbolizer(mapnik.Color(str("#f7edee")))) rule.symbols.append( mapnik.LineSymbolizer(mapnik.Color(str("#000000")), 0.5)) style = mapnik.Style() style.rules.append(rule) map.append_style(str("featureLayerStyle"), style) map.layers.append(featureLayer) map.zoom_to_box(mapnik.Box2d(minLong, minLat, maxLong, maxLat)) image = mapnik.Image(TILE_WIDTH, TILE_HEIGHT) mapnik.render(map, image) imageData = image.tostring(str('png')) print imageData return HttpResponse(imageData, content_type="image/png") except: traceback.print_exc() return HttpResponse("Error")
'k': 1.0, 'units': 'm', 'nadgrids': '@null', 'no_defs': True } gym = pyproj.Proj(srs) northwest = map.pointLocation(ModestMaps.Core.Point(0, 0)) southeast = map.pointLocation(dimensions) left, top = gym(northwest.lon, northwest.lat) right, bottom = gym(southeast.lon, southeast.lat) map = mapnik.Map(dimensions.x, dimensions.y) mapnik.load_map(map, stylesheet) map.zoom_to_box(mapnik.Envelope(left, top, right, bottom)) img = mapnik.Image(dimensions.x, dimensions.y) mapnik.render(map, img) img = PIL.Image.fromstring('RGBA', (dimensions.x, dimensions.y), img.tostring()) if format == '.jpg': img.save(output, quality=85) else: img.save(output) ########NEW FILE########
def test_pre_multiply_status_of_map1(): m = mapnik.Map(256, 256) im = mapnik.Image(m.width, m.height) eq_(validate_pixels_are_not_premultiplied(im), True) mapnik.render(m, im) eq_(validate_pixels_are_not_premultiplied(im), True)
def run(options): dim_mm = None scale = None size = None bbox = None rotate = not options.norotate if (options.ozi and options.projection.lower() != 'epsg:3857' and options.projection != EPSG_3857): raise Exception( 'Ozi map file output is only supported for Web Mercator (EPSG:3857). ' + 'Please remove --projection.') if options.url: parse_url(options.url, options) # format should not be empty if options.fmt: fmt = options.fmt.lower() elif '.' in options.output: fmt = options.output.split('.')[-1].lower() else: fmt = 'png256' need_cairo = fmt in ['svg', 'pdf'] # output projection if options.projection.isdigit(): proj_target = mapnik.Projection('+init=epsg:{}'.format( options.projection)) else: proj_target = mapnik.Projection(options.projection) transform = mapnik.ProjTransform(proj_lonlat, proj_target) # get image size in millimeters if options.paper: portrait = False if options.paper[0] == '-': portrait = True rotate = False options.paper = options.paper[1:] elif options.paper[0] == '+': rotate = False options.paper = options.paper[1:] else: rotate = True dim_mm = get_paper_size(options.paper.lower()) if not dim_mm: raise Exception('Incorrect paper format: ' + options.paper) if portrait: dim_mm = [dim_mm[1], dim_mm[0]] elif options.size: dim_mm = options.size if dim_mm and options.margin: dim_mm[0] = max(0, dim_mm[0] - options.margin * 2) dim_mm[1] = max(0, dim_mm[1] - options.margin * 2) # ppi and scale factor are the same thing if options.ppi: ppmm = options.ppi / 25.4 scale_factor = options.ppi / 90.7 else: scale_factor = options.factor ppmm = 90.7 / 25.4 * scale_factor # svg / pdf can be scaled only in cairo mode if scale_factor != 1 and need_cairo and not HAS_CAIRO: logging.error('Warning: install pycairo for using --factor or --ppi') scale_factor = 1 ppmm = 90.7 / 25.4 # convert physical size to pixels if options.size_px: size = options.size_px elif dim_mm: size = [int(round(dim_mm[0] * ppmm)), int(round(dim_mm[1] * ppmm))] if size and size[0] + size[1] <= 0: raise Exception('Both dimensions are less or equal to zero') if options.bbox: bbox = options.bbox # scale can be specified with zoom or with 1:NNN scale fix_scale = False if options.zoom: scale = 2 * 3.14159 * 6378137 / 2**(options.zoom + 8) / scale_factor elif options.scale: scale = options.scale * 0.00028 / scale_factor # Now we have to divide by cos(lat), but we might not know latitude at this point # TODO: division should only happen for EPSG:3857 or not at all if options.center: scale = scale / math.cos(math.radians(options.center[1])) elif options.bbox: scale = scale / math.cos( math.radians((options.bbox[3] + options.bbox[1]) / 2)) else: fix_scale = True # all calculations are in EPSG:3857 projection (it's easier) if bbox: bbox = transform.forward(mapnik.Box2d(*bbox)) bbox_web_merc = transform_lonlat_webmerc.forward( mapnik.Box2d(*(options.bbox))) if scale: scale = correct_scale(bbox, scale, bbox_web_merc, bbox) # calculate bbox through center, zoom and target size if not bbox and options.center and size and size[0] > 0 and size[ 1] > 0 and scale: # We don't know over which latitude range the bounding box spans, so we # first do everything in Web Mercator. center = transform_lonlat_webmerc.forward( mapnik.Coord(*options.center)) w = size[0] * scale / 2 h = size[1] * scale / 2 bbox_web_merc = mapnik.Box2d(center.x - w, center.y - h, center.x + w, center.y + h) bbox = transform_lonlat_webmerc.backward(bbox_web_merc) bbox = transform.forward(bbox) # now correct the scale scale = correct_scale(bbox, scale, bbox_web_merc, bbox) center = transform.forward(mapnik.Coord(*options.center)) w = size[0] * scale / 2 h = size[1] * scale / 2 bbox = mapnik.Box2d(center.x - w, center.y - h, center.x + w, center.y + h) # reading style xml into memory for preprocessing if options.style == '-': style_xml = sys.stdin.read() style_path = '' else: with codecs.open(options.style, 'r', 'utf-8') as style_file: style_xml = style_file.read() style_path = os.path.dirname(options.style) if options.base: style_path = options.base if options.vars: style_xml = xml_vars(style_xml, options.vars) if options.layers or options.add_layers: style_xml = reenable_layers( style_xml, parse_layers_string(options.layers) + parse_layers_string(options.add_layers)) # for layer processing we need to create the Map object # ----- BEGIN PRINTMAPS ----- # m = mapnik.Map(100, 100) # temporary size, will be changed before output m = mapnik.Map(size[0], size[1]) # ----- END PRINTMAPS ----- mapnik.load_map_from_string(m, style_xml.encode("utf-8"), False, style_path) m.srs = proj_target.params() # register non-standard fonts if options.fonts: for f in options.fonts: add_fonts(f) # get bbox from layer extents if options.fit: bbox = layer_bbox(m, options.fit.split(','), proj_target, bbox) # here's where we can fix scale, no new bboxes below if bbox and fix_scale: scale = scale / math.cos( math.radians(transform.backward(bbox.center()).y)) bbox_web_merc = transform_lonlat_webmerc.forward( transform.backward(bbox)) if scale: scale = correct_scale(bbox, scale, bbox_web_merc, bbox) # expand bbox with padding in mm if bbox and options.padding and (scale or size): if scale: tscale = scale else: tscale = min((bbox.maxx - bbox.minx) / max(size[0], 0.01), (bbox.maxy - bbox.miny) / max(size[1], 0.01)) bbox.pad(options.padding * ppmm * tscale) # bbox should be specified by this point if not bbox: raise Exception('Bounding box was not specified in any way') # rotate image to fit bbox better if rotate and size: portrait = bbox.maxy - bbox.miny > bbox.maxx - bbox.minx # take into consideration zero values, which mean they should be calculated from bbox if (size[0] == 0 or size[0] > size[1]) and portrait: size = [size[1], size[0]] # calculate pixel size from bbox and scale if not size: if scale: size = [ int(round(abs(bbox.maxx - bbox.minx) / scale)), int(round(abs(bbox.maxy - bbox.miny) / scale)) ] else: raise Exception( 'Image dimensions or scale were not specified in any way') elif size[0] == 0: size[0] = int( round(size[1] * (bbox.maxx - bbox.minx) / (bbox.maxy - bbox.miny))) elif size[1] == 0: size[1] = int( round(size[0] / (bbox.maxx - bbox.minx) * (bbox.maxy - bbox.miny))) if options.output == '-' or (need_cairo and options.tiles > 1): options.tiles = 1 # ----- BEGIN PRINTMAPS ----- # if max(size[0], size[1]) / options.tiles > 16384: # raise Exception('Image size exceeds mapnik limit ({} > {}), use --tiles'.format( # max(size[0], size[1]) / options.tiles, 16384)) # ----- END PRINTMAPS ----- # add / remove some layers if options.layers: filter_layers(m, parse_layers_string(options.layers)) if options.add_layers or options.hide_layers: select_layers(m, parse_layers_string(options.add_layers), parse_layers_string(options.hide_layers)) # ----- BEGIN PRINTMAPS ----- # logging.debug('scale=%s', scale) # logging.debug('scale_factor=%s', scale_factor) # logging.debug('size=%s,%s', size[0], size[1]) # logging.debug('bbox=%s', bbox) # logging.debug('bbox_wgs84=%s', transform.backward(bbox) if bbox else None) # logging.debug('layers=%s', ','.join([l.name for l in m.layers if l.active])) print('scale={}'.format(scale)) print('scale_factor={}'.format(scale_factor)) print('size={},{}'.format(size[0], size[1])) print('bbox={}'.format(bbox)) print('bbox_wgs84={}'.format(transform.backward(bbox) if bbox else None)) print('layers=' + ','.join([l.name for l in m.layers if l.active])) # ----- END PRINTMAPS ----- # ----- BEGIN PRINTMAPS ----- if options.info: quit() # ----- END PRINTMAPS ----- # generate metadata if options.ozi: options.ozi.write( prepare_ozi(bbox, size[0], size[1], options.output, transform)) if options.wld: options.wld.write(prepare_wld(bbox, size[0], size[1])) # export image m.aspect_fix_mode = mapnik.aspect_fix_mode.GROW_BBOX # ----- BEGIN PRINTMAPS ----- # m.resize(size[0], size[1]) # ----- END PRINTMAPS ----- m.zoom_to_box(bbox) outfile = options.output if options.output == '-': outfile = tempfile.TemporaryFile(mode='w+b') if need_cairo: if HAS_CAIRO: if fmt == 'svg': surface = cairo.SVGSurface(outfile, size[0], size[1]) else: surface = cairo.PDFSurface(outfile, size[0], size[1]) mapnik.render(m, surface, scale_factor, 0, 0) surface.finish() else: mapnik.render_to_file(m, outfile, fmt) else: if options.tiles == 1: im = mapnik.Image(size[0], size[1]) mapnik.render(m, im, scale_factor) im.save(outfile, fmt) else: # we cannot make mapnik calculate scale for us, so fixing aspect ratio outselves rdiff = (bbox.maxx - bbox.minx) / (bbox.maxy - bbox.miny) - size[0] / size[1] if rdiff > 0: bbox.height((bbox.maxx - bbox.minx) * size[1] / size[0]) elif rdiff < 0: bbox.width((bbox.maxy - bbox.miny) * size[0] / size[1]) scale = (bbox.maxx - bbox.minx) / size[0] width = max(32, int(math.ceil(1.0 * size[0] / options.tiles))) height = max(32, int(math.ceil(1.0 * size[1] / options.tiles))) m.resize(width, height) m.buffer_size = TILE_BUFFER tile_cnt = [ int(math.ceil(1.0 * size[0] / width)), int(math.ceil(1.0 * size[1] / height)) ] logging.debug('tile_count=%s %s', tile_cnt[0], tile_cnt[1]) logging.debug('tile_size=%s,%s', width, height) # ----- BEGIN PRINTMAPS ----- # tmp_tile = '{:02d}_{:02d}_{}' tmp_tile = '{}_{:02d}_{:02d}' # ----- END PRINTMAPS ----- tile_files = [] for row in range(0, tile_cnt[1]): for column in range(0, tile_cnt[0]): logging.debug('tile=%s,%s', row, column) tile_bbox = mapnik.Box2d( bbox.minx + 1.0 * width * scale * column, bbox.maxy - 1.0 * height * scale * row, bbox.minx + 1.0 * width * scale * (column + 1), bbox.maxy - 1.0 * height * scale * (row + 1)) tile_size = [ width if column < tile_cnt[0] - 1 else size[0] - width * (tile_cnt[0] - 1), height if row < tile_cnt[1] - 1 else size[1] - height * (tile_cnt[1] - 1) ] m.zoom_to_box(tile_bbox) im = mapnik.Image(tile_size[0], tile_size[1]) mapnik.render(m, im, scale_factor) # ----- BEGIN PRINTMAPS ----- # tile_name = tmp_tile.format(row, column, options.output) tile_name = tmp_tile.format(options.output, row, column) # ----- END PRINTMAPS ----- im.save(tile_name, fmt) if options.just_tiles: # write ozi/wld for a tile if needed if '.' not in tile_name: tile_basename = tile_name + '.' else: tile_basename = tile_name[0:tile_name.rindex('.') + 1] if options.ozi: with open(tile_basename + 'ozi', 'w') as f: f.write( prepare_ozi(tile_bbox, tile_size[0], tile_size[1], tile_basename + '.ozi', transform)) if options.wld: with open(tile_basename + 'wld', 'w') as f: f.write( prepare_wld(tile_bbox, tile_size[0], tile_size[1])) else: tile_files.append(tile_name) if not options.just_tiles: # join tiles and remove them if joining succeeded import subprocess result = subprocess.call([ IM_MONTAGE, '-geometry', '+0+0', '-tile', '{}x{}'.format( tile_cnt[0], tile_cnt[1]) ] + tile_files + [options.output]) if result == 0: for tile in tile_files: os.remove(tile) if options.output == '-': if sys.platform == "win32": # fix binary output on windows import msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) outfile.seek(0) sys.stdout.write(outfile.read()) outfile.close()
def renderTile(self, tile): import mapnik if self.mapnik: m = self.mapnik else: if self.fonts: engine = mapnik.FontEngine.instance() for font in self.fonts: engine.register_font(font) # Init it as 0,0 m = mapnik.Map(0, 0) if self.mapfile: mapnik.load_map(m, self.mapfile) elif self.mapstring: mapnik.load_map_from_string(m, self.mapstring) else: raise Exception( 'No map specified: either a map, mapfile or mapstring must be specified.' ) if self.projection: m.srs = self.projection # Restrict layer list, if requested if self.layers and self.layers != self.name: layers = self.layers.split(",") for layer_num in range(len(m.layers) - 1, -1, -1): l = m.layers[layer_num] if l.name not in layers: del m.layers[layer_num] if self.debug: print >> sys.stderr, "Removed layer %s loaded from %s, not in list: %s" % ( l.name, self.mapfile, layers) # this will insure that it gets cached in mod_python self.mapnik = m # Set the mapnik size to match the size of the current tile m.width = tile.size()[0] m.height = tile.size()[1] bbox = tile.bounds() bbox = mapnik.Envelope(bbox[0], bbox[1], bbox[2], bbox[3]) m.zoom_to_box(bbox) im = mapnik.Image(*tile.size()) mapnik.render(m, im) if hasattr(im, 'tostring'): if self.paletted: data = im.tostring('png256') else: data = im.tostring(self.extension) tile.data = data return tile.data elif hasattr(mapnik, 'rawdata'): data = mapnik.rawdata(im) import PIL.Image, StringIO im = PIL.Image.fromstring('RGBA', tile.size(), data) buffer = StringIO.StringIO() if self.paletted: print >> sys.stderr, "Mapnik's 8-bit (png256) format not supported with PIL" im.save(buffer, self.extension) buffer.seek(0) tile.data = buffer.read() return tile.data else: raise Exception( "Something is wrong: your version of Mapnik can't create a string from an image." )
def render(options): # create view if (options.view): columns = options.viewcolumns.split(',') if (options.extracolumns): columns += options.extracolumns.split(',') create_views(options.dsn, options.dbprefix, options.viewprefix, options.viewhstore, columns, options.date) # create map m = mapnik.Map(options.size[0], options.size[1]) # load style mapnik.load_map(m, options.style) # create projection object prj = 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" ) #c0 = prj.forward(Coord(bbox[0],bbox[1])) #c1 = prj.forward(Coord(bbox[2],bbox[3])) #e = Box2d(c0.x,c0.y,c1.x,c1.y) # map bounds if hasattr(mapnik, 'Box2d'): bbox = mapnik.Box2d(*options.bbox) else: bbox = mapnik.Envelope(*options.bbox) # project bounds to map projection e = mapnik.forward_(bbox, prj) # zoom map to bounding box m.zoom_to_box(e) options.file = options.file + "." + options.type if (options.type in ("png", "jpeg")): s = mapnik.Image(options.size[0], options.size[1]) elif cairo_exists and type == "svg": s = cairo.SVGSurface(options.file, options.size[0], options.size[1]) elif cairo_exists and type == "pdf": s = cairo.PDFSurface(options.file, options.size[0], options.size[1]) elif cairo_exists and type == "ps": s = cairo.PSSurface(options.file, options.size[0], options.size[1]) else: print "invalid image type" print parser.print_help() sys.exit(1) mapnik.render(m, s) if isinstance(s, mapnik.Image): view = s.view(0, 0, options.size[0], options.size[1]) view.save(options.file, options.type) elif isinstance(s, cairo.Surface): s.finish() if (options.view): drop_views(options.dsn, options.viewprefix)
def tile(request, version, shapefile_id, zoom, x, y): shapefile = None try: if version != "1.0": raise Http404 try: shapefile = Shapefile.objects.get(id=shapefile_id) except Shapefile.DoesNotExist: raise Http404 zoom = int(zoom) x = int(x) y = int(y) if zoom < 0 or zoom > MAX_ZOOM_LEVEL: raise Http404 xExtent = _unitsPerPixel(zoom) * TILE_WIDTH yExtent = _unitsPerPixel(zoom) * TILE_HEIGHT minLong = xExtent * x - 180.0 minLat = yExtent * y - 90.0 maxLong = minLong + xExtent maxLat = minLat + xExtent #if (minLong < -180 or maxLong > 180 or #minLat < -90 or maxLat > 90): #raise Http404 map = mapnik.Map(TILE_WIDTH, TILE_HEIGHT, "+proj=longlat +datum=WGS84") map.background = mapnik.Color("#7391ad") dbSettings = settings.DATABASES['default'] datasource = mapnik.PostGIS(host='localhost', user='******', password='******', dbname='spatial', table='"shapeEditor_basemap"', srid=4326, geometry_field="geometry", geometry_table='"shapeEditor_basemap"') baseLayer = mapnik.Layer("baseLayer") baseLayer.datasource = datasource baseLayer.styles.append("baseLayerStyle") rule = mapnik.Rule() rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color("#b5d19c"))) rule.symbols.append(mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.1)) style = mapnik.Style() style.rules.append(rule) map.append_style("baseLayerStyle", style) map.layers.append(baseLayer) geometryField = utils.calcGeometryField(shapefile.geom_type) query = '(select ' + geometryField + ' from "shapeEditor_feature" where' + ' shapefile_id=' + str( shapefile.id) + ') as geom' datasource = mapnik.PostGIS(host='localhost', user='******', password='******', dbname='spatial', table=query, srid=4326, geometry_field=geometryField, geometry_table='"shapeEditor_feature"') featureLayer = mapnik.Layer("featureLayer") featureLayer.datasource = datasource featureLayer.styles.append("featureLayerStyle") rule = mapnik.Rule() if shapefile.geom_type in ["Point", "MultiPoint"]: rule.symbols.append(mapnik.PointSymbolizer()) elif shapefile.geom_type in ["LineString", "MultiLineString"]: rule.symbols.append( mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.5)) elif shapefile.geom_type in ["Polygon", "MultiPolygon"]: rule.symbols.append( mapnik.PolygonSymbolizer(mapnik.Color("#f7edee"))) rule.symbols.append( mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.5)) style = mapnik.Style() style.rules.append(rule) map.append_style("featureLayerStyle", style) map.layers.append(featureLayer) map.zoom_to_box(mapnik.Box2d(minLong, minLat, maxLong, maxLat)) image = mapnik.Image(TILE_WIDTH, TILE_HEIGHT) mapnik.render(map, image) imageData = image.tostring('png') return HttpResponse(imageData, content_type="image/png") except: traceback.print_exc() return HttpResponse("")
if options.wld: options.wld.write(prepare_wld(bbox, size[0], size[1])) # export image m.aspect_fix_mode = mapnik.aspect_fix_mode.GROW_BBOX; m.resize(size[0], size[1]) m.zoom_to_box(bbox) outfile = options.output if options.output == '-': outfile = tempfile.TemporaryFile(mode='w+b') if need_cairo: if HAS_CAIRO: surface = cairo.SVGSurface(outfile, size[0], size[1]) if fmt == 'svg' else cairo.PDFSurface(outfile, size[0], size[1]) mapnik.render(m, surface, scale_factor, 0, 0) surface.finish() else: mapnik.render_to_file(m, outfile, fmt) else: if options.tiles == 1: im = mapnik.Image(size[0], size[1]) mapnik.render(m, im, scale_factor) im.save(outfile, fmt) else: # we cannot make mapnik calculate scale for us, so fixing aspect ratio outselves rdiff = (bbox.maxx-bbox.minx) / (bbox.maxy-bbox.miny) - size[0] / size[1] if rdiff > 0: bbox.height((bbox.maxx - bbox.minx) * size[1] / size[0]) elif rdiff < 0: bbox.width((bbox.maxy - bbox.miny) * size[0] / size[1])
def render(self, cairo_surface, dpi, osm_date): """Renders the map, the index and all other visual map features on the given Cairo surface. Args: cairo_surface (Cairo.Surface): the destination Cairo device. dpi (int): dots per inch of the device. """ LOG.info('SinglePageRenderer rendering -%s- on %dx%dmm paper at %d dpi.' % (self.rc.output_format, self.rc.paper_width_mm, self.rc.paper_height_mm, dpi)) # First determine some useful drawing parameters safe_margin_dots \ = commons.convert_pt_to_dots(Renderer.PRINT_SAFE_MARGIN_PT, dpi) usable_area_width_dots \ = commons.convert_pt_to_dots(self._usable_area_width_pt, dpi) usable_area_height_dots \ = commons.convert_pt_to_dots(self._usable_area_height_pt, dpi) title_margin_dots \ = commons.convert_pt_to_dots(self._title_margin_pt, dpi) copyright_margin_dots \ = commons.convert_pt_to_dots(self._copyright_margin_pt, dpi) map_coords_dots = list(map(lambda l: commons.convert_pt_to_dots(l, dpi), self._map_coords)) ctx = cairo.Context(cairo_surface) # Set a white background ctx.save() ctx.set_source_rgb(1, 1, 1) ctx.rectangle(0, 0, commons.convert_pt_to_dots(self.paper_width_pt, dpi), commons.convert_pt_to_dots(self.paper_height_pt, dpi)) ctx.fill() ctx.restore() ## ## Draw the map, scaled to fit the designated area ## ctx.save() # prevent map background from filling the full canvas ctx.rectangle(map_coords_dots[0], map_coords_dots[1], map_coords_dots[2], map_coords_dots[3]) ctx.clip() # Prepare to draw the map at the right location ctx.translate(map_coords_dots[0], map_coords_dots[1]) # Draw the rescaled Map ctx.save() scale_factor = int(dpi / 72) rendered_map = self._map_canvas.get_rendered_map() LOG.info('Map:') LOG.info('Mapnik scale: 1/%f' % rendered_map.scale_denominator()) LOG.info('Actual scale: 1/%f' % self._map_canvas.get_actual_scale()) LOG.info('Zoom factor: %d' % self.scaleDenominator2zoom(rendered_map.scale_denominator())) # now perform the actual drawing mapnik.render(rendered_map, ctx, scale_factor, 0, 0) ctx.restore() # Draw the rescaled Overlays for overlay_canvas in self._overlay_canvases: ctx.save() rendered_overlay = overlay_canvas.get_rendered_map() LOG.info('Overlay: %s' % overlay_canvas.get_style_name()) mapnik.render(rendered_overlay, ctx, scale_factor, 0, 0) ctx.restore() # Place the vertical and horizontal square labels if self.grid and self.index_position: self._draw_labels(ctx, self.grid, map_coords_dots[2], map_coords_dots[3], commons.convert_pt_to_dots(self._grid_legend_margin_pt, dpi)) ctx.restore() # Draw a rectangle frame around the map ctx.save() ctx.set_line_width(1) ctx.rectangle(map_coords_dots[0], map_coords_dots[1], map_coords_dots[2], map_coords_dots[3]) ctx.stroke() ctx.restore() ## ## Draw the title ## if self.rc.title: ctx.save() ctx.translate(safe_margin_dots, safe_margin_dots) self._draw_title(ctx, usable_area_width_dots, title_margin_dots, 'Droid Sans Bold') ctx.restore() # make sure that plugins do not render outside the actual map area ctx.save() ctx.rectangle(map_coords_dots[0], map_coords_dots[1], map_coords_dots[2], map_coords_dots[3]) ctx.clip() # apply effect plugin overlays for plugin_name, effect in self._overlay_effects.items(): try: effect.render(self, ctx) except Exception as e: # TODO better logging LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e)) ctx.restore() ## ## Draw the index, when applicable ## # Update the street_index to reflect the grid's actual position if self.grid and self.street_index and self.index_position is not None: self.street_index.apply_grid(self.grid) # Dump the CSV street index self.street_index.write_to_csv(self.rc.title, '%s.csv' % self.file_prefix) if self._index_renderer and self._index_area: ctx.save() # NEVER use ctx.scale() here because otherwise pango will # choose different font metrics which may be incompatible # with what has been computed by __init__(), which may # require more columns than expected ! Instead, we have # to trick pangocairo into believing it is rendering to a # device with the same default resolution, but with a # cairo resolution matching the 'dpi' specified # resolution. See # index::render::StreetIndexRenederer::render() and # comments within. self._index_renderer.render(ctx, self._index_area, dpi) ctx.restore() # Also draw a rectangle frame around the index ctx.save() ctx.set_line_width(1) ctx.rectangle(commons.convert_pt_to_dots(self._index_area.x, dpi), commons.convert_pt_to_dots(self._index_area.y, dpi), commons.convert_pt_to_dots(self._index_area.w, dpi), commons.convert_pt_to_dots(self._index_area.h, dpi)) ctx.stroke() ctx.restore() ## ## Draw the copyright notice ## ctx.save() # Move to the right position ctx.translate(safe_margin_dots, ( safe_margin_dots + title_margin_dots + usable_area_height_dots + copyright_margin_dots/4. ) ) # Draw the copyright notice self._draw_copyright_notice(ctx, usable_area_width_dots, copyright_margin_dots, osm_date=osm_date) ctx.restore() # render index on 2nd page if requested, and output format supports it if self.index_position == 'extra_page' and self._has_multipage_format() and self._index_renderer is not None: cairo_surface.show_page() # We use a fake vector device to determine the actual # rendering characteristics fake_surface = cairo.PDFSurface(None, self.paper_width_pt, self.paper_height_pt) usable_area_width_pt = (self.paper_width_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT) usable_area_height_pt = (self.paper_height_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT) index_area = self._index_renderer.precompute_occupation_area( fake_surface, Renderer.PRINT_SAFE_MARGIN_PT, ( self.paper_height_pt - Renderer.PRINT_SAFE_MARGIN_PT - usable_area_height_pt ), usable_area_width_pt, usable_area_height_pt, 'width', 'left') ctx.save() self._index_renderer.render(ctx, index_area, dpi) ctx.restore() cairo_surface.show_page() else: cairo_surface.flush()
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
right, bottom = gym(southeast.lon, southeast.lat) map = mapnik.Map(dimensions.x, dimensions.y) mapnik.load_map(map, stylesheet) map.zoom_to_box(mapnik.Envelope(left, top, right, bottom)) img = mapnik.Image(dimensions.x, dimensions.y) # http://brehaut.net/blog/2010/svg_maps_with_cairo_and_mapnik # http://trac.mapnik.org/wiki/MapnikRenderers if format in ('svg', 'pdf', 'ps'): f = open(output, 'w') if format == 'svg': surface = cairo.SVGSurface(f.name, dimensions.x, dimensions.y) elif format == 'pdf': surface = cairo.PDFSurface(f.name, dimensions.x, dimensions.y) else: surface = cairo.PSSurface(f.name, dimensions.x, dimensions.y) context = cairo.Context(surface) mapnik.render(map, context) surface.finish() else: mapnik.render(map, img) img = PIL.Image.fromstring('RGBA', (dimensions.x, dimensions.y), img.tostring()) if format == 'jpg': img.save(output, quality=85) else: img.save(output)
popplaces_rule.symbols.append(popplaces_text_symbolizer) popplaces_style.rules.append(popplaces_rule) m.append_style('popplaces', popplaces_style) popplaces_lyr.styles.append('popplaces') m.layers.append(popplaces_lyr) # Draw map # Set the initial extent of the map in 'master' spherical Mercator projection m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855)) # Render map im = mapnik.Image(m.width,m.height) mapnik.render(m, im) # Save image to files images_ = [] im.save('demo.png', 'png') # true-colour RGBA images_.append('demo.png') # old behavior, now can do 'png8:c=256' im.save('demo256.png', 'png256') # save to palette based (max 256 colours) png images_.append('demo256.png') im.save('demo64_binary_transparency.png', 'png8:c=64:t=1') images_.append('demo64_binary_transparency.png') im.save('demo128_colors_hextree_no_alpha.png', 'png8:c=100:m=h:t=0') images_.append('demo128_colors_hextree_no_alpha.png')
elif cairo_exists and type == "svg": s = cairo.SVGSurface(file, width, height) elif cairo_exists and type == "pdf": s = cairo.PDFSurface(file, width, height) elif cairo_exists and type == "ps": s = cairo.PSSurface(file, width, height) else: print "invalid image type" print parser.print_help() sys.exit(1) mapnik.render(m, s) if isinstance(s, mapnik.Image): view = s.view(0, 0, width, height) view.save(file, type) elif isinstance(s, cairo.Surface): s.finish() def zoom2size(bbox, zoom): prj = mapnik.Projection( "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs^") e = mapnik.forward_(mapnik.Envelope(*bbox), prj) wm = e.maxx - e.minx hm = e.maxy - e.miny
def render(self, cairo_surface, dpi, osm_date): ctx = cairo.Context(cairo_surface) self._render_front_page(ctx, cairo_surface, dpi, osm_date) self._render_blank_page(ctx, cairo_surface, dpi) ctx.save() # Prepare to draw the map at the right location ctx.translate( commons.convert_pt_to_dots(Renderer.PRINT_SAFE_MARGIN_PT), commons.convert_pt_to_dots(Renderer.PRINT_SAFE_MARGIN_PT)) ctx.rectangle(0, 0, self._usable_area_width_pt, self._usable_area_height_pt) ctx.clip() self._render_overview_page(ctx, cairo_surface, dpi) for map_number, (canvas, grid, overlay_canvases, overlay_effects) in enumerate(self.pages): LOG.info('Map page %d of %d' % (map_number + 1, len(self.pages))) rendered_map = canvas.get_rendered_map() LOG.debug('Mapnik scale: 1/%f' % rendered_map.scale_denominator()) LOG.debug('Actual scale: 1/%f' % canvas.get_actual_scale()) dest_tag = "mypage%d" % (map_number + self._first_map_page_number) draw_utils.anchor(ctx, dest_tag) mapnik.render(rendered_map, ctx) for overlay_canvas in overlay_canvases: rendered_overlay = overlay_canvas.get_rendered_map() mapnik.render(rendered_overlay, ctx) # Place the vertical and horizontal square labels ctx.save() ctx.translate(commons.convert_pt_to_dots(self.grayed_margin_pt), commons.convert_pt_to_dots(self.grayed_margin_pt)) self._draw_labels(ctx, grid, commons.convert_pt_to_dots(self._usable_area_width_pt) \ - 2 * commons.convert_pt_to_dots(self.grayed_margin_pt), commons.convert_pt_to_dots(self._usable_area_height_pt) \ - 2 * commons.convert_pt_to_dots(self.grayed_margin_pt), commons.convert_pt_to_dots(self._grid_legend_margin_pt)) ctx.restore() # apply effect overlays ctx.save() # we have to undo border adjustments here ctx.translate(-commons.convert_pt_to_dots(self.grayed_margin_pt)/2, -commons.convert_pt_to_dots(self.grayed_margin_pt)/2) self._map_canvas = canvas; for plugin_name, effect in overlay_effects.items(): self.grid = grid try: effect.render(self, ctx) except Exception as e: # TODO better logging LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e)) effect.render(self, ctx) ctx.restore() # Render the page number draw_utils.render_page_number(ctx, map_number + self._first_map_page_number, self._usable_area_width_pt, self._usable_area_height_pt, self.grayed_margin_pt, transparent_background = True) self._render_neighbour_arrows(ctx, cairo_surface, map_number, len(str(len(self.pages) + self._first_map_page_number))) try: # set_page_label() does not exist in older pycairo versions cairo_surface.set_page_label(_(u'Map page %d') % (map_number + self._first_map_page_number)) except: pass cairo_surface.show_page() ctx.restore mpsir = MultiPageIndexRenderer(self.rc.i18n, ctx, cairo_surface, self.index_categories, (Renderer.PRINT_SAFE_MARGIN_PT, Renderer.PRINT_SAFE_MARGIN_PT, self._usable_area_width_pt, self._usable_area_height_pt), map_number+5) mpsir.render() cairo_surface.flush()