[GIS] Efficiently generate Voronoi layers in qgis via Python

pyqgispythonqgisvoronoi-thiessen

The following python commands both appear to function when called in qgis 2.6 to generate Voronoi diagrams:

processing.runalg("qgis:voronoipolygons", pointLayer, 1, None)
processing.runalg("grass:v.voronoi",pointLayer,False,False, bbox,-1,0.0001,0, None)

but neither of them seems to work well. The first (qgis) is extremely slow, taking 38 seconds with 180 points vs 2 seconds for the grass method. The qgis method also seems to ignore the output variable when it is specified ("C:/tmp/output.shp" in place of None), but the output layer does appear in the Layers pane so I can iterate through the layers and find it.

The second algorithm seems to ignore the output parameter (again, "C:/tmp/output.shp" in place of None), and no result seems to appear in the layer pane. Trying to use memory:name generated an error message. However, the following results in a temp file path being returned:

output = processing.runalg("grass:v.voronoi",PointLayer,False,False, bbox,-1,0.0001,0, None)
print output.output

My datasets will have thousands of points, so the qgis library is much too slow and the grass library requires a workaround to get the result out.

Is there a way to make qgis:voronoipolygons run faster?
Is there a syntax I am missing to get the result layer from the algorithm? It will be an intermediate result used for future calculations so memory storage is preferred.

Best Answer

Fairly old post but will post a possible answer which would allow you to run algorithms from a script outside QGIS. Algorithms should run faster as more memory would be available without having QGIS loaded. Note that this assumes you have installed QGIS via the OSGeo4W installer.


Follow the first couple of steps as described by @gcarrillo here: Problem with import qgis.core when writing a stand-alone PyQGIS script. I use the .bat file to make life easier.

Once the PATHS are set, type python into the command line and then copy/paste the following code (edit paths/parameters etc. to your requirements:

import os, sys, glob
from qgis.core import *
from qgis.gui import *
from PyQt4.QtGui import *

from os.path import expanduser
home = expanduser("~")

QgsApplication( [], False, home + "/AppData/Local/Temp" )

QgsApplication.setPrefixPath("C://OSGeo4W64//apps//qgis", True)
QgsApplication.initQgis()
app = QApplication([])

sys.path.append(home + '/.qgis2/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *

point_directory = home + "/Desktop/Test//"     # Change to path containing point shapefiles
output = "C:/tmp//"                            # Path to save outputs

os.chdir(point_directory)
for pointLayer in glob.glob("*.shp"):
        output_0=general.runalg("qgis:voronoipolygons", pointLayer, 1, output + pointLayer)
        # For follow-on algorithms, use output_0 as input
        # Can also replace this with grass algorithms

I have tested using follow-on algorithms and replaced certain outputs with None (if I don't want the output of a certain algorithm) and it works for me. Of course, this would differ from what you require but I hope it helps somewhat :)

Related Question