#1 Mon 21 March 2022 11:37
- zutix
 - Participant actif
 - Date d'inscription: 19 Mar 2020
 - Messages: 87
 
QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
L’une de mes cartes est mise à jour assez fréquemment. L’objectif serait d’automatiser au maximum sa mise à jour.
Les données de mise à jour proviennent d’un fichier de type texte .csv. La couche destinataire est nommée CSV.
La couche qui va utiliser ces données s’appelle NB. 
Elle fait l’objet d’une jointure avec la couche CSV.  Ainsi elle récupère un champ _nb qui est utilisé comme colonne de catégorisation (style catégorisé de la couche NB).
Le champ _nb contient un nombre >=0 pour chaque entité. 
Ce nombre peut varier d’une mise à jour à l’autre : en plus, en moins ou demeurer constant.  
Par exemple, pour l’entité 1, 
mise à jour 0 : _nb=1
mise à jour 1 : _nb=5
mise à jour 3 : _nb=4
mise à jour 4 : _nb=4
En conséquence, la quantité de catégories peut varier d’une mise à jour à l’autre.
Par exemple, 
mise à jour 0 : catégories (colonne valeur) = 0  1  5  25 
mise à jour 1 : catégories (colonne valeur) = 0  1  2  3  5  23
mise à jour 3 : catégories (colonne valeur) = 0  1  2  4  7  10  21  27 
mise à jour 4 : catégories (colonne valeur) = 0  1  2  4  8  9  26 
Une fois la jointure effectuée,  le style reste sur les catégories de la mise à jour précédente.
A la main il faut aller dans le style de la couche NB. Puis sur le formulaire du style catégorisé, il faut cliquer successivement sur les boutons : Effacer tout puis Classer et enfin effacer la ligne de catégorie qui n’a pas de valeur.
A moins qu'il y ait un moyen pour que ce soit automatique ?
Sinon comment fait-on l’équivalent en python 2 ? Ou est-ce impossible ? 
PyQGIS developer cookbook n’est pas suffisant face à mon ignorance.
                                    renderer=nb.rendererV2()
Formulaire propriétés > style                              Python 
Style : Catégorisé                                              print renderer.type     affiche bien cetgorizedSymbol  
                                                                        renderer.setType( quelque chose )    ne semble pas fonctionner. 
                                                                        Comment fait-on pour changer le style ?
Colonne : _nb                                                    renderer.setClassAttribute("_nb")   
                                                                        remplace bien la colonne par celle que l’on met, ici le champ _nb 
Symbole : celui par défaut                                  Quelle instruction écrire ?
  
Palettes de couleurs : Oranges                            renderer.setSourceColorRamp( ? )   ne reconnaît pas Oranges 
                                                                        Quelle est la bonne instruction ?
Le reste du formulaire de style : par défaut.         Quelles sont les instructions python 2  ?
bouton OK                                                          nb.setRendererV2(renderer)   agit 
                                                                         mais avec le seul champ colonne initialisé cela efface le style Catégorisé.
