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())
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