Beispiel #1
0
def create_field_from_definition(field_definition, name=None, sub_name=None):
    """Helper to create a field from definition.

    :param field_definition: The definition of the field (see:
        safe.definitions.fields).
    :type field_definition: dict

    :param name: The name is required if the field name is dynamic and need a
        string formatting.
    :type name: basestring

    :param sub_name: The name is required if the field name is dynamic and need
        a string formatting.
    :type sub_name: basestring

    :return: The new field.
    :rtype: QgsField
    """
    field = QgsField()

    if name and not sub_name:
        field.setName(field_definition['field_name'] % name)
    elif name and sub_name:
        field.setName(field_definition['field_name'] % (name, sub_name))
    else:
        field.setName(field_definition['field_name'])

    if isinstance(field_definition['type'], list):
        # Use the first element in the list of type
        field.setType(field_definition['type'][0])
    else:
        field.setType(field_definition['type'])
    field.setLength(field_definition['length'])
    field.setPrecision(field_definition['precision'])
    return field
Beispiel #2
0
def create_field_from_definition(field_definition, name=None):
    """Helper to create a field from definition.

    :param field_definition: The definition of the field.
    :type field_definition: safe.definitions.fields

    :param name: The name is required if the field name is dynamic and need a
        string formatting.
    :type name: basestring

    :return: The new field.
    :rtype: QgsField
    """
    field = QgsField()

    if isinstance(name, QPyNullVariant):
        name = 'NULL'

    if name:
        field.setName(field_definition['field_name'] % name)
    else:
        field.setName(field_definition['field_name'])

    if isinstance(field_definition['type'], list):
        # Use the first element in the list of type
        field.setType(field_definition['type'][0])
    else:
        field.setType(field_definition['type'])
    field.setLength(field_definition['length'])
    field.setPrecision(field_definition['precision'])
    return field
Beispiel #3
0
 def addField(original, stat, type):
     """
     Adds a field to the output, with a specified type
     """
     field = QgsField(original)
     field.setName(field.name() + '_' + stat)
     field.setType(type)
     if type == QVariant.Double:
         field.setLength(20)
         field.setPrecision(6)
     fields_to_join.append(field)
 def addField(original, stat, type):
     """
     Adds a field to the output, with a specified type
     """
     field = QgsField(original)
     field.setName(field.name() + '_' + stat)
     field.setType(type)
     if type == QVariant.Double:
         field.setLength(20)
         field.setPrecision(6)
     fields_to_join.append(field)
Beispiel #5
0
def create_field(definition):
    """ Création d'un champ dans un table attributaire

    :param definition: Définition de nom, type, taille et précision d'un champ
    :type definition: definition
    """
    field = QgsField()
    field.setName(definition['name'])
    field.setType(definition['type'])
    field.setPrecision(definition['precision'])
    field.setLength(definition['length'])
    return field
Beispiel #6
0
 def createQgsField(self):
     qgsField = None
     if self.type.attributeType == GeoCsvAttributeType.integer:
         qgsField = QgsField(self.name, QVariant.Int)
     elif self.type.attributeType == GeoCsvAttributeType.easting or self.type.attributeType == GeoCsvAttributeType.northing or self.type.attributeType == GeoCsvAttributeType.real:
         qgsField = QgsField(self.name, QVariant.Double)
     else:
         qgsField = QgsField(self.name, QVariant.String)
     if not self.type.length == 0:
         qgsField.setLength(self.type.length)
     if not self.type.precision == 0:
         qgsField.setPrecision(self.type.precision)
     return qgsField
 def createQgsField(self):
     qgsField = None
     if self.type.attributeType == GeoCsvAttributeType.integer:
         qgsField = QgsField(self.name, QVariant.Int)
     elif self.type.attributeType == GeoCsvAttributeType.easting or self.type.attributeType == GeoCsvAttributeType.northing or self.type.attributeType == GeoCsvAttributeType.real:
         qgsField = QgsField(self.name, QVariant.Double)
     else:
         qgsField = QgsField(self.name, QVariant.String)
     if not self.type.length == 0:
         qgsField.setLength(self.type.length)
     if not self.type.precision == 0:
         qgsField.setPrecision(self.type.precision) 
     return qgsField     
def _add_id_column(layer):
    """Add an ID column if it's not present in the attribute table.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer
    """
    layer_purpose = layer.keywords['layer_purpose']
    mapping = {
        layer_purpose_exposure['key']: exposure_id_field,
        layer_purpose_hazard['key']: hazard_id_field,
        layer_purpose_aggregation['key']: aggregation_id_field
    }

    has_id_column = False
    for layer_type, field in mapping.iteritems():
        if layer_purpose == layer_type:
            safe_id = field
            if layer.keywords.get(field['key']):
                has_id_column = True
            break

    if not has_id_column:
        LOGGER.info(
            'We add an ID column in {purpose}'.format(purpose=layer_purpose))

        layer.startEditing()

        id_field = QgsField()
        id_field.setName(safe_id['field_name'])
        if isinstance(safe_id['type'], list):
            # Use the first element in the list of type
            id_field.setType(safe_id['type'][0])
        else:
            id_field.setType(safe_id['type'][0])
        id_field.setPrecision(safe_id['precision'])
        id_field.setLength(safe_id['length'])

        layer.addAttribute(id_field)

        new_index = layer.fieldNameIndex(id_field.name())

        for feature in layer.getFeatures():
            layer.changeAttributeValue(
                feature.id(), new_index, feature.id())

        layer.commitChanges()

        layer.keywords['inasafe_fields'][safe_id['key']] = (
            safe_id['field_name'])
def _add_id_column(layer):
    """Add an ID column if it's not present in the attribute table.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer
    """
    layer_purpose = layer.keywords['layer_purpose']
    mapping = {
        layer_purpose_exposure['key']: exposure_id_field,
        layer_purpose_hazard['key']: hazard_id_field,
        layer_purpose_aggregation['key']: aggregation_id_field
    }

    has_id_column = False
    for layer_type, field in mapping.iteritems():
        if layer_purpose == layer_type:
            safe_id = field
            if layer.keywords['inasafe_fields'].get(field['key']):
                has_id_column = True
            break

    if not has_id_column:
        LOGGER.info(
            'We add an ID column in {purpose}'.format(purpose=layer_purpose))

        layer.startEditing()

        id_field = QgsField()
        id_field.setName(safe_id['field_name'])
        if isinstance(safe_id['type'], list):
            # Use the first element in the list of type
            id_field.setType(safe_id['type'][0])
        else:
            id_field.setType(safe_id['type'][0])
        id_field.setPrecision(safe_id['precision'])
        id_field.setLength(safe_id['length'])

        layer.addAttribute(id_field)

        new_index = layer.fieldNameIndex(id_field.name())

        for feature in layer.getFeatures():
            layer.changeAttributeValue(
                feature.id(), new_index, feature.id())

        layer.commitChanges()

        layer.keywords['inasafe_fields'][safe_id['key']] = (
            safe_id['field_name'])
