def testWillRenderFeatureNestedElse(self):
        vl = self.mapsettings.layers()[0]
        ft = vl.getFeature(0) # 'id' = 1

        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
        ctx.expressionContext().setFeature(ft)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})
        sym2 = QgsFillSymbol.createSimple({'color': '#71bd6c', 'outline_color': 'black'})
        sym3 = QgsFillSymbol.createSimple({'color': '#1f78b4', 'outline_color': 'black'})

        self.rx1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.rx2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.rx3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        self.rx3.appendChild(self.rx1)

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.rx2)
        rootrule.appendChild(self.rx3)

        vl.setRenderer(QgsRuleBasedRenderer(rootrule))
        renderer = vl.renderer()

        # Render with else rule and all activated
        renderer.startRender(ctx, vl.fields())
        self.assertTrue(renderer.willRenderFeature(ft, ctx))
        renderer.stopRender(ctx)

        # Render with else rule where else is deactivated
        renderer.rootRule().children()[1].setActive(False)
        renderer.startRender(ctx, vl.fields())
        self.assertFalse(renderer.willRenderFeature(ft, ctx))
        renderer.stopRender(ctx)
    def setUp(self):
        self.iface = get_iface()
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f'})
        sym2 = QgsFillSymbol.createSimple({'color': '#71bd6c'})
        sym3 = QgsFillSymbol.createSimple({'color': '#1f78b4'})

        self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        self.rootrule = QgsRuleBasedRenderer.Rule(None)
        self.rootrule.appendChild(self.r1)
        self.rootrule.appendChild(self.r2)
        self.rootrule.appendChild(self.r3)

        self.renderer = QgsRuleBasedRenderer(self.rootrule)
        layer.setRenderer(self.renderer)
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer]
        self.mapsettings.setLayers(rendered_layers)
 def set_rule_based_layer_style(layer: QgsVectorLayer,
                                rules: List['StyleRule']) -> None:
     """Sets the rule based layer style."""
     # Create a new rule-based renderer.
     symbol = QgsSymbol.defaultSymbol(layer.geometryType())
     renderer = QgsRuleBasedRenderer(symbol)
     # Get the "root" rule.
     root_rule = renderer.rootRule()
     for r in rules:
         # Create a clone (i.e. a copy) of the default rule.
         rule = root_rule.children()[0].clone()
         # Set the label, expression and color.
         rule.setLabel(r.label)
         rule.setFilterExpression(r.expression)
         rule.symbol().setColor(QColor(r.color_name))
         rule.symbol().setOpacity(r.opacity)
         # Set the scale limits if they have been specified.
         if r.scale_min_denom is not None and r.scale_max_denom is not None:
             rule.setScaleMinDenom(r.scale_min_denom)
             rule.setScaleMaxDenom(r.scale_max_denom)
         # Append the rule to the list of rules.
         root_rule.appendChild(rule)
     # Delete the default rule.
     root_rule.removeChildAt(0)
     # Apply the renderer to the layer.
     layer.setRenderer(renderer)
Exemple #4
0
def create_elimlyr(canvas):
    elim_lyr = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                elimedge_lname, r"memory")
    p_elimedge = elim_lyr.dataProvider()
    QgsProject.instance().addMapLayer(elim_lyr, True)
    # Case of only one color (elimedge_mono set in global_vars)
    if elimedge_mono:
        rend_symb=QgsSymbol.defaultSymbol(elim_lyr.geometryType())
        rend_symb.setWidth(elimedge_wdt)
        rend_symb.setColor(QColor(elimedge_col))
        rend_symb.setOpacity(elimedge_opc)
        rend_elimedge = QgsSingleSymbolRenderer(rend_symb)
    # Case of multiple colors depending on the type of elimination
    else:
        rend_elimedge = QgsRuleBasedRenderer(QgsLineSymbol())
        edge_root_rule = rend_elimedge.rootRule()
        edge_rules = ((inter_rfu, "\"pb_type\" = '" + inter_rfu + "'", elimedge_col, elimedge_wdt),
                      (inter_new, "\"pb_type\" = '" + inter_new + "'", elimedge_col2, elimedge_wdt))
        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            rule.symbol().setOpacity(elimedge_opc)
            edge_root_rule.appendChild(rule)
        edge_root_rule.removeChildAt(0)
    elim_lyr.setRenderer(rend_elimedge)
    p_elimedge.addAttributes(elimlyr_atts)
    elim_lyr.updateFields()
    # Refresh the canvas
    elim_lyr.triggerRepaint()
    return elim_lyr
Exemple #5
0
    def setupBackgroundLayer(self, stateLayer):
        '''
        Sets symbol rules for background layer in localization component
        '''
        symbol = QgsSymbol.defaultSymbol(stateLayer.geometryType())
        registry = QgsSymbolLayerRegistry()
        fillMeta = registry.symbolLayerMetadata("SimpleFill")
        fillSymbolLayer = fillMeta.createSymbolLayer({
            'color': '201,201,201',
            'outline_width': 0.1
        })
        # Replace the default style
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(fillSymbolLayer)

        renderer = QgsRuleBasedRenderer(symbol)
        rootRule = renderer.rootRule()
        for state in self.estados:
            # Appends the rule to the rootRule
            rule = self.createStateRule(rootRule, state)
            rootRule.appendChild(rule)
        # Delete the default rule
        rootRule.removeChildAt(0)
        # Apply the renderer to the layer
        stateLayer.setRenderer(renderer)
        stateLayer.triggerRepaint()
Exemple #6
0
 def setStyleIcon(self, svg):
     #Dato il path di un'icona svg la setta come stile per le sole features selezionate nel layer dei beni
     vlayer = self.getLayerBeni()
     if len(vlayer.selectedFeatures()) == 1:
         svgStyle = {
             "name": svg,
             "outline": "#000000",
             "size": "15",
         }
         svgLayer = QgsSvgMarkerSymbolLayer.create(svgStyle)
         svgSymbol = QgsMarkerSymbol()
         svgSymbol.changeSymbolLayer(0, svgLayer)
         symbol = QgsSymbol.defaultSymbol(vlayer.geometryType())
         symbol.setColor(QColor("Blue"))
         centroid = QgsCentroidFillSymbolLayer()
         centroid.setSubSymbol(svgSymbol)
         selectedSymbol = QgsFillSymbol()
         selectedSymbol.changeSymbolLayer(0, centroid)
         renderer = QgsRuleBasedRenderer(symbol)
         rule = QgsRuleBasedRenderer.Rule(selectedSymbol,
                                          label="Selected",
                                          filterExp="is_selected()")
         renderer.rootRule().appendChild(rule)
         vlayer.setRenderer(renderer)
         vlayer.triggerRepaint()
Exemple #7
0
    def testPointsUsedAttributes(self):
        points_shp = os.path.join(TEST_DATA_DIR, 'points.shp')
        points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(points_layer)

        # Create rulebased style
        sym1 = QgsMarkerSymbol()
        l1 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5)
        l1.setColor(QColor(255, 0, 0))
        l1.setStrokeStyle(Qt.NoPen)
        l1.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading"))
        sym1.changeSymbolLayer(0, l1)

        sym2 = QgsMarkerSymbol()
        l2 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5)
        l2.setColor(QColor(0, 255, 0))
        l2.setStrokeStyle(Qt.NoPen)
        l2.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading"))
        sym2.changeSymbolLayer(0, l2)

        sym3 = QgsMarkerSymbol()
        l3 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5)
        l3.setColor(QColor(0, 0, 255))
        l3.setStrokeStyle(Qt.NoPen)
        l3.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading"))
        sym3.changeSymbolLayer(0, l3)

        r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"Class" = \'B52\'')
        r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"Class" = \'Biplane\'')
        r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, '"Class" = \'Jet\'')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(r1)
        rootrule.appendChild(r2)
        rootrule.appendChild(r3)

        renderer = QgsRuleBasedRenderer(rootrule)

        points_layer.setRenderer(renderer)

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([points_layer])

        ctx = QgsRenderContext.fromMapSettings(ms)
        ctx.expressionContext().appendScope(points_layer.createExpressionContextScope())

        # for symbol layer
        self.assertCountEqual(l1.usedAttributes(ctx), {'Heading'})
        # for symbol
        self.assertCountEqual(sym1.usedAttributes(ctx), {'Heading'})
        # for symbol renderer
        self.assertCountEqual(renderer.usedAttributes(ctx), {'Class', 'Heading'})

        QgsProject.instance().removeMapLayer(points_layer)
