23 votos

Actualización de capas de QGIS a partir de una fuente de datos modificada

Estoy intentando que las capas se actualicen automáticamente cuando cambia su fuente de datos. Estoy usando R para escribir un shapefile con un atributo, y colorear de acuerdo a ese atributo en QGIS.

Quiero escribir un nuevo shapefile con diferentes valores de atributos, y que los colores del mapa Qgis se actualicen. El paso 1 es desencadenar ese proceso, el paso 2 es hacer que la capa se recargue desde el shapefile modificado. Es el paso 2 lo que me preocupa aquí.

En otras preguntas/charlas de la lista de correo se menciona el uso de triggerRepaint en la capa - que no funciona. Otras sugerencias setCacheImage(None) y de nuevo no funciona. Al final la capa se actualiza, pero no veo la lógica, y a veces ocurre por sorpresa después de no haber hecho nada. O tal vez hice algo hace dos minutos.

La única forma reproducible de conseguir que se actualice es duplicar la capa desde el menú de leyenda - el duplicado siempre obtiene sus datos del shapefile actual, ¡y la capa original también se actualiza! Así que debe haber alguna manera de hacerlo.

Creo que funcionaba mejor en la 2.8, pero esta es la 2.10 así que quizás haya un nuevo bug en alguna parte.

Relacionado, pero no me funciona en 2.10:

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

Otras cosas que he probado:

  • layer.dataProvider().dataChanged.emit() - funcionó una vez, luego no volvió a hacerlo en la misma capa

Creo que he localizado por qué duplicar la capa funciona - si creo una nueva capa desechable basada en la capa actualizada y luego llamo a .triggerRepaint() en la capa actualizada, se actualiza en el lienzo del mapa:

QgsVectorLayer( layer.source(), "layer copy", layer.providerType() )
layer.triggerRepaint()

Si utilizo una fuente de capa diferente no funciona, así que parece ser que si se crea un objeto de capa basado en la misma fuente de capa...

Acabo de hacer una prueba rápida con una capa rasterizada (a partir de un GeoTIFF), y simplemente llamando a rlayer.triggerRepaint() parece actualizar de forma fiable la vista de la trama en el lienzo del mapa.

6voto

Michael Puntos 11

Esto está relacionado con la introducción del pool de conexiones OGR. [1]

Antes de QGIS 2.10, se volvía a abrir un archivo en cada acceso (por ejemplo, al repintar).

Desde QGIS 2.10 el manejador de fichero se mantiene abierto y esto significa que si un fichero es reemplazado el manejador sigue apuntando al archivo antiguo en sistemas basados en Unix.

QGIS 2.10: solución provisional

Desafortunadamente no existe una API para forzar a QGIS a reabrir el archivo en QGIS 2.10. Como una solución se puede utilizar un hack feo:

layer.dataProvider().changeAttributeValues( { -1: { 0: 0 } } )
layer.triggerRepaint()

QGIS 2.12: solución

Yo sólo introdujo un nuevo método que estará disponible a partir de QGIS 2.12:

layer.dataProvider().forceReload()
layer.triggerRepaint()

Enfoque general

Si tiene la posibilidad de controlar cómo el archivo se está sobrescribiendo, puede abrir los archivos existentes con permisos de escritura y cambiar el contenido en lugar de reemplazar los archivos por completo (eliminar/crear) en el disco.

[1] El pool de conexiones se introdujo para acelerar considerablemente el acceso a determinadas fuentes de datos.

3voto

Ricardo Reyes Puntos 3428

Si se desplaza o actualiza el mapa, debería actualizarse.

Este artículo dice que se puede utilizar lo siguiente en PyQGIS:

myLayer.triggerRepaint()

Para actualizar todas las capas se puede utilizar la siguiente función:

def refresh_layers(self):
    for layer in qgis.utils.iface.mapCanvas().layers():
         layer.triggerRepaint()

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