Beispiel #10
0
    def create_fields(self, layer, record):
        """Create the attributes for the gbif response table."""
        layer.startEditing()
        id_field = QgsField()
        id_field.setName('id')
        id_field.setType(QVariant.Int)
        id_field.setPrecision(0)
        id_field.setLength(10)
        layer.addAttribute(id_field)
        # A dict to store the field offeset for each property
        field_lookups = []
        for key in record.keys():
            new_field = QgsField()
            new_field.setName(key)
            new_field.setType(QVariant.String)
            new_field.setLength(255)
            layer.addAttribute(new_field)
            field_lookups.append(key)

        layer.commitChanges()
        return field_lookups
    def processAlgorithm(self, parameters, context, feedback):
        layer = self.parameterAsMeshLayer(parameters, self.INPUT_LAYER,
                                          context)
        levels, precision = self._parse_levels(parameters, context)
        datasets = parameters[self.INPUT_DATASETS]
        timestep = parameters[self.INPUT_TIMESTEP]
        fields_line = QgsFields()
        fields_line.append(QgsField("group", QVariant.String))
        fields_line.append(QgsField("time", QVariant.Double))
        valueField = QgsField("value", QVariant.Double)
        valueField.setPrecision(precision)
        fields_line.append(valueField)

        (sink_line,
         dest_id_line) = self.parameterAsSink(parameters, self.OUTPUT_LINE,
                                              context, fields_line,
                                              QgsWkbTypes.MultiLineString,
                                              layer.crs())

        if sink_line is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT_LINE))

        fields_poly = QgsFields()
        fields_poly.append(QgsField("group", QVariant.String))
        fields_poly.append(QgsField("time", QVariant.Double))
        minValueField = QgsField("min_value", QVariant.Double)
        minValueField.setPrecision(precision)
        fields_poly.append(minValueField)
        maxValueField = QgsField("max_value", QVariant.Double)
        maxValueField.setPrecision(precision)
        fields_poly.append(maxValueField)
        (sink_poly,
         dest_id_poly) = self.parameterAsSink(parameters, self.OUTPUT_POLY,
                                              context, fields_poly,
                                              QgsWkbTypes.MultiPolygon,
                                              layer.crs())

        if sink_poly is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT_POLY))

        total = 2 * len(datasets) * len(levels)
        runner = QgsMeshContours(layer)
        dp = layer.dataProvider()

        i = self._export_lines(levels, runner, dp, datasets, timestep, 1,
                               total, sink_line, feedback)

        self._export_polys(levels, runner, dp, datasets, timestep, i, total,
                           sink_poly, feedback)

        feedback.setProgress(100)
        return {self.OUTPUT_LINE: dest_id_line, self.OUTPUT_POLY: dest_id_poly}
    def saveAutoField( self ):
        """ Do some validation and then call AutoFieldManager """

        # Check layers
        if not self.tblLayers.selectedItems():
            self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                "[Warning] Please first select a layer." ), 'warning' )
            return

        # Check expression
        expression = u''
        if self.optXCoord.isChecked():
            expression = u'$x'
        elif self.optYCoord.isChecked():
            expression = u'$y'
        elif self.optLength.isChecked():
            expression = u'$length'
        elif self.optPerimeter.isChecked():
            expression = u'$perimeter'
        elif self.optArea.isChecked():
            expression = u'$area'
        elif self.optDate.isChecked():
            expression = u'now()'
        elif self.optCustomExpression.isChecked():
            if self.expressionDlg:
                expression = self.expressionDlg.expression
            if not self.expressionDlg or not expression:
                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                    "[Warning] Please first set a valid custom expression." ),
                    'warning' )
                return
        else: # optSpatialValue
            pass

        # Check fields
        fieldName = ''
        if self.optNewField.isChecked():
            if self.txtFieldName.text():

                fieldName = self.txtFieldName.text().strip()
                newField = QgsField( fieldName,
                    self.cboFieldType.itemData( self.cboFieldType.currentIndex(), Qt.UserRole) )

                length = self.txtFieldLength.value()
                precision = self.txtFieldPrecision.value()
                # Ensure length and precision are valid values when dealing with Real numbers
                if self.fieldTypesDict[self.cboFieldType.currentIndex()] == 'Real':
                    if precision > length:
                        precision = length
                newField.setLength( length )
                newField.setPrecision( precision )

                for item in self.tblLayers.selectedItems():
                    if item.column() == 1: # It's the layer name item
                        layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )
                        if layer.fieldNameIndex( fieldName ) != -1:
                            self.msg.show(
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] The field " ) + fieldName + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " already exists in layer " ) + layer.name() + ". " + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                'warning' )
                        else:
                            res = layer.dataProvider().addAttributes( [ newField ] )
                            if res:
                                layer.updateFields()

                                # Check if fieldName is preserved by the provider after field creation.
                                if layer.fieldNameIndex( fieldName ) == -1:
                                    self.msg.show(
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            "[Error] The field " ) + fieldName + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " was probably created with another name by the layer (" ) + \
                                        layer.name() + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            ") provider. " ) + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                        'warning' )
                                else:

                                    self.doSaveAutoField( layer, fieldName, expression )

                            else:
                                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] Couldn't create " ) + newField.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy",
                                        " field in " ) + layer.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy", " layer." ),
                                    'warning' )

                # Some fields might have been created, update the field list once
                self.updateFieldList()

            else:
                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                    "[Warning] Please first set a name for the new field." ), 'warning' )
                return
        else:
            fieldName = self.cboField.currentText()

            for item in self.tblLayers.selectedItems():
                if item.column() == 1: # It's the layer name item
                    layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )
                    self.doSaveAutoField( layer, fieldName, expression )
