Comment recharger automatiquement les couches raster si la source est modifiée dans QGIS?


8

Comment recharger automatiquement la couche raster si la source est modifiée? (Le chemin est le même mais à l'intérieur du fichier source sont des changements)

J'utilise:

 qgis.utils.iface.mapCanvas().refresh()

mais la couche ne se rafraîchit pas.

# # #

Les cartes sont repeintes mais il y a toujours la même image (le fichier source est changé sur le disque)

J'utilise:

  layers = qgis.utils.iface.legendInterface().layers()
  for layer in layers:
      layer.triggerRepaint()

Le cache de rendu est-il désactivé dans Paramètres => Options => Rendu? Si tel est le problème, vous pouvez le désactiver ou appeler setCacheImage (None) sur la couche pour fermer le cache actuel.
Matthias Kuhn

Réponses:


11

Je suppose que votre question n'inclut pas la détection des modifications, car votre échantillon ne concerne que QgsMapCanvas.refresh()

Au lieu de cela, vous devez appeler QgsRasterLayer.triggerRepaint()

Si votre calque s'appelle myLayer:

myLayer.setCacheImage( None )
myLayer.triggerRepaint()

La même méthode existe également pour les couches vectorielles.

Pour une notification de modification de fichier à faible surcharge, je proposerais d'examiner Qt QFileSystemWatcher, qui utilise inotify sur linux et des techniques similaires sur d' autres plates-formes .

from PyQt4.QtCore import QFileSystemWatcher

def refreshLayer():
    myLayer.setCacheImage( None )
    myLayer.triggerRepaint()

watcher = QFileSystemWatcher()
watcher.addPath( '/path/to/your/raster' )
watcher.fileChanged.connect( refreshLayer )

Bien sûr, cela peut être combiné avec un contrôle MD5 comme proposé par nickves ou un contrôle de temps de modification avec os.stat(proposition Nathan W).


2

Vous pouvez vérifier si le hachage du fichier a changé entre les intervalles

par exemple:

def md5checksum(fp):
        import hash
    with open(fp, 'rb') as fh:
        m = hashlib.md5()
        while True:
            data = fh.read(8192)
            if not data:
                break
            m.update(data)
        return m.hexdigest()

import time
import copy

a,b = str(),str()
while True:
    a =  md5checksum(fp) # file
    if a != b:  # the file has changed, do what you want
        myLayer.triggerRepaint()
        b = copy.copy(a) #shallow copy, otherwise a and b will point at the same object
    else:
        sleep.time(1) #wait for 1 sec, then recheck

C'est un peu hackish, mais l'idée de soulignement est valable

(La vérification du hachage md5 se trouve ici )


1
Cela aurait des frais généraux assez importants pour les grandes couches.
Nathan W

c'est vrai, cela pourrait être le cas pour de grands ensembles de données, mais c'est du python pur
nickves

1
Je voudrais simplement utiliser os.stat docs.python.org/2/library/os.html#os.stat
Nathan W
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.