In order to carry out binary shapefile operations such as the one you intend to use on more than two files you can do the process in a step wise fashion using temporary files.
A TESTED peice of code is below:
import os
import tempfile
import shutil
import processing
import glob
def delete_shape(shape_file):
shape_file_no_ext=os.path.splitext(shape_file)[0]
ext_list=('shx','dbf','qpj','prj','shp','cpg')
for extension in ext_list:
try:
os.remove(shape_file_no_ext+'.'+extension)
except:
pass
def copy_shape(shape_file,destination_shape_file):
delete_shape(destination_shape_file)
shape_file_no_ext=os.path.splitext(shape_file)[0]
destination_shape_file_no_ext=os.path.splitext(destination_shape_file)[0]
ext_list=('shx','dbf','qpj','prj','shp','cpg')
for extension in ext_list:
try:
shutil.copyfile(shape_file_no_ext+'.'+extension ,destination_shape_file_no_ext+'.'+extension)
except:
pass
def wrapped_alg(algorithm_name,file_name_list, output_file):
#Copy files to temp directory
temp_file_list=[]
for src_file in file_name_list:
dst_file=os.path.join(tempfile.gettempdir(),os.path.basename(src_file))
copy_shape(src_file,dst_file)
temp_file_list.append(dst_file)
#binary process on files in temp directory
while len(temp_file_list)>1:
temp_file=os.path.join(tempfile.gettempdir(),'multi_merge_temp_file.shp')
ultimate_file=temp_file_list.pop()
penultimate_file=temp_file_list.pop()
processing.runalg(algorithm_name, ultimate_file, penultimate_file, temp_file)
delete_shape(penultimate_file)
copy_shape(temp_file,penultimate_file)
delete_shape(temp_file)
delete_shape(ultimate_file)
temp_file_list.append(penultimate_file)
#copy over final file
copy_shape(temp_file_list.pop(),output_file)
dir_to_process="C:\\test\\files\\"
output_file="C:\\test\\result\\output.shp"
file_name_list = [shp for shp in glob.glob(dir_to_process + "*.shp")]
alg_name="qgis:mergevectorlayers"
#alg_name="qgis:union"
wrapped_alg(alg_name,file_name_list, output_file)
NB1 this code can be used for any 'binary' processing algorithm normally run with the form
processing.runalg("algorithm_name", file1, file2, outputfile)
NB2: As written it ony works on shape files
NB3: Ensure all your shape files are in the same projection
NB4: This code is now tested on "qgis:union" and "qgis:merge"
NB5: This code is for algorithms which can run on files (additional code would be required if the inputs HAD to be loaded layers)
NB6 I do realise that for merge the following would be much more efficient but I wanted to supply a generic solution
processing.runalg("saga:mergeshapeslayers", file_name_list[0], ";".join(file_name_list[1:]) , outputfile)
The topic that I think you are looking for is Linear Referencing and, to perform line-on-line overlay, the tool to use is Overlay Route Events.
I recommend reviewing About overlaying event data:
Overlaying events is another way to create new event data. This
process combines two input event tables to create a single output
event table. The new table can be used to analyze event data in ways
not possible using traditional spatial analysis techniques.
The new event table can contain either the intersection or the union
of the input events. The union of the input events splits all linear
events at their intersections and writes them to the new event table.
The intersection of the input event tables writes only overlapping
events to the output event table.
Line-on-line, line-on-point (same as point-on-line), and even
point-on-point event overlays can be performed.
Once you have the unioned linear events you should be able to convert them to features.
Best Answer
With the tools available now by default in the "processing" toolbox (aka "sextante") the best result seems to be given by GRASS v.overlay with the option "OR". You will need to change a few colum names in your inputs, otherwise you'll get an error: GRASS adds a prefix to output column names, so when truncated they could result in identical names and that is not allowed.
If you have SAGA 2.10 it also has a union tool that gives what it seems the result you expect.