Beispiel #1
0
def legend(request, layername, layertitle=False, style=None):
    """Get the legend from a layer.

    :param layername: The layer name in Geonode.
    :type layername: basestring

    :param layertitle: Add the layer title in the legend. Default to False.
    :type layertitle: bool

    :param style: Layer style to choose
    :type style: str

    :return: The HTTPResponse with a PNG.
    """
    layer = get_object_or_404(Layer, name=layername)
    qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)

    # get default style name
    if not style:
        # generate style cache
        if not qgis_layer.default_style:
            try:
                style_list(layer, internal=False)
            except Exception:
                logger.warning("Failed to fetch styles")

            # refresh values
            qgis_layer.refresh_from_db()
        if qgis_layer.default_style:
            style = qgis_layer.default_style.name

    tiles_directory = QGIS_SERVER_CONFIG['tiles_directory']
    legend_path = QGIS_SERVER_CONFIG['legend_path']
    legend_filename = legend_path % (qgis_layer.qgis_layer_name, style)
    # GOOD -- Verify with normalised version of path
    legend_filename = os.path.normpath(legend_filename)
    if not legend_filename.startswith(tiles_directory):
        return HttpResponseServerError()

    if not os.path.exists(legend_filename):
        if not os.path.exists(os.path.dirname(legend_filename)):
            os.makedirs(os.path.dirname(legend_filename))
        url = legend_url(layer, layertitle, style=style, internal=True)
        result = cache_request.apply_async((url, legend_filename))

        # Attempt to run task synchronously
        if not result.get():
            # If not succeded, provides error message.
            return HttpResponseServerError('Failed to fetch legend.')

    if image_format(legend_filename) != 'png':
        logger.error('%s is not valid PNG.' % legend_filename)
        os.remove(legend_filename)

    if not os.path.exists(legend_filename):
        return HttpResponse('The legend could not be found.', status=409)

    with open(legend_filename, 'rb') as f:
        return HttpResponse(f.read(), content_type='image/png')
Beispiel #2
0
def tile(request, layername, z, x, y, style=None):
    """Get the tile from a layer.

    :param layername: The layer name in Geonode.
    :type layername: basestring

    :param z: TMS coordinate, zoom parameter
    :type z: int, str

    :param x: TMS coordinate, longitude parameter
    :type x: int, str

    :param y: TMS coordinate, latitude parameter
    :type y: int, str

    :param style: Layer style to choose
    :type style: str

    :return: The HTTPResponse with a PNG.
    """
    x = int(x)
    y = int(y)
    z = int(z)

    layer = get_object_or_404(Layer, name=layername)
    qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)

    # get default style name
    if not style:
        # generate style cache
        if not qgis_layer.default_style:
            try:
                style_list(layer, internal=False)
            except Exception:
                logger.warning("Failed to fetch styles")

            # refresh values
            qgis_layer.refresh_from_db()
        if qgis_layer.default_style:
            style = qgis_layer.default_style.name

    tiles_directory = QGIS_SERVER_CONFIG['tiles_directory']
    tile_path = QGIS_SERVER_CONFIG['tile_path']
    tile_filename = tile_path % (qgis_layer.qgis_layer_name, style, z, x, y)
    # GOOD -- Verify with normalised version of path
    tile_filename = os.path.normpath(tile_filename)
    if not tile_filename.startswith(tiles_directory):
        return HttpResponseServerError()

    if not os.path.exists(tile_filename):

        if not os.path.exists(os.path.dirname(tile_filename)):
            os.makedirs(os.path.dirname(tile_filename))
        # Use internal url
        url = tile_url(layer, z, x, y, style=style, internal=True)
        result = cache_request.apply_async((url, tile_filename))

        # Attempt to run task synchronously
        if not result.get():
            # If not succeded, provides error message.
            return HttpResponseServerError('Failed to fetch tile.')

    if image_format(tile_filename) != 'png':
        logger.error('%s is not valid PNG.' % tile_filename)
        os.remove(tile_filename)

    if not os.path.exists(tile_filename):
        return HttpResponse('The tile could not be found.', status=409)

    with open(tile_filename, 'rb') as f:
        return HttpResponse(f.read(), content_type='image/png')