Beispiel #13
0
def reclassify(layer, exposure_key=None):
    """Reclassify a continuous vector layer.

    This function will modify the input.

    For instance if you want to reclassify like this table :
            Original Value     |   Class
            - ∞ < val <= 0     |     1
            0   < val <= 0.5   |     2
            0.5 < val <= 5     |     3
            5   < val <  + ∞   |     6

    You need a dictionary :
        ranges = OrderedDict()
        ranges[1] = [None, 0]
        ranges[2] = [0.0, 0.5]
        ranges[3] = [0.5, 5]
        ranges[6] = [5, None]

    :param layer: The raster layer.
    :type layer: QgsRasterLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str

    :return: The classified vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    output_layer_name = reclassify_vector_steps['output_layer_name']
    output_layer_name = output_layer_name % layer.keywords['title']

    # This layer should have this keyword, or it's a mistake from the dev.
    inasafe_fields = layer.keywords['inasafe_fields']
    continuous_column = inasafe_fields[hazard_value_field['key']]

    if exposure_key:
        classification_key = active_classification(
            layer.keywords, exposure_key)
        thresholds = active_thresholds_value_maps(layer.keywords, exposure_key)
        layer.keywords['thresholds'] = thresholds
        layer.keywords['classification'] = classification_key
    else:
        classification_key = layer.keywords.get('classification')
        thresholds = layer.keywords.get('thresholds')

    if not thresholds:
        raise InvalidKeywordsForProcessingAlgorithm(
            'thresholds are missing from the layer %s'
            % layer.keywords['layer_purpose'])

    continuous_index = layer.fields().lookupField(continuous_column)

    classified_field = QgsField()
    classified_field.setType(hazard_class_field['type'])
    classified_field.setName(hazard_class_field['field_name'])
    classified_field.setLength(hazard_class_field['length'])
    classified_field.setPrecision(hazard_class_field['precision'])

    layer.startEditing()
    layer.addAttribute(classified_field)

    classified_field_index = layer.fields(). \
        lookupField(classified_field.name())

    for feature in layer.getFeatures():
        attributes = feature.attributes()
        source_value = attributes[continuous_index]
        classified_value = reclassify_value(source_value, thresholds)
        if (classified_value is None
                or (hasattr(classified_value, 'isNull')
                    and classified_value.isNull())):
            layer.deleteFeature(feature.id())
        else:
            layer.changeAttributeValue(
                feature.id(), classified_field_index, classified_value)

    layer.commitChanges()
    layer.updateFields()

    # We transfer keywords to the output.
    inasafe_fields[hazard_class_field['key']] = (
        hazard_class_field['field_name'])

    value_map = {}

    hazard_classes = definition(classification_key)['classes']
    for hazard_class in reversed(hazard_classes):
        value_map[hazard_class['key']] = [hazard_class['value']]

    layer.keywords['value_map'] = value_map
    layer.keywords['title'] = output_layer_name

    check_layer(layer)
    return layer
Beispiel #14
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        fieldName = self.parameterAsString(parameters, self.FIELD, context)
        useField = bool(fieldName)

        field_index = None
        f = QgsField('value', QVariant.String, '', 255)
        if useField:
            field_index = source.fields().lookupField(fieldName)
            fType = source.fields()[field_index].type()
            if fType in [
                    QVariant.Int, QVariant.UInt, QVariant.LongLong,
                    QVariant.ULongLong
            ]:
                f.setType(fType)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 20))
        fields.append(f)
        fields.append(QgsField('area', QVariant.Double, '', 20, 6))
        fields.append(QgsField('perim', QVariant.Double, '', 20, 6))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Polygon,
                                               source.sourceCrs())

        outFeat = QgsFeature()
        outGeom = QgsGeometry()

        fid = 0
        val = None
        if useField:
            unique = source.uniqueValues(field_index)
            current = 0
            total = 100.0 / (source.featureCount() *
                             len(unique)) if source.featureCount() else 1
            for i in unique:
                if feedback.isCanceled():
                    break

                first = True
                hull = []
                features = source.getFeatures(
                    QgsFeatureRequest().setSubsetOfAttributes([field_index]))
                for f in features:
                    if feedback.isCanceled():
                        break

                    idVar = f.attributes()[field_index]
                    if str(idVar).strip() == str(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = f.geometry()
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    feedback.setProgress(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        if outGeom:
                            area = outGeom.geometry().area()
                            perim = outGeom.geometry().perimeter()
                        else:
                            area = NULL
                            perim = NULL
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
                    except:
                        raise QgsProcessingException(
                            self.tr('Exception while computing convex hull'))
                fid += 1
        else:
            hull = []
            total = 100.0 / source.featureCount() if source.featureCount(
            ) else 1
            features = source.getFeatures(
                QgsFeatureRequest().setSubsetOfAttributes([]))
            for current, f in enumerate(features):
                if feedback.isCanceled():
                    break

                inGeom = f.geometry()
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                feedback.setProgress(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                if outGeom:
                    area = outGeom.geometry().area()
                    perim = outGeom.geometry().perimeter()
                else:
                    area = NULL
                    perim = NULL
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, 'all', area, perim])
                sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
            except:
                raise QgsProcessingException(
                    self.tr('Exception while computing convex hull'))

        return {self.OUTPUT: dest_id}
def reclassify(layer, exposure_key=None, callback=None):
    """Reclassify a continuous vector layer.

    This function will modify the input.

    For instance if you want to reclassify like this table :
            Original Value     |   Class
            - ∞ < val <= 0     |     1
            0   < val <= 0.5   |     2
            0.5 < val <= 5     |     3
            5   < val <  + ∞   |     6

    You need a dictionary :
        ranges = OrderedDict()
        ranges[1] = [None, 0]
        ranges[2] = [0.0, 0.5]
        ranges[3] = [0.5, 5]
        ranges[6] = [5, None]

    :param layer: The raster layer.
    :type layer: QgsRasterLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str

    :param callback: A function to all to indicate progress. The function
        should accept params 'current' (int), 'maximum' (int) and 'step' (str).
        Defaults to None.
    :type callback: function

    :return: The classified vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    output_layer_name = reclassify_vector_steps['output_layer_name']
    output_layer_name = output_layer_name % layer.keywords['title']
    processing_step = reclassify_vector_steps['step_name']

    # This layer should have this keyword, or it's a mistake from the dev.
    inasafe_fields = layer.keywords['inasafe_fields']
    continuous_column = inasafe_fields[hazard_value_field['key']]

    if exposure_key:
        classification_key = active_classification(layer.keywords,
                                                   exposure_key)
        thresholds = active_thresholds_value_maps(layer.keywords, exposure_key)
        layer.keywords['thresholds'] = thresholds
        layer.keywords['classification'] = classification_key
    else:
        classification_key = layer.keywords.get('classification')
        thresholds = layer.keywords.get('thresholds')

    if not thresholds:
        raise InvalidKeywordsForProcessingAlgorithm(
            'thresholds are missing from the layer %s' %
            layer.keywords['layer_purpose'])

    continuous_index = layer.fieldNameIndex(continuous_column)

    classified_field = QgsField()
    classified_field.setType(hazard_class_field['type'])
    classified_field.setName(hazard_class_field['field_name'])
    classified_field.setLength(hazard_class_field['length'])
    classified_field.setPrecision(hazard_class_field['precision'])

    layer.startEditing()
    layer.addAttribute(classified_field)

    classified_field_index = layer.fieldNameIndex(classified_field.name())

    for feature in layer.getFeatures():
        attributes = feature.attributes()
        source_value = attributes[continuous_index]
        classified_value = _classified_value(source_value, thresholds)
        if not classified_value:
            layer.deleteFeature(feature.id())
        else:
            layer.changeAttributeValue(feature.id(), classified_field_index,
                                       classified_value)

    layer.commitChanges()
    layer.updateFields()

    # We transfer keywords to the output.
    inasafe_fields[hazard_class_field['key']] = (
        hazard_class_field['field_name'])

    value_map = {}

    hazard_classes = definition(classification_key)['classes']
    for hazard_class in reversed(hazard_classes):
        value_map[hazard_class['key']] = [hazard_class['value']]

    layer.keywords['value_map'] = value_map
    layer.keywords['title'] = output_layer_name

    check_layer(layer)
    return layer
Beispiel #16
0
    def on_btnRun_clicked(self):
        
        #Check for combo and list box selections
        if self.ui.cmbBaseLayer.count() < 1 or self.ui.cmbProcessLayer.count() < 1:
            QMessageBox.critical(self, 'Vector Geoprocessor', 'Invalid layer selection.')
            return
        if len(self.ui.listFields.selectedItems()) < 1:
            QMessageBox.critical(self, 'Vector Geoprocessor', 'Invalid field selection.')
            return            
      
        #Initializations
        self.ui.ProgressBar.setValue(0)
        self.setCursor(Qt.WaitCursor)
        data = []
            
        #Add new attributes to base layer
        bprovider = self.blayer.dataProvider()
        pprovider = self.player.dataProvider()
        pfields = pprovider.fields()
        for item in self.ui.listFields.selectedItems():
            fname = item.text()
            for fld in pfields.toList():
                if fname == fld.name():                                               
                    newfield = QgsField()
                    newfield.setName(fld.name())
                    newfield.setType(fld.type())
                    newfield.setTypeName(fld.typeName())
                    newfield.setLength(fld.length())
                    newfield.setPrecision(fld.precision())
                    newfield.setComment(fld.comment())
                    bprovider.addAttributes([newfield])            

        #Create a spatial index for faster processing
        spindex = QgsSpatialIndex()
        for pfeat in pprovider.getFeatures():
            spindex.insertFeature(pfeat)
        
        #Find the intersection of process layer features with base layer
        #To increase speed, intersect with a bounding box rectangle first
        #Then further process within the geometric shape
        #Add requested processed information to base layer                
        featreq = QgsFeatureRequest()
        bfields = bprovider.fields()
        ddic = {}
        len1 = len(self.ui.listFields.selectedItems())
        len2 = len(bfields)
        b1 = 0
        b2 = bprovider.featureCount()
        attr={}
        for bfeat in bprovider.getFeatures():
            b1+=1
            attr.clear()
            bgeom = bfeat.geometry()                                          
            intersect = spindex.intersects(bgeom.boundingBox())
            data[:] = []
            for fid in intersect:               
                pfeat = self.player.getFeatures(featreq.setFilterFid(fid)).next()
                if pfeat.geometry().intersects(bgeom) == False:
                    data.append(fid)           
            for fid in data:        
                intersect.pop(intersect.index(fid))
                              
            count = 0
            for item in self.ui.listFields.selectedItems():
                pfindx = pprovider.fieldNameIndex(item.text())
                if pfindx < 0:
                    self.setCursor(Qt.ArrowCursor)
                    QMessageBox.critical(self, 'Vector Geoprocessor', 'Processing error.')
                    return
                data[:] = []
                for fid in intersect:
                    pfeat = self.player.getFeatures(featreq.setFilterFid(fid)).next()
                    if self.oindex in [0,1,2,3,4]:
                        data.append(float(pfeat.attribute(item.text())))
                    elif self.oindex in [5,6]:
                        data.append(str(pfeat.attribute(item.text())))
                if len(data) == 0:
                    value = None
                elif self.oindex == 0: #Find mean value of points within polygons
                    value = sum(data)/float(len(data))
                elif self.oindex == 1: #Find median value of points within polygons
                    data = sorted(data)
                    lendata = len(data)
                    if lendata % 2:
                        value = data[(lendata+1)/2-1]
                    else:
                        d1 = data[lendata/2-1]
                        d2 = data[lendata/2]
                        value = (d1 + d2)/2.0
                elif self.oindex == 2: #Find maximum value of points within polygons
                    value = max(data)
                elif self.oindex == 3: #Find minimum value of points within polygons
                    value = min(data)
                elif self.oindex == 4: #Find mean value (area-weighted) of polygons within polygons
                    value = 0.0
                    totalarea = 0.0
                    for fid in intersect:
                        pfeat = self.player.getFeatures(featreq.setFilterFid(fid)).next()
                        pgeom = pfeat.geometry()
                        isect = bgeom.intersection(pgeom)
                        parea = isect.area()
                        value+=(float(pfeat.attribute(item.text())*parea))
                        totalarea+=parea
                    value = value / totalarea
                elif self.oindex == 5: #Find largest area polygon within polygons
                    data = list(set(data))  #Get unique items in data                          
                    ddic.clear()
                    for i in data:
                        ddic.update({i : 0.0})
                    for fid in intersect:
                        pfeat = self.player.getFeatures(featreq.setFilterFid(fid)).next()
                        pgeom = pfeat.geometry()
                        isect = bgeom.intersection(pgeom)
                        parea = isect.area()
                        key = str(pfeat.attribute(item.text()))
                        parea = parea + ddic[key]
                        ddic.update({key : parea})
                    parea = -1
                    for key in ddic.keys():
                        if ddic[key] > parea:
                            parea = ddic[key]
                            value = key
                elif self.oindex == 6: #Add polygon attribute to points
                    if len(data) != 1:
                        QMessageBox.warning(self, 'Vector Geoprocessor',
                                            'Point intersects more than one polygon.')
                    value = data[0]
                
                attr.update({(len2-len1+count):value})
                count+=1
            result = bprovider.changeAttributeValues({bfeat.id():attr})
            if not result:
                QMessageBox.critical(self, 'Vector Geoprocessor', 'Could not change attribute value.')
                return           
            self.ui.ProgressBar.setValue(float(b1)/float(b2) * 100.0)
            QApplication.processEvents()

        self.setCursor(Qt.ArrowCursor)
