예제 #1
0
def render_png(tile, zoom, xml, overscan):
    map_tile_size = TILE_SIZE + (overscan * 2)
    # mapnik is installed in a non-standard way.
    # It confuses pylint.
    # pylint: disable=no-member
    """
    Render the tile for the given zoom
    """
    logger = get_logger()
    ctx = mapnik.Context()

    map_tile = mapnik.Map(map_tile_size, map_tile_size)
    # scale_denom = 1 << (BASE_ZOOM - int(zoom or 1))
    # scale_factor = scale_denom / map_tile.scale_denominator()
    # map_tile.zoom(scale_factor)  # Is overriden by zoom_to_box.

    mapnik.load_map_from_string(map_tile, xml)

    box_min = -overscan
    box_max = TILE_SIZE + overscan - 1
    map_tile.zoom_to_box(mapnik.Box2d(box_min, box_min, box_max, box_max))

    for (name, features) in tile.items():
        name = name.encode('ascii', 'ignore')
        source = mapnik.MemoryDatasource()
        map_layer = mapnik.Layer(name)
        map_layer.datasource = source

        for feature in features:
            feat = mapnik.Feature(ctx, 0)

            try:
                feat.add_geometries_from_wkb(feature)
            except RuntimeError:
                from mapnik import Path  # pylint: disable=no-name-in-module
                try:
                    wkt = Path.from_wkb(feature).to_wkt()
                    logger.error('Invalid feature: %s', wkt)
                except RuntimeError:
                    logger.error('Corrupt feature: %s', feature.encode('hex'))

            source.add_feature(feat)

        map_layer.styles.append(name)
        map_tile.layers.append(map_layer)

    image = mapnik.Image(TILE_SIZE, TILE_SIZE)
    # tile, image, scale, offset_x, offset_y
    mapnik.render(map_tile, image, 1, overscan, overscan)

    return image.tostring('png')
def to_wkb(*wkts):
    from mapnik import Path, wkbByteOrder  # pylint: disable=no-name-in-module
    return [Path.from_wkt(wkt).to_wkb(wkbByteOrder.XDR) for wkt in wkts]