Exemplo n.º 1
0
    def create(self, qgis_project: QgsProject, group=None):
        if not group:
            group = qgis_project.layerTreeRoot()

        existing_layer_source_uris = [
            found_layer.layer().dataProvider().dataSourceUri()
            for found_layer in qgis_project.layerTreeRoot().findLayers()
        ]

        static_index = 0
        for item in self.items:
            if isinstance(item, LegendGroup):
                subgroup = group.findGroup(item.name)
                if subgroup is None:
                    subgroup = group.addGroup(item.name)
                item.create(qgis_project, subgroup)
                subgroup.setExpanded(item.expanded)
                subgroup.setItemVisibilityChecked(item.checked)
                subgroup.setIsMutuallyExclusive(item.mutually_exclusive,
                                                item.mutually_exclusive_child)
            else:
                layer = item.layer
                if (layer.dataProvider().dataSourceUri()
                        not in existing_layer_source_uris):
                    if self.static_sorting:
                        index = static_index
                    elif layer.isSpatial():
                        index = get_suggested_index_for_layer(
                            layer, group, self.ignore_node_names)
                    else:
                        index = 0
                    layernode = QgsLayerTreeLayer(layer)
                    layernode.setExpanded(item.expanded)
                    layernode.setItemVisibilityChecked(item.checked)
                    layernode.setCustomProperty("showFeatureCount",
                                                item.featurecount)
                    group.insertChildNode(index, layernode)
            static_index += 1
