def render_png(tile, zoom, xml, overscan): map_tile_size = TILE_SIZE + (overscan * 2) # mapnik is installed in a non-standard way. # It confuses pylint. # pylint: disable=no-member """ Render the tile for the given zoom """ logger = get_logger() ctx = mapnik.Context() map_tile = mapnik.Map(map_tile_size, map_tile_size) # scale_denom = 1 << (BASE_ZOOM - int(zoom or 1)) # scale_factor = scale_denom / map_tile.scale_denominator() # map_tile.zoom(scale_factor) # Is overriden by zoom_to_box. mapnik.load_map_from_string(map_tile, xml) box_min = -overscan box_max = TILE_SIZE + overscan - 1 map_tile.zoom_to_box(mapnik.Box2d(box_min, box_min, box_max, box_max)) for (name, features) in tile.items(): name = name.encode('ascii', 'ignore') source = mapnik.MemoryDatasource() map_layer = mapnik.Layer(name) map_layer.datasource = source for feature in features: feat = mapnik.Feature(ctx, 0) try: feat.add_geometries_from_wkb(feature) except RuntimeError: from mapnik import Path # pylint: disable=no-name-in-module try: wkt = Path.from_wkb(feature).to_wkt() logger.error('Invalid feature: %s', wkt) except RuntimeError: logger.error('Corrupt feature: %s', feature.encode('hex')) source.add_feature(feat) map_layer.styles.append(name) map_tile.layers.append(map_layer) image = mapnik.Image(TILE_SIZE, TILE_SIZE) # tile, image, scale, offset_x, offset_y mapnik.render(map_tile, image, 1, overscan, overscan) return image.tostring('png')
def to_wkb(*wkts): from mapnik import Path, wkbByteOrder # pylint: disable=no-name-in-module return [Path.from_wkt(wkt).to_wkb(wkbByteOrder.XDR) for wkt in wkts]