Bagaimana cara memuat ulang layer raster secara otomatis jika sumber diubah di QGIS?

8

Bagaimana cara me-reload layer raster secara otomatis jika sumber diubah? (Pathnya sama tetapi file sumber di dalamnya berubah)

Saya menggunakan:

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

tetapi lapisan tidak menyegarkan.

# # #

Peta mengecat ulang tetapi masih ada gambar yang sama (file sumber diubah pada disk)

Saya menggunakan:

  layers = qgis.utils.iface.legendInterface().layers()
  for layer in layers:
      layer.triggerRepaint()
pengguna7172
sumber
Apakah rendering cache dinonaktifkan di Pengaturan => Opsi => Rendering? Jika ini masalahnya, Anda dapat menonaktifkannya atau memanggil setCacheImage (Tidak Ada) pada layer untuk mengabaikan cache saat ini.
Matthias Kuhn

Jawaban:

11

Saya kira pertanyaan Anda tidak termasuk deteksi perubahan, karena sampel Anda hanya menyangkut QgsMapCanvas.refresh()

Sebaliknya, Anda harus menelepon QgsRasterLayer.triggerRepaint()

Jika lapisan Anda disebut myLayer:

myLayer.setCacheImage( None )
myLayer.triggerRepaint()

Metode yang sama juga ada untuk layer vektor.

Untuk pemberitahuan perubahan file overhead yang rendah, saya akan mengusulkan melihat ke Qt QFileSystemWatcher, yang menggunakan inotify di linux dan teknik serupa di platform lain .

from PyQt4.QtCore import QFileSystemWatcher

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

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

Tentu saja ini dapat digabungkan dengan cek MD5 seperti yang diusulkan oleh nikel atau cek waktu modifikasi dengan os.stat(proposal Nathan W).

Matthias Kuhn
sumber
2

Anda dapat memeriksa apakah hash file telah berubah di antara interval

misalnya:

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

Ini agak meretas, tetapi gagasan garis bawahnya valid

(Cek hash MD5 ditemukan di sini )

Nickes
sumber
1
Ini akan memiliki overhead yang cukup besar untuk lapisan besar.
Nathan W
benar, itu bisa untuk dataset besar, tapi itu murni python
nickves
1
Saya hanya akan menggunakan os.stat docs.python.org/2/library/os.html#os.stat
Nathan W