9

I'm writing a generic script which involves writing shapefiles to a directory which are then merged together. After writing the files out to the Output folder, I'm trying to get the saga:mergeshapeslayers algorithm to merge all the files in the Output folder. I have used the Model Builder and although it is helpful to an extent, I find that it is used for specific purposes whereas I am attempting to make a script for generic purposes.

Code:

##Test=name
##Select_folder=folder
##Result=output vector

import os
import glob

path_1 = Select_folder
path = path_1
os.chdir(path)

def function():

    output = glob.glob(path_1 + './*.shp')
    x = 0

    while output[x]:
        for fname in glob.glob("*.shp"):
            outputs_1 = processing.runandload("qgis:fieldcalculator", output[x], 'Number', 1, 10, 0, True, 1 , "C:\Users\Me\Desktop\Output\\"  + fname)
            multiple_0 = glob.glob("*.shp")
            x = x + 1

        if x + 1 > len(output):
            processing.runalg("saga:mergeshapeslayers", output[0], ";".join(multiple_0) , Result)
            break
        else:
            continue

if path_1:
    function()
else:
   pass
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Joseph
  • 75,746
  • 7
  • 171
  • 282
  • 1
    Sorry, but I don't know what you are trying to do. What is Z?. What does the function(Z) serve if it returns nothing ? What is the difference between glob.glob(Z + './*.shp')and glob.glob("*.shp")? – gene Jun 10 '14 at 18:18
  • Thanks @gene and apologies, edited the code so that it hopefully looks better. To my limited understanding, the difference is that glob.glob(path_1 + './*.shp') defines where the .shp files are; and glob.glob("*.shp") fetches the filenames of the .shp files. Please correct me if I'm mistaken. – Joseph Jun 11 '14 at 11:52
  • To try to be more clear as to what I want: I can write the shapefiles from a given folder into "C:\Users\Me\Desktop\Output\". I would then like the saga:mergeshapeslayers to merge all files in that Output folder. The code for the merge algorithm is incorrect and would like to know any solutions. – Joseph Jun 11 '14 at 12:00

2 Answers2

6

You can simplify your script without using while... and x, x+1: for simple Python list, it would be best to use for or list comprehensions:

##Test=name
##Select_folder=folder
##Result=output vector

import os
import glob
# folder path of Result shapefile
path_res = os.path.dirname(Result)
# go to Select_folder
os.chdir(Select_folder)
# copy the shapefiles (you don't need to load the shapefiles, so use runalg)
for fname in glob.glob("*.shp"):
     outputs_1 = processing.runalg("qgis:fieldcalculator", fname, 'Number', 1, 10, 0, True, 1 , path_res  + "/"+ fname) 

# paths of the shapefiles in the Result folder with list comprehension
output = [path_res + "/"+ shp for shp in glob.glob("*.shp")]
# merge the shapefiles
processing.runalg("saga:mergeshapeslayers", output[0], ";".join(output) , Result)

Some explications:

#  folder path of the Result shapefile # = path_res
print  os.path.dirname("/Users/Shared/test.shp")
/Users/Shared

# list comprehension
print [shp for shp in glob.glob("*.shp")]
['shape1.shp', 'shape2.shp',..., 'shapen.shp']
print [path_res + "/"+ shp for shp in glob.glob("*.shp")]
['/Users/Shared/shape1.shp', '/Users/Shared/shape2.shp', ...,'/Users/Shared/shapen.shp']

or better with os.path.join (universal, Windows, Linux, Mac OS X):

print [os.path.join(path_res, shp) for shp in glob.glob("*.shp")]
print [os.path.join(path_res, shp) for shp in glob.glob("*.shp")][0] # = output[0]
/Users/Shared/shape1.shp
gene
  • 54,868
  • 3
  • 110
  • 187
5

Found the answer thanks to @gene who's comments helped me focus on the right area. Just had to simply to use glob for the saga:mergeshapeslayers function to call:

multiple_0=glob.glob("*.shp")

Added this to the code above which now merges all files in the folder.

Joseph
  • 75,746
  • 7
  • 171
  • 282
  • can you correct the indentation of your script, please. As proposed, it does not work. – gene Jun 11 '14 at 16:24
  • ok but you can simplify your script (see below) – gene Jun 12 '14 at 13:21
  • 1
    Just in case someone runs into the same problem as I did. saga:mergeshapeslayers wasn't found, but saga:mergelayers does the same thing. This was on 2.12.1 (OS X 10.11.3). – cmyk Feb 19 '16 at 08:50
  • @cmyk - Thanks buddy, I didn't mention in the post but it was an old version of QGIS and the Processing plugin (I think v2.2 for both). – Joseph Feb 19 '16 at 09:58