|
""" |
|
view_related.py - an attribute action for QGIS to view related records to the identified feature |
|
To add the action to the selected vector layer easily, run this script with Script Runner Plugin |
|
""" |
|
#===== |
|
from PyQt4.QtCore import * |
|
from PyQt4.QtGui import * |
|
from qgis.core import * |
|
from qgis.gui import * |
|
|
|
def write_table(layer, featureIds): |
|
html = QStringList() |
|
html << QString("<div style='font-size:x-large;font-weight:bold'>%1</div>").arg(layer.name()) |
|
html << "<table border cellspacing=0 cellpadding=2>" |
|
|
|
fieldnames = layer.dataProvider().fieldNameMap().keys() |
|
html << QString("<tr style='background-color:lightgray;'><td>%1</td></tr>").arg(QStringList(fieldnames).join("</td><td>")) |
|
|
|
f = QgsFeature() |
|
for fid in featureIds: |
|
if layer.featureAtId(fid, f, False): |
|
vals = QStringList() |
|
attrs = f.attributeMap() |
|
for i in layer.dataProvider().fields().keys(): |
|
vals << attrs[i].toString() |
|
html << QString("<tr><td>%1</td></tr>").arg(vals.join("</td><td>")) |
|
html << "</table><br>" |
|
if len(featureIds) > 1: |
|
html << QString("%1 records<br>").arg(len(featureIds)) |
|
return html |
|
|
|
def view_related(layer, fid): |
|
fOrigin = QgsFeature() |
|
if not layer.featureAtId(fid, fOrigin, False): |
|
return |
|
html = QStringList() |
|
html << write_table(layer, [fid]) |
|
for j in layer.vectorJoins(): |
|
joinLayer = QgsMapLayerRegistry.instance().mapLayer(j.joinLayerId) |
|
joinFieldName = joinLayer.dataProvider().fields()[j.joinField].name() |
|
joinValue = fOrigin.attributeMap()[j.targetField] |
|
|
|
subsetString = joinLayer.dataProvider().subsetString() |
|
bkSubsetString = QString(subsetString) |
|
if not subsetString.isEmpty(): |
|
subsetString.append(" AND ") |
|
subsetString.append(QString('"%1" = "%2"').arg(joinFieldName).arg(joinValue.toString())) |
|
joinLayer.dataProvider().setSubsetString(subsetString) |
|
joinLayer.select([j.joinField]) |
|
|
|
f = QgsFeature() |
|
featureIds = [] |
|
while joinLayer.nextFeature(f): |
|
featureIds.append(f.id()) |
|
joinLayer.dataProvider().setSubsetString(bkSubsetString) |
|
html << write_table(joinLayer, featureIds) |
|
|
|
message = QgsMessageOutput.createMessageOutput() |
|
message.setTitle(QString("Related records - %1 (fid: %2)").arg(layer.name()).arg(fid)) |
|
message.setMessage(html.join(""), QgsMessageOutput.MessageHtml) |
|
message.showMessage() |
|
|
|
if "[% $id %]".isdigit(): |
|
view_related(qgis.utils.iface.activeLayer(), int("[% $id %]")) |
|
#===== |
|
def run_script(iface): |
|
layer = iface.activeLayer() |
|
if layer is None or layer.type() != QgsMapLayer.VectorLayer: |
|
QMessageBox.information(None, QFileInfo(__file__).fileName(), "Select a vector layer") |
|
return |
|
f = open(QString(__file__).replace(QRegExp("c$"), "")) |
|
script = f.read().split("#=====")[1].strip() |
|
f.close() |
|
layer.actions().addAction(QgsAction.GenericPython, "View related records", script) |
|
QMessageBox.information(None, QFileInfo(__file__).fileName(), |
|
QString("Added an action to layer '%1'").arg(layer.name())) |