Rilascio dei blocchi dei file PyQGIS?


16

Mi chiedevo cosa scatena il rilascio dei blocchi dei file in pyQGIS?

Sto cercando di eliminare alcune origini dati (utilizzate temporaneamente) chiamando QgsVectorFileWriter.deleteShapeFile, ma devo chiudere QGIS prima di poterlo fare. Ho caricato le fonti negli oggetti QgsVectorLayer. Tutti questi oggetti e riferimenti ad essi devono essere raccolti in modo inutile prima di poter eliminare la fonte? C'è un modo per forzare questo?


Sono riuscito a creare un esempio di codice minimo che non riesce. Assicurarsi che la directory temporanea sia vuota prima di eseguire.

from qgis.core import *
import processing, os, gc

project_temp_dir = "C:/Path/To/My/Dir/"      
layer1_path = project_temp_dir + "layer1.shp"
layer2_path = project_temp_dir + "layer2.shp"
input_layer = QgsMapLayerRegistry.instance().mapLayersByName('in_layer')[0]
if not input_layer.isValid(): raise Exception("Failed to grab input layer")

# Create layer 1
err = QgsVectorFileWriter.writeAsVectorFormat(input_layer, layer1_path, "utf-8", input_layer.crs())   
if err != QgsVectorFileWriter.NoError: raise Exception("Failed to write layer 1")

# Load layer 1
layer1 = QgsVectorLayer(layer1_path, "lyr1", "ogr")
if not layer1.isValid(): raise Exception("Failed to load layer 1")

# Use layer 1 to create layer 2, read-only makes no difference
# if not layer1.setReadOnly(): raise Exception("Could not set layer 1 to read-only")
processing.runalg("qgis:reprojectlayer", layer1, "EPSG:54030", layer2_path)

# Load layer 2
layer2 = QgsVectorLayer(layer2_path, "lyr2", "ogr")
if not layer2.isValid(): raise Exception("Failed to load layer 2")

del layer1
del layer2 
del input_layer
gc.collect()
print "Garbage: " + str(gc.garbage) # Empty

# Remove data sources for layers - FAILS!!
for f in os.listdir(project_temp_dir):          
    if f.endswith(".shp") and not os.path.isdir(project_temp_dir + f):              
        if not QgsVectorFileWriter.deleteShapeFile(project_temp_dir + f):
            # F*%&ing locks. 
            print "Failed to clear project temp directory."

Ho scoperto che funziona se uso QgsVectorFileWriterper creare layer2, invece dell'algoritmo di elaborazione. Ottengo lo stesso errore se provo l' qgis:clipalgoritmo. Quindi è un bug in elaborazione? Lo sto usando male?

Risposte:


9

Mi dispiace continuare a rispondere alle mie domande, ma penso di aver trovato una soluzione.

A quanto pare, funziona bene se aggiungi il livello al registro delle mappe e poi lo rimuovi di nuovo. Il registro delle mappe diventa proprietario del livello, quindi quando viene eliminato dal registro, i blocchi vengono liberati. Nota che devi aggiungere il layer alla legenda ( .addMapLayer(layer, addToLegend = False) non funzionerà).

Non sono ancora sicuro se chiamare questa una soluzione o una soluzione alternativa, ma fa il lavoro.

# ...

# Replace the following code (note: should do error checking on map registry functions):

# Load layer 1
layer1 = QgsVectorLayer(layer1_path, "lyr1", "ogr")
if not layer1.isValid(): raise Exception("Failed to load layer 1")
QgsMapLayerRegistry.instance().addMapLayer(layer1) #!!!!

# Use layer 1 to create layer 2  
processing.runalg("qgis:reprojectlayer", layer1, "EPSG:54030", layer2_path)

# Load layer 2
layer2 = QgsVectorLayer(layer2_path, "lyr2", "ogr")
if not layer2.isValid(): raise Exception("Failed to load layer 2")
QgsMapLayerRegistry.instance().addMapLayer(layer2) #!!!!

# Remove layer references
QgsMapLayerRegistry.instance().removeMapLayer(layer1.id()) #!!!!
QgsMapLayerRegistry.instance().removeMapLayer(layer2.id()) #!!!!

# Remove data sources for layers
for f in os.listdir(project_temp_dir):          
    if f.endswith(".shp") and not os.path.isdir(project_temp_dir + f):    
    # ...

Se qualcuno ha più informazioni, sarei felice di saperne di più su questo.


Devo eliminare due di questi livelli ... Sono in grado di eliminarne uno usando il metodo sopra. Tutti gli altri file tranne .dbf e .shp del secondo vengono eliminati. Esiste una soluzione per eliminare quei due file anche?
rao,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.