Skip to Content

QGIS : Gérer un catalogue d'images, comment se passer de Show/Hide Image ?


Il y a quelques temps j'avais fait un article sur comment gérer un catalogue d'images à l'aide des plugins Image boundary et Show/Hide Image : Plugin QGIS - Image boundary et Show/Hide Image : Gérer un catalogue d'images. Malheureusement si Image Boundary existe encore pour QGIS 2, ce n'est pas le cas pour Show/Hide Image. Alors comment faire en se passant de ces deux plugins ?

Image Boundary permet de créer un tableau d'assemblage de rasters contenus dans un dossier, il est possible de faire la même chose à l'aide de gdaltindex, disponible également dans QGIS :

Menu Raster / Divers / Index de tuiles

Je choisis d'écrire le chemin absolu dans le shapefile, mais un chemin relatif fonctionne tout aussi bien, et permet de déplacer les rasters et le tableau d'assemblage ailleurs sans avoir à modifier le tableau d'assemblage.

Une fois le tableau d'assemblage créé, il faut l'ouvrir dans QGIS.

Nous allons utiliser les actions pour gérer l'affichage ou non de nos rasters :

Il faut ouvrir les propriétés du tableau d'assemblage (clic droit sur la couche / Propriétés) puis se rendre sur l'onglet actions. Nous allons créer deux actions de type python, l'une pour ouvrir le raster et l'autre pour le fermer :

action openRaster :

  • choisir le type python
  • donner un nom à l'action : openRaster
  • puis entrer le code suivant dans la zone Action :
import os
chemin='[% "location" %]'
nomCouche = str(os.path.splitext(os.path.split(chemin)[1])[0])
qgis.utils.iface.addRasterLayer(chemin,nomCouche)

[% "location" %] correspond au nom du champ contenant le chemin vers le raster

  • puis cliquer sur Ajouter l'action à la liste

action closeRaster :

Faire de même que pour openRaster, mais dans la zone Action, entrez le code suivant :

closeRaster.py

  1. import os
  2. chemin='[% "location" %]'
  3. nomCouche = str(os.path.splitext(os.path.split(chemin)[1])[0])
  4. instRegistry = QgsMapLayerRegistry.instance()
  5. couche = instRegistry.mapLayersByName(nomCouche)
  6. if len(couche) > 0:
  7. instRegistry.removeMapLayer(couche[0].id())

Vous devez maintenant avoir deux actions liées au tableau d'assemblage

Appliquez et fermez les propiétés en validant par OK, puis vous pourrez utiliser les boutons d'actions :

Il ne vous reste plus qu'à sélectionner le tableau d'assemblage comme couche active, choisir l'une ou l'autre des actions et cliquer sur la dalle souhaitée.

L'inconvénient majeur de cette solution, c'est que les actions sont enregistrées dans le document courant, si vous ouvrez votre tableau d'assemblage dans un autre document, elles ne seront plus présentes. Il est possible de régler ce problème en cliquant sur le bouton Sauvegarder par défaut des propriétés de la couche. Ainsi lorsque vous ouvrirez à nouveau votre tableau d'assemblage, les actions seront présentes.

Il est probablement possible de faire mieux et plus propre, mais on voit qu'en quelques minutes il est possible de faire des choses très utiles assez simplement, j'espère que cela vous sera utile.


Site officiel : PyQGIS Developper CookBook


Creative Commons License
licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Pas de Modification 2.0 France

Commentaires

Un petit peu plus à peu de frais

Bonjour,

J'ai essayé de faire cela pour un client et j'ai eu quelques problèmes de chemin relatifs sous Windows et de fichiers très nombreux.

