1) With PyQt4.QtSql: Gary Sherman shows how to query a spatial table in Creating a PostgreSQL Connection From a QGIS Layer Datasource:
from PyQt4.QtSql import *
layer = iface.activeLayer()
uri = QgsDataSourceURI()
uri.setConnection("localhost", "5432", "testpostgis", "me", "")
uri.setDataSource("public", "teststrati", "the_geom")
# add the layer to the canvas
vlayer = QgsVectorLayer(uri.uri(), "tot", "postgres")
# now query the table
db = QSqlDatabase.addDatabase("QPSQL");
db.setHostName(uri.host())
db.setDatabaseName(uri.database())
db.setPort(int(uri.port()))
db.setUserName(uri.username())
db.setPassword(uri.password())
db.open()
# query the table
query = db.exec_("""select * from teststrati""")
query.next()
query.value(0)
130
# etc read the documentation of QtSQL
And you can open all the other tables/views (spatial or non spatial) similarly:
db = QSqlDatabase.addDatabase("QPSQL")
db.setHostName("localhost")
db.setPort(5432)
# non spatial table or view
db.setDatabaseName("people")
db.setUserName("me")
db.setPassword("")
query = QSqlQuery(db)
query.exec_("select * from people;")
# etc.
2) Or you can use the standard Python module for PostgreSQL/PostGIS: Psycopg2:
import psycopg2
conn = psycopg2.connect("dbname='testpostgis'host='localhost' user='me'")
cur = conn.cursor()
sql = """SELECT "DIP_DIR","DIP", ST_AsGeoJSON(the_geom) from teststrati;"""
cur.execute(sql)
result = cur.fetchone()
print result
(130, 30, u'{"type":"Point","coordinates":[272070.600040999997873,155389.387920000008307]}')
With a non spatial table or view and the result as a dictionary:
conn = psycopg2.connect("dbname='testpostgis'host='localhost' user='me'")
dict_cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
dict_cur.execute("""SELECT * from people;""")
rec = dict_cur.fetchone()
rec.keys()
['name', 'id']
rec.values()
('Jon Doe',1)
# etc read the documentation of the module
The documentation on pyqgis is not very self-explanatory, but i figured out how to properly call the associated interpolation classes (QgsInterpolator
, QgsTINInterpolator
, QgsIDWInterpolator
, QgsGridFileWriter
) from python. I am going to describe every step of the script in great detail:
Step 1:
Import the core and analysis module and get the desired vector layer for interpolation by selecting it with a mouseclick in the layer tab.
import qgis.core
import qgis.analysis
layer = qgis.utils.iface.activeLayer()
Step 2:
Prepare the interpolation classes with the necessary Parameters. The exact parameters for initialization of the LayerData struct can be found in the QGIS API docs (searchterm: QgsInterpolator).
layer_data = QgsInterpolator.LayerData()
layer_data.vectorLayer = layer
layer_data.zCoordInterpolation=False
layer_data.interpolationAttribute =0
layer_data.mInputType = 1
Please notice that I don't use the z Coordinate, I get the first available field (index = 0) as interpolation attribute, and use POINTS as input type.
Step 3:
Choose your interpolation engine. Here you can choose between the TIN-Interpolation method (QgsTINInterpolator
) and IDW-Interpolation (QgsIDWInterpolator
). I took the QgsTINInterpolator
in my code.
tin_interpolator = QgsTINInterpolator([layer_data])
Keep in mind that you have to pass a python list of layer_data
to the interpolation engine! This also allows you to add multiple layer_data scenarios.
Step 4:
Setup the parameters that are needed for the export of the interpolation-output (see documentation of QgsGridFileWriter
). Those include similar information as the interpolation gui (filepath, extent, resolution, number of colums and rows).
export_path ="C:/SomeFolder/output.asc"
rect = layer.extent()
res = 10
ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
output = QgsGridFileWriter(tin_interpolator,export_path,rect,ncol, nrows,res,res)
output.writeFile(True)
iface.addRasterLayer(export_path, "interpolation_output")
Be aware of the file extension of your output-raster as QgsGridFileWriter
only writes ASCII-grids (.asc
). The data gets written to disk by calling the writeFile()
method. After export you can add the grid-file as raster to the canvas.
Full script for reference:
import qgis.analysis
import qgis.core
layer = qgis.utils.iface.activeLayer()
layer_data = QgsInterpolator.LayerData()
layer_data.vectorLayer = layer
layer_data.zCoordInterpolation=False
layer_data.interpolationAttribute =0
layer_data.mInputType = 1
tin_interpolator = QgsTINInterpolator([layer_data])
export_path = "E:/GIS_Workbench/script_output/test.asc"
rect = layer.extent()
res = 10
ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
output = QgsGridFileWriter(tin_interpolator,export_path,rect,ncol,nrows,res,res)
output.writeFile(True)
Keep in mind that the QGIS-API is currently rewritten to version 3.0 and the used interpolation-classes are moved from qgis.analysis
to qgis.core
! This will have a huge impact on the functionality of this script so that it must be rewritten for version 3.0!
Best Answer
I can't test properly right now, but I believe you set the legend labels like so: