2

I've been trying to run QGIS procedures from python scripts via terminal on Ubuntu (ultimately I want to automate a process via cron). The first task I have tried to script is the "explode lines" function. In particular, I have input QGIS with a roads shapefile that I hope to split into smaller segments.

I've been following several stackexchange links to get to where I am, but can't seem to get the last step to work. In the following bit of code, I get through the statement print("6") in the print statements, but fail correctly use alg.processAlgorithm(process). There is no error provided and the code seemingly exits.

#!/usr/bin/env python
import sys
from qgis.core import *
import qgis.utils
from qgis.gui import *     # QgsMapCanvas
from PyQt4.QtGui import *
app = QApplication([])
QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()

# Prepare processing framework 
sys.path.append('/usr/share/qgis/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *
from processing.algs.Explode import *
from processing.core.SilentProgress import SilentProgress
progress = SilentProgress()

# Run the algorithm
print("1")
map = QgsMapCanvas()
print("2")
layerInput = QgsVectorLayer('/home/user/Downloads/input.shp', 'test', 'ogr')
print("3")
#map.setLayerSet([layerInput])
outLayer = '/home/user/out.shp'
print("4")
alg = Explode()
alg.setParameterValue('INPUT', layerInput)
print("5")
alg.setOutputValue('OUTPUT', outLayer)
print("6")
alg.processAlgorithm(progress)
print("7")
QgsApplication.exitQgis()
QApplication.exit()

Can anyone see what I've done incorrectly? I've been using the following link for help: How can I access `processing` with Python?

0

2 Answers 2

2

This error was occurring while using an old version of QGIS (2.0). Updating to version 2.8 (LTR) allows the above code to work as expected. In addition, in the newer version (2.8), the line:

from processing.algs.Explode import *

should be:

from processing.algs.qgis.Explode import *

and

from processing.core.SilentProgress import SilentProgress

should be

from processing.gui.SilentProgress import SilentProgress

This takes a shapefile of approximately 3000 lines and explodes these lines into approximately 300,000 smaller segments in just a few seconds.

Thanks to gene for suggesting the Fiona and Shapely packages. I'm new to Python, so I will look into how I can get these packages to do the same process.

1

To automate a process outside of QGIS why don't use pure Python geospatial modules instead of working with PyQGIS ? It is easier and faster if you want to work in the Python shell.

This task is very easy to do with Fiona and Shapely, for example.

Original polylines

enter image description here

from shapely.geometry import Point, LineString, mapping
import fiona
def pair(list):
    '''Iterate over pairs in a list '''
    for i in range(1, len(list)):
         yield list[i-1], list[i]

with fiona.open('original_lines.shp') as input:
    # get the crs, driver, and schema 
    meta = input.meta
    # explode lines
    with fiona.open('lines_splitted.shp', 'w',**meta) as output:
        for line in input:
        # use  pair function to extract the line segments
        for seg_start, seg_end in pair(line['geometry']['coordinates']):
            segment = LineString([Point(seg_start),Point(seg_end)])
            output.write({'geometry':mapping(segment),'properties':line['properties']})

Result

enter image description here

3
  • Thanks for giving me an example of how to use Shapely and Fiona. However, there is one main reason I was trying to use QGIS. After this step, I wanted to use the Saga algorithm add.grid.values.to.shapes to take values from a raster (geotiff) image and add them to the exploded line segments, and saving the result as an image (colored lines by the raster values on an Open Street Layer map). I've been successful with this in the QGIS gui, which is why I've been trying to script it. Is this sort of operation also easy/possible with Shapely and Fiona?
    – dms
    Mar 13, 2016 at 16:57
  • Yes, but a better solution is to use directly the original Saga command with the module subprocess as in the file /../plugins:processing:algs:saga:SagaUtils.py
    – gene
    Mar 13, 2016 at 20:49
  • gene, thanks for your suggestions. I'm not a Python expert just yet, so I will look into how I can get your method to do what I need. However, it looks like upgrading QGIS to version 2.8 (LTR) answered my question in terms of being able to use PyQGIS to do the task.
    – dms
    Mar 13, 2016 at 21:49

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.