Exemple #8
0
    def testIntersectionRuleBased(self):
        """
        Test that rule based renderer using intersection clip paths correctly uses original feature area for rule
        evaluation, not clipped area
        """
        poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp'))
        self.assertTrue(poly_layer.isValid())

        sym1 = QgsFillSymbol.createSimple({'color': '#ff00ff', 'outline_color': '#000000', 'outline_width': '1'})
        sym2 = QgsFillSymbol.createSimple({'color': '#00ffff', 'outline_color': '#000000', 'outline_width': '1'})

        r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, 'area($geometry)>25')
        r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(r1)
        rootrule.appendChild(r2)
        renderer = QgsRuleBasedRenderer(rootrule)
        poly_layer.setRenderer(renderer)

        mapsettings = QgsMapSettings()
        mapsettings.setOutputSize(QSize(400, 400))
        mapsettings.setOutputDpi(96)
        mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5))
        mapsettings.setLayers([poly_layer])
        mapsettings.setEllipsoid('')

        region = QgsMapClippingRegion(QgsGeometry.fromWkt(
            'Polygon ((-11725957 5368254, -12222900 4807501, -12246014 3834025, -12014878 3496059, -11259833 3518307, -10751333 3621153, -10574129 4516741, -10847640 5194995, -11105742 5325957, -11725957 5368254))'))
        region.setFeatureClip(QgsMapClippingRegion.FeatureClippingType.ClipToIntersection)
        region2 = QgsMapClippingRegion(QgsGeometry.fromWkt(
            'Polygon ((-11032549 5421399, -11533344 4693167, -11086481 4229112, -11167378 3742984, -10616504 3553984, -10161936 3925771, -9618766 4668482, -9472380 5620753, -10115709 5965063, -11032549 5421399))'))
        region2.setFeatureClip(QgsMapClippingRegion.FeatureClippingType.ClipToIntersection)
        mapsettings.addClippingRegion(region)
        mapsettings.addClippingRegion(region2)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_intersection_rule_based')
        result = renderchecker.runTest('expected_intersection_rule_based')
        self.report += renderchecker.report()
        self.assertTrue(result)

        # also try with symbol levels
        renderer.setUsingSymbolLevels(True)
        poly_layer.setRenderer(renderer)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_intersection_rule_based')
        result = renderchecker.runTest('expected_intersection_rule_based')
        self.report += renderchecker.report()
        self.assertTrue(result)
Exemple #9
0
    def testWillRenderFeatureTwoElse(self):
        """Regression #21287, also test rulesForFeature since there were no tests any where and I've found a couple of issues"""

        vl = self.mapsettings.layers()[0]
        ft = vl.getFeature(0)  # 'id' = 1

        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
        ctx.expressionContext().setFeature(ft)

        # Create rulebased style
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })
        sym4 = QgsFillSymbol.createSimple({
            'color': '#ff00ff',
            'outline_color': 'black'
        })

        self.rx2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 200')
        self.rx3 = QgsRuleBasedRenderer.Rule(sym3, 1000, 100000000,
                                             'ELSE')  # <<< - match this!
        self.rx4 = QgsRuleBasedRenderer.Rule(sym4, 0.1, 999, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.rx2)
        rootrule.appendChild(self.rx3)
        rootrule.appendChild(self.rx4)  # <- failed in regression #21287

        vl.setRenderer(QgsRuleBasedRenderer(rootrule))
        renderer = vl.renderer()

        # Render with else rule and all activated
        renderer.startRender(ctx, vl.fields())
        self.assertTrue(renderer.willRenderFeature(ft, ctx))

        # No context? All rules
        self.assertEqual(len(rootrule.rulesForFeature(ft)), 2)
        self.assertTrue(set(rootrule.rulesForFeature(ft)),
                        set([self.rx3, self.rx4]))

        # With context: only the matching one
        self.assertEqual(len(rootrule.rulesForFeature(ft, ctx)), 1)
        self.assertEqual(rootrule.rulesForFeature(ft, ctx)[0], self.rx3)
        renderer.stopRender(ctx)
Exemple #10
0
    def defStyle(self, layer):
        #
        # fs=l.renderer().rootRule().children()[1].symbols()[0]
        # sl ==> QgsSimpleLineSymbolLayer
        # sl=fs.symbolLayers()[0]
        # symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        # Exporterle Style (.qml) pour determiner les attributs
        symb_def = {
            'color': '53,227,47,77',
            'joinstyle': 'bevel',
            'outline_color': '0,0,0,255',
            'outline_style': 'dash',
            'outline_width': '0.5',
            'outline_width_unit': 'MM',
            'style': 'solid'
        }
        symbol = QgsFillSymbol.createSimple(symb_def)
        renderer = QgsRuleBasedRenderer(symbol)
        root_rule = renderer.rootRule()
        rule = root_rule.children()[0]
        rule.setLabel("Valide")
        rule.setFilterExpression(
            "\"valide\" is not null and \"supprime\" is null")
        # root_rule.appendChild(rule)

        symb_def = {
            'capstyle': 'square',
            'customdash': '5;2',
            'customdash_unit': 'MM',
            'customdash_unit': '0',
            'line_style': 'dash',
            'line_color': '200,194,194,255',
            'joinstyle': 'bevel',
            'line_width': '0.80',
            'line_width_unit': 'MM',
            'offset': '0',
            'use_custom_dash': '1'
        }
        symbol = QgsFillSymbol.createSimple(symb_def)

        symbol.changeSymbolLayer(0, QgsSimpleLineSymbolLayer.create(symb_def))

        rule = QgsRuleBasedRenderer.Rule(symbol)
        rule.setLabel("En attente")
        rule.setFilterExpression("\"valide\" is null and \"supprime\" is null")
        root_rule.appendChild(rule)

        layer.setRenderer(renderer)
Exemple #11
0
    def testUsedAttributes(self):
        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)

        # Create rulebased style
        sym2 = QgsFillSymbol.createSimple({'color': '#71bd6c', 'outline_color': 'black'})
        sym3 = QgsFillSymbol.createSimple({'color': '#1f78b4', 'outline_color': 'black'})

        self.rx2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 200')
        self.rx3 = QgsRuleBasedRenderer.Rule(sym3, 1000, 100000000, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.rx2)
        rootrule.appendChild(self.rx3)

        renderer = QgsRuleBasedRenderer(rootrule)

        self.assertCountEqual(renderer.usedAttributes(ctx), {'id'})
def set_selection_based_style(layer, s_color, else_color):
    # noinspection PyCallByClass
    fill_for_selected = QgsFillSymbol.createSimple({'color': 'blue'})
    fill_for_selected.setColor(s_color)
    rule_s = QgsRuleBasedRenderer.Rule(fill_for_selected, label=tr(u"Selected"),
                                       filterExp="is_selected()")

    fill_for_else = fill_for_selected.clone()
    fill_for_else.setColor(else_color)
    rule_else = QgsRuleBasedRenderer.Rule(fill_for_else, label=tr(u"Not Selected"),
                                          elseRule=True)

    renderer = QgsRuleBasedRenderer(QgsRuleBasedRenderer.Rule(None))
    root_rule = renderer.rootRule()
    root_rule.appendChild(rule_s)
    root_rule.appendChild(rule_else)

    layer.setRenderer(renderer)
    return layer
Exemple #13
0
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Rectangles', 'ogr')
        vfield = QgsField('fa_cy-fie+ld', QVariant.Int)
        layer.addExpressionField('"id"', vfield)
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })

        self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.r1)
        rootrule.appendChild(self.r2)
        rootrule.appendChild(self.r3)

        layer.setRenderer(QgsRuleBasedRenderer(rootrule))
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer]
        self.mapsettings.setLayers(rendered_layers)
        self.mapsettings_archive.append(self.mapsettings)
Exemple #14
0
    def testGroupAndElseRules(self):
        vl = self.mapsettings.layers()[0]

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })

        self.rx1 = QgsRuleBasedRenderer.Rule(None, 0, 0, '"id" < 3')
        self.rx2 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        self.subrx1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.subrx2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.rx1.appendChild(self.subrx1)
        self.rx1.appendChild(self.subrx2)

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.rx1)
        rootrule.appendChild(self.rx2)
        rootrule.children()[0].children()[0].setActive(False)
        rootrule.children()[0].children()[1].setActive(False)

        vl.setRenderer(QgsRuleBasedRenderer(rootrule))

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_rulebased_group_else')
        self.assertTrue(renderchecker.runTest('rulebased_group_else'))
def color_depares(layer, isoBreaks):
    # https://gis.stackexchange.com/a/282345
    # DEPARE COLORS and LIMITS
    # [land, intertidal, danger, shallow, deep]
    limits = [0, 2, 5, 8]
    limits = isoBreaks
    landLimit = [-10e9, limits[0]]
    intertidalLimit = [limits[0], limits[1]]
    dangerLimit = [limits[1], limits[2]]
    shallowLimit = [limits[2], limits[3]]
    deepLimit = [limits[3], 10e9]
    landColor = [248, 243, 161]
    intertidalColor = [187, 217, 146]
    dangerColor = [190, 229, 238]
    shallowColor = [232, 246, 249]
    deepColor = [255, 255, 255]
    #
    fullList = [[landLimit, landColor, 'land'],
                [intertidalLimit, intertidalColor, 'intertidal'],
                [dangerLimit, dangerColor, 'danger'],
                [shallowLimit, shallowColor, 'shallow'],
                [deepLimit, deepColor, 'deep']]
    fullList.reverse()
    #
    print('depare!')
    # layer = iface.activeLayer()
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    renderer = QgsRuleBasedRenderer(symbol)
    #
    for pair in fullList:
        expression = ' if(\"dep_min\" < {}, True, None) '.format(pair[0][1])
        color = pair[1]
        label = '{} (>{})'.format(pair[2], pair[0][1])
        rule_based_style(layer, symbol, renderer, label, expression, color)
    renderer.rootRule().removeChildAt(0)
    iface.layerTreeView().refreshLayerSymbology(layer.id())
