Using QGIS, how to properly link a postgis sql layer?

╄→гoц情女王★ 提交于 2019-12-06 07:12:38

Unfortunately the repaintRequested() signal is not triggered refreshing the canvas so I write a little python function that you can paste in QGIS python console editor to generate a materialized view from a query and add to mapcanvas as layer on the fly adding an action to legend menu for refreshing and reloading the view on demand

from qgis.core import QgsVectorLayer, QgsDataSourceURI, QgsMapLayerRegistry
from PyQt4.QtSql import QSqlDatabase
from PyQt4.QtGui import QAction

PSQLHost = "your_db_host"
PSQLPort = 5432
PSQLDatabase = "your_db"
PSQLUsername = "your_db_user"
PSQLPassword = "your_db_password"

LAYERNAME = "my materialized_view_layer"
QUERY = "select * from your_table"

class materialized_layer:

    def __init__(self):
        #setup connection
        geom_field = "geom"
        pkey_field = "id"
        self.db = QSqlDatabase.addDatabase("QPSQL")
        self.db.setHostName(PSQLHost)
        self.db.setPort(PSQLPort)
        self.db.setDatabaseName(PSQLDatabase)
        self.db.setUserName(PSQLUsername)
        self.db.setPassword(PSQLPassword)
        self.db.open()
        # generate materialized view
        create_query = 'CREATE MATERIALIZED VIEW "%s" AS %s' % (LAYERNAME,QUERY)
        self.db.exec_(create_query)
        # add to canvas
        qgis_uri = QgsDataSourceURI()
        qgis_uri.setConnection(PSQLHost,str(PSQLPort),PSQLDatabase,PSQLUsername,PSQLPassword)
        qgis_uri.setDataSource("",LAYERNAME,geom_field,"",pkey_field)
        self.materialized_layer = QgsVectorLayer(qgis_uri.uri(), LAYERNAME, "postgres")
        if self.materialized_layer.isValid():
            #register new qgis layer and add action to layer contextual menu
            QgsMapLayerRegistry.instance().addMapLayer(self.materialized_layer,True)
            refresh_materialized_action = QAction( "Refresh materialized view and reload", iface.legendInterface() )
            iface.legendInterface().addLegendLayerAction(refresh_materialized_action, "","", QgsMapLayer.VectorLayer,False)
            iface.legendInterface().addLegendLayerActionForLayer(refresh_materialized_action, self.materialized_layer)
            refresh_materialized_action.triggered.connect(self.refresh_layer)
        else:
            print "invalid layer"

    def reload_layer(self):
        print "RELOADING MATERIALIZED VIEW"
        self.materialized_layer.reload()

    def refresh_layer(self):
        print "REFRESHING MATERIALIZED VIEW"
        refresh_query = 'REFRESH MATERIALIZED VIEW "%s"' % LAYERNAME
        self.db.exec_(refresh_query)
        self.reload_layer()

l = materialized_layer ()

I wrote a plugin called postgisQueryBuilder that helps in db view creation, even with materialized, directive and allows, browsing the db connection available layers, to refresh the materialized views from QGIS. Check if you can be helpful.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!