def accept( self ): if not self.config: return if self.leOutput.text().isEmpty(): QMessageBox.warning( self, self.tr( "Reporter" ), self.tr( "Please specify output report file" ) ) return self.cleanupConfigAndGui() self.saveSettings() # get layer count layerCount = 0 layerNames = [] for i in xrange( self.lstLayers.topLevelItemCount() ): item = self.lstLayers.topLevelItem( i ) if item.checkState( 0 ) == Qt.Checked: layerCount += 1 layerNames.append( item.text( 0 ) ) self.progressBar.setRange( 0, layerCount ) QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) ) self.btnOk.setEnabled( False ) # ***************** create reports ************************ overlayLayer = utils.getVectorLayerByName( self.cmbAnalysisRegion.currentText() ) overlayProvider = overlayLayer.dataProvider() isFirst = True mapCRS = self.iface.mapCanvas().mapRenderer().destinationCrs() hasOTFR = self.iface.mapCanvas().hasCrsTransformEnabled() crsTransform = QgsCoordinateTransform( overlayLayer.crs(), mapCRS ) needTransform = ( overlayLayer.crs() != mapCRS ) dirName = QFileInfo( self.leOutput.text() ).absolutePath() # get dimensioning coefficient coef = 1.0 settings = QSettings( "NextGIS", "reporter" ) if settings.value( "dimensioning", "none" ).toString() == "none": coef = 1.0 elif settings.value( "dimensioning", "none" ).toString() == "kilo": coef = 0.00001 else: coef = 0.0000001 # variables to store information used in reports dataArea = dict() dataObjects = dict() # init report writer writer = wordmlwriter.WordMLWriter() for layerName in layerNames: self.progressBar.setFormat( self.tr( "%p% processing: %1" ).arg( layerName ) ) QCoreApplication.processEvents() layerElement = utils.findLayerInConfig( self.cfgRoot, layerName ) labelFieldName = utils.labelFieldName( layerElement ) vLayer = utils.getVectorLayerByName( layerName ) vProvider = vLayer.dataProvider() vProvider.rewind() vProvider.select( vProvider.attributeIndexes() ) # check layer renderer and determine classification field rendererType = None fieldName = None fieldIndex = None categories = None if vLayer.isUsingRendererV2(): renderer = vLayer.rendererV2() rendererType = renderer.type() if rendererType in [ "singleSymbol", "Single Symbol" ]: tmp = utils.labelFieldName( layerElement ) if tmp.isEmpty(): fieldIndex = 0 fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) else: fieldName = tmp fieldIndex = utils.fieldIndexByName( vProvider, fieldName ) elif rendererType in [ "categorizedSymbol", "Unique Value" ]: fieldName = renderer.classAttribute() fieldIndex = utils.fieldIndexByName( vProvider, fieldName ) categories = renderer.categories() else: print "Invalid renderer type! Skip this layer..." continue else: renderer = vLayer.renderer() rendererType = renderer.name() if rendererType in [ "singleSymbol", "Single Symbol" ]: tmp = utils.labelFieldName( layerElement ) if tmp.isEmpty(): fieldIndex = 0 fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) else: fieldName = tmp fieldIndex = utils.fieldIndexByName( vProvider, fieldName ) elif rendererType in [ "categorizedSymbol", "Unique Value" ]: fieldIndex = renderer.classificationField() fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) categories = renderer.symbolMap() else: print "Invalid renderer type! Skip this layer..." continue # override fieldIndex using layer from config tryLegendLabels = False attributeIndexes = [] labelFieldIndex = utils.fieldIndexByName( vProvider, labelFieldName ) if labelFieldIndex == fieldIndex: tryLegendLabels = True attributeIndexes.append( fieldIndex ) else: attributeIndexes.append( fieldIndex ) attributeIndexes.append( labelFieldIndex ) # unsupported renderer, process next layer if rendererType not in [ "categorizedSymbol", "Unique Value", "singleSymbol", "Single Symbol" ]: print "Invalid renderer type! Skip this layer..." continue # prepare to collect information overlayFeat = QgsFeature() currentFeat = QgsFeature() geom = QgsGeometry() spatialIndex = utils.createSpatialIndex( vProvider ) if overlayLayer.selectedFeatureCount() != 0: sel = overlayLayer.selectedFeaturesIds() overlayProvider.featureAtId( max( sel ), overlayFeat ) else: overlayProvider.featureAtId( overlayProvider.featureCount() - 1, overlayFeat ) dataArea.clear() dataObjects.clear() legendCategories = [] featureClass = None category = None geom = QgsGeometry( overlayFeat.geometry() ) if needTransform: if geom.transform( crsTransform ) != 0: print "Unable transform geometry" continue dataArea[ "totalArea" ] = float( geom.area() * coef ) # find intersections in data layer intersections = spatialIndex.intersects( geom.boundingBox() ) for i in intersections: vProvider.featureAtId( int( i ), currentFeat, True, attributeIndexes ) tmpGeom = QgsGeometry( currentFeat.geometry() ) # precision test for intersection if geom.intersects( tmpGeom ): # get data for area report attrMap = currentFeat.attributeMap() if tryLegendLabels: featureClass = attrMap[ fieldIndex ].toString() if vLayer.isUsingRendererV2(): if vLayer.rendererV2().type() in [ "categorizedSymbol", "Unique Value" ]: category = categories[ renderer.categoryIndexForValue( attrMap.values()[ 0 ] ) ].label() else: if vLayer.renderer().name() in [ "categorizedSymbol", "Unique Value" ]: category = categories[ attrMap.values()[ 0 ].toString() ].label() if categories is not None: if category.isEmpty(): category = featureClass if category not in legendCategories: legendCategories.append( category ) else: if categories is not None: category = attrMap[ labelFieldIndex ].toString() tmp = attrMap[ fieldIndex ].toString() if tmp not in legendCategories: legendCategories.append( tmp ) # count objects if categories is not None: if category not in dataObjects: dataObjects[ category ] = 1 else: dataObjects[ category ] += 1 else: if str(fieldName) not in dataObjects: dataObjects[ str(fieldName) ] = 1 else: dataObjects[ str(fieldName) ] += 1 # calculate intersection area intGeom = QgsGeometry( geom.intersection( tmpGeom ) ) if intGeom.wkbType() == 7: intCom = geom.combine( tmpGeom ) intSym = geom.symDifference( tmpGeom ) intGeom = QgsGeometry( intCom.difference( intSym ) ) if categories is not None: if category not in dataArea: dataArea[ category ] = float( intGeom.area() * coef ) else: dataArea[ category ] += float( intGeom.area() * coef ) else: if str(fieldName) not in dataArea: dataArea[ str(fieldName) ] = float( intGeom.area() * coef ) else: dataArea[ str(fieldName) ] += float( intGeom.area() * coef ) # get extent of the overlay geometry (for reports) rect = geom.boundingBox() dw = rect.width() * 0.025 dh = rect.height() * 0.025 rect.setXMinimum( rect.xMinimum() - dw ) rect.setXMaximum( rect.xMaximum() + dw ) rect.setYMinimum( rect.yMinimum() - dh ) rect.setYMaximum( rect.yMaximum() + dh ) # create map #mapImage = utils.createMapImage( overlayLayer, vLayer, rect, mapCRS, hasOTFR, dataObjects.keys() ) mapImage = utils.createMapImage( overlayLayer, vLayer, rect, mapCRS, hasOTFR, legendCategories ) # create all necessary reports layerConfig = utils.findLayerInConfig( self.cfgRoot, layerName ) # add page break after first layer if not isFirst: writer.addPageBreak() isFirst = False # print title writer.addTitle( layerName ) writer.addDescription( self.txtComment.toPlainText() + " " + utils.layerComment( layerConfig ) ) if utils.hasReport( layerConfig, "area" ): writer.addAreaTable( fieldName, dataArea ) if utils.hasReport( layerConfig, "objects" ): writer.addObjectsTable( dataObjects ) # embed image in report if requested if self.chkAddMapsToReport.isChecked(): imgData = QByteArray() buff = QBuffer( imgData ) buff.open( QIODevice.WriteOnly ) mapImage.save( buff, "png" ) writer.addThematicImage( layerName, QString.fromLatin1( imgData.toBase64() ) ) # save separate map if requested if self.chkCreateMaps.isChecked(): mapImage.save( dirName + "/" + layerName + ".png", "png" ) self.progressBar.setValue( self.progressBar.value() + 1 ) QCoreApplication.processEvents() # save report to files writer.closeReport() writer.write( self.leOutput.text() ) # restore UI self.progressBar.setFormat( "%p%" ) self.progressBar.setRange( 0, 1 ) self.progressBar.setValue( 0 ) QApplication.restoreOverrideCursor() QMessageBox.information( self, self.tr( "Done" ), self.tr( "Completed!" ) ) self.btnOk.setEnabled( True )
def toggleLayer( self, item, column ): if self.config: if item.checkState( 0 ) == Qt.Checked: utils.addLayerToConfig( self.config, self.cfgRoot, item.text( 0 ) ) layerElement = utils.findLayerInConfig( self.cfgRoot, item.text( 0 ) ) vLayer = utils.getVectorLayerByName( item.text( 0 ) ) vProvider = vLayer.dataProvider() # check layer renderer and determine classification field fieldName = None fieldIndex = None if vLayer.isUsingRendererV2(): renderer = vLayer.rendererV2() rendererType = renderer.type() if rendererType in [ "categorizedSymbol", "Unique Value" ]: fieldName = renderer.classAttribute() fieldIndex = utils.fieldIndexByName( vProvider, fieldName ) elif rendererType in [ "singleSymbol", "Single Symbol" ]: fieldIndex = 0 fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) else: print "Invalid renderer type! Skip this layer..." item.setCheckState( 0, Qt.Unchecked ) return else: renderer = vLayer.renderer() rendererType = renderer.name() if rendererType in [ "categorizedSymbol", "Unique Value" ]: fieldIndex = renderer.classificationField() fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) elif rendererType in [ "singleSymbol", "Single Symbol" ]: fieldIndex = 0 fieldName = utils.fieldNameByIndex( vProvider, fieldIndex ) else: print "Invalid renderer type! Skip this layer..." item.setCheckState( 0, Qt.Unchecked ) return d = layersettingsdialog.LayerSettingsDialog( self, vLayer ) d.setAreasReport( utils.hasReport( layerElement, "area" ) ) d.setObjectsReport( utils.hasReport( layerElement, "objects" ) ) tmp = utils.labelFieldName( layerElement ) if tmp.isEmpty(): d.setLabelField( fieldName ) else: d.setLabelField( tmp ) d.setComment( utils.layerComment( layerElement ) ) if not d.exec_() == QDialog.Accepted: item.setCheckState( 0, Qt.Unchecked ) return # update layer config if necessary if d.areasReport(): utils.addLayerReport( self.config, layerElement, "area" ) else: utils.removeLayerReport( layerElement, "area" ) if d.objectsReport(): utils.addLayerReport( self.config, layerElement, "objects" ) else: utils.removeLayerReport( layerElement, "objects" ) utils.setLabelFieldName( self.config, layerElement, d.getLabelField() ) utils.setLayerComment( self.config, layerElement, d.getComment() ) else: utils.removeLayerFromConfig( self.cfgRoot, item.text( 0 ) )