Exemple #16
0
    def styleCreator(self, feature_geometry, layer_bound, utmSRID, id_attr,
                     id_value, spacing, crossX, crossY, scale, fontSize, font,
                     fontLL, llcolor, linwidth_geo, linwidth_utm,
                     linwidth_buffer_geo, linwidth_buffer_utm, geo_grid_color,
                     utm_grid_color, geo_grid_buffer_color,
                     utm_grid_buffer_color, masks_check):
        """Getting Input Data For Grid Generation"""
        linwidth_buffer_utm += linwidth_utm
        linwidth_buffer_geo += linwidth_geo
        grid_spacing = spacing
        geo_number_x = crossX
        geo_number_y = crossY
        fSize = fontSize
        fontType = font
        LLfontType = fontLL

        #Defining CRSs Transformations
        trLLUTM = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem('EPSG:4326'),
            QgsCoordinateReferenceSystem('EPSG:' + str(utmSRID)),
            QgsProject.instance())
        trUTMLL = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem('EPSG:' + str(utmSRID)),
            QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance())

        #Transforming to Geographic and defining bounding boxes
        feature_bbox = feature_geometry.boundingBox()
        bound_UTM_bb = str(feature_bbox).replace(',', '').replace('>', '')
        feature_geometry.transform(trUTMLL)
        feature_geo_bbox = feature_geometry.boundingBox()
        feature_bbox_or = feature_geometry.orientedMinimumBoundingBox()
        geo_bound_bb = str(feature_geo_bbox).replace(',', '').replace('>', '')
        oriented_geo_bb = str(feature_bbox_or).replace(',', '').replace(
            '>', '').replace('((', '').replace('))', '')

        #Defining UTM Grid Symbology Type
        properties = {'color': 'black'}
        grid_symb = QgsFillSymbol.createSimple(properties)
        """ Creating UTM Grid """
        extentsUTM = (float(bound_UTM_bb.split()[1]),
                      float(bound_UTM_bb.split()[2]),
                      float(bound_UTM_bb.split()[3]),
                      float(bound_UTM_bb.split()[4]))
        extentsGeo = (float(geo_bound_bb.split()[1]),
                      float(geo_bound_bb.split()[2]),
                      float(geo_bound_bb.split()[3]),
                      float(geo_bound_bb.split()[4]))
        if grid_spacing > 0:
            UTM_num_x = floor(extentsUTM[2] / grid_spacing) - floor(
                extentsUTM[0] / grid_spacing)
            UTM_num_y = floor(extentsUTM[3] / grid_spacing) - floor(
                extentsUTM[1] / grid_spacing)

            if linwidth_buffer_utm != linwidth_utm:
                #Generating Buffer Vertical Lines
                for x in range(1, UTM_num_x + 1):
                    grid_symb = self.utm_Symb_Generator(
                        utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb,
                        properties, UTM_num_x, UTM_num_y, x, 0, extentsGeo,
                        extentsUTM, linwidth_buffer_utm, utm_grid_buffer_color)

                #Generating Buffer Horizontal Lines
                for y in range(1, UTM_num_y + 1):
                    grid_symb = self.utm_Symb_Generator(
                        utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb,
                        properties, UTM_num_x, UTM_num_y, 0, y, extentsGeo,
                        extentsUTM, linwidth_buffer_utm, utm_grid_buffer_color)

            #Generating Vertical Lines
            for x in range(1, UTM_num_x + 1):
                grid_symb = self.utm_Symb_Generator(
                    utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb,
                    properties, UTM_num_x, UTM_num_y, x, 0, extentsGeo,
                    extentsUTM, linwidth_utm, utm_grid_color)

            #Generating Horizontal Lines
            for y in range(1, UTM_num_y + 1):
                grid_symb = self.utm_Symb_Generator(
                    utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb,
                    properties, UTM_num_x, UTM_num_y, 0, y, extentsGeo,
                    extentsUTM, linwidth_utm, utm_grid_color)
        """ Creating Geo Grid """
        px = (round(extentsGeo[2], 6) -
              round(extentsGeo[0], 6)) / (geo_number_x + 1)
        py = (round(extentsGeo[3], 6) -
              round(extentsGeo[1], 6)) / (geo_number_y + 1)
        if linwidth_buffer_geo != linwidth_geo:
            grid_symb = self.geoGridcreator(utmSRID, grid_symb, extentsGeo, px,
                                            py, geo_number_x, geo_number_y,
                                            scale, trLLUTM,
                                            linwidth_buffer_geo,
                                            geo_grid_buffer_color)
        grid_symb = self.geoGridcreator(utmSRID, grid_symb, extentsGeo, px, py,
                                        geo_number_x, geo_number_y, scale,
                                        trLLUTM, linwidth_geo, geo_grid_color)
        """ Rendering UTM and Geographic Grid """
        #Changing UTM Grid Color
        grid_symb.deleteSymbolLayer(0)

        #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule)
        symb_new = QgsRuleBasedRenderer.Rule(grid_symb)
        symb_new.setFilterExpression('\"' + str(id_attr) + '\" = ' +
                                     str(id_value))
        symb_new.setLabel('layer')

        #Appending rules to symbol root rule
        root_symbol_rule = QgsRuleBasedRenderer.Rule(None)
        root_symbol_rule.setFilterExpression('')
        root_symbol_rule.appendChild(symb_new)

        #Applying New Renderer
        render_base = QgsRuleBasedRenderer(root_symbol_rule)
        layer_bound.setRenderer(render_base)
        """Rendering outside area"""
        #Duplicating original layer
        layers_names = [
            i.name() for i in QgsProject.instance().mapLayers().values()
        ]
        if (layer_bound.name() + "_outside") not in layers_names:
            outside_bound_layer = QgsVectorLayer(
                layer_bound.source(),
                layer_bound.name() + "_outside", layer_bound.providerType())
            if layer_bound.providerType() == 'memory':
                feats = [feat for feat in layer_bound.getFeatures()]
                outside_bound_layer_data = outside_bound_layer.dataProvider()
                outside_bound_layer_data.addFeatures(feats)
            QgsProject.instance().addMapLayer(outside_bound_layer)
        else:
            outside_bound_layer = QgsProject.instance().mapLayersByName(
                layer_bound.name() + "_outside")[0]

        #Creating Rule Based Renderer (Rule For The Other Features)
        properties = {'color': 'white'}
        ext_grid_symb = QgsFillSymbol.createSimple(properties)
        symb_out = QgsSimpleFillSymbolLayer()
        symb_out.setFillColor(QColor('white'))
        symb_out.setStrokeWidth(linwidth_utm)
        ext_grid_symb.changeSymbolLayer(0, symb_out)
        rule_out = QgsRuleBasedRenderer.Rule(ext_grid_symb)
        rule_out.setFilterExpression('\"' + str(id_attr) + '\" = ' +
                                     str(id_value))
        rule_out.setLabel('outside')

        root_symbol_rule_out = QgsRuleBasedRenderer.Rule(None)
        root_symbol_rule_out.appendChild(rule_out)

        render_base_out = QgsRuleBasedRenderer(root_symbol_rule_out)
        new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer(
            render_base_out)
        outside_bound_layer.setRenderer(new_renderer)
        """ Labeling Geo Grid """
        dx = [2.0, -11.0, -8.0, -3.6]
        dx = [i * scale * fSize / 1.5 for i in dx]
        dy = [1.7, -3.8, -0.8, -0.8]
        dy = [i * scale * fSize / 1.5 for i in dy]

        root_rule = self.geoGridlabelPlacer(extentsGeo, px, py, geo_number_x,
                                            geo_number_y, dx, dy, fSize,
                                            LLfontType, trLLUTM, llcolor,
                                            scale, layer_bound, trUTMLL)
        """ Labeling UTM Grid"""
        dx = [-2.9, -2.9, -8.9, 2.0]
        dx = [i * scale * fSize / 1.5 for i in dx]
        dy = [1.4, -4.6, -0.5, -1.5]
        dy = [i * scale * fSize / 1.5 for i in dy]
        dy0 = [5.0, -7.2, -3.2, -4.2]
        dy0 = [i * scale * fSize / 1.5 for i in dy0]
        dy1 = [2.15, 1.2]
        dy1 = [i * scale * fSize / 1.5 for i in dy1]

        root_rule = self.utmGridlabelPlacer(root_rule, grid_spacing,
                                            extentsGeo, extentsUTM, px, py,
                                            UTM_num_x, UTM_num_y, trUTMLL,
                                            trLLUTM, dx, dy, dy0, dy1, fSize,
                                            fontType, scale, oriented_geo_bb,
                                            layer_bound)
        """ Activating Labels """
        rules = QgsRuleBasedLabeling(root_rule)
        layer_bound.setLabeling(rules)
        layer_bound.setLabelsEnabled(True)

        if masks_check:
            self.apply_masks(layer_bound)

        layer_bound.triggerRepaint()

        return
