Випускаєте блокування файлів 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 другого, видаляються .. чи є рішення видалити ці два файли так само?
rao
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.