使用QGIS,如何正确链接postgis sql图层?

时间:2016-12-16 01:54:14

标签: postgis qgis

在QGIS 2.18中使用数据管理器没有问题,但如果我尝试根据长时间运行的查询(1分钟+)添加图层,QGIS将完全无法使用。看起来每个地图平移,每次鼠标点击等都会触发某种层刷新。

这对于一个人来说似乎很愚蠢,特别是考虑到您可以右键单击图层并请求刷新。更重要的是,它使应用程序无法使用。我在这做错了什么?是否无法创建图层并仅在请求时更新它?

显然我可以在postgres中为所有空间查询创建物化视图,但这似乎打败了能够在QGIS中完成它的点

2 个答案:

答案 0 :(得分:1)

不幸的是,没有触发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 ()

enter image description here

答案 1 :(得分:0)

我编写了一个名为postgisQueryBuilder 的插件,它有助于db视图的创建,即使是物化,指令和允许浏览数据库连接可用层,也可以刷新QGIS中的物化视图。 Check if you can be helpful