Exemplo n.º 2
0
    def processLoading(self):
        '''
        Load all the layers in QGIS
        and apply corresponding style
        '''
        self.startTime = datetime.now()
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # default style to apply for Cadastre layers
        self.themeDir = str(self.dialog.liTheme.currentText())
        if not os.path.exists(
                os.path.join(self.qc.plugin_dir, "styles/%s" % self.themeDir)):
            self.themeDir = self.defaultThemeDir

        # set Cadastre SVG path if not set
        cadastreSvgPath = os.path.join(self.qc.plugin_dir,
                                       "styles/%s/svg" % self.themeDir)
        s = QSettings()
        qgisSvgPaths = s.value("svg/searchPathsForSVG", 10, type=str)
        a = list(qgisSvgPaths)
        if cadastreSvgPath not in a:
            a.append(cadastreSvgPath)
            s.setValue("svg/searchPathsForSVG", a)
            self.qc.updateLog(
                u"* Le chemin contenant les SVG du plugin Cadastre a été ajouté dans les options de QGIS"
            )

        # Get selected options
        providerName = self.dialog.dbpluginclass.providerName()
        qgisCadastreLayers = []
        self.dialog.schema = str(self.dialog.liDbSchema.currentText())
        self.dialog.totalSteps = len(self.qgisCadastreLayerList)

        # Run the loading
        self.updateTimer()
        self.qc.updateLog(u'Chargement des tables :')

        # Get database list of tables
        if self.dialog.dbType == 'postgis':
            schemaSearch = [
                s for s in self.dialog.db.schemas()
                if s.name == self.dialog.schema
            ]
            schemaInst = schemaSearch[0]
            dbTables = self.dialog.db.tables(schemaInst)
        if self.dialog.dbType == 'spatialite':
            dbTables = self.dialog.db.tables()

        # Get commune filter by expression
        communeExpression = self.dialog.communeFilter.text().strip()
        communeFilter = None
        cExp = QgsExpression(communeExpression)
        if communeExpression != '' and not cExp.hasParserError():
            self.qc.updateLog(u'Filtrage à partir des communes : %s' %
                              communeExpression)
            cReq = QgsFeatureRequest(cExp)
            cTableList = [a for a in dbTables if a.name == 'geo_commune']
            cTable = cTableList[0]
            cUniqueCol = 'ogc_fid'
            cSchema = self.dialog.schema
            cGeomCol = 'geom'
            cLayerUri = self.dialog.db.uri()
            cLayerUri.setDataSource(cSchema, cTable.name, cGeomCol, '',
                                    cUniqueCol)
            clayer = QgsVectorLayer(cLayerUri.uri(), 'com', providerName)
            cfeatures = clayer.getFeatures(cReq)
            cids = [a['commune'] for a in cfeatures]
            if len(cids):
                communeFilter = cids
        else:
            self.qc.updateLog(
                u'Filtrage à partir des communes, expression invalide : %s' %
                cExp.parserErrorString())

        # Loop throuhg qgisQastreLayerList and load each corresponding table
        for item in self.qgisCadastreLayerList:

            if item['label'] not in self.mainLayers and self.dialog.cbMainLayersOnly.isChecked(
            ):
                continue

            if 'dbType' in item and item['dbType'] != self.dialog.dbType:
                continue

            # update progress bar
            self.qc.updateLog(u'* %s' % item['label'])
            self.dialog.step += 1
            self.qc.updateProgressBar()

            # Tables - Get db_manager table instance
            tableList = [a for a in dbTables if a.name == item['table']]
            if len(tableList) == 0 and 'isView' not in item:
                self.qc.updateLog(u'  - Aucune table trouvée pour %s' %
                                  item['label'])
                continue

            if tableList:
                table = tableList[0]
                source = table.name
                try:
                    uniqueField = table.getValidQGisUniqueFields(True)
                    uniqueCol = uniqueField.name
                except:
                    uniqueCol = 'ogc_fid'

            schema = self.dialog.schema

            # View
            if 'isView' in item:
                if self.dialog.dbType == 'spatialite':
                    schemaReplace = ''
                else:
                    schemaReplace = '"%s".' % self.dialog.schema
                source = item['table'].replace('schema.', schemaReplace)
                uniqueCol = item['key']
                schema = None

            sql = item['sql']
            geomCol = item['geom']

            if communeFilter:
                communeFilterText = "'" + "', '".join(communeFilter) + "'"
                nschema = ''
                if self.dialog.dbType == 'postgis':
                    nschema = '"%s".' % schema
                if 'subset' in item:
                    subset = item['subset']
                    sql += subset % communeFilterText
                else:
                    itemcol = item['table']
                    if item['table'] == 'geo_label':
                        itemcol = 'ogc_fid'
                    subset = itemcol + '''
                         IN (

                            SELECT b.''' + itemcol + '''
                            FROM  ''' + nschema + item['table'] + ''' b
                            JOIN  ''' + nschema + '''geo_commune c
                            ON ST_Within(b.geom, c.geom)
                            WHERE 2>1
                            AND c.geo_commune IN ( %s )

                        )
                    '''
                    if sql:
                        sql += ' AND '
                    sql += subset % communeFilterText

            # Create vector layer
            alayerUri = self.dialog.db.uri()
            alayerUri.setDataSource(schema, source, geomCol, sql, uniqueCol)

            vlayer = QgsVectorLayer(alayerUri.uri(), item['label'],
                                    providerName)

            # apply style
            qmlPath = os.path.join(
                self.qc.plugin_dir,
                "styles/%s/%s.qml" % (self.themeDir, item['name']))
            if os.path.exists(qmlPath):
                vlayer.loadNamedStyle(qmlPath)

            # append vector layer to the list
            qgisCadastreLayers.append(vlayer)

        self.updateTimer()

        # Get canvas and disable rendering
        from qgis.utils import iface
        canvas = iface.mapCanvas()
        canvas.freeze(True)

        # Add all layers to QGIS registry (but not yet to the layer tree)
        self.qc.updateLog(u'Ajout des couches dans le registre de QGIS')
        QgsProject.instance().addMapLayers(qgisCadastreLayers, False)
        self.updateTimer()

        # Create a group "Cadastre" and move all layers into it
        self.qc.updateLog(u'Ajout des couches dans le groupe Cadastre')
        root = QgsProject.instance().layerTreeRoot()
        g1 = root.findGroup(u"Cadastre")
        if g1:
            gf = root.findGroup(u"Fond")
            if not gf:
                gf = g1.addGroup("Fond")

            ge = root.findGroup(u'Étiquettes cadastre')
            if not ge:
                ge = gf.addGroup(u'Étiquettes cadastre')

            gd = root.findGroup(u"Données cadastre")
            if not gd:
                gd = gf.addGroup(u"Données cadastre")
        else:
            g1 = root.insertGroup(0, "Cadastre")
            gf = g1.addGroup("Fond")
            ge = gf.addGroup(u'Étiquettes cadastre')
            gd = gf.addGroup(u'Données cadastre')

        variables = QgsProject.instance().customVariables()
        for layer in qgisCadastreLayers:
            #~ layer.updateExtents()
            # Get layertree item
            nodeLayer = QgsLayerTreeLayer(layer)

            # Get layer options
            qlayer = [
                a for a in self.qgisCadastreLayerList
                if a['label'] == layer.name()
            ]
            if qlayer:
                qlayer = qlayer[0]

                # Move layer to proper group
                if qlayer['group'] == 'E':
                    ge.insertChildNode(0, nodeLayer)
                elif qlayer['group'] == 'D':
                    gd.insertChildNode(0, nodeLayer)
                else:
                    g1.insertChildNode(0, nodeLayer)

                # Enable/Disable layer
                if not qlayer['active']:
                    nodeLayer.setItemVisibilityChecked(Qt.Unchecked)
            else:
                # Move layer to Cadastre group
                g1.insertChildNode(-1, nodeLayer)

            # Do not expand layer legend
            nodeLayer.setExpanded(False)

            # set varaibles
            if layer.name() in self.variableLayers:
                varlayer = self.variableLayers[layer.name()]
                variables['cadastre_' + varlayer['var_key'] +
                          '_layer_id'] = layer.id()
                variables['cadastre_' + varlayer['var_key'] +
                          '_unique_field'] = varlayer['unique_field']

        QgsProject.instance().setCustomVariables(variables)

        self.updateTimer()

        # Zoom to full extent
        self.qc.updateLog(u'Zoom sur les couches')
        canvas.zoomToFullExtent()
        canvas.freeze(False)
        canvas.refresh()
        self.updateTimer()

        # progress bar
        self.dialog.step += 1
        self.qc.updateProgressBar()

        # Emit signal
        self.qc.updateLog(u'Mise à jour des outils cadastre')
        self.cadastreLoadingFinished.emit()
        self.updateTimer()

        # Final message
        QApplication.restoreOverrideCursor()
        QMessageBox.information(
            self.dialog, u"Cadastre",
            u"Les données ont bien été chargées dans QGIS")
        self.dialog.pbProcess.setValue(0)

        QApplication.restoreOverrideCursor()
    def processLoading(self):
        '''
        Load all the layers in QGIS
        and apply corresponding style
        '''
        self.startTime = datetime.now()
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # default style to apply for Cadastre layers
        self.themeDir = str(self.dialog.liTheme.currentText())
        if not os.path.exists(os.path.join(
            self.qc.plugin_dir,
            "styles/%s" % self.themeDir
        )):
            self.themeDir = self.defaultThemeDir

        # set Cadastre SVG path if not set
        cadastreSvgPath = os.path.join(
            self.qc.plugin_dir,
            "styles/%s/svg" % self.themeDir
        )
        s = QSettings()
        qgisSvgPaths = s.value("svg/searchPathsForSVG", 10, type=str)
        a = list(qgisSvgPaths)
        if cadastreSvgPath not in a:
            a.append(cadastreSvgPath)
            s.setValue("svg/searchPathsForSVG", a)
            self.qc.updateLog(u"* Le chemin contenant les SVG du plugin Cadastre a été ajouté dans les options de QGIS")

        # Get selected options
        providerName = self.dialog.dbpluginclass.providerName()
        qgisCadastreLayers = []
        self.dialog.schema = str(self.dialog.liDbSchema.currentText())
        self.dialog.totalSteps = len(self.qgisCadastreLayerList)

        # Run the loading
        self.updateTimer()
        self.qc.updateLog(u'Chargement des tables :')

        # Get database list of tables
        if self.dialog.dbType == 'postgis':
            schemaSearch = [s for s in self.dialog.db.schemas() if s.name == self.dialog.schema]
            schemaInst = schemaSearch[0]
            dbTables = self.dialog.db.tables(schemaInst)
        if self.dialog.dbType == 'spatialite':
            dbTables = self.dialog.db.tables()

        # Get commune filter by expression
        communeExpression = self.dialog.communeFilter.text().strip()
        communeFilter = None
        cExp = QgsExpression(communeExpression)
        if communeExpression != '' and not cExp.hasParserError():
            self.qc.updateLog(u'Filtrage à partir des communes : %s' % communeExpression)
            cReq = QgsFeatureRequest(cExp)
            cTableList = [a for a in dbTables if a.name == 'geo_commune']
            cTable = cTableList[0]
            cUniqueCol = 'ogc_fid'
            cSchema = self.dialog.schema
            cGeomCol = 'geom'
            cLayerUri = self.dialog.db.uri()
            cLayerUri.setDataSource(
                cSchema,
                cTable.name,
                cGeomCol,
                '',
                cUniqueCol
            )
            clayer = QgsVectorLayer(cLayerUri.uri(), 'com', providerName)
            cfeatures = clayer.getFeatures( cReq )
            cids = [a['commune'] for a in cfeatures]
            if len(cids):
                communeFilter = cids
        else:
            self.qc.updateLog(u'Filtrage à partir des communes, expression invalide : %s' % cExp.parserErrorString())


        # Loop throuhg qgisQastreLayerList and load each corresponding table
        for item in self.qgisCadastreLayerList:

            if item['label'] not in self.mainLayers and self.dialog.cbMainLayersOnly.isChecked():
                continue

            if 'dbType' in item and item['dbType'] != self.dialog.dbType:
                continue

            # update progress bar
            self.qc.updateLog(u'* %s' % item['label'])
            self.dialog.step+=1
            self.qc.updateProgressBar()

            # Tables - Get db_manager table instance
            tableList = [a for a in dbTables if a.name == item['table']]
            if len(tableList) == 0 and 'isView' not in item:
                self.qc.updateLog(u'  - Aucune table trouvée pour %s' % item['label'])
                continue

            if tableList:
                table = tableList[0]
                source = table.name
                try:
                    uniqueField = table.getValidQGisUniqueFields(True)
                    uniqueCol = uniqueField.name
                except:
                    uniqueCol = 'ogc_fid'

            schema = self.dialog.schema

            # View
            if 'isView' in item:
                if self.dialog.dbType == 'spatialite':
                    schemaReplace = ''
                else:
                    schemaReplace = '"%s".' % self.dialog.schema
                source = item['table'].replace('schema.', schemaReplace)
                uniqueCol = item['key']
                schema = None

            sql = item['sql']
            geomCol = item['geom']

            if communeFilter:
                communeFilterText = "'" + "', '".join(communeFilter) + "'"
                nschema = ''
                if self.dialog.dbType == 'postgis':
                    nschema = '"%s".' % schema
                if 'subset' in item:
                    subset = item['subset']
                    sql+= subset % communeFilterText
                else:
                    itemcol = item['table']
                    if item['table'] == 'geo_label':
                        itemcol = 'ogc_fid'
                    subset = itemcol + '''
                         IN (

                            SELECT b.''' + itemcol + '''
                            FROM  ''' + nschema + item['table'] + ''' b
                            JOIN  ''' + nschema + '''geo_commune c
                            ON ST_Within(b.geom, c.geom)
                            WHERE 2>1
                            AND c.geo_commune IN ( %s )

                        )
                    '''
                    if sql:
                        sql+= ' AND '
                    sql+= subset % communeFilterText


            # Create vector layer
            alayerUri = self.dialog.db.uri()
            alayerUri.setDataSource(
                schema,
                source,
                geomCol,
                sql,
                uniqueCol
            )

            vlayer = QgsVectorLayer(alayerUri.uri(), item['label'], providerName)

            # apply style
            qmlPath = os.path.join(
                self.qc.plugin_dir,
                "styles/%s/%s.qml" % (self.themeDir, item['name'])
            )
            if os.path.exists(qmlPath):
                vlayer.loadNamedStyle(qmlPath)

            # append vector layer to the list
            qgisCadastreLayers.append(vlayer)

        self.updateTimer()

        # Get canvas and disable rendering
        from qgis.utils import iface
        canvas = iface.mapCanvas()
        canvas.freeze(True)

        # Add all layers to QGIS registry (but not yet to the layer tree)
        self.qc.updateLog(u'Ajout des couches dans le registre de QGIS')
        QgsProject.instance().addMapLayers(qgisCadastreLayers, False)
        self.updateTimer()

        # Create a group "Cadastre" and move all layers into it
        self.qc.updateLog(u'Ajout des couches dans le groupe Cadastre')
        root = QgsProject.instance().layerTreeRoot()
        g1 = root.findGroup(u"Cadastre")
        if g1:
            gf = root.findGroup(u"Fond")
            if not gf:
                gf = g1.addGroup("Fond")

            ge = root.findGroup(u'Étiquettes cadastre')
            if not ge:
                ge = gf.addGroup(u'Étiquettes cadastre')

            gd = root.findGroup(u"Données cadastre")
            if not gd:
                gd = gf.addGroup(u"Données cadastre")
        else:
            g1 = root.insertGroup(0, "Cadastre")
            gf = g1.addGroup("Fond")
            ge = gf.addGroup(u'Étiquettes cadastre')
            gd = gf.addGroup(u'Données cadastre')

        variables = QgsProject.instance().customVariables()
        for layer in qgisCadastreLayers:
            #~ layer.updateExtents()
            # Get layertree item
            nodeLayer = QgsLayerTreeLayer(layer)

            # Get layer options
            qlayer = [ a for a in self.qgisCadastreLayerList if a['label'] == layer.name() ]
            if qlayer:
                qlayer = qlayer[0]

                # Move layer to proper group
                if qlayer['group'] == 'E':
                    ge.insertChildNode(0, nodeLayer)
                elif qlayer['group'] == 'D':
                    gd.insertChildNode(0, nodeLayer)
                else:
                    g1.insertChildNode(0, nodeLayer)

                # Enable/Disable layer
                if not qlayer['active']:
                    nodeLayer.setItemVisibilityChecked(Qt.Unchecked)
            else:
                # Move layer to Cadastre group
                g1.insertChildNode(-1, nodeLayer)

            # Do not expand layer legend
            nodeLayer.setExpanded(False)

            # set varaibles
            if layer.name() in self.variableLayers:
                varlayer = self.variableLayers[layer.name()]
                variables['cadastre_'+varlayer['var_key']+'_layer_id'] = layer.id()
                variables['cadastre_'+varlayer['var_key']+'_unique_col'] = varlayer['unique_col']

        QgsProject.instance().setCustomVariables(variables)

        self.updateTimer()


        # Zoom to full extent
        self.qc.updateLog(u'Zoom sur les couches')
        canvas.zoomToFullExtent()
        canvas.freeze(False)
        canvas.refresh()
        self.updateTimer()

        # progress bar
        self.dialog.step+=1
        self.qc.updateProgressBar()

        # Emit signal
        self.qc.updateLog(u'Mise à jour des outils cadastre')
        self.cadastreLoadingFinished.emit()
        self.updateTimer()

        # Final message
        QApplication.restoreOverrideCursor()
        QMessageBox.information(
            self.dialog,
            u"Cadastre",
            u"Les données ont bien été chargées dans QGIS"
        )
        self.dialog.pbProcess.setValue(0)


        QApplication.restoreOverrideCursor()