Merci d’avance de votre aide et bonne journée.
Cordialement
Hors ligne
#2 Wed 23 March 2022 09:10
- romainbh
 - Participant assidu
 - Date d'inscription: 20 Aug 2013
 - Messages: 355
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Vu que vous travaillez avec des valeurs chiffrées, vous pourriez utiliser le style Gradué plutôt que Catégorisé, en renseignant les valeurs max et min pour qu'elles couvrent votre cas d'utilisation. Ainsi plus besoin d'actualiser à chaque mise à jour.
Sinon l'option PYQGIS doit aussi être possible, mais là je ne peux pas vous aider.
Hors ligne
#3 Thu 24 March 2022 15:43
- zutix
 - Participant actif
 - Date d'inscription: 19 Mar 2020
 - Messages: 87
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Merci de votre réponse.
Mais j‘avais testé le mode gradué.  Il ne convient pas car il regroupe des valeurs. L’affichage souhaité est obtenu avec catégorisé mais pas avec gradué.
Par exemple avec le même champ _nb :
obtenu avec catégorisé    obtenu avec gradué
0                    0.000 – 5.000
1                    5.000 – 10.000
2                    10.000 – 15.000
3                    15.000 – 20.000
4                    20.000 – 25.000
5
8
25
Hors ligne
#4 Fri 25 March 2022 09:20
- lylambda
 - Participant actif
 - Date d'inscription: 31 Aug 2016
 - Messages: 127
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Et en modifiant manuellement la graduation ? Via un passage en "Ensemble de règles" ?
Pour l'exemple cité :
0                    0.000 – 0.999
1                    1.000 – 1.999
2                    2.000 – 2.999
etc.
Dernière modification par lylambda (Fri 25 March 2022 09:20)
Hors ligne
#5 Fri 25 March 2022 10:15
- SANTANNA
 - Moderateur
 - Lieu: Angers
 - Date d'inscription: 18 Jan 2008
 - Messages: 4138
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Si vous voulez choper toutes les valeurs sans trop vous casser la tête (et au risque d'horripiler les "Bertinois"), créez une entrée dans la classification pour chacune des valeurs possibles. Dans votre dernier message (0-25), ça voudra dire 26 lignes de classification dont un certain nombre à la mano. A vous de trouver votre valeur max possible pour nb. Ensuite, si les valeurs changent, bah, l'entité ne ferait que switcher de classe donc tutto bene.
Je sais que j'avais déjà posée la question et ne suis pas sûr de la réponse, si j'en avais reçue, mais: QGIS 2.18, quoi! Python 2, abandonné depuis 2 ans. La dette technique que vous êtes en train de trimballer, plus toutes les nouveautés et facilités possibles dans QGIS à côté desquelles vous passez certainement m'inquiètent, mais bon...
Hors ligne
#6 Mon 28 March 2022 10:55
- zutix
 - Participant actif
 - Date d'inscription: 19 Mar 2020
 - Messages: 87
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Merci de vos réponses.
La difficulté réside dans le fait que je ne connais pas la valeur maximale. L’évolution est imprévisible pour tous les cas.
Donc cela réclame une souplesse importante :
- non compatible avec l’ « Ensemble de règles » qui doivent être connues d’avance ;
- ni avec toutes les valeurs de 0 à valeur max inconnue. De plus, si l’on prenait 50 par exemple cela poserait des problèmes de couleurs trop proches car utilisées alors qu’inutiles et une légende trop longue.
En ce qui concerne la version 2.18. Elle ne dépend pas de moi. Une version 3 est en cours de test , elle va finir par arriver.
Merci en tous cas.
Hors ligne
#7 Mon 28 March 2022 14:46
- SANTANNA
 - Moderateur
 - Lieu: Angers
 - Date d'inscription: 18 Jan 2008
 - Messages: 4138
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Effectivement j'avais occulté le cas de couleurs inutilement trop proches. Pour la légende, elle peut se limiter à ce qui est effectivement visible dans la mise en page (mais c'est peut-être une fonction v3).
A moins qu'il y ait déjà un plugin de reclassification automatique ou en un clic (vous avez regardé l'offre en la matière?), je pense en effet que la solution passe par écrire vous-même le script. Et une fois que j'ai dit cela, désolé, je passe la main à plus compétent...
Hors ligne
#8 Mon 26 December 2022 16:04
- zutix
 - Participant actif
 - Date d'inscription: 19 Mar 2020
 - Messages: 87
 
