Como recarregar automaticamente as camadas de varredura se a origem for alterada no QGIS?

8

Como recarregar automaticamente a camada rasterizada se a fonte for alterada? (O caminho é o mesmo, mas dentro do arquivo de origem há alterações)

Eu uso:

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

mas a camada não é atualizada.

# # #

Os mapas estão pintando novamente, mas ainda há a mesma imagem (o arquivo de origem foi alterado no disco)

Eu uso:

  layers = qgis.utils.iface.legendInterface().layers()
  for layer in layers:
      layer.triggerRepaint()
user7172
fonte
O cache de renderização está desativado em Configurações => Opções => Renderização? Se esse for o problema, você pode desativá-lo ou chamar setCacheImage (None) na camada para descartar o cache atual.
Matthias Kuhn

Respostas:

11

Suponho que sua pergunta não inclua detecção de alterações, pois sua amostra se refere apenas a QgsMapCanvas.refresh()

Em vez disso, você deve ligar QgsRasterLayer.triggerRepaint()

Se sua camada for chamada myLayer:

myLayer.setCacheImage( None )
myLayer.triggerRepaint()

O mesmo método existe também para as camadas vetoriais.

Para baixa notificação de alteração de arquivo de sobrecarga, proponho olhar para os Qt's QFileSystemWatcher, que usam o inotify no linux e técnicas semelhantes em outras 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 )

Obviamente, isso pode ser combinado com uma verificação MD5, conforme proposto por nickves, ou com uma verificação de tempo de modificação com os.stat(proposta de Nathan W).

Matthias Kuhn
fonte
2

Você pode verificar se o hash do arquivo mudou entre os intervalos

por exemplo:

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

É um pouco tolo, mas a ideia sublinhada é válida

(A verificação de hash MD5 encontrada aqui )

nickves
fonte
1
Isso teria uma sobrecarga bastante grande para grandes camadas.
Nathan W
verdade, que podia para grandes conjuntos de dados, mas é python puro
nickves
1
Gostaria apenas de utilizar os.stat docs.python.org/2/library/os.html#os.stat
Nathan W