Melepaskan kunci file PyQGIS?


16

Saya bertanya-tanya apa yang memicu pelepasan kunci file di pyQGIS?

Saya mencoba menghapus beberapa sumber data (digunakan sementara) dengan menelepon QgsVectorFileWriter.deleteShapeFile, tetapi saya harus keluar dari QGIS sebelum dapat melakukannya. Saya telah memuat sumber ke objek QgsVectorLayer. Apakah semua objek dan referensi ini harus dikumpulkan sebelum saya dapat menghapus sumbernya? Apakah ada cara untuk memaksakan ini?


Saya telah berhasil membuat contoh kode minimal yang gagal. Pastikan temp sementara kosong sebelum dijalankan.

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

Saya menemukan bahwa itu berfungsi jika saya gunakan QgsVectorFileWriteruntuk membuat layer2, bukan algoritma pemrosesan. Saya mendapatkan kesalahan yang sama jika mencoba qgis:clipalgoritma. Jadi ini bug dalam pemrosesan? Apakah saya salah menggunakannya?

Jawaban:


9

Maaf terus menjawab pertanyaan saya sendiri, tapi saya rasa saya menemukan solusinya.

Ternyata, itu berfungsi dengan baik jika Anda menambahkan lapisan ke registri peta, dan kemudian hapus lagi. Registri peta mengambil kepemilikan lapisan, jadi ketika dihapus dari registri, kunci dibebaskan. Perhatikan bahwa Anda harus menambahkan layer ke legenda ( .addMapLayer(layer, addToLegend = False) tidak akan berfungsi).

Masih tidak yakin apakah menyebut ini solusi atau solusi, tetapi berhasil.

# ...

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

Jika ada yang punya info lebih lanjut, saya akan senang mempelajari lebih lanjut tentang ini.


saya harus menghapus dua lapisan seperti itu ... saya bisa menghapus satu menggunakan metode di atas .. semua file lain kecuali .dbf dan .shp yang kedua sedang dihapus .. adakah solusi untuk menghapus kedua file tersebut demikian juga?
rao
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.