#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
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
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
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
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
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 
 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" 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
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