Exemple #17
0
def apply_style(layer, style, is_new, name):
    """Apply the style to a new or existing layer

    :param layer: QGIS layer instance
    :type layer: QgsVectorLayer
    :param style: optional, dictionary with style properties: example {'color': [100, 50, 123], 'transparency': 0.5, 'stroke_width: 3 }
    :type style: dict
    :param is_new: True is the layer is a new layer
    :type is_new: bool
    :param name: name of the isochrone, if blank/None create a timestamp for the name if the layer is not new
    :type name: str
    """

    if style is None:
        return

    def _set_labeling():
        pal_layer = QgsPalLayerSettings()
        pal_layer.fieldName = 'value'
        pal_layer.enabled = True
        pal_layer.placementFlags = QgsLabeling.OnLine
        pal_layer.placement = QgsPalLayerSettings.PerimeterCurved
        text_format = pal_layer.format()
        buffer = text_format.buffer()
        buffer.setColor(QColor(255, 255, 255))
        buffer.setOpacity(0.5)
        buffer.setEnabled(True)
        text_format.setBuffer(buffer)
        pal_layer.setFormat(text_format)
        labels = QgsVectorLayerSimpleLabeling(pal_layer)
        return labels

    def _set_rule(renderer):
        root_rule = renderer.rootRule()
        if is_new:
            rule = root_rule.children()[0]
        else:
            rule = root_rule.children()[0].clone()
        rule.setLabel(name)
        expression = '"name" = {}'.format(QgsExpression.quotedString(name))
        rule.setFilterExpression(expression)
        rule.symbol().setColor(QColor(*style['color'], 255))
        rule.symbol().setOpacity(1 - style['transparency'])
        rule.symbol().symbolLayers()[0].setStrokeWidth(style['stroke_width'])
        rule.symbol().symbolLayers()[0].setStrokeColor(QColor(255, 255, 255))
        if not is_new:
            root_rule.appendChild(rule)

    if is_new:  # Create the new style
        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        renderer = QgsRuleBasedRenderer(symbol)
        req = QgsFeatureRequest()
        req.addOrderBy('"value"', False, False)
        renderer.setOrderBy(req.orderBy())
        renderer.setOrderByEnabled(True)
        _set_rule(renderer)
        # Delete first rule
        layer.setRenderer(renderer)
        labels = _set_labeling()
        layer.setLabeling(labels)
        layer.setCustomProperty("labeling/bufferDraw", True)
        layer.setLabelsEnabled(True)

    else:
        # Check for rule based renderer, pass if not present
        renderer = layer.renderer()
        if isinstance(renderer, QgsRuleBasedRenderer):
            _set_rule(renderer)
