Bonjour, Je suis débutant en PyQgis, mais j'ai déjà pratiqué d'autres langages de programmation. Je vous explique mon problème :
Je cherche à mettre en place une fonction permettant de calculer des nouveaux champs dans une table, mais à partir de donnés appartenant à une autre table.
Concrètement : deux tables de polygone, une table de zones et une table de bâtiments contenue dans ces zones. Un champ commun aux deux tables (Idzone, unique pour la table des zones, permettant de savoir à quelle zone appartient le bâti). La table des bâtis dispose d'un champ surface et je voudrai avoir la surface bâtie sur la zone.
Dans un premier temps, j'ai évidemment cherché une extension existante permettant de faire le travail, mais je n'ai pas trouvé (j'ai peut être mal cherché, je me sentirai dans ce cas un peu bête).
J'ai donc voulu coder un PyQgis pour arriver à faire ce calcul (et pourquoi pas jeter les bases sur une future extension, mais c'est pas pour tout de suite). Le forum m'a beaucoup aidé et je suis arrivé au code suivant :
Bon c'est peut être pas ce qui se fait de mieux, mais il a l'air de fonctionner correctement (je suis ouvert à toute critique pour l'améliorer).
Seulement voilà le problème c'est que c'est bien beau d'écrire les composants si on ne peut pas les enregistrer.... J'ai passé des heures sur l'API pas moyen de comprendre EditAttributes ou QgsVectorLayer.
Voici comment je vois la suite du programme :
J'aimerai créer une nouvelle couche (et non pas éditer la couche existante pour ne pas la perdre) avec les nouvelles informations et notamment le attr1[y] mis à jour. Alors je ne m'y suis peut-être pas bien pris pour ce programme, mais en gros voilà comment je vois les choses :
Dans la boucle for elem1 in tbl1.getFeatures(): je parcours la géometry également : geom1 = elem1.geometry() et du coup, à la fin, au lieu de print (attr[w], attr[y]) je créer une nouvelle table en partant d'une table vide et en ajoutant des nouveaux features possédant à chaque fois les données géométriques geom1 et les données attributaires attr1. J'ai besoin d'autre donnée ?
Dernières choses si possibles le plus utiles serait de détailler un peu l'API pour EditAttribute et pour QgsVectorLayer parce que c'est assez compliqué de comprendre (s'il existe un tutoriel préexistant je ne lai pas trouvé). Enfin, si vous êtes motivé, pourquoi ne pas expliquer d'autres éléments de l'API qui est honnêtement assez flou (je ne comprends toujours pas exactement ce qui se cache derrière un QgsvectorLayer).
Merci d'avance
Bien cordialement
Jonathan
Je cherche à mettre en place une fonction permettant de calculer des nouveaux champs dans une table, mais à partir de donnés appartenant à une autre table.
Concrètement : deux tables de polygone, une table de zones et une table de bâtiments contenue dans ces zones. Un champ commun aux deux tables (Idzone, unique pour la table des zones, permettant de savoir à quelle zone appartient le bâti). La table des bâtis dispose d'un champ surface et je voudrai avoir la surface bâtie sur la zone.
Dans un premier temps, j'ai évidemment cherché une extension existante permettant de faire le travail, mais je n'ai pas trouvé (j'ai peut être mal cherché, je me sentirai dans ce cas un peu bête).
J'ai donc voulu coder un PyQgis pour arriver à faire ce calcul (et pourquoi pas jeter les bases sur une future extension, mais c'est pas pour tout de suite). Le forum m'a beaucoup aidé et je suis arrivé au code suivant :
def Calculateur_champ (tbl1, tbl2, chp1_tbl1, chp1_tbl2, chp2_tbl1, chp2_tbl2):
w=-1
x=-1
y=-1
z=-1
i=-1
champ_1=tbl1.pendingFields()
nom_champ_1=[champs.name() for champs in champ_1]
for n in nom_champ_1:
i+=1
if n==chp1_tbl1:
w=i
elif n==chp2_tbl1:
y=i
if w==-1:
print ("le champs", chp1_tbl1, " ne fait pas partie de la table", tbl1)
elif y==-1:
print ("le champs", chp2_tbl1, " ne fait pas partie de la table", tbl1)
else:
i=-1
champ_2=tbl2.pendingFields()
nom_champ_2=[champs.name() for champs in champ_2]
for n in nom_champ_2:
i+=1
if n==chp1_tbl2:
x=i
elif n==chp2_tbl2:
z=i
if x==-1:
print ("le champs", chp1_tbl2, " ne fait pas partie de la table", tbl2)
elif z==-1:
print ("le champs", chp2_tbl2, " ne fait pas partie de la table", tbl2)
else:
for elem1 in tbl1.getFeatures():
attr1 = elem1.attributes ()
for elem2 in tbl2.getFeatures():
attr2 = elem2.attributes ()
if attr1[w]==attr2[x]:
attr1[y]=attr1[y]+(attr2[z]/10000)
else:
attr1[y]=attr1[y]
print (attr1[w], attr1[y])
Bon c'est peut être pas ce qui se fait de mieux, mais il a l'air de fonctionner correctement (je suis ouvert à toute critique pour l'améliorer).
Seulement voilà le problème c'est que c'est bien beau d'écrire les composants si on ne peut pas les enregistrer.... J'ai passé des heures sur l'API pas moyen de comprendre EditAttributes ou QgsVectorLayer.
Voici comment je vois la suite du programme :
J'aimerai créer une nouvelle couche (et non pas éditer la couche existante pour ne pas la perdre) avec les nouvelles informations et notamment le attr1[y] mis à jour. Alors je ne m'y suis peut-être pas bien pris pour ce programme, mais en gros voilà comment je vois les choses :
Dans la boucle for elem1 in tbl1.getFeatures(): je parcours la géometry également : geom1 = elem1.geometry() et du coup, à la fin, au lieu de print (attr[w], attr[y]) je créer une nouvelle table en partant d'une table vide et en ajoutant des nouveaux features possédant à chaque fois les données géométriques geom1 et les données attributaires attr1. J'ai besoin d'autre donnée ?
Dernières choses si possibles le plus utiles serait de détailler un peu l'API pour EditAttribute et pour QgsVectorLayer parce que c'est assez compliqué de comprendre (s'il existe un tutoriel préexistant je ne lai pas trouvé). Enfin, si vous êtes motivé, pourquoi ne pas expliquer d'autres éléments de l'API qui est honnêtement assez flou (je ne comprends toujours pas exactement ce qui se cache derrière un QgsvectorLayer).
Merci d'avance
Bien cordialement
Jonathan