Pour les fichiers nombreux, la commande écrite par l'outil de QGIS n'est pas optimale. Il vaut mieux appelé l'outil gdaltindex ( disponible dans le répertoire bin du rep d'installation de QGIs) sous une forme "c:/...gdaltindex.exe" toto.shp ./repDalles/*.tif. En faisant cela, l'attibut location est en position relative par rapport au SHP

J'ai aussi un peu amélioré le script pour l'ouverture lors que l'on a des fichiers relatifs. J'ai ajouté la fonctionnalité qui fait que le script revient sur la couche du tableau d'assemblage après chaque ouverture.

Le voici :

import os
from qgis.utils import iface
p=os.path.dirname(iface.activeLayer().source())
chemin=os.path.join(p,'[% "location" %]')
nomCouche = str(os.path.splitext(os.path.split(chemin)[1])[0])
qgis.utils.iface.addRasterLayer(chemin,nomCouche)
nbLayer=(qgis.utils.iface.mapCanvas().layerCount())
calqueaActiver=qgis.utils.iface.mapCanvas().layer(nbLayer-1)
qgis.utils.iface.setActiveLayer(calqueaActiver)

Merci pour cette piste

Merci Ludovic pour cette piste. Ca fait un moment que je me demandais comment contourner le fait de devoir noter sur papier l'emprise de mon périmètre pour n'aller récupérer que les bonnes dalles et là, tu m'apportes cette astuce. Merci beaucoup.
Par contre, je l'ai un peu modifié, dans un premier temps, comme l'a fait le précédent commentateur car j'utilise aussi la grille issue de Image Boundary mais aussi pour avoir un comportement proche de Show/Hide Image (c'est-à-dire pouvoir importer plusieurs dalles à la suite sans devoir sélectionner la couche catalogue après chaque import et les rendre visibles par défaut).
Je précise que je n'y connais pas grand chose en python, si ce n'est (pour l'instant) que modifier des variables ici et là; mon code n'est peut-être pas optimisé mais il fait ce que je veux.

import os
macouche = qgis.utils.iface.activeLayer()
chemin='[% "Path" ||'/'||"IMAGE" %]'
nomCouche = str(os.path.splitext(os.path.split(chemin)[1])[0])
qgis.utils.iface.addRasterLayer(chemin,nomCouche)
monraster=qgis.utils.iface.legendInterface().currentLayer()
qgis.utils.iface.legendInterface().setLayerVisible(monraster, True)
qgis.utils.iface.legendInterface().setCurrentLayer(macouche)

Ce que j'aurais souhaité en plus, c'est :
- conserver le surlignage bleu sur la couche catalogue
- toujours comme avec Show/Hide Image, pouvoir rendre invisible la dalle si elle est déjà présente dans la couche lorsqu'on clique dans son emprise.
Mais bon, mes premières tentatives de code ayant échoué, je me contente pour l'heure de ce fonctionnement qui nous facilite ÉNORMÉMENT la tâche. Et en espérant que ces compléments puissent aider d'autres lecteurs.
Encore une fois, MERCI!

Bravo!

Alors là, je dis bravo et surtout un grand merci!
Ca marche et même très bien, l'ergonomie est également impeccable.
Merci d'avoir fait un tuto aussi détaillé et facile à suivre/appliquer.
C'est donc officiel, je n'ouvre plus QGis 1.8!
J'imagine que ça risque d'en dépanner plus d'un.

Juste un petit détail, je n'ai pas réussi à utiliser l'index de tuiles. J'ai une erreur: "Unable to find field `location' in DBF file `C:/DATA QGIS/Catalogues/Cat_Ortho_80.shp'". Je ne comprends pas comment QGIS ne peut pas trouver un champs dans un fichier dbf qu'il est justement supposé créer. Je sèche.
J'ai contourné ce problème en utilisant Image boudary: j'ai ouvert la table attributaire de la grille crée et utilisé la calculatrice afin de créer un nouveau champs contenant les champs 'PATH' et 'IMAGE' concaténés( "PATH" ||'/'||"IMAGE"). Ce champs contient donc le chemin complet des dalles Ortho. Champs que j'ai appelé "CHEMIN" et qui remplace "location" dans [% "location" %]

Encore merci !

Poster un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.