Exemple #18
0
    def layer_to_QgsVectorLayer(
            source_layer,  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
            input_file,
            context: Context,
            fallback_crs=QgsCoordinateReferenceSystem(),
            defer_layer_uri_set: bool = False):
        """
        Converts a vector layer
        """
        if source_layer.__class__.__name__ == 'CadFeatureLayer':
            layer = source_layer.layer
        else:
            layer = source_layer

        crs = CrsConverter.convert_crs(
            layer.layer_extent.crs,
            context) if layer.layer_extent else QgsCoordinateReferenceSystem()
        if not crs.isValid():
            crs = fallback_crs

        subset_string = ''
        if layer.selection_set:
            subset_string = 'fid in ({})'.format(','.join(
                [str(s) for s in layer.selection_set]))
        elif layer.definition_query:
            subset_string = ExpressionConverter.convert_esri_sql(
                layer.definition_query)

        base, _ = os.path.split(input_file)

        uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri(
            source_layer=source_layer,
            obj=layer,
            base=base,
            crs=crs,
            subset=subset_string,
            context=context)

        if wkb_type is None or wkb_type == QgsWkbTypes.Unknown:
            wkb_type = VectorLayerConverter.layer_to_wkb_type(layer)
        context.layer_type_hint = wkb_type

        if Qgis.QGIS_VERSION_INT >= 31600:
            # try to get the layer name so that we can remove it from field references.
            # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format
            parts = QgsProviderRegistry.instance().decodeUri(provider, uri)
            context.main_layer_name = parts.get('layerName')
            if not context.main_layer_name and provider == 'ogr':
                context.main_layer_name = Path(parts['path']).stem

            if context.main_layer_name:
                subset_string = subset_string.replace(
                    context.main_layer_name + '.', '')
        else:
            context.main_layer_name = None

        if provider == 'ogr' and (not file_name
                                  or not os.path.exists(file_name)
                                  ) and context.invalid_layer_resolver:
            res = context.invalid_layer_resolver(layer.name, uri, wkb_type)
            uri = res.uri
            provider = res.providerKey

        if Qgis.QGIS_VERSION_INT >= 31000:
            opts = QgsVectorLayer.LayerOptions()
            if wkb_type is not None:
                opts.fallbackWkbType = wkb_type

            if provider == 'ogr' and subset_string:
                uri += '|subset={}'.format(subset_string)

            original_uri = uri
            if defer_layer_uri_set:
                uri = 'xxxxxxxxx' + uri

            vl = QgsVectorLayer(uri, layer.name, provider, opts)
            if defer_layer_uri_set:
                vl.setCustomProperty('original_uri', original_uri)
        else:
            vl = QgsMemoryProviderUtils.createMemoryLayer(
                layer.name, QgsFields(), wkb_type, crs)

        # context.style_folder, _ = os.path.split(output_file)
        if layer.renderer:
            renderer = VectorRendererConverter.convert_renderer(
                layer.renderer, context)
            try:
                if not renderer.usingSymbolLevels():
                    renderer.setUsingSymbolLevels(
                        layer.use_advanced_symbol_levels)
            except AttributeError:
                pass

            if layer.use_page_definition_query:
                filter_expression = '"{}" {} @atlas_pagename'.format(
                    layer.page_name_field, layer.page_name_match_operator)
                root_rule = QgsRuleBasedRenderer.Rule(None)

                # special case -- convert a simple renderer
                if isinstance(renderer, QgsSingleSymbolRenderer):
                    filter_rule = QgsRuleBasedRenderer.Rule(
                        renderer.symbol().clone())
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel(layer.name)
                    filter_rule.setDescription(layer.name)
                    root_rule.appendChild(filter_rule)
                else:
                    source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer(
                        renderer)
                    filter_rule = QgsRuleBasedRenderer.Rule(None)
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel('Current Atlas Page')
                    filter_rule.setDescription('Current Atlas Page')
                    root_rule.appendChild(filter_rule)
                    for child in source_rule_renderer.rootRule().children():
                        filter_rule.appendChild(child.clone())

                renderer = QgsRuleBasedRenderer(root_rule)

            if renderer:
                vl.setRenderer(renderer)
                vl.triggerRepaint()
        else:
            vl.setRenderer(QgsNullSymbolRenderer())
            vl.triggerRepaint()

        metadata = vl.metadata()
        metadata.setAbstract(layer.description)
        vl.setMetadata(metadata)  #

        # layer.zoom_max = "don't show when zoomed out beyond"
        zoom_max = layer.zoom_max
        # layer.zoom_min = "don't show when zoomed in beyond"
        zoom_min = layer.zoom_min

        enabled_scale_range = bool(zoom_max or zoom_min)
        if zoom_max and zoom_min and zoom_min > zoom_max:
            # inconsistent scale range -- zoom_max should be bigger number than zoom_min
            zoom_min, zoom_max = zoom_max, zoom_min

        # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max
        vl.setMinimumScale(
            zoom_max if enabled_scale_range else layer.stored_zoom_max)
        # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min
        vl.setMaximumScale(
            zoom_min if enabled_scale_range else layer.stored_zoom_min)
        vl.setScaleBasedVisibility(enabled_scale_range)

        vl.setOpacity(1.0 - (layer.transparency or 0) / 100)

        if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None:
            vl.setDisplayExpression(
                ExpressionConverter.convert(
                    layer.display_expression_properties.expression,
                    layer.display_expression_properties.expression_parser,
                    layer.display_expression_properties.advanced, context))

        if Qgis.QGIS_VERSION_INT < 31000:
            vl.setDataSource(uri, layer.name, provider)

        if encoding:
            vl.dataProvider().setEncoding(encoding)

        if subset_string:
            vl.setSubsetString(subset_string)

        vl.setCrs(crs)

        for e in layer.extensions:
            if e.__class__.__name__ == 'ServerLayerExtension':
                if 'CopyrightText' in e.properties.properties:
                    layer_credits = e.properties.properties['CopyrightText']
                    metadata = vl.metadata()
                    rights = metadata.rights()
                    rights.append(layer_credits)
                    metadata.setRights(rights)
                    vl.setMetadata(metadata)

        LabelConverter.convert_annotation_collection(
            layer.annotation_collection, dest_layer=vl, context=context)
        vl.setLabelsEnabled(layer.labels_enabled)

        DiagramConverter.convert_diagrams(layer.renderer,
                                          dest_layer=vl,
                                          context=context)

        # setup joins
        join_layer = VectorLayerConverter.add_joined_layer(
            source_layer=layer,
            input_file=input_file,
            base_layer=vl,
            context=context)

        context.dataset_name = ''

        vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl))

        if layer.hyperlinks:
            VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl)

        vl.setDisplayExpression(
            QgsExpression.quotedColumnRef(layer.display_field))

        res = [vl]
        if join_layer:
            res.append(join_layer)

        context.main_layer_name = None
        return res
    def style_maps(layer,
                   style_by,
                   iface,
                   output_type='damages-rlzs',
                   perils=None,
                   add_null_class=False,
                   render_higher_on_top=False,
                   repaint=True,
                   use_sgc_style=False):
        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        # see properties at:
        # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073
        symbol.setOpacity(1)
        if isinstance(symbol, QgsMarkerSymbol):
            # do it only for the layer with points
            symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))

        style = get_style(layer, iface.messageBar())

        # this is the default, as specified in the user settings
        ramp = QgsGradientColorRamp(style['color_from'], style['color_to'])
        style_mode = style['style_mode']

        # in most cases, we override the user-specified setting, and use
        # instead a setting that was required by scientists
        if output_type in OQ_TO_LAYER_TYPES:
            default_qgs_style = QgsStyle().defaultStyle()
            default_color_ramp_names = default_qgs_style.colorRampNames()
            if output_type in (
                    'damages-rlzs',
                    'avg_losses-rlzs',
                    'avg_losses-stats',
            ):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Jenks
                else:
                    style_mode = 'Jenks'
                ramp_type_idx = default_color_ramp_names.index('Reds')
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
                inverted = False
            elif (output_type in ('gmf_data', 'ruptures')
                  or (output_type == 'hmaps' and not use_sgc_style)):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if output_type == 'ruptures':
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.Pretty
                    else:
                        style_mode = 'PrettyBreaks'
                else:
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                    else:
                        style_mode = 'EqualInterval'
                ramp_type_idx = default_color_ramp_names.index('Spectral')
                inverted = True
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
            elif output_type == 'hmaps' and use_sgc_style:
                # FIXME: for SGC they were using size 10000 map units

                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Pretty
                else:
                    style_mode = 'PrettyBreaks'
                try:
                    ramp_type_idx = default_color_ramp_names.index(
                        'SGC_Green2Red_Hmap_Color_Ramp')
                except ValueError:
                    raise ValueError(
                        'Color ramp SGC_Green2Red_Hmap_Color_Ramp was '
                        'not found. Please import it from '
                        'Settings -> Style Manager, loading '
                        'svir/resources/sgc_green2red_hmap_color_ramp.xml')
                inverted = False
                registry = QgsApplication.symbolLayerRegistry()
                symbol_props = {
                    'name': 'square',
                    'color': '0,0,0',
                    'color_border': '0,0,0',
                    'offset': '0,0',
                    'size': '1.5',  # FIXME
                    'angle': '0',
                }
                square = registry.symbolLayerMetadata(
                    "SimpleMarker").createSymbolLayer(symbol_props)
                symbol = QgsSymbol.defaultSymbol(layer.geometryType()).clone()
                symbol.deleteSymbolLayer(0)
                symbol.appendSymbolLayer(square)
                symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))
            elif output_type in ['asset_risk', 'input']:
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                else:
                    style_mode = 'EqualInterval'
                # exposure_strings = ['number', 'occupants', 'value']
                # setting exposure colors by default
                colors = {
                    'single': RAMP_EXTREME_COLORS['Blues']['top'],
                    'ramp_name': 'Blues'
                }
                inverted = False
                if output_type == 'asset_risk':
                    damage_strings = perils
                    for damage_string in damage_strings:
                        if damage_string in style_by:
                            colors = {
                                'single':
                                RAMP_EXTREME_COLORS['Spectral']['top'],
                                'ramp_name': 'Spectral'
                            }
                            inverted = True
                            break
                else:  # 'input'
                    colors = {
                        'single': RAMP_EXTREME_COLORS['Greens']['top'],
                        'ramp_name': 'Greens'
                    }
                    symbol.symbolLayer(0).setShape(
                        QgsSimpleMarkerSymbolLayerBase.Square)
                single_color = colors['single']
                ramp_name = colors['ramp_name']
                ramp_type_idx = default_color_ramp_names.index(ramp_name)
                symbol.setColor(QColor(single_color))
            else:
                raise NotImplementedError(
                    'Undefined color ramp for output type %s' % output_type)
            ramp = default_qgs_style.colorRamp(
                default_color_ramp_names[ramp_type_idx])
            if inverted:
                ramp.invert()
        # get unique values
        fni = layer.fields().indexOf(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        num_unique_values = len(unique_values - {NULL})
        if num_unique_values > 2:
            if Qgis.QGIS_VERSION_INT < 31000:
                renderer = QgsGraduatedSymbolRenderer.createRenderer(
                    layer, style_by, min(num_unique_values, style['classes']),
                    style_mode, symbol.clone(), ramp)
            else:
                renderer = QgsGraduatedSymbolRenderer(style_by, [])
                # NOTE: the following returns an instance of one of the
                #       subclasses of QgsClassificationMethod
                classification_method = \
                    QgsApplication.classificationMethodRegistry().method(
                        style_mode)
                renderer.setClassificationMethod(classification_method)
                renderer.updateColorRamp(ramp)
                renderer.updateSymbols(symbol.clone())
                renderer.updateClasses(
                    layer, min(num_unique_values, style['classes']))
            if not use_sgc_style:
                if Qgis.QGIS_VERSION_INT < 31000:
                    label_format = renderer.labelFormat()
                    # NOTE: the following line might be useful
                    # label_format.setTrimTrailingZeroes(True)
                    label_format.setPrecision(2)
                    renderer.setLabelFormat(label_format, updateRanges=True)
                else:
                    renderer.classificationMethod().setLabelPrecision(2)
                    renderer.calculateLabelPrecision()
        elif num_unique_values == 2:
            categories = []
            for unique_value in unique_values:
                symbol = symbol.clone()
                try:
                    symbol.setColor(
                        QColor(RAMP_EXTREME_COLORS[ramp_name]
                               ['bottom' if unique_value ==
                                min(unique_values) else 'top']))
                except Exception:
                    symbol.setColor(
                        QColor(style['color_from'] if unique_value ==
                               min(unique_values) else style['color_to']))
                category = QgsRendererCategory(unique_value, symbol,
                                               str(unique_value))
                # entry for the list of category items
                categories.append(category)
            renderer = QgsCategorizedSymbolRenderer(style_by, categories)
        else:
            renderer = QgsSingleSymbolRenderer(symbol.clone())
        if add_null_class and NULL in unique_values:
            # add a class for NULL values
            rule_renderer = QgsRuleBasedRenderer(symbol.clone())
            root_rule = rule_renderer.rootRule()
            not_null_rule = root_rule.children()[0].clone()
            # strip parentheses from stringified color HSL
            not_null_rule.setFilterExpression(
                '%s IS NOT NULL' % QgsExpression.quotedColumnRef(style_by))
            not_null_rule.setLabel('%s:' % style_by)
            root_rule.appendChild(not_null_rule)
            null_rule = root_rule.children()[0].clone()
            null_rule.setSymbol(
                QgsFillSymbol.createSimple({
                    'color': '160,160,160',
                    'style': 'diagonal_x'
                }))
            null_rule.setFilterExpression(
                '%s IS NULL' % QgsExpression.quotedColumnRef(style_by))
            null_rule.setLabel(tr('No points'))
            root_rule.appendChild(null_rule)
            if isinstance(renderer, QgsGraduatedSymbolRenderer):
                # create value ranges
                rule_renderer.refineRuleRanges(not_null_rule, renderer)
                # remove default rule
            elif isinstance(renderer, QgsCategorizedSymbolRenderer):
                rule_renderer.refineRuleCategoris(not_null_rule, renderer)
            for rule in rule_renderer.rootRule().children()[1].children():
                label = rule.label()
                # by default, labels are like:
                # ('"collapse-structural-ASH_DRY_sum" >= 0.0000 AND
                # "collapse-structural-ASH_DRY_sum" <= 2.3949')
                first, second = label.split(" AND ")
                bottom = first.rsplit(" ", 1)[1]
                top = second.rsplit(" ", 1)[1]
                simplified = "%s - %s" % (bottom, top)
                rule.setLabel(simplified)
            root_rule.removeChildAt(0)
            renderer = rule_renderer
        if render_higher_on_top:
            renderer.setUsingSymbolLevels(True)
            symbol_items = [item for item in renderer.legendSymbolItems()]
            for i in range(len(symbol_items)):
                sym = symbol_items[i].symbol().clone()
                key = symbol_items[i].ruleKey()
                for lay in range(sym.symbolLayerCount()):
                    sym.symbolLayer(lay).setRenderingPass(i)
                renderer.setLegendSymbolItem(key, sym)
        layer.setRenderer(renderer)
        if not use_sgc_style:
            layer.setOpacity(0.7)
        if repaint:
            layer.triggerRepaint()
            iface.setActiveLayer(layer)
            iface.zoomToActiveLayer()
            # NOTE QGIS3: probably not needed
            # iface.layerTreeView().refreshLayerSymbology(layer.id())
            iface.mapCanvas().refresh()
    def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX,
                     crossY, scale, color, fontSize, font, fontLL, llcolor,
                     utmcheck):
        """Getting Input Data For Grid Generation"""
        grid_spacing = spacing
        geo_number_x = crossX
        geo_number_y = crossY
        fSize = fontSize
        fontType = font
        LLfontType = fontLL

        #Loading feature
        layer_bound = layer
        query = '"' + str(id_attr) + '"=' + str(id_value)
        layer_bound.selectByExpression(query, QgsVectorLayer.SelectBehavior(0))
        feature_bound = layer_bound.selectedFeatures()[0]
        layer_bound.removeSelection()

        #Getting Feature Source CRS and Geometry
        if utmcheck:
            feature_geometry = feature_bound.geometry()
            bound_UTM = layer_bound.crs().authid()
            feature_bbox = feature_geometry.boundingBox()
            bound_UTM_bb = str(feature_bbox).replace(',', '').replace('>', '')
            # Transforming to Geographic
            transform_feature = QgsCoordinateTransform(
                QgsCoordinateReferenceSystem(bound_UTM),
                QgsCoordinateReferenceSystem('EPSG:4674'),
                QgsProject.instance())
            feature_geometry.transform(transform_feature)
            bound_sourcecrs = 'EPSG:4674'
            feature_bbox = feature_geometry.boundingBox()
            feature_bbox_or = feature_geometry.orientedMinimumBoundingBox()
        else:
            feature_geometry = feature_bound.geometry()
            bound_sourcecrs = layer_bound.crs().authid()
            feature_bbox = feature_geometry.boundingBox()
            feature_bbox_or = feature_geometry.orientedMinimumBoundingBox()
        geo_bound_bb = str(feature_bbox).replace(',', '').replace('>', '')
        oriented_geo_bb = str(feature_bbox_or).replace(',', '').replace(
            '>', '').replace('((', '').replace('))', '')

        #Defining CRSs Transformations
        inom = feature_bound[index]
        if inom[0] == 'N':
            bound_UTM = 'EPSG:319' + str(72 + int(inom[3:5]) - 18)
        elif inom[0] == 'S':
            bound_UTM = 'EPSG:319' + str(78 + int(inom[3:5]) - 18)
        else:
            iface.messageBar().pushMessage("Error",
                                           "Invalid index attribute",
                                           level=Qgis.Critical)
            return
        trLLUTM = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem(bound_sourcecrs),
            QgsCoordinateReferenceSystem(bound_UTM), QgsProject.instance())
        trUTMLL = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem(bound_UTM),
            QgsCoordinateReferenceSystem(bound_sourcecrs),
            QgsProject.instance())

        #Defining UTM Grid Symbology Type
        renderer = layer.renderer()
        properties = {'color': 'black'}
        grid_symb = QgsFillSymbol.createSimple(properties)
        symb_out = QgsSimpleFillSymbolLayer()
        symb_out.setStrokeColor(QColor('black'))
        symb_out.setFillColor(QColor('white'))
        symb_out.setStrokeWidth(0.05)
        """ Creating UTM Grid """
        if not utmcheck:
            geo_UTM = feature_bound.geometry()
            geo_UTM.transform(trLLUTM)
            bound_UTM_bb = str(geo_UTM.boundingBox()).replace(',', '').replace(
                '>', '')
        xmin_UTM = float(bound_UTM_bb.split()[1])
        ymin_UTM = float(bound_UTM_bb.split()[2])
        xmax_UTM = float(bound_UTM_bb.split()[3])
        ymax_UTM = float(bound_UTM_bb.split()[4])

        if grid_spacing > 0:
            UTM_num_x = floor(xmax_UTM / grid_spacing) - floor(
                xmin_UTM / grid_spacing)
            UTM_num_y = floor(ymax_UTM / grid_spacing) - floor(
                ymin_UTM / grid_spacing)
            #Generating Vertical Lines
            for x in range(1, UTM_num_x + 1):
                grid_symb = self.utm_symb_generator(
                    grid_spacing, trUTMLL, trLLUTM, grid_symb, properties,
                    geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, x, 0,
                    geo_bound_bb, bound_UTM_bb, utmcheck)
            #Generating Horizontal Lines
            for y in range(1, UTM_num_y + 1):
                grid_symb = self.utm_symb_generator(
                    grid_spacing, trUTMLL, trLLUTM, grid_symb, properties,
                    geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, 0, y,
                    geo_bound_bb, bound_UTM_bb, utmcheck)
        """ Creating Geo Grid """
        grid_symb = self.geoGridcreator(grid_symb, geo_bound_bb, geo_number_x,
                                        geo_number_y, scale, utmcheck, trLLUTM)
        """ Rendering UTM and Geographic Grid """
        #Changing UTM Grid Color
        grid_symb.setColor(color)
        grid_symb.changeSymbolLayer(0, symb_out)
        #Creating Rule Based Renderer (Rule For The Other Features)
        properties = {'color': 'white'}
        ext_grid_symb = QgsFillSymbol.createSimple(properties)
        symb_ot = QgsRuleBasedRenderer.Rule(ext_grid_symb)
        symb_ot.setFilterExpression('\"' + str(id_attr) + '\" <> ' +
                                    str(id_value))
        symb_ot.setLabel('other')
        #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule)
        symb_new = QgsRuleBasedRenderer.Rule(grid_symb)
        symb_new.setFilterExpression('\"' + str(id_attr) + '\" = ' +
                                     str(id_value))
        symb_new.setLabel('layer')
        symb_new.appendChild(symb_ot)
        #Applying New Renderer
        render_base = QgsRuleBasedRenderer(symb_new)
        new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer(
            render_base)
        layer_bound.setRenderer(new_renderer)
        """ Labeling Geo Grid """
        if utmcheck:
            dx = [
                2 * scale * fSize / 1.5, -13.6 * scale * fSize / 1.5,
                6 * scale * fSize / 1.5
            ]
            dy = [1.7 * scale * fSize / 1.5, -3.8 * scale * fSize / 1.5]
        else:
            dx = [0.000018 * scale, -0.000120 * scale, 0.00005 * scale]
            dy = [0.000015 * scale, -0.000040 * scale]

        root_rule = self.geoGridlabelPlacer(geo_bound_bb, geo_number_x,
                                            geo_number_y, dx, dy, fSize,
                                            LLfontType, trLLUTM, trUTMLL,
                                            llcolor, utmcheck, scale)
        """ Labeling UTM Grid"""
        if utmcheck:
            dx = [-2.7, -9.7, -6.2, 5.4]
            dx = [i * scale * fSize / 1.5 for i in dx]
            dy = [2.5, -1.7, -0.5, -1.5]
            dy = [i * scale * fSize / 1.5 for i in dy]
            dy0 = [5.45, -4.8, -3.2, -4.2]
            dy0 = [i * scale * fSize / 1.5 for i in dy0]
            dy1 = [2.15, 1.2]
            dy1 = [i * scale * fSize / 1.5 for i in dy1]
        else:
            dx = [-0.00003, -0.000107, -0.000070, 0.000060]
            dx = [i * scale * fSize / 1.5 for i in dx]
            dy = [0.000027, 0.000016, -0.000041, -0.000052]
            dy = [i * scale * fSize / 1.5 for i in dy]
            dy0 = [0.0000644, 0.000053, -0.000076, -0.000087]
            dy0 = [i * scale * fSize / 1.5 for i in dy0]
            dy1 = [0.000032, 0.000020]
            dy1 = [i * scale * fSize / 1.5 for i in dy1]

        root_rule = self.utmGridlabelPlacer(
            root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x,
            geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0,
            dy1, fSize, fontType, scale, utmcheck, oriented_geo_bb)
        """ Activating Labels """
        rules = QgsRuleBasedLabeling(root_rule)
        layer.setLabeling(rules)
        layer.setLabelsEnabled(True)
        layer.triggerRepaint()
        return
    def processAlgorithm(self, parameters, context, feedback):

        t_file = self.parameterAsVectorLayer(
            parameters,
            self.FILE_TABLE,
            context
        )
        t_troncon = self.parameterAsVectorLayer(
            parameters,
            self.SEGMENTS_TABLE,
            context
        )
        t_obs = self.parameterAsVectorLayer(
            parameters,
            self.OBSERVATIONS_TABLE,
            context
        )
        t_regard = self.parameterAsVectorLayer(
            parameters,
            self.MANHOLES_TABLE,
            context
        )

        g_regard = self.parameterAsVectorLayer(
            parameters,
            self.GEOM_MANHOLES,
            context
        )
        g_troncon = self.parameterAsVectorLayer(
            parameters,
            self.GEOM_SEGMENT,
            context
        )
        g_obs = self.parameterAsVectorLayer(
            parameters,
            self.GEOM_OBSERVATION,
            context
        )

        v_regard = self.parameterAsVectorLayer(
            parameters,
            self.VIEW_MANHOLES_GEOLOCALIZED,
            context
        )

        # define variables
        variables = context.project().customVariables()
        variables['itv_rerau_t_file'] = t_file.id()
        variables['itv_rerau_t_troncon'] = t_troncon.id()
        variables['itv_rerau_t_obs'] = t_obs.id()
        variables['itv_rerau_t_regard'] = t_regard.id()

        variables['itv_rerau_g_regard'] = g_regard.id()
        variables['itv_rerau_g_troncon'] = g_troncon.id()
        variables['itv_rerau_g_obs'] = g_obs.id()

        context.project().setCustomVariables(variables)

        # define relations
        relations = [
            {
                'id': 'fk_obs_id_file',
                'name': tr('Link File - Observation'),
                'referencingLayer': t_obs.id(),
                'referencingField': 'id_file',
                'referencedLayer': t_file.id(),
                'referencedField': 'id'
            }, {
                'id': 'fk_regard_id_file',
                'name': tr('Link File - Manhole'),
                'referencingLayer': t_regard.id(),
                'referencingField': 'id_file',
                'referencedLayer': t_file.id(),
                'referencedField': 'id'
            }, {
                'id': 'fk_troncon_id_file',
                'name': tr('Link File - Pipe segment'),
                'referencingLayer': t_troncon.id(),
                'referencingField': 'id_file',
                'referencedLayer': t_file.id(),
                'referencedField': 'id'
            }, {
                'id': 'fk_obs_id_troncon',
                'name': tr('Link Pipe segment - Observation'),
                'referencingLayer': t_obs.id(),
                'referencingField': 'id_troncon',
                'referencedLayer': t_troncon.id(),
                'referencedField': 'id'
            }, {
                'id': 'fk_regard_id_geom_regard',
                'name': tr('Link Manhole inspection - Reference'),
                'referencingLayer': t_regard.id(),
                'referencingField': 'id_geom_regard',
                'referencedLayer': g_regard.id(),
                'referencedField': 'id'
            }, {
                'id': 'fk_troncon_id_geom_trononc',
                'name': tr('Link Pipe segment inspection - Reference'),
                'referencingLayer': t_troncon.id(),
                'referencingField': 'id_geom_troncon',
                'referencedLayer': g_troncon.id(),
                'referencedField': 'id'
            }
        ]

        relation_manager = context.project().relationManager()
        for rel_def in relations:
            feedback.pushInfo(
                'Link: {}'.format(rel_def['name'])
            )
            rel = QgsRelation()
            rel.setId(rel_def['id'])
            rel.setName(rel_def['name'])
            rel.setReferencingLayer(rel_def['referencingLayer'])
            rel.setReferencedLayer(rel_def['referencedLayer'])
            rel.addFieldPair(
                rel_def['referencingField'],
                rel_def['referencedField']
            )
            rel.setStrength(QgsRelation.Association)
            relation_manager.addRelation(rel)
            feedback.pushInfo(
                'Count relations {}'.format(
                    len(relation_manager.relations())
                )
            )

        joins = [
            {
                'layer': t_obs,
                'targetField': 'id_troncon',
                'joinLayer': t_troncon,
                'joinField': 'id',
                'fieldNamesSubset': ['ack']
            }, {
                'layer': g_obs,
                'targetField': 'id',
                'joinLayer': t_obs,
                'joinField': 'id',
                'fieldNamesSubset': []
            }
        ]
        for j_def in joins:
            layer = j_def['layer']

            join = QgsVectorLayerJoinInfo()
            join.setJoinFieldName(j_def['joinField'])
            join.setJoinLayerId(j_def['joinLayer'].id())
            join.setTargetFieldName(j_def['targetField'])

            if j_def['fieldNamesSubset']:
                join.setJoinFieldNamesSubset(j_def['fieldNamesSubset'])

            join.setUsingMemoryCache(False)
            join.setPrefix('')
            join.setEditable(False)
            join.setCascadedDelete(False)

            join.setJoinLayer(j_def['joinLayer'])

            layer.addJoin(join)
            layer.updateFields()

        # load styles
        styles = [
            {
                'layer': t_file,
                'namedStyles': [
                    {
                        'file': 'itv_file_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_file_actions.qml',
                        'type': QgsMapLayer.Actions
                    }
                ]
            }, {
                'layer': t_troncon,
                'namedStyles': [
                    {
                        'file': 'itv_troncon_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_troncon_table.qml',
                        'type': QgsMapLayer.AttributeTable
                    }
                ]
            }, {
                'layer': t_obs,
                'namedStyles': [
                    {
                        'file': 'itv_obs_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_obs_table.qml',
                        'type': QgsMapLayer.AttributeTable
                    }
                ]
            }, {
                'layer': t_regard,
                'namedStyles': [
                    {
                        'file': 'itv_regard_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_regard_forms.qml',
                        'type': QgsMapLayer.Forms
                    }, {
                        'file': 'itv_regard_table.qml',
                        'type': QgsMapLayer.AttributeTable
                    }
                ]
            }, {
                'layer': g_regard,
                'namedStyles': [
                    {
                        'file': 'itv_geom_regard_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_geom_regard_symbology.qml',
                        'type': QgsMapLayer.Symbology
                    }
                ]
            }, {
                'layer': g_troncon,
                'namedStyles': [
                    {
                        'file': 'itv_geom_troncon_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_geom_troncon_symbology.qml',
                        'type': QgsMapLayer.Symbology
                    }, {
                        'file': 'itv_geom_troncon_actions.qml',
                        'type': QgsMapLayer.Actions
                    }
                ]
            }, {
                'layer': g_obs,
                'namedStyles': [
                    {
                        'file': 'itv_geom_obs_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_geom_obs_symbology.qml',
                        'type': QgsMapLayer.Symbology
                    }
                ]
            }, {
                'layer': v_regard,
                'namedStyles': [
                    {
                        'file': 'itv_view_regard_fields.qml',
                        'type': QgsMapLayer.Fields
                    }, {
                        'file': 'itv_view_regard_symbology.qml',
                        'type': QgsMapLayer.Symbology
                    }, {
                        'file': 'itv_view_regard_labeling.qml',
                        'type': QgsMapLayer.Labeling
                    }
                ]
            }
        ]
        for style in styles:
            layer = style['layer']
            for n_style in style['namedStyles']:
                layer.loadNamedStyle(
                    resources_path('styles', n_style['file']),
                    categories=n_style['type']
                )
                # layer.saveStyleToDatabase('style', 'default style', True, '')
                layer.triggerRepaint()

        # Creation de la symbologie g_obs
        g_obs_rules = (
            'BAA', 'BAB', 'BAC', 'BAD', 'BAE', 'BAF', 'BAG', 'BAH',
            'BAI', 'BAJ', 'BAK', 'BAL', 'BAM', 'BAN', 'BAO', 'BAP',
            'BBA', 'BBB', 'BBC', 'BBD', 'BBE', 'BBF', 'BBG', 'BBH',
            'BCA', 'BCB', 'BCC', 'BDA', 'BDB', 'BDC', 'BDD', 'BDE',
            'BDF', 'BDG'
        )
        g_obs_rule_descs = {
            'BAA': 'Déformation',
            'BAB': 'Fissure',
            'BAC': 'Rupture/Effondrement',
            'BAD': 'Elt maçonnerie',
            'BAE': 'Mortier manquant',
            'BAF': 'Dégradation de surface',
            'BAG': 'Branchement pénétrant',
            'BAH': 'Raccordement défectueux',
            'BAI': 'Joint étanchéité apparent',
            'BAJ': 'Déplacement d\'assemblage',
            'BAK': 'Défaut de révêtement',
            'BAL': 'Réparation défectueuse',
            'BAM': 'Défaut soudure',
            'BAN': 'Conduite poreuse',
            'BAO': 'Sol visible',
            'BAP': 'Trou visible',
            'BBA': 'Racines',
            'BBB': 'Dépots Adhérents',
            'BBC': 'Dépôts',
            'BBD': 'Entrée de terre',
            'BBE': 'Autres obstacles',
            'BBF': 'Infiltration',
            'BBG': 'Exfiltration',
            'BBH': 'Vermine',
            'BCA': 'Raccordement',
            'BCB': 'Réparation',
            'BCC': 'Courbure de collecteur',
            'BDA': 'Photographie générale',
            'BDB': 'Remarque générale',
            'BDC': 'Inspection abandonnée',
            'BDD': 'Niveau d\'eau',
            'BDE': 'Ecoulement dans une canlisation entrante',
            'BDF': 'Atmosphère canalisation',
            'BDG': 'Perte de visibilité'
        }
        g_obs_rootrule = QgsRuleBasedRenderer.Rule(None)
        rendering_pass_idx = len(g_obs_rules)
        for rule in g_obs_rules:
            # get svg path
            svg_path = resources_path('styles', 'img_obs', rule + '.svg')
            # create svg symbol layer
            svg_symbol_layer = QgsSvgMarkerSymbolLayer(svg_path)
            svg_symbol_layer.setRenderingPass(rendering_pass_idx)
            # create white square symbol layer for the backend
            simple_symbol_layer = QgsSimpleMarkerSymbolLayer(
                shape=QgsSimpleMarkerSymbolLayerBase.Circle,
                size=svg_symbol_layer.size(),
                color=QColor('white'),
                strokeColor=QColor('white')
            )
            simple_symbol_layer.setRenderingPass(rendering_pass_idx)
            # create marker
            svg_marker = QgsMarkerSymbol()
            # set the backend symbol layer
            svg_marker.changeSymbolLayer(0, simple_symbol_layer)
            # add svg symbol layer
            svg_marker.appendSymbolLayer(svg_symbol_layer)
            # create rule
            svg_rule = QgsRuleBasedRenderer.Rule(
                svg_marker, 0, 10000,
                QgsExpression.createFieldEqualityExpression('a', rule),
                rule
            )
            if rule in g_obs_rule_descs:
                svg_rule.setLabel(g_obs_rule_descs[rule])
                svg_rule.setDescription('{}: {}'.format(
                    rule,
                    g_obs_rule_descs[rule]
                ))
            # add rule
            g_obs_rootrule.appendChild(svg_rule)
            rendering_pass_idx -= 1
        g_obs_rootrule.appendChild(
            QgsRuleBasedRenderer.Rule(
                QgsMarkerSymbol.createSimple(
                    {
                        'name': 'circle',
                        'color': '#0000b2',
                        'outline_color': '#0000b2',
                        'size': '1'
                    }
                ),
                0, 10000, 'ELSE', 'Autres'
            )
        )
        g_obs.setRenderer(QgsRuleBasedRenderer(g_obs_rootrule))
        feedback.pushInfo('Project has been setup')
        return {}
