1 votos

Refrescar el lienzo del mapa en el bucle for en QGIS 3

Tengo un script de consola en el que estoy tratando de iterar a través de los marcadores guardados del proyecto abierto para tener el mapa pan / zoom a la extensión del marcador. Me gustaría guardar eventualmente cada lienzo del mapa como archivo pdf. Puedo establecer manualmente los parámetros adecuados para recorrer los marcadores y el lienzo se actualiza cada vez que establezco la extensión.

Sin embargo, si recorro los marcadores guardados y establezco la extensión del lienzo en un bucle for (como se indica a continuación), el lienzo no se actualiza con cada cambio de extensión, sólo se actualiza una vez que el script ha seguido su curso. He añadido sleep comandos en el for bucle para permitir el tiempo de redibujado, pero eso no funcionó. ¿Me estoy perdiendo algo sencillo?

bmarks = QgsApplication.bookmarkManager()

bmarks.bookmarks() 

for b in bmarks.bookmarks():
    canv = iface.mapCanvas()
    canv.setExtent(b.extent())
    iface.mapCanvas().refresh()

4voto

Michael Puntos 11

Veo que su solicitud es para el lienzo, pero parece que el objetivo final es una salida basada en archivos, así que voy a responder a esa en su lugar.

No es necesario actualizar el propio lienzo. También se puede hacer muy bien en trabajos que renderizan a imágenes.

bmarks = QgsApplication.bookmarkManager()
bmarks.bookmarks() 

settings = iface.mapCanvas().mapSettings()

for i, b in enumerate(bmarks.bookmarks()):
    settings.setExtent(b.extent())
    renderer = QgsMapRendererParallelJob(settings)

    event_loop = QEventLoop()
    renderer.finished.connect(event_loop.quit)
    renderer.start()
    event_loop.exec_()

    img = renderer.renderedImage()
    img.save('/tmp/img{}.png'.format(i))

La ventaja de este enfoque es también que puede ajustar los parámetros en la configuración, por ejemplo, la anchura y la altura de la imagen renderizada (por defecto depende del tamaño de la ventana) o que puede tener un fondo transparente. Véase https://qgis.org/api/classQgsMapSettings.html para más detalles.

Incluso podría lanzar varias tareas en segundo plano en paralelo para esto, esto se deja como un ejercicio para el lector.

1voto

D'oh Puntos 1

En primer lugar, parece que el uso de time.sleep() podría no dar el efecto deseado, ver: https://stackoverflow.com/questions/55301747/how-to-make-python-wait-while-qgis-renders-a-shapefile

Así que para probar que la solución funciona, he introducido guardar las imágenes (por favor, no te olvides de ajustar la ruta) La diferencia clave es el uso de waitWhileRendering(), que aparentemente, bueno, espera hasta que el renderizado haya terminado, para que el refresco del lienzo haga su trabajo.

bmarks = QgsApplication.bookmarkManager()
canv = iface.mapCanvas()
i=0
for b in bmarks:
    i+=1
    canv.setExtent(b.extent(),False)
    canv.refresh()
    canv.waitWhileRendering() #probably that makes the difference
    canv.saveAsImage('/home/username/Documents/j{0}'.format(i)) ##adjust the path

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X