不幸的是,repaintRequested() 信号没有触发刷新画布,所以我编写了一个小 Python 函数,您可以将其粘贴到 QGIS Python 控制台编辑器中,以从查询中生成物化视图并添加到 mapcanvas 作为动态图层添加用于根据需要刷新和重新加载视图的图例菜单操作
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 ()