Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Printemps des cartes 2024

#1 Fri 07 May 2021 13:31

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

QGIS 3: pyqgis ajouter geometry generator

Bonjour,

J'ai un layer de type point.
Avec pyqgis, je voudrais ajouter dans la symbologie un générateur de géométrie (tracé d'une ligne à partir du point).

Code:

generator = QgsGeometryGeneratorSymbolLayer.create({})
generator.setSymbolType(QgsSymbol.Line)
expression = 'CASE WHEN abs( "SECTR1" - "SECTR2") < 360 THEN make_line($geometry, make_point($x + 0.1*cos(radians(180+90 - "SECTR1")), $y + 0.1*sin(radians(180+90 - "SECTR1")))) END'
generator.setGeometryExpression(expression)
symbol = QgsSymbol.defaultSymbol(self.layer.geometryType())
symbol.changeSymbolLayer(0,generator)

Mais je n'ai rien à l'affichage? Pourquoi?

Merci, Nico

Hors ligne

 

#2 Mon 10 May 2021 06:53

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

J'ai essayé ça:

Code:

        generator = QgsGeometryGeneratorSymbolLayer.create({})
        generator.setSymbolType(QgsSymbol.Line)
        expression = 'CASE WHEN abs( "SECTR1" - "SECTR2") < 360 THEN make_line($geometry, make_point($x + 0.1*cos(radians(180+90 - "SECTR1")), $y + 0.1*sin(radians(180+90 - "SECTR1")))) END'
        generator.setGeometryExpression(expression)

        single_symbol_renderer = self.layer.renderer()
        symbol = single_symbol_renderer.symbol()
        
        symbol.appendSymbolLayer(generator)
        self.layer.renderer().setSymbol(symbol)
        
        iface.layerTreeView().refreshLayerSymbology( self.layer.id() )
        self.layer.triggerRepaint()

Mais ça fait planter QGIS (version 3.18)

(L'expression est correcte, car quand je fais la manip à la main, ça fonctionne)

Nico

Dernière modification par nico-29 (Mon 10 May 2021 07:10)

Hors ligne

 

#3 Mon 10 May 2021 07:26

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

Bonjour,

Essaie avec

Code:

symbol = QgsLineSymbol()

ou

Code:

symbol = single_symbol_renderer.symbol().clone()

Dernière modification par SIGEAL (Mon 10 May 2021 07:26)


Christophe Damour (SIGéal)

Hors ligne

 

#4 Mon 10 May 2021 08:56

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Code:

symbol = QgsLineSymbol()

ça plante avec l'erreur:

Code:

QgsGeometryGeneratorSymbolLayer.setSymbolType(): argument 1 has unexpected type 'QgsLineSymbol'

Code:

symbol = single_symbol_renderer.symbol().clone()

ça ne plante pas mais le symbol geometry generator ne s'affiche pas

Nico

Hors ligne

 

#5 Mon 10 May 2021 10:54

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

Code:

symbol = QgsLineSymbol()

à la place de

Code:

symbol = QgsSymbol.defaultSymbol(self.layer.geometryType())

Christophe Damour (SIGéal)

Hors ligne

 

#6 Mon 10 May 2021 12:59

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Code:

generator = QgsGeometryGeneratorSymbolLayer.create({})
        generator.setSymbolType(QgsSymbol.Line)
        expression = 'CASE WHEN abs( "SECTR1" - "SECTR2") < 360 THEN make_line($geometry, make_point($x + 0.1*cos(radians(180+90 - "SECTR1")), $y + 0.1*sin(radians(180+90 - "SECTR1")))) END'
        generator.setGeometryExpression(expression)

        symbol = QgsLineSymbol()
        
        symbol.changeSymbolLayer(0, generator)
        
        self.layer.renderer().setSymbol(symbol)
       
        iface.layerTreeView().refreshLayerSymbology( self.layer.id() )
        self.layer.triggerRepaint()

pas mieux... ça ne plante pas, mais le geometry generator ne s'affiche pas
Nico

Hors ligne

 

#7 Mon 10 May 2021 13:03

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

Un exemple de code complet :

Code:

    def createLineGeomGenSymbolLayer(
                self,
                exp,  # Expression générant la géométrie
                width=0.2,  # Épaisseur de la ligne
                color=QColor(227, 26, 28, 255),  # Couleur de la ligne
                penStyle=Qt.SolidLine  # Style de la ligne
            ) -> QgsGeometryGeneratorSymbolLayer:
        """ Création d'une couche de symbole générateur de géométrie ligne """

        lnGenSymbolLayer = QgsGeometryGeneratorSymbolLayer.create(
            {'geometryModifier': ''})
        lnGenSymbolLayer.setGeometryExpression(exp)
        lnGenSymbolLayer.setSymbolType(QgsSymbol.Line)
        lnSubSymbol = QgsLineSymbol()
        lnSubSymbol.deleteSymbolLayer(0)
        lnSubSymbolLayer = QgsSimpleLineSymbolLayer()
        lnSubSymbolLayer.setWidth(width)
        lnSubSymbolLayer.setColor(color)
        lnSubSymbolLayer.setPenStyle(penStyle)
        lnSubSymbol.appendSymbolLayer(lnSubSymbolLayer)
        lnGenSymbolLayer.setSubSymbol(lnSubSymbol)

        return lnGenSymbolLayer

Essaie avec une expression de génération plus simple.


Christophe Damour (SIGéal)

Hors ligne

 

#8 Tue 11 May 2021 07:50

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Bonjour,

ce code crée le geometry generator.
Mais comment l'ajouter ensuite au renderer du layer?

J'ai trouvé:

Code:

single_symbol_renderer = vl.renderer()
        symbol = single_symbol_renderer.symbol()
        

        symbol.appendSymbolLayer(lnGenSymbolLayer1)

Merci
Nico

Dernière modification par nico-29 (Tue 11 May 2021 08:04)

Hors ligne

 

#9 Tue 11 May 2021 08:03

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

Bonjour,

Cette fonction renvoie une couche de symbole de type geometry generator, qu'il faut ajouter au symbole.
Le symbole est ensuite passé au constructeur du renderer qui est affecté au layer :

Code:

symbol = QgsLineSymbol()
symbol.deleteSymbolLayer(0)
lnGenSymbolLayer = createLineGeomGenSymbolLayer(exp, 0.2, lnColor, Qt.SolidLine)
symbol.appendSymbolLayer(lnGenSymbolLayer)
renderer = QgsSingleSymbolRenderer(symbol)
layer.setRenderer(renderer)

Christophe Damour (SIGéal)

Hors ligne

 

#10 Tue 11 May 2021 09:29

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Comment faire pour affecter la couleur en passant par une expression ?

Code:

color = 'CASE ' + \
                'WHEN  "COLOUR" = \'1\' THEN color_rgb(255,255,255) ' + \
                'WHEN "COLOUR" = \'3\' THEN color_rgb(227,26,28) ' + \
                'WHEN "COLOUR" = \'4\' THEN color_rgb(51,160,44) ' + \
                'END'

Nico

Hors ligne

 

#11 Tue 11 May 2021 09:42

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

Google "pyqgis datadefined color"

QGIS API doc : https://qgis.org/api/3.16/classQgsProperty.html

Dernière modification par SIGEAL (Tue 11 May 2021 09:43)


Christophe Damour (SIGéal)

Hors ligne

 

#12 Tue 11 May 2021 10:38

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Si j'essaie ce code, la couleur n'est pas affectée :

Code:

color = 'CASE ' + \
                'WHEN  "COLOUR" = \'1\' THEN QColor.fromRgb(255,255,255) ' + \
                'WHEN "COLOUR" = \'3\' THEN QColor.fromRgb(227,26,28) ' + \
                'WHEN "COLOUR" = \'4\' THEN QColor.fromRgb(51,160,44) ' + \
                'END'
        prop = QgsProperty()
        prop.setExpressionString(color)
        prop.setActive(True)
        lnSubSymbolLayer3.setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, prop)

Si je le fait à la main, ça marche, et que j'enregistre le style en qml, j'ai :

Code:

<Option type="Map" name="outlineColor">
                      <Option type="bool" value="true" name="active"/>
                      <Option type="QString" value="CASE &#xd;&#xa; WHEN  &quot;COLOUR&quot; = '1' THEN color_rgb(255,255,255) &#xd;&#xa;                WHEN &quot;COLOUR&quot; = '3' THEN color_rgb(227,26,28) &#xd;&#xa;WHEN &quot;COLOUR&quot; = '4' THEN color_rgb(51,160,44) &#xd;&#xa; END" name="expression"/>
                      <Option type="int" value="3" name="type"/>
                    </Option>

Dans le qml, il y a une option outlineColor, mais quand je regarde la doc de QgsSymbolLayer, il n'y a pas de property outlineColor, il y a strokeColor (mais qui ne marche pas -> la couleur n'est pas affectée)

