PyQGIS-Dateisperren aufheben?

16

Ich habe mich gefragt, was die Freigabe von Dateisperren in pyQGIS auslöst.

Ich versuche, einige Datenquellen (die vorübergehend verwendet werden) durch Aufrufen zu löschen QgsVectorFileWriter.deleteShapeFile, aber ich muss QGIS beenden, bevor ich das tun kann. Ich habe die Quellen in QgsVectorLayer-Objekte geladen. Müssen alle diese Objekte und Verweise auf sie müllsammelbar sein, bevor ich die Quelle löschen kann? Gibt es eine Möglichkeit, dies zu erzwingen?


Ich habe es geschafft, ein minimales Codebeispiel zu erstellen, das fehlschlägt. Stellen Sie sicher, dass das temporäre Verzeichnis leer ist, bevor Sie es ausführen.

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."

Ich fand, dass es funktioniert, wenn ich anstelle des Verarbeitungsalgorithmus QgsVectorFileWritererstellen layer2. Ich erhalte den gleichen Fehler, wenn ich den qgis:clipAlgorithmus ausprobiere . Ist das ein Fehler in der Verarbeitung? Benutze ich es falsch?

Oystein
quelle

Antworten:

9

Es tut mir leid, meine eigenen Fragen weiter zu beantworten, aber ich glaube, ich habe eine Lösung gefunden.

Wie sich herausstellt, funktioniert es gut, wenn Sie den Layer zur Kartenregistrierung hinzufügen und ihn dann wieder entfernen. Die Kartenregistrierung übernimmt den Besitz des Layers. Wenn dieser aus der Registrierung gelöscht wird, werden die Sperren freigegeben. Beachten Sie, dass Sie die Ebene zur Legende hinzufügen müssen ( .addMapLayer(layer, addToLegend = False) funktioniert nicht).

Ich bin mir immer noch nicht sicher, ob ich das eine Lösung oder eine Problemumgehung nennen soll, aber es macht den Job.

# ...

# 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):    
    # ...

Wenn jemand mehr Informationen hat, würde ich mich freuen, mehr darüber zu erfahren.

Oystein
quelle
Ich muss zwei solche Ebenen löschen ... Ich kann eine mit der obigen Methode löschen. Alle anderen Dateien außer .dbf und .shp der zweiten werden gelöscht. Gibt es eine Lösung, um diese beiden Dateien zu löschen auch?
Rao