¿Cómo recargar automáticamente las capas ráster si la fuente se cambia en QGIS?

8

¿Cómo recargar automáticamente la capa ráster si se cambia la fuente? (La ruta es la misma pero dentro del archivo fuente hay cambios)

Yo suelo:

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

pero la capa no se actualiza.

# # #

Los mapas se están repintando, pero todavía hay la misma imagen (el archivo fuente se cambia en el disco)

Yo suelo:

  layers = qgis.utils.iface.legendInterface().layers()
  for layer in layers:
      layer.triggerRepaint()
usuario7172
fuente
¿La memoria caché de representación está deshabilitada en Configuración => Opciones => Representación? Si este es el problema, puede deshabilitarlo o llamar a setCacheImage (None) en la capa para descartar el caché actual.
Matthias Kuhn

Respuestas:

11

Supongo que su pregunta no incluye la detección de cambios, ya que su muestra solo concierne QgsMapCanvas.refresh()

En cambio tienes que llamar QgsRasterLayer.triggerRepaint()

Si su capa se llama myLayer:

myLayer.setCacheImage( None )
myLayer.triggerRepaint()

El mismo método existe para las capas vectoriales también.

Para una notificación de cambio de archivo de baja sobrecarga, propongo buscar en Qt's QFileSystemWatcher, que hace uso de inotify en linux y técnicas similares en otras plataformas .

from PyQt4.QtCore import QFileSystemWatcher

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

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

Por supuesto, esto se puede combinar con una verificación MD5 según lo propuesto por nickves o una verificación de tiempo de modificación con os.stat(propuesta de Nathan W).

Matthias Kuhn
fuente
2

Puede verificar si el hash del archivo ha cambiado entre intervalos

p.ej:

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

Es un poco difícil, pero la idea de subrayado es válida.

(La comprobación de hash md5 se encuentra aquí )

nickves
fuente
1
Esto tendría una sobrecarga bastante grande para capas grandes.
Nathan W
Es cierto, podría para grandes conjuntos de datos, pero es puro Python
Nickves
1
Simplemente usaría os.stat docs.python.org/2/library/os.html#os.stat
Nathan W