Nico

Hors ligne

 

#13 Tue 11 May 2021 10:58

SIGEAL
Participant assidu
Lieu: Saint Laurent des Combes
Date d'inscription: 5 Sep 2005
Messages: 195
Site web

Re: QGIS 3: pyqgis ajouter geometry generator

L'expression à affecter à la QgsProperty doit être la même que celle que tu utilises manuellement.
Ce n'est donc pas du python (QColor.fromRgb(255,255,255)) mais du langage d'expression QGIS (color_rgb(255,255,255)).


Christophe Damour (SIGéal)

Hors ligne

 

#14 Tue 11 May 2021 11:21

nico-29
Participant assidu
Lieu: Brest
Date d'inscription: 2 Jun 2006
Messages: 185

Re: QGIS 3: pyqgis ajouter geometry generator

Désolé, ça ne fonctionne pas :
Dans mon code, j'ai :

Code:

color = 'CASE ' + \
                'WHEN  "COLOUR" = \'1\' THEN color_rgb(255,255,0) ' + \
                'WHEN "COLOUR" = \'3\' THEN color_rgb(227,26,28) ' + \
                'WHEN "COLOUR" = \'4\' THEN color_rgb(51,160,44) ' + \
                'END'

A l'exécution, je fais un print(color) dans la console.
Si je fait un copier-coller du résultat du print dans le sélecteur d'expression pour la définition de la symbologie, ça fonctionne... donc l'expression est correcte.
J'ai oublié une instruction dans mon code pour activer la propriété de couleur?


En mettant

Code:

lnSubSymbolLayer3.setDataDefinedProperty(QgsSymbolLayer.PropertyStrokeColor, prop)

ça fonctionne!

nico

Dernière modification par nico-29 (Tue 11 May 2021 11:38)

Hors ligne

 

Pied de page des forums

Powered by FluxBB