예제 #1
0
 def updateFieldList(self, layerName):
     self.cmbGroupField.clear()
     vLayer = utils.getVectorLayerByName(layerName)
     fields = utils.getFieldList(vLayer)
     for i in fields:
         if fields[i].type() in [QVariant.Int, QVariant.String]:
             self.cmbGroupField.addItem(fields[i].name())
예제 #2
0
    def accept(self):
        # check input parameters
        if self.cmbRasterLayer.currentIndex() == -1:
            QMessageBox.warning(self, self.tr("ZonalStats: Warning"), self.tr("Please select raster layer to analyse"))
            return

        if self.cmbVectorLayer.currentIndex() == -1:
            QMessageBox.warning(self, self.tr("ZonalStats: Warning"), self.tr("Please select vector layer to analyse"))
            return

        if self.leReportFile.text().isEmpty():
            QMessageBox.warning(
                self, self.tr("ZonalStats: Warning"), self.tr("Please select where to save report file")
            )
            return

        if self.leDataFile.text().isEmpty():
            QMessageBox.warning(self, self.tr("ZonalStats: Warning"), self.tr("Please select where to save data file"))
            return

        rasterPath = utils.getRasterLayerByName(self.cmbRasterLayer.currentText()).source()
        vLayer = utils.getVectorLayerByName(self.cmbVectorLayer.currentText())
        reportPath = self.leReportFile.text()
        dataPath = self.leDataFile.text()

        self.progressBar.setRange(0, 3)
        self.progressBar.setValue(0)

        memLayer = utils.loadInMemory(vLayer)
        memProvider = memLayer.dataProvider()

        self.progressBar.setValue(self.progressBar.value() + 1)

        # get pixel size (need it for area calculation)
        pixelSize = utils.getRasterLayerByName(self.cmbRasterLayer.currentText()).rasterUnitsPerPixel()

        # TODO: check attribute prefix
        prefix = ""

        # calculate zonal statistics
        zs = QgsZonalStatistics(memLayer, rasterPath, prefix)
        pd = QProgressDialog(self.tr("Calculating zonal statistics"), self.tr("Abort..."), 0, 0)
        zs.calculateStatistics(pd)

        self.progressBar.setValue(self.progressBar.value() + 1)

        if pd.wasCanceled():
            QMessageBox.error(
                self,
                self.tr("ZonalStats: Error"),
                self.tr("Hey!.. You abort statistics calculation, so there are no data for analysis. Exiting..."),
            )
            self.progressBar.setValue(0)
            return

        # save full statistics to file near the input shapefile
        # fi = QFileInfo( vLayer.source() )
        # fPath = fi.path() + "/" + fi.completeBaseName() + "_full_stat.csv"
        # utils.saveStatsToCSV( memLayer, fPath )

        # get count field index
        # idxCount = memLayer.fieldNameIndex( "count" )
        idxCount = memLayer.fieldNameIndex("sum")

        reportData = []
        ft = QgsFeature()

        # generate report
        if self.chkGroupZones.isChecked():
            grpFieldIndex = 0
            isString = False
            fieldName = self.cmbGroupField.currentText()
            for k, v in memProvider.fields().iteritems():
                if v.name() == fieldName:
                    if v.type() == QVariant.String:
                        isString = True
                    grpFieldIndex = k
                    break

            # get unique values
            uniqueValues = memProvider.uniqueValues(grpFieldIndex)
            allAttrs = memProvider.attributeIndexes()

            sqlString = None
            if isString:
                sqlString = QString(fieldName + " = '%1'")
            else:
                sqlString = QString(fieldName + " = %1")

            # create zones
            for v in uniqueValues:
                groupName = v.toString()
                qry = sqlString.arg(groupName)
                fIds = utils.searchInLayer(memLayer, qry)
                stats = [unicode(groupName), str(len(fIds)), 0]
                for i in fIds:
                    memLayer.featureAtId(i, ft, False, True)
                    attrMap = ft.attributeMap()
                    stats[2] += attrMap[idxCount].toFloat()[0]
                stats[2] = str(stats[2] * pixelSize)
                reportData.append(stats)
        else:
            allAttrs = memProvider.attributeIndexes()
            memLayer.select(allAttrs, QgsRectangle(), False)
            nameFieldIndex = memLayer.fieldNameIndex(self.cmbGroupField.currentText())
            while memLayer.nextFeature(ft):
                attrMap = ft.attributeMap()
                stats = [unicode(attrMap[nameFieldIndex].toString()), "1", "0"]
                stats[2] = str(attrMap[idxCount].toFloat()[0] * pixelSize)
                reportData.append(stats)

        # save report as HTML
        rpt = utils.writeReport(reportPath, dataPath, reportData, unicode(self.cmbGroupField.currentText()))

        self.progressBar.setValue(self.progressBar.value() + 1)

        # display report in viewer
        self.teReport.setHtml(rpt)
        self.progressBar.setValue(0)

        memLayer = None