Beispiel #17
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
        useField = self.getParameterValue(self.METHOD) == 1
        fieldName = self.getParameterValue(self.FIELD)

        f = QgsField("value", QVariant.String, "", 255)
        if useField:
            index = layer.fields().lookupField(fieldName)
            fType = layer.fields()[index].type()
            if fType in [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong]:
                f.setType(fType)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = [
            QgsField("id", QVariant.Int, "", 20),
            f,
            QgsField("area", QVariant.Double, "", 20, 6),
            QgsField("perim", QVariant.Double, "", 20, 6),
        ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs())

        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()

        fid = 0
        val = None
        features = vector.features(layer)
        if useField:
            unique = layer.uniqueValues(index)
            current = 0
            total = 100.0 / (len(features) * len(unique))
            for i in unique:
                first = True
                hull = []
                features = vector.features(layer)
                for f in features:
                    idVar = f[fieldName]
                    if str(idVar).strip() == str(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = f.geometry()
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    progress.setPercentage(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        (area, perim) = vector.simpleMeasure(outGeom)
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        writer.addFeature(outFeat)
                    except:
                        raise GeoAlgorithmExecutionException(self.tr("Exception while computing convex hull"))
                fid += 1
        else:
            hull = []
            total = 100.0 / layer.featureCount()
            features = vector.features(layer)
            for current, f in enumerate(features):
                inGeom = f.geometry()
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                progress.setPercentage(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                (area, perim) = vector.simpleMeasure(outGeom)
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, "all", area, perim])
                writer.addFeature(outFeat)
            except:
                raise GeoAlgorithmExecutionException(self.tr("Exception while computing convex hull"))

        del writer
Beispiel #18
0
    def CheckControlFile(self):

        #Open control file
        if not os.path.exists(self.cfilename):
            QMessageBox.critical(self, 'Simulation Controller',
                                 'Control file does not exist.')
            return 1
        else:
            self.cfile = ControlFile.ControlFile()
            ret = self.cfile.ReadFile(self.cfilename)
            if ret:
                QMessageBox.critical(self, 'Simulation Controller',
                                     'Error reading control file.')
                return 1

        #Set working directory
        if not os.path.exists(self.cfile.ModelDirectory):
            QMessageBox.critical(self, 'Simulation Controller',
                                 'Model directory does not exist.')
            return 1
        else:
            os.chdir(self.cfile.ModelDirectory)

        #Get base layer
        count = 0
        for i in self.layers:
            if i.name() == self.cfile.BaseLayer:
                self.blayer = i
                self.bprovider = self.blayer.dataProvider()
                count += 1
        if not count:  #Count==0
            QMessageBox.critical(self, 'Simulation Controller',
                                 'Base layer not found.')
            return 1
        if count > 1:
            QMessageBox.critical(
                self, 'Simulation Controller',
                'Found more than one layer with base layer name.')
            return 1

        #Check template files
        for key in sorted(self.cfile.TemplateInput.keys()):
            if not os.path.exists(self.cfile.TemplateInput[key][0]):
                QMessageBox.critical(
                    self, 'Simulation Controller', 'File does not exist: %s' %
                    self.cfile.TemplateInput[key][0])
                return 1
            else:
                f = open(self.cfile.TemplateInput[key][0], 'r')
                lines = f.readlines()
                f.close()
                if lines[0][
                        0:41] != 'Geospatial Simulation Template (GST) File':
                    QMessageBox.critical(self, 'Simulation Controller',
                                         'Check template file.')
                    return 1

        #Check for input attributes in base layer
        for key in sorted(self.cfile.AttributeCode.keys()):
            bfindx = self.bprovider.fieldNameIndex(
                self.cfile.AttributeCode[key][0])
            if bfindx < 0:
                QMessageBox.critical(
                    self, 'Simulation Controller',
                    'Missing attribute in base layer: %s' %
                    self.cfile.AttributeCode[key][0])
                return 1

        #Check instruction files
        for key in sorted(self.cfile.InstructionOutput.keys()):
            if not os.path.exists(self.cfile.InstructionOutput[key][0]):
                QMessageBox.critical(
                    self, 'Simulation Controller', 'File does not exist: %s' %
                    self.cfile.InstructionOutput[key][0])
                return 1
            else:
                f = open(self.cfile.InstructionOutput[key][0], 'r')
                lines = f.readlines()
                f.close()
                if lines[0][
                        0:44] != 'Geospatial Simulation Instruction (GSI) File':
                    QMessageBox.critical(self, 'Simulation Controller',
                                         'Check instruction file.')
                    return 1
                for line in lines[1:]:
                    line = line.split(',')
                    if len(line) < 2:
                        continue
                    found = 0
                    for key in sorted(self.cfile.AttributeType.keys()):
                        if self.cfile.AttributeType[key][0] == line[0]:
                            found = 1
                            break
                    if not found:
                        QMessageBox.critical(
                            self, 'Simulation Controller',
                            'Check control file for missing output attribute: '
                            + line[0])
                        return 1

        #Check for output attributes in base layer.  Add if missing.
        for key in sorted(self.cfile.AttributeType.keys()):
            typename = self.cfile.AttributeType[key][1].split('(')[0]
            length = self.cfile.AttributeType[key][1].split('(')[1]
            bfindx = self.bprovider.fieldNameIndex(
                self.cfile.AttributeType[key][0])
            if bfindx < 0:  #Field not found, must add it
                newfield = QgsField()
                newfield.setName(self.cfile.AttributeType[key][0])
                if typename in ['String', 'string', 'STRING']:
                    newfield.setType(QVariant.String)
                    newfield.setTypeName('String')
                    newfield.setLength(int(length.split(')')[0]))
                elif typename in ['Integer', 'integer', 'INTEGER']:
                    newfield.setType(QVariant.Int)
                    newfield.setTypeName('Integer')
                    newfield.setLength(int(length.split(')')[0]))
                elif typename in ['Real', 'real', 'REAL']:
                    newfield.setType(QVariant.Double)
                    newfield.setTypeName('Real')
                    newfield.setLength(int(length.split('.')[0]))
                    newfield.setPrecision(
                        int(length.split('.')[1].split(')')[0]))
                self.bprovider.addAttributes([newfield])

        #Enable Run button
        self.ui.btnRun.setEnabled(True)

        return 0
Beispiel #19
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        useField = self.getParameterValue(self.METHOD) == 1
        fieldName = self.getParameterValue(self.FIELD)

        f = QgsField('value', QVariant.String, '', 255)
        if useField:
            index = layer.fields().lookupField(fieldName)
            fType = layer.fields()[index].type()
            if fType in [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong]:
                f.setType(fType)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = [QgsField('id', QVariant.Int, '', 20),
                  f,
                  QgsField('area', QVariant.Double, '', 20, 6),
                  QgsField('perim', QVariant.Double, '', 20, 6)
                  ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QgsWkbTypes.Polygon, layer.crs())

        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()

        fid = 0
        val = None
        features = vector.features(layer)
        if useField:
            unique = layer.uniqueValues(index)
            current = 0
            total = 100.0 / (len(features) * len(unique))
            for i in unique:
                first = True
                hull = []
                features = vector.features(layer)
                for f in features:
                    idVar = f[fieldName]
                    if str(idVar).strip() == str(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = f.geometry()
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    progress.setPercentage(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        (area, perim) = vector.simpleMeasure(outGeom)
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        writer.addFeature(outFeat)
                    except:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Exception while computing convex hull'))
                fid += 1
        else:
            hull = []
            total = 100.0 / layer.featureCount()
            features = vector.features(layer)
            for current, f in enumerate(features):
                inGeom = f.geometry()
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                progress.setPercentage(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                (area, perim) = vector.simpleMeasure(outGeom)
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, 'all', area, perim])
                writer.addFeature(outFeat)
            except:
                raise GeoAlgorithmExecutionException(
                    self.tr('Exception while computing convex hull'))

        del writer
Beispiel #20
0
def update_value_map(layer, exposure_key=None, callback=None):
    """Assign inasafe values according to definitions for a vector layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str

    :param callback: A function to all to indicate progress. The function
        should accept params 'current' (int), 'maximum' (int) and 'step' (str).
        Defaults to None.
    :type callback: function

    :return: The classified vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    output_layer_name = assign_inasafe_values_steps['output_layer_name']
    processing_step = assign_inasafe_values_steps['step_name']
    output_layer_name = output_layer_name % layer.keywords['layer_purpose']

    keywords = layer.keywords
    inasafe_fields = keywords['inasafe_fields']

    classification = None
    if keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not inasafe_fields.get(hazard_value_field['key']):
            raise InvalidKeywordsForProcessingAlgorithm
        old_field = hazard_value_field
        new_field = hazard_class_field
        classification = active_classification(layer.keywords, exposure_key)

    elif keywords['layer_purpose'] == layer_purpose_exposure['key']:
        if not inasafe_fields.get(exposure_type_field['key']):
            raise InvalidKeywordsForProcessingAlgorithm
        old_field = exposure_type_field
        new_field = exposure_class_field
    else:
        raise InvalidKeywordsForProcessingAlgorithm

    # It's a hazard layer
    if exposure_key:
        if not active_thresholds_value_maps(keywords, exposure_key):
            raise InvalidKeywordsForProcessingAlgorithm
        value_map = active_thresholds_value_maps(keywords, exposure_key)
    # It's exposure layer
    else:
        if not keywords.get('value_map'):
            raise InvalidKeywordsForProcessingAlgorithm
        value_map = keywords.get('value_map')

    unclassified_column = inasafe_fields[old_field['key']]
    unclassified_index = layer.fieldNameIndex(unclassified_column)

    reversed_value_map = {}
    for inasafe_class, values in value_map.iteritems():
        for val in values:
            reversed_value_map[val] = inasafe_class

    classified_field = QgsField()
    classified_field.setType(new_field['type'])
    classified_field.setName(new_field['field_name'])
    classified_field.setLength(new_field['length'])
    classified_field.setPrecision(new_field['precision'])

    layer.startEditing()
    layer.addAttribute(classified_field)

    classified_field_index = layer.fieldNameIndex(classified_field.name())

    for feature in layer.getFeatures():
        attributes = feature.attributes()
        source_value = attributes[unclassified_index]
        classified_value = reversed_value_map.get(source_value)

        if not classified_value:
            classified_value = ''

        layer.changeAttributeValue(
            feature.id(), classified_field_index, classified_value)

    layer.commitChanges()

    remove_fields(layer, [unclassified_column])

    # We transfer keywords to the output.
    # We add new class field
    inasafe_fields[new_field['key']] = new_field['field_name']

    # and we remove hazard value field
    inasafe_fields.pop(old_field['key'])

    layer.keywords = keywords
    layer.keywords['inasafe_fields'] = inasafe_fields
    if exposure_key:
        value_map_key = 'value_maps'
    else:
        value_map_key = 'value_map'
    if value_map_key in layer.keywords.keys():
        layer.keywords.pop(value_map_key)
    layer.keywords['title'] = output_layer_name
    if classification:
        layer.keywords['classification'] = classification

    check_layer(layer)
    return layer
Beispiel #21
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
        useField = self.getParameterValue(self.METHOD) == 1
        fieldName = self.getParameterValue(self.FIELD)

        f = QgsField('value', QVariant.String, '', 255)
        if useField:
            index = layer.fields().lookupField(fieldName)
            fType = layer.fields()[index].type()
            if fType in [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong]:
                f.setType(fType)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 20))
        fields.append(f)
        fields.append(QgsField('area', QVariant.Double, '', 20, 6))
        fields.append(QgsField('perim', QVariant.Double, '', 20, 6))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs(), context)

        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()

        fid = 0
        val = None
        features = QgsProcessingUtils.getFeatures(layer, context)
        if useField:
            unique = layer.uniqueValues(index)
            current = 0
            total = 100.0 / (layer.featureCount() * len(unique)) if layer.featureCount() else 1
            for i in unique:
                first = True
                hull = []
                features = QgsProcessingUtils.getFeatures(layer, context)
                for f in features:
                    idVar = f[fieldName]
                    if str(idVar).strip() == str(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = f.geometry()
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    feedback.setProgress(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        (area, perim) = vector.simpleMeasure(outGeom)
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
                    except:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Exception while computing convex hull'))
                fid += 1
        else:
            hull = []
            total = 100.0 / layer.featureCount() if layer.featureCount() else 1
            features = QgsProcessingUtils.getFeatures(layer, context)
            for current, f in enumerate(features):
                inGeom = f.geometry()
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                feedback.setProgress(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                (area, perim) = vector.simpleMeasure(outGeom)
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, 'all', area, perim])
                writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
            except:
                raise GeoAlgorithmExecutionException(
                    self.tr('Exception while computing convex hull'))

        del writer
Beispiel #22
0
    def on_btnRun_clicked(self):

        #Check for combo and list box selections
        if self.ui.cmbBaseLayer.count() < 1 or self.ui.cmbProcessLayer.count(
        ) < 1:
            QMessageBox.critical(self, 'Vector Geoprocessor',
                                 'Invalid layer selection.')
            return
        if len(self.ui.listFields.selectedItems()) < 1:
            QMessageBox.critical(self, 'Vector Geoprocessor',
                                 'Invalid field selection.')
            return

        #Initializations
        self.ui.ProgressBar.setValue(0)
        self.setCursor(Qt.WaitCursor)
        data = []

        #Add new attributes to base layer
        bprovider = self.blayer.dataProvider()
        pprovider = self.player.dataProvider()
        pfields = pprovider.fields()
        for item in self.ui.listFields.selectedItems():
            fname = item.text()
            for fld in pfields.toList():
                if fname == fld.name():
                    newfield = QgsField()
                    newfield.setName(fld.name())
                    newfield.setType(fld.type())
                    newfield.setTypeName(fld.typeName())
                    newfield.setLength(fld.length())
                    newfield.setPrecision(fld.precision())
                    newfield.setComment(fld.comment())
                    bprovider.addAttributes([newfield])

        #Create a spatial index for faster processing
        spindex = QgsSpatialIndex()
        for pfeat in pprovider.getFeatures():
            spindex.insertFeature(pfeat)

        #Find the intersection of process layer features with base layer
        #To increase speed, intersect with a bounding box rectangle first
        #Then further process within the geometric shape
        #Add requested processed information to base layer
        featreq = QgsFeatureRequest()
        bfields = bprovider.fields()
        ddic = {}
        len1 = len(self.ui.listFields.selectedItems())
        len2 = len(bfields)
        b1 = 0
        b2 = bprovider.featureCount()
        attr = {}
        for bfeat in bprovider.getFeatures():
            b1 += 1
            attr.clear()
            bgeom = bfeat.geometry()
            intersect = spindex.intersects(bgeom.boundingBox())
            data[:] = []
            for fid in intersect:
                pfeat = next(self.player.getFeatures(
                    featreq.setFilterFid(fid)))
                if pfeat.geometry().intersects(bgeom) == False:
                    data.append(fid)
            for fid in data:
                intersect.pop(intersect.index(fid))

            count = 0
            for item in self.ui.listFields.selectedItems():
                pfindx = pprovider.fieldNameIndex(item.text())
                if pfindx < 0:
                    self.setCursor(Qt.ArrowCursor)
                    QMessageBox.critical(self, 'Vector Geoprocessor',
                                         'Processing error.')
                    return
                data[:] = []
                for fid in intersect:
                    pfeat = next(
                        self.player.getFeatures(featreq.setFilterFid(fid)))
                    if self.oindex in [0, 1, 2, 3, 4]:
                        data.append(float(pfeat.attribute(item.text())))
                    elif self.oindex in [5, 6]:
                        data.append(str(pfeat.attribute(item.text())))
                if len(data) == 0:
                    value = None
                elif self.oindex == 0:  #Find mean value of points within polygons
                    value = sum(data) / float(len(data))
                elif self.oindex == 1:  #Find median value of points within polygons
                    data = sorted(data)
                    lendata = len(data)
                    if lendata % 2:
                        value = data[(lendata + 1) / 2 - 1]
                    else:
                        d1 = data[lendata / 2 - 1]
                        d2 = data[lendata / 2]
                        value = (d1 + d2) / 2.0
                elif self.oindex == 2:  #Find maximum value of points within polygons
                    value = max(data)
                elif self.oindex == 3:  #Find minimum value of points within polygons
                    value = min(data)
                elif self.oindex == 4:  #Find mean value (area-weighted) of polygons within polygons
                    value = 0.0
                    totalarea = 0.0
                    for fid in intersect:
                        pfeat = next(
                            self.player.getFeatures(featreq.setFilterFid(fid)))
                        pgeom = pfeat.geometry()
                        isect = bgeom.intersection(pgeom)
                        parea = isect.area()
                        value += (float(pfeat.attribute(item.text()) * parea))
                        totalarea += parea
                    value = value / totalarea
                elif self.oindex == 5:  #Find largest area polygon within polygons
                    data = list(set(data))  #Get unique items in data
                    ddic.clear()
                    for i in data:
                        ddic.update({i: 0.0})
                    for fid in intersect:
                        pfeat = next(
                            self.player.getFeatures(featreq.setFilterFid(fid)))
                        pgeom = pfeat.geometry()
                        isect = bgeom.intersection(pgeom)
                        parea = isect.area()
                        key = str(pfeat.attribute(item.text()))
                        parea = parea + ddic[key]
                        ddic.update({key: parea})
                    parea = -1
                    for key in list(ddic.keys()):
                        if ddic[key] > parea:
                            parea = ddic[key]
                            value = key
                elif self.oindex == 6:  #Add polygon attribute to points
                    if len(data) != 1:
                        QMessageBox.warning(
                            self, 'Vector Geoprocessor',
                            'Point intersects more than one polygon.')
                    value = data[0]

                attr.update({(len2 - len1 + count): value})
                count += 1
            result = bprovider.changeAttributeValues({bfeat.id(): attr})
            if not result:
                QMessageBox.critical(self, 'Vector Geoprocessor',
                                     'Could not change attribute value.')
                return
            self.ui.ProgressBar.setValue(float(b1) / float(b2) * 100.0)
            QApplication.processEvents()

        self.setCursor(Qt.ArrowCursor)
Beispiel #23
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        # Retrieve the feature source and sink. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        source = self.parameterAsSource(
            parameters,
            self.INPUT,
            context
        )

        # If source was not found, throw an exception to indicate that the
        # algorithm encountered a fatal error. The exception text can be any
        # string, but in this case we use the pre-built invalidSourceError
        # method to return a standard helper text for when a source cannot be
        # evaluated
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        fields_to_transform = self.parameterAsFields(
            parameters, self.FIELDS_TO_TRANSFORM, context)
        source_fields = source.fields()
        if not fields_to_transform:
            # no fields selected, use all numeric ones
            fields_to_transform = [source_fields.at(i).name()
                                   for i in range(len(source_fields))
                                   if source_fields.at(i).isNumeric()]
        self.transformed_fields = QgsFields()

        transformation_name = self.name()

        fields_to_transform_idxs = []
        for f in fields_to_transform:
            idx = source.fields().lookupField(f)
            if idx >= 0:
                fields_to_transform_idxs.append(idx)
                field_to_transform = source.fields().at(idx)
                if field_to_transform.isNumeric():
                    transformed_field = QgsField(field_to_transform)
                    transformed_field.setName(
                        "%s_%s" % (field_to_transform.name(),
                                   transformation_name))
                    transformed_field.setType(QVariant.Double)
                    transformed_field.setLength(20)
                    transformed_field.setPrecision(6)
                    self.transformed_fields.append(transformed_field)

        out_fields = QgsProcessingUtils.combineFields(
            source_fields, self.transformed_fields)

        (sink, self.dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT,
            context,
            out_fields,
            source.wkbType(),
            source.sourceCrs()
        )

        # Send some information to the user
        feedback.pushInfo('CRS is {}'.format(source.sourceCrs().authid()))

        # If sink was not created, throw an exception to indicate that the
        # algorithm encountered a fatal error. The exception text can be any
        # string, but in this case we use the pre-built invalidSinkError method
        # to return a standard helper text for when a sink cannot be evaluated
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        total = 100.0 / len(fields_to_transform)
        transformed_values = {}

        for current, fieldname_to_transform in enumerate(fields_to_transform):
            original_values = vector.values(
                source, fieldname_to_transform)[fieldname_to_transform]
            transformed_values[fieldname_to_transform] = self.transform_values(
                original_values, parameters, context)
            feedback.setProgress(int(current * total))

        feedback.setProgress(0)

        # Compute the number of steps to display within the progress bar and
        # get features from source
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        for current, source_feature in enumerate(source.getFeatures()):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break

            sink_feature = QgsFeature(out_fields)

            # copy original fields
            for field in source.fields():
                sink_feature[field.name()] = source_feature[field.name()]

            for original_fieldname, transformed_field in zip(
                    fields_to_transform, self.transformed_fields):
                sink_feature[transformed_field.name()] = \
                    transformed_values[original_fieldname][current]
            sink_feature.setGeometry(source_feature.geometry())

            # Add a feature in the sink
            sink.addFeature(sink_feature, QgsFeatureSink.FastInsert)

            # Update the progress bar
            feedback.setProgress(int(current * total))

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: self.dest_id}
Beispiel #24
0
    def addResultToLayer(self, newOutputLayer):
        ''' prepare results to be integrated in gis context
        '''
        try:
            # start editing
            newOutputLayer.startEditing()

            # read the out file and for each line update relative record in the result
            with open(self.algOutputFileName, 'r') as algOutputFile:

                # read all lines
                managedHeader = False
                fieldNameIndexMap = {}
                fieldNames = None
                for line in algOutputFile:
                    line = line.strip()

                    # manage header
                    if not managedHeader:
                        managedHeader = True

                        # add columns to the output layer
                        fieldNames = line.split('\t')
                        fieldNames = [x.split('(')[0] for x in fieldNames]
                        for fieldName in fieldNames:
                            # check if field is already available
                            if newOutputLayer.fieldNameIndex(fieldName) >= 0:
                                continue

                            # add the new field
                            newField = QgsField(fieldName,
                                                QtCore.QVariant.Double)
                            newField.setLength(7)
                            newField.setPrecision(5)
                            added = newOutputLayer.addAttribute(newField)
                            if not added:
                                raise Exception(
                                    self.
                                    tr('Can not add fieldname {} to the output vector'
                                       .format(fieldName)))

                        newOutputLayer.updateFields()

                        # add the fieldName in fieldNames
                        for fieldName in fieldNames:
                            fieldNameIndexMap[
                                fieldName] = newOutputLayer.fieldNameIndex(
                                    fieldName)

                        # jump to the next line = values
                        continue

                    # map values with fieldnames
                    values = line.split('\t')
                    fieldValueMap = zip(fieldNames, values)

                    # update record
                    id = None
                    for columnIndex, (fieldName,
                                      fieldValue) in enumerate(fieldValueMap):

                        if columnIndex == 0:
                            id = int(fieldValue)
                            continue

                        fieldValue = float(fieldValue)
                        newOutputLayer.changeAttributeValue(
                            id - 1, fieldNameIndexMap[fieldName], fieldValue)

        except Exception as ex:
            # rollback
            newOutputLayer.rollBack()

            traceback.print_exc()
            QgsMessageLog.logMessage(str(ex), 'QTraffic',
                                     QgsMessageLog.CRITICAL)
            iface.messageBar().pushCritical(
                'QTraffic',
                self.tr("Error formatting alg result in the output layer"))

        else:
            if not newOutputLayer.commitChanges():
                raise Exception(
                    self.tr('Error committing changes in the result layer'))
    def saveAutoField(self):
        """ Do some validation and then call AutoFieldManager """

        # Check layers
        if not self.tblLayers.selectedItems():
            self.msg.show(
                QApplication.translate(
                    "AutoFieldsDockWidgetPy",
                    "[Warning] Please first select a layer."), 'warning')
            return

        # Check expression
        expression = u''
        if self.optXCoord.isChecked():
            expression = u'$x'
        elif self.optYCoord.isChecked():
            expression = u'$y'
        elif self.optLength.isChecked():
            expression = u'$length'
        elif self.optPerimeter.isChecked():
            expression = u'$perimeter'
        elif self.optArea.isChecked():
            expression = u'$area'
        elif self.optDate.isChecked():
            expression = u'now()'
        elif self.optCustomExpression.isChecked():
            if self.expressionDlg:
                expression = self.expressionDlg.expression
            if not self.expressionDlg or not expression:
                self.msg.show(
                    QApplication.translate(
                        "AutoFieldsDockWidgetPy",
                        "[Warning] Please first set a valid custom expression."
                    ), 'warning')
                return
        else:  # optSpatialValue
            pass

        # Check fields
        fieldName = ''
        if self.optNewField.isChecked():
            if self.txtFieldName.text():

                fieldName = self.txtFieldName.text().strip()
                newField = QgsField(
                    fieldName,
                    self.cboFieldType.itemData(
                        self.cboFieldType.currentIndex(), Qt.UserRole))

                length = self.txtFieldLength.value()
                precision = self.txtFieldPrecision.value()
                # Ensure length and precision are valid values when dealing with Real numbers
                if self.fieldTypesDict[
                        self.cboFieldType.currentIndex()] == 'Real':
                    if precision > length:
                        precision = length
                newField.setLength(length)
                newField.setPrecision(precision)

                for item in self.tblLayers.selectedItems():
                    if item.column() == 1:  # It's the layer name item
                        layer = QgsMapLayerRegistry.instance().mapLayer(
                            item.data(Qt.UserRole))
                        if layer.fieldNameIndex(fieldName) != -1:
                            self.msg.show(
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] The field " ) + fieldName + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " already exists in layer " ) + layer.name() + ". " + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                'warning' )
                        else:
                            res = layer.dataProvider().addAttributes(
                                [newField])
                            if res:
                                layer.updateFields()

                                # Check if fieldName is preserved by the provider after field creation.
                                if layer.fieldNameIndex(fieldName) == -1:
                                    self.msg.show(
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            "[Error] The field " ) + fieldName + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " was probably created with another name by the layer (" ) + \
                                        layer.name() + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            ") provider. " ) + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                        'warning' )
                                else:

                                    self.doSaveAutoField(
                                        layer, fieldName, expression)

                            else:
                                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] Couldn't create " ) + newField.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy",
                                        " field in " ) + layer.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy", " layer." ),
                                    'warning' )

                # Some fields might have been created, update the field list once
                self.updateFieldList()

            else:
                self.msg.show(
                    QApplication.translate(
                        "AutoFieldsDockWidgetPy",
                        "[Warning] Please first set a name for the new field."
                    ), 'warning')
                return
        else:
            fieldName = self.cboField.currentText()

            for item in self.tblLayers.selectedItems():
                if item.column() == 1:  # It's the layer name item
                    layer = QgsMapLayerRegistry.instance().mapLayer(
                        item.data(Qt.UserRole))
                    self.doSaveAutoField(layer, fieldName, expression)
Beispiel #26
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        useField = self.getParameterValue(self.METHOD) == 1
        fieldName = self.getParameterValue(self.FIELD)

        f = QgsField('value', QVariant.String, '', 255)
        if useField:
            index = layer.fieldNameIndex(fieldName)
            fType = layer.pendingFields()[index].type()
            if fType == QVariant.Int:
                f.setType(QVariant.Int)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = [QgsField('id', QVariant.Int, '', 20),
                  f,
                  QgsField('area', QVariant.Double, '', 20, 6),
                  QgsField('perim', QVariant.Double, '', 20, 6)
                 ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QGis.WKBPolygon, layer.dataProvider().crs())

        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()

        current = 0

        fid = 0
        val = None
        features = vector.features(layer)
        if useField:
            unique = layer.uniqueValues(index)
            total = 100.0 / (len(features) * len(unique))
            for i in unique:
                first = True
                hull = []
                features = vector.features(layer)
                for f in features:
                    idVar = f[fieldName]
                    if unicode(idVar).strip() == unicode(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = QgsGeometry(f.geometry())
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    progress.setPercentage(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        (area, perim) = vector.simpleMeasure(outGeom)
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        writer.addFeature(outFeat)
                    except:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Exception while computing convex hull'))
                fid += 1
        else:
            hull = []
            total = 100.0 / float(layer.featureCount())
            features = vector.features(layer)
            for f in features:
                inGeom = QgsGeometry(f.geometry())
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                current += 1
                progress.setPercentage(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                (area, perim) = vector.simpleMeasure(outGeom)
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, 'all', area, perim])
                writer.addFeature(outFeat)
            except:
                raise GeoAlgorithmExecutionException(
                    self.tr('Exception while computing convex hull'))

        del writer
Beispiel #27
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        fieldName = self.parameterAsString(parameters, self.FIELD, context)
        useField = bool(fieldName)

        field_index = None
        f = QgsField('value', QVariant.String, '', 255)
        if useField:
            field_index = source.fields().lookupField(fieldName)
            fType = source.fields()[field_index].type()
            if fType in [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong]:
                f.setType(fType)
                f.setLength(20)
            elif fType == QVariant.Double:
                f.setType(QVariant.Double)
                f.setLength(20)
                f.setPrecision(6)
            else:
                f.setType(QVariant.String)
                f.setLength(255)

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 20))
        fields.append(f)
        fields.append(QgsField('area', QVariant.Double, '', 20, 6))
        fields.append(QgsField('perim', QVariant.Double, '', 20, 6))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Polygon, source.sourceCrs())

        outFeat = QgsFeature()
        outGeom = QgsGeometry()

        fid = 0
        val = None
        if useField:
            unique = source.uniqueValues(field_index)
            current = 0
            total = 100.0 / (source.featureCount() * len(unique)) if source.featureCount() else 1
            for i in unique:
                if feedback.isCanceled():
                    break

                first = True
                hull = []
                features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([field_index]))
                for f in features:
                    if feedback.isCanceled():
                        break

                    idVar = f.attributes()[field_index]
                    if str(idVar).strip() == str(i).strip():
                        if first:
                            val = idVar
                            first = False

                        inGeom = f.geometry()
                        points = vector.extractPoints(inGeom)
                        hull.extend(points)
                    current += 1
                    feedback.setProgress(int(current * total))

                if len(hull) >= 3:
                    tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
                    try:
                        outGeom = tmpGeom.convexHull()
                        if outGeom:
                            area = outGeom.geometry().area()
                            perim = outGeom.geometry().perimeter()
                        else:
                            area = NULL
                            perim = NULL
                        outFeat.setGeometry(outGeom)
                        outFeat.setAttributes([fid, val, area, perim])
                        sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
                    except:
                        raise QgsProcessingException(
                            self.tr('Exception while computing convex hull'))
                fid += 1
        else:
            hull = []
            total = 100.0 / source.featureCount() if source.featureCount() else 1
            features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]))
            for current, f in enumerate(features):
                if feedback.isCanceled():
                    break

                inGeom = f.geometry()
                points = vector.extractPoints(inGeom)
                hull.extend(points)
                feedback.setProgress(int(current * total))

            tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
            try:
                outGeom = tmpGeom.convexHull()
                if outGeom:
                    area = outGeom.geometry().area()
                    perim = outGeom.geometry().perimeter()
                else:
                    area = NULL
                    perim = NULL
                outFeat.setGeometry(outGeom)
                outFeat.setAttributes([0, 'all', area, perim])
                sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
            except:
                raise QgsProcessingException(
                    self.tr('Exception while computing convex hull'))

        return {self.OUTPUT: dest_id}
Beispiel #28
0
def update_value_map(layer, exposure_key=None):
    """Assign inasafe values according to definitions for a vector layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str

    :return: The classified vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    output_layer_name = assign_inasafe_values_steps['output_layer_name']
    output_layer_name = output_layer_name % layer.keywords['layer_purpose']

    keywords = layer.keywords
    inasafe_fields = keywords['inasafe_fields']

    classification = None
    if keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not inasafe_fields.get(hazard_value_field['key']):
            raise InvalidKeywordsForProcessingAlgorithm
        old_field = hazard_value_field
        new_field = hazard_class_field
        classification = active_classification(layer.keywords, exposure_key)

    elif keywords['layer_purpose'] == layer_purpose_exposure['key']:
        if not inasafe_fields.get(exposure_type_field['key']):
            raise InvalidKeywordsForProcessingAlgorithm
        old_field = exposure_type_field
        new_field = exposure_class_field
    else:
        raise InvalidKeywordsForProcessingAlgorithm

    # It's a hazard layer
    if exposure_key:
        if not active_thresholds_value_maps(keywords, exposure_key):
            raise InvalidKeywordsForProcessingAlgorithm
        value_map = active_thresholds_value_maps(keywords, exposure_key)
    # It's exposure layer
    else:
        if not keywords.get('value_map'):
            raise InvalidKeywordsForProcessingAlgorithm
        value_map = keywords.get('value_map')

    unclassified_column = inasafe_fields[old_field['key']]
    unclassified_index = layer.fields().lookupField(unclassified_column)

    reversed_value_map = {}
    for inasafe_class, values in list(value_map.items()):
        for val in values:
            reversed_value_map[val] = inasafe_class

    classified_field = QgsField()
    classified_field.setType(new_field['type'])
    classified_field.setName(new_field['field_name'])
    classified_field.setLength(new_field['length'])
    classified_field.setPrecision(new_field['precision'])

    layer.startEditing()
    layer.addAttribute(classified_field)

    classified_field_index = layer.fields(). \
        lookupField(classified_field.name())

    for feature in layer.getFeatures():
        attributes = feature.attributes()
        source_value = attributes[unclassified_index]
        classified_value = reversed_value_map.get(source_value)

        if not classified_value:
            classified_value = ''

        layer.changeAttributeValue(feature.id(), classified_field_index,
                                   classified_value)

    layer.commitChanges()

    remove_fields(layer, [unclassified_column])

    # We transfer keywords to the output.
    # We add new class field
    inasafe_fields[new_field['key']] = new_field['field_name']

    # and we remove hazard value field
    inasafe_fields.pop(old_field['key'])

    layer.keywords = keywords
    layer.keywords['inasafe_fields'] = inasafe_fields
    if exposure_key:
        value_map_key = 'value_maps'
    else:
        value_map_key = 'value_map'
    if value_map_key in list(layer.keywords.keys()):
        layer.keywords.pop(value_map_key)
    layer.keywords['title'] = output_layer_name
    if classification:
        layer.keywords['classification'] = classification

    check_layer(layer)
    return layer
Beispiel #29
0
 def addResultToLayer(self, newOutputLayer):
     ''' prepare results to be integrated in gis context
     '''
     try:
         # start editing
         newOutputLayer.startEditing()
         
         # read the out file and for each line update relative record in the result
         with open(self.algOutputFileName, 'r') as algOutputFile:
             
             # read all lines
             managedHeader = False
             fieldNameIndexMap = {}
             fieldNames = None
             for line in algOutputFile:
                 line = line.strip()
                 
                 # manage header
                 if not managedHeader:
                     managedHeader = True
                     
                     # add columns to the output layer
                     fieldNames = line.split('\t')
                     fieldNames = [x.split('(')[0] for x in fieldNames]
                     for fieldName in fieldNames:
                         # check if field is already available
                         if newOutputLayer.fieldNameIndex(fieldName) >= 0:
                             continue
                         
                         # add the new field
                         newField = QgsField(fieldName, QtCore.QVariant.Double)
                         newField.setLength(7)
                         newField.setPrecision(5)
                         added = newOutputLayer.addAttribute(newField)
                         if not added:
                            raise Exception(self.tr('Can not add fieldname {} to the output vector'.format(fieldName))) 
                         
                     newOutputLayer.updateFields()
                     
                     # add the fieldName in fieldNames
                     for fieldName in fieldNames:
                         fieldNameIndexMap[ fieldName ] = newOutputLayer.fieldNameIndex(fieldName)
                     
                     # jump to the next line = values
                     continue
                     
                 # map values with fieldnames
                 values = line.split('\t')
                 fieldValueMap = zip(fieldNames, values)
                 
                 # update record
                 id = None
                 for columnIndex, (fieldName, fieldValue) in enumerate(fieldValueMap):
                     
                     if columnIndex == 0:
                         id = int(fieldValue)
                         continue
                     
                     fieldValue = float(fieldValue)
                     newOutputLayer.changeAttributeValue(id-1, fieldNameIndexMap[fieldName], fieldValue)
         
     except Exception as ex:
         # rollback
         newOutputLayer.rollBack()
         
         traceback.print_exc()
         QgsMessageLog.logMessage(str(ex), 'QTraffic', QgsMessageLog.CRITICAL)
         iface.messageBar().pushCritical('QTraffic', self.tr("Error formatting alg result in the output layer"))
     
     else:
         if not newOutputLayer.commitChanges():
             raise Exception(self.tr('Error committing changes in the result layer'))