0

I want to check if a vector layer (filepath) can be used in the pyqgis algorithm processing module. Before using the processing module, I need to check the layer is not loaded in a Q instance, if it is not loaded then I can overwrite it.

If I try to execute a processing algorithm and write to an existing layer that is already loaded - say in the QGIS 3.20 program, the error ERROR 1: C:/xxx/Tool/inputs/outlets_temp.shp is not a directory. is returned. Presumably because it won't overwrite a layer that is in use. Going through traceback, the full message is _core.QgsProcessingException: Could not create layer C:/xxx/Tool/inputs/outlets_temp.shp: Creation of data source failed (OGR error: C:/xxx/Tool/inputs/outlets_temp.shp is not a directory.)

I don't really want to wrap the entire processing module in a try/except statement and it looks like the failure is due to an OGR error. My Attempt at catching this error is below:

The problem with the code below i, that the driver still seems to delete the shx and prj files even when I have the layer loaded in Q which renders it unuseable - I could make a temporary copy of the layer and reinstate it but perhaps there is a simpler way to check if a file is in use?

DriverName = "ESRI Shapefile"      # e.g.: GeoJSON, ESRI Shapefile
FileName  = "C:/xxxx/Tool/inputs/outlets.shp"
driver = ogr.GetDriverByName(DriverName)
def check_file_path(FileName):
    fp = Path(FileName)
    data_source = driver.LoadDataSource(FileName)
    if data_source == None:
        print(f'could not access layer {FileName} - likely the file is open. Preparing new name')
        current_stem = fp.stem
        if current_stem[-4] == 'V':
            version = int(current_stem[-3:])+1
            new_stem = current_stem[:-3] + f'{version:03}'
        else:
            new_stem = current_stem + '_V001'
        new_fp = str(fp.parent/(new_stem+fp.suffix))
        return check_file_path(new_fp)
    data_source = None
    return FileName

fp = check_file_path(FileName)
print(fp)

1 Answer 1

1

I am not sure if this is what you want, but if I understand your question correctly, this could be a simpler way to check if a layer with a particular source file path is loaded in a QGIS project instance:

file_path = 'C:/xxxx/Tool/inputs/outlets.shp'

def isLoaded(data_source):
    for layer in QgsProject.instance().mapLayers().values():
        if layer.source() == data_source:
            return True
    return False
        
if not isLoaded(file_path):
    print('Layer is not loaded')
    # you can overwrite the file...
else:
    print('Layer is loaded')
3
  • Thanks, but it doesn't seem to work for me. I think Qgs.Project.instance() will not capture all QGIS instances? The issue I have is that a user may open the file in a seperate QGIS instance that my tool does not know about, then when I try to use that file, I get an error Aug 10, 2021 at 0:00
  • @user1650538, ok- no problem.
    – Ben W
    Aug 10, 2021 at 0:14
  • The issue in my opinion is the fact you want to use Python/PyQGIS to check a file is not opened across multiple users or multiple instances of QGIS. You better look at recipes that ease the way to control what files are opened on your OS or shared network volume e.g stackoverflow.com/a/13994351/768440 You may then wrap the system calls within Python.
    – ThomasG77
    Sep 12, 2021 at 14:22

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.