Example #1
1
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
Example #3
0
    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')
Example #4
0
    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
Example #5
0
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))
Example #6
0
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)'])
Example #7
0
    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
Example #8
0
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)'])
Example #10
0
    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)
Example #15
0
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')
Example #16
0
    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
Example #17
0
    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))
Example #19
0
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))
Example #20
0
 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())
Example #22
0
 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)
Example #23
0
 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])
Example #24
0
    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)
Example #25
0
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();
Example #26
0
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)
Example #27
0
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')
Example #28
0
 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())
Example #30
0
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
Example #31
0
    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
Example #32
0
 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)
Example #33
0
 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)
Example #34
0
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")
Example #35
0
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
Example #37
0
      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))
Example #38
0
         
         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):
Example #39
0
 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)
Example #40
0
    # 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")
Example #41
0
 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')
Example #42
0
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')))
Example #43
0
    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))
Example #45
0
 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)
Example #46
0
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")
Example #47
0
        '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)
Example #49
0
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()
Example #50
0
    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."
            )
Example #51
0
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)
Example #52
0
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("")
Example #53
0
	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()
Example #55
0
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
Example #56
0
    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)
Example #57
0
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
Example #59
0
    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()