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

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#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: 3940

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


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

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: 3940

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: 3940

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


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

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)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

Pied de page des forums

Powered by FluxBB