Освобождение файловых блокировок PyQGIS?


16

Мне было интересно, что вызывает освобождение файловых блокировок в pyQGIS?

Я пытаюсь удалить несколько источников данных (используемых временно) по телефону QgsVectorFileWriter.deleteShapeFile, но мне нужно выйти из QGIS, прежде чем я смогу это сделать. Я загрузил источники в объекты QgsVectorLayer. Должны ли все эти объекты и ссылки на них быть мусором, прежде чем я смогу удалить источник? Есть ли способ заставить это?


Мне удалось создать минимальный пример кода, который не удается. Убедитесь, что временный каталог пуст перед запуском.

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

Я обнаружил, что это работает, если я использую QgsVectorFileWriterдля создания layer2, а не алгоритм обработки. Я получаю ту же ошибку, если попробую qgis:clipалгоритм. Так это ошибка в обработке? Я использую это неправильно?

Ответы:


9

Извините, что продолжаю отвечать на мои собственные вопросы, но я думаю, что нашел решение.

Оказывается, это хорошо работает, если вы добавляете слой в реестр карты, а затем удаляете его снова. Реестр карт становится владельцем слоя, поэтому при удалении из реестра блокировки снимаются. Обратите внимание, что вы должны добавить слой к легенде ( .addMapLayer(layer, addToLegend = False) не будет работать).

Все еще не уверен, можно ли назвать это решением или обходным путем, но он делает свою работу.

# ...

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

Если у кого-то есть больше информации, я был бы рад узнать об этом больше.


мне нужно удалить два таких слоя ... я могу удалить один из них, используя вышеуказанный метод ... все остальные файлы, кроме .dbf и .shp второго, удаляются .. есть ли какое-либо решение удалить эти два файла также?
Рао
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.