Re: QGIS 2.18: automatiser mise a jour style categorise
Bonjour,
Il semble que ce qui suit réponde au besoin exprimé. 
En espérant que cela aide certains à ne pas galérer comme je l’ai fait.
Bonnes fêtes de changement d'année !
Cordialement
###  definition de fonctions
# trouver et trier les valeurs distinctes du champ nomme zFieldName de la couche objet zlayer
# appel, exemple : trouverValDistChp(layer,"_NB")
# retour, exemple : [0, 1, 2, 3, 4, 5, 8, 25]
def trouverValDistChp(zlayer,zFieldName):
    vals=[]
    for feature in zlayer.getFeatures():
        val=feature[zFieldName]
        if not val in vals:
            vals.append(val)
    vals.sort()
    return(vals)
# definir les categories qui s'afficheront : case cochee, carre, valeur, legende 
# appel, exemple : categories=definirCategies(catNb,catVals,ramp)
# retour, exemple : [<qgis._core.QgsRendererCategoryV2 object at 0x0000000024FFEC80>, <qgis._core.QgsRendererCategoryV2 object at 0x0000000024FFEEA0>, 
#     <qgis._core.QgsRendererCategoryV2 object at 0x0000000024FFE048>, <qgis._core.QgsRendererCategoryV2 object at 0x0000000024FFED90>, 
#     <qgis._core.QgsRendererCategoryV2 object at 0x000000002514D840>, <qgis._core.QgsRendererCategoryV2 object at 0x000000002514D950>, 
#    <qgis._core.QgsRendererCategoryV2 object at 0x000000002514DA60>, <qgis._core.QgsRendererCategoryV2 object at 0x000000002514DB70>]
def definirCategies(catNb,catVals,catRamp):
    categories=[]
    for i in range(catNb):
        n=i*100/catNb
        if n<100:
            if n<10:
                step=float('0.0' +str(n))
            else:
                step=float('0.' +str(n))
        #   state=True
        # valeur 100% non utilisee
        #else:
        #   step=1
        #   state=False
        state=True    # case cochee (False sinon)
        value=catVals[i]    # valeur
        # symbole generique qui reste constant et correspond a Modification 
        symbol=QgsFillSymbolV2.defaultSymbol(layer.geometryType())      # symbole plein
        symbol.symbolLayer(0).setOutlineColor(QColor(169,169,169,100))  # symbole bord gris 
        # symbole de categorie qui correspond a 1 ligne category
        symbol.setColor(ramp.color(step))                               # couleur a la position du pas dans la palette
        category=QgsRendererCategoryV2(value,symbol,str(value),state)   # elements de la categorisation
        categories.append(category)
    return(categories)
# trouver l'objet palette de nom fourni
# appel, exemple : trouverPalette("Oranges")
# retour, exemple : <qgis._core.QgsVectorGradientColorRampV2 object at 0x0000000024935F28>
def trouverPalette(zRampName):
    style=QgsStyleV2().defaultStyle()
    allColorRampNames=style.colorRampNames()
    i=-1
    for rampName in allColorRampNames:
        i=i+1
        if rampName=="Oranges":
            break 
    ramp=style.colorRamp(allColorRampNames[i])
    return(ramp)
###
# creer le style : categorise, colonne=_NB, palette=Oranges a l’aides fonctions ci-avant
# trouver la palette
ramp=trouverPalette("Oranges")
# trouver la liste des valeurs entieres distinctes du champ
catVals=trouverValDistChp(layer,"_NB")  # liste de valeurs
catNb=len(catVals)                          # nombre de valeurs
# definir les categories, i.e. les lignes : state(True->coche), symbol(carre colore), value(_NB), label(_NB en texte) de categorisation qui seront affichees
categories=definirCategies(catNb,catVals,ramp)
# creer style categorise avec colonne=_NB, lignes de categorie=categories et palette=ramp
renderer=QgsCategorizedSymbolRendererV2('_NB',categories)
renderer.setSourceColorRamp(ramp)
# appliquer ce style a la couche
layer.setRendererV2(renderer)
# modifier effectivement la couche 
QgsMapLayerRegistry.instance().addMapLayer(layer)
Hors ligne


