Exemplo n.º 1
0
    def fetch_and_apply_style(layer: QgsMapLayer,
                              url: str,
                              style_attr: str = '') -> Optional[str]:
        """
        Fetches a QML style from the specified URL, and applies it to a layer.
        @param layer: target layer to apply style to
        @param url: URL for QML content
        @param style_attr: optional str specifying name of existing field in layer to automatically
        update classified references to
        @return: Returns a str if an error occurred, or None if the fetch and apply was successful
        """
        request = QgsBlockingNetworkRequest()
        if request.get(QNetworkRequest(
                QUrl(url))) != QgsBlockingNetworkRequest.NoError:
            return 'Error while fetching QML style: {}'.format(
                request.errorMessage())

        reply = request.reply().content()
        tmp_file = QTemporaryFile('{}/XXXXXX.qml'.format(QDir.tempPath()))
        tmp_file.open()
        tmp_file_name = tmp_file.fileName()
        tmp_file.close()
        with open(tmp_file_name, 'wt', encoding='utf8') as f:
            f.write(reply.data().decode())

        layer.loadNamedStyle(tmp_file_name)

        if style_attr:
            StyleUtils.update_class_attribute(layer, style_attr)

        layer.triggerRepaint()
        return None
Exemplo n.º 2
0
def _set_output_layer_style(layerName: str, layer: QgsMapLayer,
                            alg: QgsProcessingAlgorithm,
                            details: 'QgsProcessingContext::LayerDetails',
                            context: QgsProcessingContext, parameters) -> None:
    """ Set layer style 

        Original code is from python/plugins/processing/gui/Postprocessing.py
    """
    '''If running a model, the execution will arrive here when an algorithm that is part of
    that model is executed. We check if its output is a final otuput of the model, and
    adapt the output name accordingly'''
    outputName = details.outputName
    if parameters:
        expcontext = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        expcontext.appendScope(scope)
        for out in alg.outputDefinitions():
            if out.name() not in parameters:
                continue
            outValue = parameters[out.name()]
            if hasattr(outValue, "sink"):
                outValue = outValue.sink.valueAsString(expcontext)[0]
            else:
                outValue = str(outValue)
            if outValue == layerName:
                outputName = out.name()
                break

    style = None
    if outputName:
        # If a style with the same name as the outputName exists
        # in workdir then use it
        style = os.path.join(context.workdir, outputName + '.qml')
        if not os.path.exists(style):
            style = RenderingStyles.getStyle(alg.id(), outputName)
        LOGGER.debug("Getting style for %s: %s <%s>", alg.id(), outputName,
                     style)

    # Get defaults styles
    if style is None:
        if layer.type() == QgsMapLayer.RasterLayer:
            style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE)
        else:
            if layer.geometryType() == QgsWkbTypes.PointGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POINT_STYLE)
            elif layer.geometryType() == QgsWkbTypes.LineGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_LINE_STYLE)
            else:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POLYGON_STYLE)
    if style:
        LOGGER.debug("Adding style '%s' to layer %s (outputName %s)", style,
                     details.name, outputName)
        layer.loadNamedStyle(style)

    LOGGER.debug("Layer name set to %s <details name: %s>", layer.name(),
                 details.name)
Exemplo n.º 3
0
def update_symbology(layer: QgsMapLayer,
                     color: typing.Tuple[int, int, int] = None,
                     size: float = None,
                     file: str = None) -> None:
    assert layer, 'Layer is not defined'

    if file:
        assert isinstance(file, str)

        (msg, noError) = layer.loadNamedStyle(file)

        if not noError:
            raise Exception(msg)

    renderer = layer.renderer()

    symbol = None

    if isinstance(renderer, QgsSingleSymbolRenderer):
        symbol = renderer.symbol()
    elif isinstance(renderer, QgsGraduatedSymbolRenderer):
        symbol = renderer.sourceSymbol()
    else:
        raise Exception('Unknown renderer!')

    if color:
        assert isinstance(
            color, collections.abc.Sequence
        ), 'Color should be a iteratable of three numbers for Red, Green, Blue; Each of them between 0 and 255'
        assert len(color) in (
            3, 4
        ), 'There should be three numbers passed for Red, Green, Blue; Each of them between 0 and 255'

        symbol.setColor(QColor.fromRgb(*color))

    if size:
        # For lines
        if type(symbol) == QgsLineSymbol:
            symbol.setWidth(size)

        # For points
        if type(symbol) == QgsMarkerSymbol:
            symbol.setSize(size)

        layer.triggerRepaint()
        iface.layerTreeView().refreshLayerSymbology(layer.id())
Exemplo n.º 4
0
def _load_qml_style(map_layer: qgc.QgsMapLayer, style_path: Path) -> None:
    msg, status = map_layer.loadNamedStyle(str(style_path))

    if not status:
        raise RuntimeError(f"Problem loading '{style_path}': '{msg}'")