示例#1
0
class QvFormNovaMapificacio(QvFormBaseMapificacio):
    def __init__(self, llegenda, amplada=500, mapificacio=None, simple=True):
        super().__init__(llegenda, amplada)

        self.fCSV = mapificacio
        self.simple = simple
        self.taulaMostra = None

        self.setWindowTitle('Afegir capa amb mapa simbòlic')

        self.layout = QVBoxLayout()
        self.layout.setSpacing(14)
        self.setLayout(self.layout)

        if self.fCSV is None:
            self.arxiu = QgsFileWidget()
            self.arxiu.setStorageMode(QgsFileWidget.GetFile)
            self.arxiu.setDialogTitle('Selecciona fitxer de dades…')
            self.arxiu.setDefaultRoot(RUTA_LOCAL)
            self.arxiu.setFilter('Arxius CSV (*.csv)')
            self.arxiu.setSelectedFilter('Arxius CSV (*.csv)')
            self.arxiu.lineEdit().setReadOnly(True)
            self.arxiu.fileChanged.connect(self.arxiuSeleccionat)

        self.zona = QComboBox(self)
        self.zona.setEditable(False)
        self.zona.addItem('Selecciona zona…')
        self.zona.currentIndexChanged.connect(self.canviaZona)

        self.mapa = QComboBox(self)
        self.mapa.setEditable(False)
        self.mapa.setIconSize(QSize(126, 126))
        self.mapa.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        self.mapa.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.mapa.addItem(QIcon(os.path.join(imatgesDir, 'Àrees.PNG')), 'Àrees')
        self.mapa.addItem(QIcon(os.path.join(imatgesDir, 'Cercles.PNG')), 'Cercles')

        self.capa = QLineEdit(self)
        self.capa.setMaxLength(40)

        self.tipus = QComboBox(self)
        self.tipus.setEditable(False)
        self.tipus.addItem('Selecciona tipus…')
        self.tipus.addItems(mv.MAP_AGREGACIO.keys())
        self.tipus.currentIndexChanged.connect(self.canviaTipus)

        self.distribucio = QComboBox(self)
        self.distribucio.setEditable(False)
        self.distribucio.addItem(next(iter(mv.MAP_DISTRIBUCIO.keys())))

        self.calcul = QvComboBoxCamps(self)
        self.filtre = QvComboBoxCamps(self, multiple=True)

        self.color = QComboBox(self)
        self.color.setEditable(False)
        self.comboColors(self.color)

        self.metode = QComboBox(self)
        self.metode.setEditable(False)
        self.metode.addItems(mv.MAP_METODES.keys())

        self.intervals = QSpinBox(self)
        self.intervals.setMinimum(2)
        self.intervals.setMaximum(mv.MAP_MAX_CATEGORIES)
        self.intervals.setSingleStep(1)
        self.intervals.setValue(4)
        self.intervals.setSuffix("  (depèn del mètode)")
        # self.intervals.valueChanged.connect(self.deselectValue)

        self.bTaula = QPushButton('Veure arxiu')
        self.bTaula.setEnabled(False)
        self.bTaula.clicked.connect(self.veureArxiu)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.accepted.connect(self.accept)
        self.buttons.addButton(QDialogButtonBox.Cancel)
        self.buttons.rejected.connect(self.cancel)
        self.buttons.addButton(self.bTaula, QDialogButtonBox.ResetRole)

        self.gDades = QGroupBox('Agregació de dades')
        self.lDades = QFormLayout()
        self.lDades.setSpacing(14)
        self.gDades.setLayout(self.lDades)

        if self.fCSV is None:
            self.lDades.addRow('Arxiu de dades:', self.arxiu)
        self.lDades.addRow('Zona:', self.zona)
        self.lDades.addRow("Tipus d'agregació:", self.tipus)
        self.lDades.addRow('Camp de càlcul:', self.calcul)
        if self.simple:
            self.filtre.setVisible(False)
            self.distribucio.setVisible(False)
        else:
            self.lDades.addRow('Filtre:', self.filtre)
            self.lDades.addRow('Distribució:', self.distribucio)

        self.gMapa = QGroupBox('Definició del mapa simbòlic')
        self.lMapa = QFormLayout()
        self.lMapa.setSpacing(14)
        self.gMapa.setLayout(self.lMapa)

        self.lMapa.addRow('Nom de capa:', self.capa)
        self.lMapa.addRow('Tipus de mapa:', self.mapa)

        self.gSimb = QGroupBox('Simbologia del mapa')
        self.lSimb = QFormLayout()
        self.lSimb.setSpacing(14)
        self.gSimb.setLayout(self.lSimb)

        self.lSimb.addRow('Color base:', self.color)
        self.lSimb.addRow('Mètode classificació:', self.metode)
        self.lSimb.addRow("Nombre d'intervals:", self.intervals)

        self.layout.addWidget(self.gDades)
        self.layout.addWidget(self.gMapa)
        if self.simple:
            self.gSimb.setVisible(False)
        else:
            self.layout.addWidget(self.gSimb)
        self.layout.addWidget(self.buttons)

        self.adjustSize()

        self.nouArxiu()

    def exec(self):
        # La mapificación solo funciona si está instalado el módulo pandas
        if PANDAS_ENABLED:
            return super().exec()
        else:
            self.msgError(PANDAS_ERROR)
            return QDialog.Rejected

    @pyqtSlot()
    def veureArxiu(self):
        if self.taulaMostra is not None:
            self.taulaMostra.show()
            self.taulaMostra.activateWindow()

    def campsDB(self, nom):
        res = []
        if nom != '':
            fich = RUTA_DADES + mv.MAP_ZONES_DB
            if os.path.isfile(fich):
                conn = sqlite3.connect('file:' + fich + '?mode=ro', uri=True)
                conn.row_factory = sqlite3.Row
                c = conn.cursor()
                c.execute('select * from ' + nom)   # nom.split('.')[0])
                row = c.fetchone()
                # res = [i[0].upper() for i in c.description]
                res = [i.upper() for i in row.keys()]
                conn.close()
        return res

    def soloPrimerItem(self, combo):
        combo.setCurrentIndex(0)
        ultimo = combo.count() - 1
        for n in range(ultimo, 0, -1):
            combo.removeItem(n)

    @pyqtSlot()
    def canviaZona(self):
        self.distribucio.setCurrentIndex(0)
        self.soloPrimerItem(self.distribucio)
        if self.zona.currentIndex() > 0:
            z = self.zona.currentText()
            campsZona = self.campsDB(mv.MAP_ZONES[z][1])
            # Carga combo con distribuciones si el campo correspondiente está en la BBDD
            for dist, campo in mv.MAP_DISTRIBUCIO.items():
                if campo != '' and campo in campsZona:
                    self.distribucio.addItem(dist)

    @pyqtSlot()
    def canviaTipus(self):
        if self.tipus.currentText() == 'Recompte':
            self.calcul.setCurrentIndex(-1)
            self.calcul.setEnabled(False)
        else:
            self.calcul.setEnabled(True)

    def borrarArxiu(self):
        if self.taulaMostra is not None:
            self.taulaMostra.hide()
            self.taulaMostra = None
        self.bTaula.setEnabled(False)
        self.tipus.setCurrentIndex(0)
        self.soloPrimerItem(self.zona)
        self.calcul.clear()
        self.filtre.clear()

    def nouArxiu(self):
        if self.fCSV is None:
            return

        # Carga combo con zonas si el campo correspondiente está en el fichero CSV
        num = 0
        for zona, val in mv.MAP_ZONES.items():
            if val[1] != '' and self.fCSV.prefixe + QvSqlite.getAlias(val[0]) in self.fCSV.camps:
                self.zona.addItem(zona)
                num = num + 1

        # Comprobar si la extensión del mapa está limitada
        if num > 0:
            extensio = self.fCSV.testExtensioArxiu(mv.MAP_EXTENSIO)
            if extensio:  # Mapa limitado
                self.comboDelete(self.zona, mv.MAP_TRUE_EXTENSIO)
            else:  # Mapa completo
                self.comboDelete(self.zona, mv.MAP_FALSE_EXTENSIO)

        # Ajustar combo de zonas
        if num == 0:
            self.msgInfo("El fitxer " + self.fCSV.fZones + " no té cap camp de zona")
            if hasattr(self, 'arxiu'):
                self.arxiu.lineEdit().clear()
                self.arxiu.setFocus()
            return
        if num == 1:
            self.zona.setCurrentIndex(1)
            self.capa.setFocus()
        else:
            self.zona.setFocus()

        self.taulaMostra = QvEditorCsv(self.fCSV.fZones, [], 'utf-8', self.fCSV.separador, self)
        self.taulaMostra.setWindowTitle("Vista prèvia d'arxiu geocodificat")
        self.taulaMostra.setReadOnly(True)

        self.bTaula.setEnabled(True)
        self.calcul.setItems(self.fCSV.camps, primer='')
        self.filtre.setItems(self.fCSV.camps)

    @pyqtSlot(str)
    def arxiuSeleccionat(self, nom):
        if nom == '':
            return
        self.borrarArxiu()
        self.fCSV = QvMapificacio(nom)
        self.nouArxiu()

    def validaSortida(self, nom):
        fSalida = self.fCSV.nomArxiuSortida(self.fCSV.netejaString(nom, True))
        return self.msgSobreescriure(fSalida)

    def valida(self):
        ok = False
        if hasattr(self, 'arxiu') and self.arxiu.filePath() == '':
            self.msgInfo("S'ha de seleccionar un arxiu de dades")
            self.arxiu.setFocus()
        elif self.zona.currentIndex() <= 0:
            self.msgInfo("S'ha de seleccionar una zona")
            self.zona.setFocus()
        elif self.capa.text().strip() == '':
            self.msgInfo("S'ha de introduir un nom de capa")
            self.capa.setFocus()
        elif self.tipus.currentIndex() <= 0:
            self.msgInfo("S'ha de seleccionar un tipus d'agregació")
            self.tipus.setFocus()
        elif self.calcul.currentText().strip() == '' and self.tipus.currentText() != 'Recompte':
            self.msgInfo("S'ha de introduir un cálcul per fer l'agregació")
            self.calcul.setFocus()
        elif self.fCSV is None:
            return self.msgInfo("No hi ha cap fitxer seleccionat")
        elif not self.validaSortida(self.capa.text().strip()):
            self.capa.setFocus()
        else:
            ok = True
        return ok

    def setRenderParams(self):
        self.renderParams = QvMapRendererParams(self.mapa.currentText())
        if self.simple:
            self.renderParams.colorBase = mv.MAP_COLORS[self.renderParams.colorBase]
        else:
            self.renderParams.colorBase = mv.MAP_COLORS[self.color.currentText()]
        if self.renderParams.colorContorn is None or self.renderParams.colorContorn == 'Base':
            self.renderParams.colorContorn = self.renderParams.colorBase
        else:
            self.renderParams.colorContorn = mv.MAP_CONTORNS[self.renderParams.colorContorn]
        if self.tipus.currentText().startswith('Recompte') and \
           self.distribucio.currentText() == "Total":
            self.renderParams.numDecimals = 0
        else:
            self.renderParams.numDecimals = 2
        if self.renderParams.tipusMapa == 'Àrees':
            self.renderParams.modeCategories = mv.MAP_METODES[self.metode.currentText()]
            self.renderParams.numCategories = self.intervals.value()
        if self.renderParams.tipusMapa == 'Cercles':
            zona = self.zona.currentText()
            if zona == 'Districte':
                self.renderParams.increase = 8
            elif zona == 'Barri':
                self.renderParams.increase = 4
            elif zona == 'Àrea estadística bàsica':
                self.renderParams.increase = 3
            elif zona == 'Secció censal':
                self.renderParams.increase = 2
            else:
                self.renderParams.increase = 1

    def procesa(self):
        if self.taulaMostra is not None:
            self.taulaMostra.hide()
        self.setRenderParams()
        ok = self.fCSV.agregacio(self.llegenda, self.capa.text().strip(),
                                 self.zona.currentText(), self.tipus.currentText(),
                                 self.renderParams,
                                 campAgregat=self.calcul.currentText().strip(),
                                 simple=self.simple,
                                 filtre=self.filtre.currentText().strip(),
                                 tipusDistribucio=self.distribucio.currentText(),
                                 form=self)
        if ok:
            return ''
        else:
            return self.fCSV.msgError
