3

I am having problems with deleting files on disk after using "processing.runalg()" in a plugin I created when running it in windows. I have no problem in linux.

I found an issue regarding the same topic at https://hub.qgis.org/issues/12502, and was wondering if the issue in had been fixed in qgis 2.18.

The code is simple as follows, where outName is the path to the output chosen by the user, and tarNames is a list of file names to be processed:

import processing
import sys, gdal_merge as gm

rlayer = QgsRasterLayer(os.path.join(out,inputName), "input")

args = ['-of', "GTiff", '-n', "0", '-a_nodata', "0", '-separate', 
    '-ot', "UInt32",'-o', out+"/"+tmpName]
args.extend([out+"/"+t for t in tarNames])

sys.argv = args
gm.main()

processing.runalg("gdalogr:warpreproject", {"INPUT":os.path.join(out,tmpName), 
            "SOURCE_SRS":"EPSG:"+str(rlayer.crs().postgisSrid()), 
            "DEST_SRS":"EPSG:32724", "NO_DATA":0, "METHOD":0, 
            "RTYPE":3, "OUTPUT":os.path.join(out,outName)})

os.remove(os.path.join(out,tmpName))

os.remove fails, saying that the file is not available. As I mentioned, I don't have this issue in linux.

I tried to implement the workaround proposed in Releasing PyQGIS file locks?, but it does not solve the problem.

The only solution I have for the moment is to create a bunch of temp files with unique names and have the user delete them by hand... less than optimal. The temp file is created on disk by gdal_merge.py, I did not find an option to create it in memory. If anybody has a solution for that, I am very interested. I understand this is a separate question, and I am happy to post it if there is a solution.

2

I found a solution from this post Releasing PyQGIS file locks?.

I had to import the raster first and to pass it to the map layer registry. This way the registry has ownership before the processing. Then once the processing is finished I remove the layer from the registry, which releases the file on disk, and lets me delete it. Quick example below.

rlayer = QgsRasterLayer(os.path.join(out,inputName), "input")

QgsMapLayerRegistry.instance().addMapLayer(rlayer)

processing.runalg("gdalogr:warpreproject", {"INPUT":rlayer, 
        "SOURCE_SRS":"EPSG:"+str(rlayer.crs().postgisSrid()), 
        "DEST_SRS":"EPSG:32724", "NO_DATA":0, "METHOD":0, 
        "RTYPE":3, "OUTPUT":os.path.join(out,outName)})

QgsMapLayerRegistry.instance().removeMapLayer(rlayer.id())
del rlayer
os.remove(os.path.join(out,inputName))
0

If you don't need to use the output for further elaborations, you may save it as memory layer. For doing this you only need to set the output parameter as None:

processing.runalg("gdalogr:warpreproject", {"INPUT":os.path.join(out,tmpName), 
            "SOURCE_SRS":"EPSG:"+str(rlayer.crs().postgisSrid()), 
            "DEST_SRS":"EPSG:32724", "NO_DATA":0, "METHOD":0, 
            "RTYPE":3, "OUTPUT":None})

Instead, if you want to use the output, you may easily do this by giving it a name and then by calling it with getObject():

# you can use any name intead of warp_rep 
warp_rep = processing.runalg("gdalogr:warpreproject", {"INPUT":os.path.join(out,tmpName), 
            "SOURCE_SRS":"EPSG:"+str(rlayer.crs().postgisSrid()), 
            "DEST_SRS":"EPSG:32724", "NO_DATA":0, "METHOD":0, 
            "RTYPE":3, "OUTPUT":None})
# you can use any name intead of warp
warp = processing.getObject(warp_rep['OUTPUT'])
1
  • I know I can work with a layer in memory through processing, but the problem here is with the input, not the output. I don't manage to do a similar thing with gdal_merge as it is not available in the processing toolbox.
    – Olivier
    Jan 24 '17 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.