Wie werden Rasterebenen automatisch neu geladen, wenn die Quelle in QGIS geändert wird?

8

Wie wird die Rasterebene automatisch neu geladen, wenn die Quelle geändert wird? (Der Pfad ist der gleiche, aber innerhalb der Quelldatei gibt es Änderungen.)

Ich benutze:

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

aber Schicht nicht aktualisieren.

# # #

Die Karten werden neu gestrichen, aber es gibt immer noch das gleiche Bild (Quelldatei wird auf Disc geändert)

Ich benutze:

  layers = qgis.utils.iface.legendInterface().layers()
  for layer in layers:
      layer.triggerRepaint()
user7172
quelle
Ist der Rendering-Cache unter Einstellungen => Optionen => Rendern deaktiviert? Wenn dies das Problem ist, können Sie es entweder deaktivieren oder setCacheImage (None) auf der Ebene aufrufen, um den aktuellen Cache zu schließen.
Matthias Kuhn

Antworten:

11

Ich nehme an, Ihre Frage enthält keine Änderungserkennung, da Ihre Stichprobe nur Bedenken betrifft QgsMapCanvas.refresh()

Stattdessen musst du anrufen QgsRasterLayer.triggerRepaint()

Wenn Ihre Ebene myLayer heißt:

myLayer.setCacheImage( None )
myLayer.triggerRepaint()

Die gleiche Methode gibt es auch für Vektorebenen.

Für niedrige Overhead - Dateiänderungsbenachrichtigung würde ich in Qt schlagen suchen QFileSystemWatcher, die Verwendung macht inotify auf Linux und ähnliche Techniken auf anderen Plattformen .

from PyQt4.QtCore import QFileSystemWatcher

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

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

Dies kann natürlich mit einer MD5-Prüfung kombiniert werden, wie von Nickves vorgeschlagen, oder einer Änderung der Änderungszeit mit os.stat(Vorschlag von Nathan W).

Matthias Kuhn
quelle
2

Sie können überprüfen, ob sich der Datei-Hash zwischen den Intervallen geändert hat

z.B:

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 ist ein bisschen hackisch, aber die unterstreichende Idee ist gültig

(Der MD5-Hash-Check finden Sie hier )

Nickves
quelle
1
Dies hätte einen ziemlich großen Overhead für große Schichten.
Nathan W
Es stimmt, es könnte für große Datenmengen sein, aber es ist reine Python
Nickves
1
Ich würde nur os.stat docs.python.org/2/library/os.html#os.stat
Nathan W