示例#2
0
class TOMsExport:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'TOMsExport_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&TOMsExport')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

        self.closeTOMs = False

    def tr(self, message):
        """Get the translation for a string using Qt translation API.
        """
        return QCoreApplication.translate('TOMsExport', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/TOMsExport/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'TOMs Export'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&TOMsExport'), action)
            self.iface.removeToolBarIcon(action)

    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started

        self.TOMsConfigFileObject = TOMsConfigFile()
        self.TOMsConfigFileObject.TOMsConfigFileNotFound.connect(
            self.setCloseTOMsFlag)
        self.TOMsConfigFileObject.initialiseTOMsConfigFile()

        utils = TOMsExportUtils(self.iface, self.TOMsConfigFileObject)

        if self.first_start == True:
            self.first_start = False

        self.tableNames = TOMsLayers(self.iface)
        #self.tableNames = setupTableNames(self.iface)
        self.tableNames.TOMsLayersNotFound.connect(self.setCloseTOMsFlag)
        #self.TOMsExportLayerList = self.tableNames.getLayers()
        #requiredFields = self.tableNames.getRequiredFields()

        self.tableNames.TOMsLayersNotFound.connect(self.setCloseTOMsFlag)
        self.tableNames.getLayers(self.TOMsConfigFileObject)

        if self.closeTOMs:
            QMessageBox.information(self.iface.mainWindow(), "ERROR",
                                    ("Unable to start TOMs ..."))
            return

        #self.TOMsExportLayerList = utils.getTOMsExportLayerList()  # not required as list comes from dialog
        # TODO: Check that export layers are present ...

        self.setupUi()

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        # TODO: Make sure that there is a valid file location

        if result:

            # Open geopackage

            canvas = self.iface.mapCanvas()
            layer = canvas.currentLayer()

            fileName = self.fileNameWidget.filePath()
            # QMessageBox.information(self.iface.mainWindow(), "Message", ("Filename is ..." + str(fileName)))
            TOMsMessageLog.logMessage("Filename is ..." + str(fileName),
                                      level=Qgis.Info)

            # Get list of all the layers that are required within the Geopackage

            layerItemsList = self.layerList.getSelectedLayers()
            for currLayerItem in layerItemsList:
                TOMsMessageLog.logMessage("Processing {} ...".format(
                    currLayerItem.text()),
                                          level=Qgis.Warning)

                currLayer = QgsProject.instance().mapLayersByName(
                    currLayerItem.text())[0]

                outputLayersList = utils.processLayer(currLayer)
                if outputLayersList:
                    #status = utils.saveOutputLayers(outputlayersList, fileName)
                    for newLayerName, newLayer in outputLayersList:
                        utils.saveLayerToGpkg(newLayer, fileName)

                        newLayerA = QgsVectorLayer(
                            fileName + "|layername=" + newLayerName,
                            newLayerName, "ogr")
                        QgsProject.instance().addMapLayer(newLayerA)

            TOMsMessageLog.logMessage("******** FINISHED EXPORT ********",
                                      level=Qgis.Warning)

            #self.dlg.close()

    def setupUi(self):

        self.dlg = QDialog()
        self.dlg.setWindowTitle("TOMs Export")
        self.dlg.setWindowModality(Qt.ApplicationModal)

        self.generalLayout = QVBoxLayout()

        layerGroup = QGroupBox("Choose layers to export")

        # add map layer list
        self.layerList = checkableMapLayerList()
        vbox1 = QVBoxLayout()
        vbox1.addWidget(self.layerList)
        layerGroup.setLayout(vbox1)
        self.generalLayout.addWidget(layerGroup)

        # add file chooser
        outputGroup = QGroupBox("Choose output file")
        self.fileNameWidget = QgsFileWidget()
        self.fileNameWidget.setStorageMode(QgsFileWidget.SaveFile)
        self.fileNameWidget.setFilter(
            "Geopackage (*.gpkg);;JPEG (*.jpg *.jpeg);;TIFF (*.tif)")
        self.fileNameWidget.setSelectedFilter("Geopackage (*.gpkg)")
        vbox2 = QVBoxLayout()
        vbox2.addWidget(self.fileNameWidget)
        outputGroup.setLayout(vbox2)
        self.generalLayout.addWidget(outputGroup)

        # add buttons
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self.dlg.accept)
        self.buttonBox.rejected.connect(self.dlg.reject)
        self.generalLayout.addWidget(self.buttonBox)

        self.dlg.setLayout(self.generalLayout)
        checkableMapLayerListCtrl(self.layerList)

    def setCloseTOMsFlag(self):
        self.closeTOMs = True