2

I have moved all my QGIS layer files from C:// drive to One Drive, and I would like to re-map the old filepaths to the new drive.

I know I can open the QGIS file as a text file and run a find and replace on the old filepath, so that works. But I would like to know how to do this in the Python console within the QGIS project.

I've tried lots of variations of the code below, but the layers just won't update. What am I missing?

def my_processor(path):
    return path.replace('../../../../GIS - GIS Data - GIS Data', 'D:/OneDrive - CM/GIS - GIS Data/')

QgsPathResolver.setPathPreprocessor(my_processor)
3
  • I suggest opening your project file using a text editor and using ctrl+h (search & replace) to repair the faulty paths. If your project is saved to .qgz, you need to unzip the file first.
    – Erik
    Commented Aug 3, 2021 at 13:22
  • Thank you, as I said in my post I know how to do this in text editor, but I would like to know how to do this in the Python console.
    – Mr Magoo
    Commented Aug 4, 2021 at 0:17
  • Oh, my bad, I somehow skimmed that part, sorry.
    – Erik
    Commented Aug 4, 2021 at 7:38

1 Answer 1

3

From inside the python console within the project with broken layers, you can use the method setDataSourcelike in this answer by @J.Monticolo.

for layer in QgsProject.instance().mapLayers().values():
    name = layer.name()
    provider = layer.providerType()
    options = layer.dataProvider().ProviderOptions()
    new_path = 'D:/OneDrive - CM/GIS - GIS Data/'
    new_url = new_path+str(name) +".shp"
    layer.setDataSource(new_url, name, provider, options)

EDIT after author's comment :

If you only have one folder to replace and it's always the same you can use replace() like this :

old_root_folder = "GIS - GIS Data - GIS Data"
new_root_folder = "GIS - GIS Data"

for layer in QgsProject.instance().mapLayers().values():
    name = layer.name()
    old_url = layer.dataProvider().dataSourceUri()
    new_url = old_url.replace(old_root_folder, new_root_folder)
    provider = layer.providerType()
    options = layer.dataProvider().ProviderOptions()
    layer.setDataSource(new_url, name, provider, options)
    
3
  • Thank you, this works perfectly when all shapefiles have the same parent folder, but my layers are in several different folders under a shared root folder e.g. 'GIS - GIS Data/Internal/Homestead.shp' and 'GIS - GIS Data/Boundaries/Boundary.shp'. Is there any way to update just the shared root folder part of the filepath i.e. '../GIS - GIS Data/' - the remainder of the filepath is still correct in the broken links, just not the root folder part.
    – Mr Magoo
    Commented Aug 4, 2021 at 0:13
  • @MrMagoo, I edit my answer, I think I found an appropriate solution for your trouble.
    – JULESG
    Commented Aug 4, 2021 at 7:15
  • 1
    that code worked perfectly. All my layers have updated! You've saved me so much time, legend! Thank you so much :D
    – Mr Magoo
    Commented Aug 4, 2021 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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