Monthly Archives: March 2014

pyQGIS convert polygons to lines

This example uses one of the many many algorithms from the powerful processing toolbox.

import processing
import os
polygon_input_file="temp.shp"
line_output_file=os.path.splitext(os.path.basename(polygon_input_file))[0]+"_line.shp"
vlayer = QgsVectorLayer(polygon_input_file, "temp", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
qgis.utils.iface.setActiveLayer(vlayer)
vlayer.selectAll()
processing.runalg("qgis:polygonstolines",vlayer,line_output_file)
QgsMapLayerRegistry.instance().removeMapLayer(vlayer.id())

pyQGIS processing algorithms

A good link for adding the power of the QGIS processing algorithms to a python QGIS script can be found athttp://docs.qgis.org/2.2/en/docs/user_manual/processing/console.html?highlight=processing

Also, see my “pyQGIS convert polygons to lines” post for an example of this.

Note: The linked page also contains good instructions for converting your script into an algorithm which you can then call from other scripts. Just like a real programmer!

pyQGIS use non-spatial data in a spatialite database

Just incase you want to build and use non spatial database tables from inside python you can use the following commands.
You can also do as you would to add spatial columns too but I needed code to be able spcifically to get at non spatial tables/data
from pyspatialite import dbapi2 as db
spatialitedb='LINZ.sqlite'
conn = db.connect(spatialitedb)
cur = conn.cursor()
cur.execute('DROP TABLE IF EXISTS LINZ_mapsets')
cur.execute('CREATE TABLE LINZ_mapsets (id integer, Name integer, EPSG integer, Title text)')
cur.execute("INSERT INTO LINZ_mapsets VALUES (1,1197,5479,'NZ Ross Dependency')")
cur.execute("INSERT INTO LINZ_mapsets VALUES (2,89,3793,'NZ Chatham Is')")
conn.commit()
rs = cur.execute('SELECT * from LINZ_mapsets')
for row in rs:
print row

My first QGIS python script

When I searched the internet for the title of this post all I found were links to plugin tutorials… Not exactly what you need when you want to get started with python SCRIPTING in QGIS.

Here’s how to start.

First install QGIS version 2.0 or higher.

Open the python console by clicking “plugins/python console”

When the console launches it adds the QGIS core modules straight off the bat making those functions immediately available to the console. You can start importing shape files or creating layers directly in the console command line right now. Try copying the following at the console >>> prompt

bbox_min_lon=0
bbox_min_lat=0
bbox_max_lon=10
bbox_max_lat=10
bboxlayer=QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer&field=name:string(20)&index=yes","bbox_polygon","memory")
bbl_dp = bboxlayer.dataProvider()
bboxlayer.startEditing()
bbox_feature = QgsFeature()
bbox_feature.setGeometry(QgsGeometry.fromPolygon( [ [ \
QgsPoint(bbox_min_lon,bbox_min_lat),\
QgsPoint(bbox_min_lon,bbox_max_lat), \
QgsPoint(bbox_max_lon,bbox_max_lat),
QgsPoint(bbox_max_lon,bbox_min_lat) ] ] ))
(res, outFeats) = bboxlayer.dataProvider().addFeatures([bbox_feature])
bboxlayer.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(bboxlayer)

yay you made a simple polygon in WGS84 from scratch

Now if you want to put code in a script you can open the script editor from the python console. Its the button that looks like a pencil and paper.

Now you can paste the example code directly in here then hit the blue triangle to run it.

Look you made anothe layer with a single polygon in it hooray.

Now that you’re started you need to head over to http://docs.qgis.org/2.2/en/docs/pyqgis_developer_cookbook/index.html

It’s great. Feel free to come back here to copy and paste from my examples.

pyQGIS fetch WFS manually

Sometimes I only want to fetch a small amount of data from WFS. While this is easily possible from the direct WFS interface in QGIS its more difficult from a python script:
In this example I set a bbox and download the WFS xml file directly from python. The resulting xml file file can be loaded directly as an "OGR" layer
bbox_min_lon=0
bbox_max_lon=10
bbox_min_lat=0
bbox_max_lat=10
xmlconnect=urllib.urlopen('http://wfs.geoserver.com/wfs?service=WFS&version=1.1.0&request=GetFeature&typename=FEATURENAME&filter=<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><ogc:BBOX><ogc:PropertyName>GEOMETRY</ogc:PropertyName><gml:Envelope><gml:lowerCorner>'+str(bbox_min_lat)+' '+str(bbox_min_lon)+'</gml:lowerCorner><gml:upperCorner>'+str(bbox_max_lat)+' '+str(bbox_max_lon)+'</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter>')
xmlbuffer = xmlconnect.read()
xmlconnect.close()
print "saving temporary xml file"
f = open('geoserver-GetFeature.xml', 'w')
f.write(xmlbuffer)
f.close()

pyQGIS supress CRS dialog

As per:
http://pyqgis.blogspot.co.nz/2012/10/basics-automatic-use-of-crs-for-new.html
from PyQt4.QtCore import QSettings
s = QSettings()
oldValidation = s.value( "/Projections/defaultBehaviour")
s.setValue( "/Projections/defaultBehaviour", "useGlobal" )
vlayer = QgsVectorLayer("importfilename.shp", "layer name", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
vlayer.setCrs( QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) )
s.setValue( "/Projections/defaultBehaviour", oldValidation )

Or to force dialog back again:

from PyQt4.QtCore import QSettings
s=QSettings()
s.setValue( "/Projections/defaultBehaviour", "prompt" )