Exemple #22
0
    def extract_layers(self, tree):
        """Return a list of RFU layers."""

        # Create vector layers..
        l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  "Sommet RFU", r"memory")
        l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                "Limite RFU", r"memory")

        p_vertex = l_vertex.dataProvider()
        p_edge = l_edge.dataProvider()

        # Define default style renderer..
        renderer_vertex = QgsRuleBasedRenderer(QgsMarkerSymbol())
        vertex_root_rule = renderer_vertex.rootRule()

        # Modified in v2.1 (som_nature replaced by som_typologie_nature) >>
        vertex_rules = (
            (("Borne, borne à puce, pierre, piquet, clou ou broche"),
             ("$id >= 0 AND \"som_typologie_nature\" IN ('Borne',"
              "'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"),
             r"#EC0000", 2.2),
            (("Axe cours d'eau, axe fossé, haut de talus, pied de talus"),
             ("$id >= 0 AND \"som_typologie_nature\" IN ('Axe cours d\'\'eau',"
              "'Axe fossé', 'Haut de talus', 'Pied de talus')"), r"#EE8012",
             2.2), (("Angle de bâtiment, axe de mur, angle de mur, "
                     "angle de clôture, pylône et toute autre valeur"),
                    ("$id >= 0 AND \"som_typologie_nature\" NOT IN ('Borne',"
                     "'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche',"
                     "'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus',"
                     "'Pied de talus')"), r"#9784EC", 2.2),
            ("Temporaire", r"$id < 0", "cyan",
             2.4), ("Point nouveau à traiter car proche d'un existant",
                    r"point_rfu_proche is not null", "#bcff03", 3))

        # >>

        for label, expression, color, size in vertex_rules:
            rule = vertex_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setSize(size)
            vertex_root_rule.appendChild(rule)

        vertex_root_rule.removeChildAt(0)
        l_vertex.setRenderer(renderer_vertex)

        renderer_edge = QgsRuleBasedRenderer(QgsLineSymbol())
        edge_root_rule = renderer_edge.rootRule()

        # Modified in v2.1 (lim_typologie_nature added) <<
        edge_rules = (("Limite privée",
                       "$id >= 0 AND \"lim_typologie_nature\" = '" +
                       lim_typo_nat_vals[0] + "'", "#0A0AFF", 0.5),
                      ("Limite naturelle",
                       "$id >= 0 AND \"lim_typologie_nature\" = '" +
                       lim_typo_nat_vals[1] + "'", "#aa876d", 0.5),
                      ("Temporaire", "$id < 0", "cyan", 1))

        # >>

        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            edge_root_rule.appendChild(rule)

        edge_root_rule.removeChildAt(0)
        l_edge.setRenderer(renderer_edge)

        # Add fields..
        p_vertex.addAttributes(vtx_atts)

        p_edge.addAttributes(edge_atts)

        # Add features from xml tree..
        # ..to vertex layer..
        fts_vertex = []
        for e in tree.findall(r"sommet"):

            ft_vertex = QgsFeature()
            ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))
            _id_noeud = int(e.attrib[r"id_noeud"])
            _version = int(e.attrib[r"version"])
            som_ge_createur = str(e.find(r"./som_ge_createur").text)
            som_nature = str(e.find(r"./som_nature").text)
            som_prec_rattcht = int(
                e.find(r"./som_precision_rattachement").text)
            som_coord_est = float(e.find(r"./som_coord_est").text)
            som_coord_nord = float(e.find(r"./som_coord_nord").text)
            som_repres_plane = str(e.find(r"./som_representation_plane").text)
            som_tolerance = float(e.find(r"./som_tolerance").text)
            # Field used to store the attestation_qualite value
            # when modifying a vertex ("false" or "true")
            attestation_qualite = "false"

            som_delim_pub = str(e.find(r"./som_delimitation_publique").text)
            som_typo_nature = str(e.find(r"./som_typologie_nature").text)

            ft_vertex.setAttributes([
                _id_noeud, _version, som_ge_createur, som_delim_pub,
                som_typo_nature, som_nature, som_prec_rattcht, som_coord_est,
                som_coord_nord, som_repres_plane, som_tolerance,
                attestation_qualite, NULL
            ])

            fts_vertex.append(ft_vertex)

        # ..to edge layer..
        fts_edge = []
        for e in tree.findall(r"limite"):

            ft_edge = QgsFeature()
            ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))
            _id_arc = int(e.attrib[r"id_arc"])
            _version = int(e.attrib[r"version"])
            lim_ge_createur = str(e.find(r"./lim_ge_createur").text)

            lim_typo_nature = str(e.find(r"./lim_typologie_nature").text)
            lim_delim_pub = str(e.find(r"./lim_delimitation_publique").text)

            ft_edge.setAttributes([
                _id_arc, _version, lim_ge_createur, lim_delim_pub,
                lim_typo_nature
            ])

            fts_edge.append(ft_edge)

        # Add features to layers..
        p_vertex.addFeatures(fts_vertex)
        p_edge.addFeatures(fts_edge)

        # Update fields..
        l_vertex.updateFields()
        l_edge.updateFields()

        # Update layer's extent..
        l_vertex.updateExtents()
        l_edge.updateExtents()

        # Check if valid..
        if not l_vertex.isValid() or not l_edge.isValid():
            raise Exception(
                "Une erreur est survenue lors du chargement de la couche.")

        # Then return layers..
        return [l_vertex, l_edge]
