Pages: 1
- Sujet précédent - QGIS/Python: appliquer un style (qml) sur un cadre Rectangle - Sujet suivant
#1 Thu 22 February 2024 12:11
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
QGIS 3.28 - Bonjour,
J'ai des fichiers de style qml qui ne représenta qu'une représentation à chaque fois. (pas de fichier où il y a plusieurs symbols).
Je voudrais savoir si c'est possible thématiser des rectangles en appelant pour chacun un fichier de style.
Avez-vous une idée de comment faire ?
Merci de vos réponses, PYJ
Hors ligne
#2 Thu 22 February 2024 12:33
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3945
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Aller indiquer pour chaque classe de catégorie, un fichier de style particulier, je ne pense pas que ce soit possible. Mais bon, je peux me tromper...
Sans conviction aucune, peut-être essayer de fusionner vos fichiers dans un seul fichier DB de style, notamment avec l'algorithme "Combiner les styles". Si ça passe, vous aurez un fichier de style et vous pourrez soit en charger les éléments dans la BD des styles et faire la symbologie classiquement, soit l'utiliser comme un fichier de styles en correspondance (pour peu que vos classes soient nommées pareil que vos symboles - voir le menu Avancé à la fin de la section "rendu catégorisé".
Juste après avoir cliqué sur le bouton "Envoyer", j'ai vu PYQGIS dans l'énoncé... Désolé.
Dernière modification par SANTANNA (Thu 22 February 2024 12:34)
Hors ligne
#3 Thu 22 February 2024 12:49
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Merci pour votre réponse,
Mais quand je parle de Rectangle, ce ne sont pas des entités issues d'une couche de données , mais des rectangles dessinés comme ce qui suit, et je voudrais en fait passer un fichier de style au lieu de passer par props
Code:
polygon = QPolygonF() polygon.append(QPointF(x1, y1)) polygon.append(QPointF(x1,y2)) polygon.append(QPointF(x2,y2)) polygon.append(QPointF(x2,y1)) polygon.append(QPointF(x1, y1)) layoutItemPolygon = QgsLayoutItemPolygon(polygon,layout) layout.addLayoutItem(layoutItemPolygon) props = {} props["color"] = fcouleur props["color_border"] = bcouleur props["width_border"] = float(epais) props["joinstyle"] = "miter" style = QgsFillSymbol.createSimple(props) layoutItemPolygon.setSymbol(style)
Merci
Hors ligne
#4 Tue 19 March 2024 12:58
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Je me permet de relancer le sujet ;-)
Il s'agit pour moi de tracer des rectangle (voir extrait de code ci-dessus) en appliquant une classe de représentation définie dans un qml.
le qml est un fichier contenant un ensemble de règles
Si ce n'est techniquement pas faisable, je serai alors obligé de créer ces rectangles dans ma vue, leur affecter une valeur d'attribut et enfin d'appliquer la représentation.
Usine à gaz mais cela devrait fonctionner
PYJ
Dernière modification par pyjoubert (Tue 19 March 2024 12:59)
Hors ligne
#5 Thu 21 March 2024 11:10
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Je pense qu'il est possible de charger votre qml dans un objet QgsStyle (https://qgis.org/pyqgis/3.4/core/QgsSty … Style.load).
Avec cet objet, il est possible de récupérer les symboles chargés (https://qgis.org/pyqgis/3.4/core/QgsSty … ndSymbolsl), de trouver celui qui vous intéresse et de l'utiliser pour votre rectangle.
Donc oui, d'après la documentation cela semble faisable.
Hors ligne
#6 Thu 21 March 2024 11:27
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour yoann,
Merci pour ta réponse, je vais voir cela dès le début de la semaine prochaine
PYJ
Hors ligne
#7 Tue 26 March 2024 07:30
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Et voici le résultat en pièce jointe.(reste pour moi à affiner les calages)
Mais de toutes manières, cela fonctionne nickel avec ta dernière solution
Je récupère bien la symbologie d'une règle donnée et je l'applique bien à mon rectangle (dessin)
Merci encore
PYJ
Hors ligne
#8 Tue 26 March 2024 09:11
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Parfait si cela fonctionne. Ca vous fera une belle légende pour votre PLU (si je ne m'abuse).
Bonne journée.
Hors ligne
#9 Tue 26 March 2024 09:52
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3945
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Mais de toutes manières, cela fonctionne nickel avec ta dernière solution
Je récupère bien la symbologie d'une règle donnée et je l'applique bien à mon rectangle (dessin)
Ça pourrait certainement aider de partager le code auquel vous avez abouti in fine, je pense. Merci.
Hors ligne
#10 Tue 26 March 2024 10:35
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Etrange, j'avais posté le code qui a permis a PYJOUBERT d'aboutir mais mon message à disparu...
je le repartage ici (ce code n'est pas destiné à être utilisé, il nécessite encore pas mal de nettoyage mais il montre l'idée)
:
Code:
# -*- coding: utf-8 -*- import sys import os import qgis from qgis.utils import iface from qgis.core import QgsStyle,QgsProject,QgsPrintLayout,QgsLayoutItemMap,QgsMapSettings,QgsRectangle,QgsLayoutSize,QgsLayoutExporter,QgsUnitTypes,QgsLayoutItemPolygon,QgsFillSymbol def MonTest(): project = QgsProject.instance() layout = QgsPrintLayout(project) layout.initializeDefaults() layout.setUnits(QgsUnitTypes.LayoutMillimeters) page = layout.pageCollection().pages()[0] page.setPageSize(QgsLayoutSize(100,50)) nomfic = "C:/Temp/Rectangle.png" if (os.path.exists(nomfic)): os.remove(nomfic) TracerRectangleRepres (layout,10,10,80,30) exporter = QgsLayoutExporter(layout) settings = exporter.ImageExportSettings() exporter.exportToImage(nomfic, settings) def TracerRectangleRepres (layout,x,y,larg,haut): polygon = QPolygonF() polygon.append(QPointF(float(x),float(y))) polygon.append(QPointF(float(x),(float(y) + float(haut)))) polygon.append(QPointF((float(x) + float(larg)),(float(y) + float(haut)))) polygon.append(QPointF((float(x) + float(larg)),float(y))) layoutItemPolygon = QgsLayoutItemPolygon(polygon,layout) layout.addLayoutItem(layoutItemPolygon) style_layer = QgsVectorLayer('polygon', 'style', 'memory') style_layer.loadNamedStyle("C:/Temp/SPE_PSDETAIL_C.qml") r = style_layer.renderer() root = r.rootRule() rule = find_rule_by_label(root, 'COMMENCE_PAR_UA1_5000') # a adapter symbol = rule.symbol() layoutItemPolygon.setSymbol(symbol) def find_rule_by_label(root, label): for child in root.descendants(): if child.label() == label: return child if __name__ == '__console__': MonTest()
Hors ligne
#11 Tue 26 March 2024 11:49
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3945
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Ah OK @YoLecomte. Certainement l'effet du bug d'hier.
Hors ligne
#12 Tue 26 March 2024 15:51
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
J'en profite pour rebondir, car tout est presque terminé (voir pièce jointe de ce matin)
Reste à traiter le cas des ponctuels où je veux appliquer un marqueur contenu dans un fichier qml
Pour les rectangle, on utilise donc QgsLayoutItemPolygon et un QgsVectorLayer('polygon', 'truc', 'memory')
Pour les lignes , on utilise donc QgsLayoutItemPolyline et un QgsVectorLayer('stringline', 'bidule', 'memory')
Pour ces ponctuels, je pensais utiliser QgsLayoutItemMarker , avec un QgsVectorLayer('point', 'bidule', 'memory') mais celui ci ne prend pas les coordonnées de l'endroit où je veux placer ce marqueur.
Avez-vous une idée
Et après cela, mon mécanisme de légende (du PLU-H) sera terminé ;-)
Merci
PYJ
Hors ligne
#13 Wed 27 March 2024 10:58
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
J'imagine que c'est avec cette méthode en regardant la doc.
https://qgis.org/pyqgis/master/core/Qgs … rencePoint
Hors ligne
#14 Wed 27 March 2024 15:04
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Voici mon bout de code qui reprend la même philosophie.
Code:
def WBO_STYLE_RechercherRegleParLabel (root, label): for child in root.descendants(): if child.label() == label: return child def WBO_MT_TracerPointRepres (layout,dico_trace,echelle,x,y,ficrepres,classe): truc = QgsLayoutItemMarker(layout) truc.setReferencePoint(QgsLayoutPoint(x,y, QgsUnitTypes.LayoutMillimeters)) layout.addLayoutItem(truc) dummy_layer = QgsVectorLayer('point', 'point', 'memory') dummy_layer.loadNamedStyle(ficrepres) r = dummy_layer.renderer() root = r.rootRule() rule = WBO_STYLE_RechercherRegleParLabel(root, classe) if (rule != None): symbol = rule.symbol() truc.setSymbol(symbol)
Il se trouve qu'une erreur subsiste quant au passage du point
Code:
truc.setReferencePoint(QgsLayoutPoint(x,y, QgsUnitTypes.LayoutMillimeters)) TypeError: QgsLayoutItem.setReferencePoint(): argument 1 has unexpected type 'QgsLayoutPoint'
J'ai aussi d'eesayé avec GgsPoint(x,y) et QgsPointXY(x,y) --> Même erreur
PYJ
Hors ligne
#15 Thu 28 March 2024 10:15
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Vous avez un exemple d'utilisation de cette classe dans les tests python de qgis
https://github.com/qgis/QGIS/blob/8fd91 … er.py#L142
Il semblerait que ce soit attemptMove sur l'objet QgsLayoutItemMarker qui permet de le placer.
Hors ligne
#16 Tue 02 April 2024 08:15
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Bonjour,
Désolé de continuer à demander de l'aide sur ce sujet.
J'ai testé diverses solutions, en vain.
J'ai fais un zip contenant le code python (le même que tu m'avais communiqué pour les rectangles, mais adapté pour les marker) ainsi qu'un fichier de représentation qml.
tout se déroule, sauf qu'au moment d'exécuter 'truc.setSymbol, je ma fais littéralement jeter de QGIS !!
Il me semble avoir pris en compte tes remarques et tes ajustements pourtant
Merci
PYJ
Hors ligne
#17 Tue 02 April 2024 11:27
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Probablement une histoire de réference d'objet. symbol ne doit plus exister en mémoire au moment où vous l'apellez.
Essayer de remplacer la ligne
Code:
symbol = rule.symbol()
par
Code:
symbol = rule.symbol().clone()
de manière à obtenir un nouvel objet et non pas une référence.
Chez moi cela fonctionne.
Dernière modification par YoLecomte (Tue 02 April 2024 11:28)
Hors ligne
#18 Tue 02 April 2024 11:35
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Nickel,
Est-ce qu'il faut que fasse pareil aux cas précédents (rectangle et ligne) ou je laisse comme tel
Merci encore
PYJ
Hors ligne
#19 Tue 02 April 2024 12:02
- YoLecomte
- Participant assidu
- Lieu: Epinal
- Date d'inscription: 7 Jul 2015
- Messages: 266
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
A votre place je n'aurais qu'une seul fonction qui fait ce travail donc un seul endroit où le modifier.
mais oui dans votre cas, comme vous avez trois fonctions vous devriez sans doute le faire dans chacune d'elles.
Hors ligne
#20 Tue 02 April 2024 12:03
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
OK, Ca marche
Merci
Hors ligne
#21 Tue 02 April 2024 13:34
- pyjoubert
- Participant assidu
- Lieu: Lyon
- Date d'inscription: 21 Mar 2006
- Messages: 347
Re: QGIS/Python: appliquer un style (qml) sur un cadre Rectangle
Je crois que l(on va pouvoir clore ce post
Ci-joint la légende complète
Merci encore
PYJ
Dernière modification par pyjoubert (Tue 02 April 2024 13:36)
Hors ligne
Pages: 1
- Sujet précédent - QGIS/Python: appliquer un style (qml) sur un cadre Rectangle - Sujet suivant