def mapFeatures(self, inputPreparedLayers, outputLayers, featureConversionMap=None, feedback=None): """ Maps features from a given set of layers to a different set of layers (including attributes). :param inputPreparedLayers: (dict) map of layers to be translated. :param outputLayers: (dict) map of layers to be filled. :param featureConversionMap: (dict) map of features based on given input. :param feedback: (QgsProcessingMultiStepFeedback) QGIS tool for progress tracking. :return: (dict) map of (list-of-QgsFeature) features to be added to a (str) layer. """ if featureConversionMap is not None: # do the conversion in here using the map - NOT YET SUPPORTED pass else: featuresMap = collections.defaultdict(set) lh = LayerHandler() fh = FeatureHandler() if feedback is not None: stepSize = 100 / len(inputPreparedLayers) if len( inputPreparedLayers) else 0 for current, (layer, vl) in enumerate(inputPreparedLayers.items()): if feedback is not None and feedback.isCanceled(): break if vl.featureCount() == 0 or layer not in outputLayers: continue outuputLayer = outputLayers[layer] k = "{0}->{1}".format(vl.crs().authid(), outuputLayer.crs().authid()) if k not in self.coordinateTransformers: self.coordinateTransformers[ k] = lh.getCoordinateTransformer( inputLyr=vl, outputLyr=outuputLayer) coordinateTransformer = self.coordinateTransformers[k] param = lh.getDestinationParameters(vl) for feature in vl.getFeatures(QgsFeatureRequest()): featuresMap[layer] |= fh.handleConvertedFeature( feat=feature, lyr=outuputLayer, parameterDict=param, coordinateTransformer=coordinateTransformer) if feedback is not None: feedback.setProgress(current * stepSize) return featuresMap
def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ featureHandler = FeatureHandler() layerHandler = LayerHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) inputAttr = self.parameterAsFields(parameters, self.FLAG_FIELD, context) inputAttr = inputAttr[0] tableSchema = self.parameterAsString(parameters, self.TABLE_SCHEMA, context) if tableSchema is None or tableSchema == '': raise QgsProcessingException(self.tr('Invalid table schema')) tableName = self.parameterAsString(parameters, self.TABLE_NAME, context) if tableName is None or tableName == '': raise QgsProcessingException(self.tr('Invalid table name')) geometryColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context) if geometryColumn is None or geometryColumn == '': raise QgsProcessingException(self.tr('Invalid geometry column')) flagTextAttr = self.parameterAsString(parameters, self.OUTPUT_FLAG_TEXT_FIELD, context) if flagTextAttr is None or flagTextAttr == '': raise QgsProcessingException( self.tr('Invalid flag attribute column')) crs = self.parameterAsCrs(parameters, self.CRS, context) if crs is None or not crs.isValid(): raise QgsProcessingException(self.tr('Invalid CRS.')) outputLyr = self.getOutputFromInput(inputLyr, tableSchema, tableName, geometryColumn) if not outputLyr.isValid(): raise QgsProcessingException(self.tr('Invalid output layer.')) coordinateTransformer = QgsCoordinateTransform( QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()), crs, QgsProject.instance()) parameterDict = layerHandler.getDestinationParameters(outputLyr) outputLyr.startEditing() outputLyr.beginEditCommand('Adding flag features') count = inputLyr.featureCount() progress_count = 100 / count if count else 0 for current, feat in enumerate(inputLyr.getFeatures()): if feedback.isCanceled(): break for newFeat in featureHandler.handleConvertedFeature( feat, outputLyr, parameterDict=parameterDict, coordinateTransformer=coordinateTransformer): newFeat[flagTextAttr] = feat[inputAttr] outputLyr.addFeature(newFeat) feedback.setProgress(current * progress_count) outputLyr.endEditCommand() outputLyr.commitChanges() return {}