Exemple #23
0
    def test_legend_key_to_expression(self):

        root_rule = QgsRuleBasedRenderer.Rule(None)
        renderer = QgsRuleBasedRenderer(root_rule)

        exp, ok = renderer.legendKeyToExpression('xxxx', None)
        self.assertFalse(ok)

        exp, ok = renderer.legendKeyToExpression(root_rule.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, 'TRUE')

        rule2 = QgsRuleBasedRenderer.Rule(None, filterExp='"field_name" = 5')
        rule3 = QgsRuleBasedRenderer.Rule(None,
                                          maximumScale=2000,
                                          filterExp='"field_name" = 6')
        rule4 = QgsRuleBasedRenderer.Rule(None,
                                          minimumScale=1000,
                                          filterExp='"field_name" = 7')
        rule5 = QgsRuleBasedRenderer.Rule(None,
                                          minimumScale=3000,
                                          maximumScale=1000)

        root_rule.appendChild(rule2)
        root_rule.appendChild(rule3)
        root_rule.appendChild(rule4)
        root_rule.appendChild(rule5)

        exp, ok = renderer.legendKeyToExpression(root_rule.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, 'TRUE')

        exp, ok = renderer.legendKeyToExpression(rule2.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '"field_name" = 5')

        exp, ok = renderer.legendKeyToExpression(rule3.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '("field_name" = 6) AND (@map_scale >= 2000)')

        exp, ok = renderer.legendKeyToExpression(rule4.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '("field_name" = 7) AND (@map_scale <= 1000)')

        exp, ok = renderer.legendKeyToExpression(rule5.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '(@map_scale <= 3000) AND (@map_scale >= 1000)')

        rule6 = QgsRuleBasedRenderer.Rule(None,
                                          filterExp='"field_name" = \'a\'')
        rule4.appendChild(rule6)

        exp, ok = renderer.legendKeyToExpression(rule6.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(
            exp,
            '("field_name" = \'a\') AND (("field_name" = 7) AND (@map_scale <= 1000))'
        )

        # group only rule
        rule7 = QgsRuleBasedRenderer.Rule(None)
        rule3.appendChild(rule7)

        rule8 = QgsRuleBasedRenderer.Rule(None,
                                          filterExp='"field_name" = \'c\'')
        rule7.appendChild(rule8)

        exp, ok = renderer.legendKeyToExpression(rule7.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '("field_name" = 6) AND (@map_scale >= 2000)')

        exp, ok = renderer.legendKeyToExpression(rule8.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(
            exp,
            """("field_name" = 'c') AND (("field_name" = 6) AND (@map_scale >= 2000))"""
        )

        # else rules
        root_rule = QgsRuleBasedRenderer.Rule(None)
        renderer = QgsRuleBasedRenderer(root_rule)

        rule2 = QgsRuleBasedRenderer.Rule(None, filterExp='"field_name" = 5')
        rule3 = QgsRuleBasedRenderer.Rule(None,
                                          maximumScale=2000,
                                          filterExp='"field_name" = 6')
        rule4 = QgsRuleBasedRenderer.Rule(None, elseRule=True)

        root_rule.appendChild(rule2)
        root_rule.appendChild(rule3)
        root_rule.appendChild(rule4)

        exp, ok = renderer.legendKeyToExpression(root_rule.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, 'TRUE')

        exp, ok = renderer.legendKeyToExpression(rule2.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '"field_name" = 5')

        exp, ok = renderer.legendKeyToExpression(rule3.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(exp, '("field_name" = 6) AND (@map_scale >= 2000)')

        exp, ok = renderer.legendKeyToExpression(rule4.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(
            exp,
            'NOT (("field_name" = 5) OR (("field_name" = 6) AND (@map_scale >= 2000)))'
        )

        rule5 = QgsRuleBasedRenderer.Rule(None, filterExp='"field_name" = 11')
        rule4.appendChild(rule5)

        exp, ok = renderer.legendKeyToExpression(rule5.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(
            exp,
            '("field_name" = 11) AND (NOT (("field_name" = 5) OR (("field_name" = 6) AND (@map_scale >= 2000))))'
        )

        # isolated ELSE rule, with no siblings

        root_rule = QgsRuleBasedRenderer.Rule(None)
        renderer = QgsRuleBasedRenderer(root_rule)

        rule2 = QgsRuleBasedRenderer.Rule(None, filterExp='"field_name" = 5')
        rule3 = QgsRuleBasedRenderer.Rule(None,
                                          maximumScale=2000,
                                          filterExp='"field_name" = 6')

        root_rule.appendChild(rule2)
        root_rule.appendChild(rule3)

        rule4 = QgsRuleBasedRenderer.Rule(None, elseRule=True)
        rule3.appendChild(rule4)

        exp, ok = renderer.legendKeyToExpression(rule4.ruleKey(), None)
        self.assertTrue(ok)
        self.assertEqual(
            exp, '(TRUE) AND (("field_name" = 6) AND (@map_scale >= 2000))')