0

I recently discovered that several years worth of .qgs files were using an input shapefile with a space in the file name. I do not like spaces in file names! I did the following, to fix the problem:

  1. In Windows Explorer, I renamed the shapefiles by replacing the blank with an underscore. This was simple enough to do, and I have done this for many years with shapefiles.
  2. I wrote a small Python program that is run in a Command Prompt to replace the blank with an underscore for all occurrences of the pattern in all of the .qgs files with: out_rec = in_rec.replace("X1 El", "X1_El")

Before

    <layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321499_Greeley_W_1X1 Elev_Contour.shp" name="Elev_321499_Greeley_W_1X1 Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321499_Greeley_W_1X1 Elev_Contour.shp" name="Elev_321499_Greeley_W_1X1 Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321379_Denver_W_1X1 Elev_Contour.shp" name="Elev_321379_Denver_W_1X1 Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321379_Denver_W_1X1 Elev_Contour.shp" name="Elev_321379_Denver_W_1X1 Elev_Contour">
<legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Elev_321499_Greeley_W_1X1 Elev_Contour" showFeatureCount="0">
<legendlayer drawingOrder="-1" open="true" checked="Qt::Checked" name="Elev_321379_Denver_W_1X1 Elev_Contour" showFeatureCount="0">
  <datasource>../Data/GDD/Elev_321379_Denver_W_1X1 Elev_Contour.shp</datasource>
  <layername>Elev_321379_Denver_W_1X1 Elev_Contour</layername>
  <datasource>../Data/GDD/Elev_321499_Greeley_W_1X1 Elev_Contour.shp</datasource>
  <layername>Elev_321499_Greeley_W_1X1 Elev_Contour</layername>

After

    <layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321499_Greeley_W_1X1_Elev_Contour.shp" name="Elev_321499_Greeley_W_1X1_Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321499_Greeley_W_1X1_Elev_Contour.shp" name="Elev_321499_Greeley_W_1X1_Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321499_Greeley_W_1X1_Elev_Contour.shp" name="Elev_321499_Greeley_W_1X1_Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321379_Denver_W_1X1_Elev_Contour.shp" name="Elev_321379_Denver_W_1X1_Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321379_Denver_W_1X1_Elev_Contour.shp" name="Elev_321379_Denver_W_1X1_Elev_Contour">
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" id="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354" source="C:/Users/Steve/Documents/QGIS/Projects/Garmin/Data/GDD/Elev_321379_Denver_W_1X1_Elev_Contour.shp" name="Elev_321379_Denver_W_1X1_Elev_Contour">
  <layer_coordinate_transform destAuthId="EPSG:32613" srcAuthId="EPSG:4269" srcDatumTransform="-1" destDatumTransform="-1" layerid="Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354"/>
  <layer_coordinate_transform destAuthId="EPSG:32613" srcAuthId="EPSG:4269" srcDatumTransform="-1" destDatumTransform="-1" layerid="Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869"/>
  <item>Elev_321379_Denver_W_1X1_Elev_Contour20170611105418354</item>
  <item>Elev_321499_Greeley_W_1X1_Elev_Contour20170611105508869</item>

Now all of the .qgs files have the shapefile name with the blank replaced by an underscore but when I open any .qgs file, I get an error window with the title "Handle Bad Layers" and a list of all layers being bad including those that I did not change.

Obviously my logic of using this technique which worked with old ArcInfo .aml files and ArcView 2 and 3 .apr files does not work with QGIS .qgs files.

I do not want to manually open and change several years of .qgs files. I am using QGIS 3.4 but some of the .qgs files go back to 2.14.

What am I missing in the structure of the QGIS .qgs files besides replacing the blank with an underscore in the shapefile names?

  • 1
    An individual "shapefile" actually consists of several files ending with the suffix .shp, .shx, .dbf, and so forth. It appears to me that you only modified the .shp files. You'll have to replace the spaces for ALL files in each shapefile. – Stu Smith Sep 23 at 6:35
  • Stu, Thanks for your reply. See my solution below. Within the QGIS .qgs file, my Python program searched for and replaced all occurrences of the blank with an underscore. It never looked for .shp, .shx, .dbf, and so forth because it did not need to. Besides, I have been working with ESRI shapefiles for over 20 years so I know that they consist of multiple files. – Steve Haymes Sep 23 at 7:19
0

Actually, the problem was that my Python program was writing the fixed QGIS .qgs files to a new directory (as to not overwrite the original files) and in QGIS .qgs files, it appears that relative paths are used and not absolute paths so the new files in the new directory no longer knew where all of the input data sets were located.

In my old ArcInfo .aml files and ArcView 2 and 3 .apr files, absolute paths were used. The solution was to first copy the original files to a backup directory and then when fixing the files, overwrite them in the original directory where the relative path would work as it based on that directory. Here is a code snippet:

# backup all files before fixing them
if not os.path.exists("Bak"):
    os.mkdir("Bak")
print("Backing up files", end="")

for in_file in file_list:
    out_file = os.path.join(os.getcwd(), "Bak", in_file)
    shutil.copy(in_file, out_file)
    print(".", end="")

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.