def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(
            shapefile_path, self.tr('Jakarta Floods'), 'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from PyQt4.QtCore import QVariant
        layer.startEditing()
        field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([field])
        layer.commitChanges()
        layer.startEditing()
        idx = layer.fieldNameIndex('flooded')
        expression = QgsExpression('state > 0')
        expression.prepare(layer.pendingFields())
        for feature in layer.getFeatures():
            feature[idx] = expression.evaluate(feature)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
Exemple #2
0
    def add_geom_columns(context, layer: QgsVectorLayer) -> None:
        """ Add latitude and longitude columns in the layer. """
        fields = [
            QgsField('longitude', type=QVariant.Double),
            QgsField('latitude', type=QVariant.Double),
        ]
        transform = QgsCoordinateTransform(
            layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326'),
            context.project())

        with edit(layer):
            for field in fields:
                layer.addAttribute(field)

            request = QgsFeatureRequest()
            request.setSubsetOfAttributes(['latitude', 'longitude'],
                                          layer.fields())
            for feature in layer.getFeatures(request):
                geom = QgsGeometry(feature.geometry())
                if not geom:
                    continue

                geom.transform(transform)
                geom = geom.centroid().asPoint()
                feature.setAttribute('longitude', geom.x())
                feature.setAttribute('latitude', geom.y())
                layer.updateFeature(feature)
Exemple #3
0
    def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(shapefile_path, self.tr('Jakarta Floods'),
                               'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from PyQt4.QtCore import QVariant
        layer.startEditing()
        field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([field])
        layer.commitChanges()
        layer.startEditing()
        idx = layer.fieldNameIndex('flooded')
        expression = QgsExpression('state > 0')
        expression.prepare(layer.pendingFields())
        for feature in layer.getFeatures():
            feature[idx] = expression.evaluate(feature)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
 def update_feature(feature: QgsFeature, layer: QgsVectorLayer,
                    field_name: str, field_value, commit: bool) -> None:
     """Updates feature to the specified value."""
     layer.startEditing()
     feature[field_name] = field_value
     layer.updateFeature(feature)
     if commit:
         layer.commitChanges()
 def update_selected_features(layer: QgsVectorLayer, field_name: str,
                              field_value) -> None:
     """Updates selected features to the specified value."""
     layer.startEditing()
     features = layer.selectedFeatures()
     for f in features:
         f[field_name] = field_value
         layer.updateFeature(f)
     layer.commitChanges()
    def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(
            shapefile_path, self.tr('Jakarta Floods'), 'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from qgis.PyQt.QtCore import QVariant
        layer.startEditing()
        # Add field with integer from 0 to 4 which represents the flood
        # class. Its the same as 'state' field except that is being treated
        # as a string.
        # This is used for cartography
        flood_class_field = QgsField('floodclass', QVariant.Int)
        layer.addAttribute(flood_class_field)
        layer.commitChanges()
        layer.startEditing()
        flood_class_idx = layer.fields().lookupField('floodclass')
        flood_class_expression = QgsExpression('to_int(state)')
        context = QgsExpressionContext()
        context.setFields(layer.fields())
        flood_class_expression.prepare(context)

        # Add field with boolean flag to say if the area is flooded
        # This is used by the impact function
        flooded_field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([flooded_field])
        layer.commitChanges()
        layer.startEditing()
        flooded_idx = layer.fields().lookupField('flooded')
        flood_flag_expression = QgsExpression('state > 0')
        flood_flag_expression.prepare(context)
        for feature in layer.getFeatures():
            context.setFeature(feature)
            feature[flood_class_idx] = flood_class_expression.evaluate(context)
            feature[flooded_idx] = flood_flag_expression.evaluate(context)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
    def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(shapefile_path, self.tr('Jakarta Floods'),
                               'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from PyQt4.QtCore import QVariant
        layer.startEditing()
        # Add field with integer from 0 to 4 which represents the flood
        # class. Its the same as 'state' field except that is being treated
        # as a string.
        # This is used for cartography
        flood_class_field = QgsField('floodclass', QVariant.Int)
        layer.dataProvider().addAttributes([flood_class_field])
        layer.commitChanges()
        layer.startEditing()
        flood_class_idx = layer.fieldNameIndex('floodclass')
        flood_class_expression = QgsExpression('to_int(state)')
        context = QgsExpressionContext()
        context.setFields(layer.pendingFields())
        flood_class_expression.prepare(context)

        # Add field with boolean flag to say if the area is flooded
        # This is used by the impact function
        flooded_field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([flooded_field])
        layer.commitChanges()
        layer.startEditing()
        flooded_idx = layer.fieldNameIndex('flooded')
        flood_flag_expression = QgsExpression('state > 0')
        flood_flag_expression.prepare(context)
        for feature in layer.getFeatures():
            context.setFeature(feature)
            feature[flood_class_idx] = flood_class_expression.evaluate(context)
            feature[flooded_idx] = flood_flag_expression.evaluate(context)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
Exemple #8
0
    def test_ZFeatureRequestSortByAuxiliaryField(self):
        s = QgsAuxiliaryStorage()
        self.assertTrue(s.isValid())

        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f1 = QgsFeature()
        f1.setAttributes(["test", 123])
        f2 = QgsFeature()
        f2.setAttributes(["test", 124])
        self.assertTrue(pr.addFeatures([f1, f2]))

        # Create a new auxiliary layer with 'pk' as key
        pkf = layer.fields().field(layer.fields().indexOf('fldint'))
        al = s.createAuxiliaryLayer(pkf, layer)
        self.assertTrue(al.isValid())
        layer.setAuxiliaryLayer(al)

        prop = QgsPropertyDefinition()
        prop.setComment('test_field')
        prop.setDataType(QgsPropertyDefinition.DataTypeNumeric)
        prop.setOrigin('user')
        prop.setName('custom')
        self.assertTrue(al.addAuxiliaryField(prop))

        layer.startEditing()
        i = 2
        for feat in layer.getFeatures():
            feat.setAttribute(2, i)
            layer.updateFeature(feat)
            i -= 1
        layer.commitChanges()

        request = QgsFeatureRequest()
        request.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause(layer.fields()[2].name(), True)]))
        ids = []
        for feat in layer.getFeatures(request):
            ids.append(feat.id())
        self.assertEqual(ids, [2, 1])

        request.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause(layer.fields()[2].name(), False)]))
        ids = []
        for feat in layer.getFeatures(request):
            ids.append(feat.id())
        self.assertEqual(ids, [1, 2])

        QgsProject.instance().removeMapLayers([layer.id()])
Exemple #9
0
def checkCartoDBId(layer, convert=False):
    """Check if layer has cartodb_id field"""
    new_layer = layer

    if convert and layer.fieldNameIndex('cartodb_id') == -1:
        checkTempDir()
        temp = tempfile.NamedTemporaryFile()
        error = QgsVectorFileWriter.writeAsVectorFormat(layer, temp.name, 'utf-8', None, 'ESRI Shapefile')
        if error == QgsVectorFileWriter.NoError:
            new_layer = QgsVectorLayer(temp.name + '.shp', layer.name(), 'ogr')
            new_layer.dataProvider().addAttributes([QgsField('cartodb_id', QVariant.Int)])
            new_layer.updateFields()
            features = new_layer.getFeatures()
            i = 1
            for feature in features:
                fid = feature.id()
                aid = new_layer.fieldNameIndex('cartodb_id')
                attrs = {aid: i}
                new_layer.dataProvider().changeAttributeValues({fid : attrs})
                i = i + 1
                new_layer.updateFeature(feature)
    return new_layer
Exemple #10
0
    def testEdit(self):
        """Test `with edit(layer):` code"""

        ml = QgsVectorLayer(
            "Point?crs=epsg:4236&field=id:integer&field=value:double",
            "test_data", "memory")
        # Data as list of x, y, id, value
        self.assertTrue(ml.isValid())
        fields = ml.fields()

        # Check insert
        with edit(ml):
            feat = QgsFeature(fields)
            feat['id'] = 1
            feat['value'] = 0.9
            self.assertTrue(ml.addFeature(feat))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 0.9)

        # Check update
        with edit(ml):
            f = next(ml.getFeatures())
            f['value'] = 9.9
            self.assertTrue(ml.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)

        # Check for rollBack after exceptions
        with self.assertRaises(NameError):
            with edit(ml):
                f = next(ml.getFeatures())
                f['value'] = 3.8
                crashycrash()  # NOQA

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)
        self.assertEqual(next(ml.getFeatures())['value'], 9.9)

        # Check for `as`
        with edit(ml) as l:
            f = next(l.getFeatures())
            f['value'] = 10
            self.assertTrue(l.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 10)

        # Check that we get a QgsEditError exception when the commit fails
        with self.assertRaises(QgsEditError):
            with edit(ml) as l:
                l.rollBack()
Exemple #11
0
def checkCartoDBId(layer, convert=False):
    """Check if layer has cartodb_id field"""
    new_layer = layer

    if convert and layer.fieldNameIndex('cartodb_id') == -1:
        checkTempDir()
        temp = tempfile.NamedTemporaryFile()
        error = QgsVectorFileWriter.writeAsVectorFormat(
            layer, temp.name, 'utf-8', None, 'ESRI Shapefile')
        if error == QgsVectorFileWriter.NoError:
            new_layer = QgsVectorLayer(temp.name + '.shp', layer.name(), 'ogr')
            new_layer.dataProvider().addAttributes(
                [QgsField('cartodb_id', QVariant.Int)])
            new_layer.updateFields()
            features = new_layer.getFeatures()
            i = 1
            for feature in features:
                fid = feature.id()
                aid = new_layer.fieldNameIndex('cartodb_id')
                attrs = {aid: i}
                new_layer.dataProvider().changeAttributeValues({fid: attrs})
                i = i + 1
                new_layer.updateFeature(feature)
    return new_layer
    def testEdit(self):
        """Test `with edit(layer):` code"""

        ml = QgsVectorLayer("Point?crs=epsg:4236&field=id:integer&field=value:double",
                            "test_data", "memory")
        # Data as list of x, y, id, value
        self.assertTrue(ml.isValid())
        fields = ml.fields()

        # Check insert
        with edit(ml):
            feat = QgsFeature(fields)
            feat['id'] = 1
            feat['value'] = 0.9
            self.assertTrue(ml.addFeature(feat))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 0.9)

        # Check update
        with edit(ml):
            f = next(ml.getFeatures())
            f['value'] = 9.9
            self.assertTrue(ml.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)

        # Check for rollBack after exceptions
        with self.assertRaises(NameError):
            with edit(ml):
                f = next(ml.getFeatures())
                f['value'] = 3.8
                crashycrash()  # NOQA

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)
        self.assertEqual(next(ml.getFeatures())['value'], 9.9)

        # Check for `as`
        with edit(ml) as l:
            f = next(l.getFeatures())
            f['value'] = 10
            self.assertTrue(l.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 10)

        # Check that we get a QgsEditError exception when the commit fails
        with self.assertRaises(QgsEditError):
            with edit(ml) as l:
                l.rollBack()
Exemple #13
0
def run(settings, progress_bars):

    for key in list(progress_bars.keys()):
        bar = progress_bars[key]
        bar['bar'].setValue(0)
        bar['label'].setText('')

    CreateTempDir()

    receiver_layer_name = os.path.splitext(
        os.path.basename(settings['receivers_path']))[0]
    receiver_layer = QgsVectorLayer(settings['receivers_path'],
                                    receiver_layer_name, "ogr")

    if settings['sources_pts_path'] is not None:
        source_pts_layer_name = os.path.splitext(
            os.path.basename(settings['sources_pts_path']))[0]
        source_pts_layer = QgsVectorLayer(settings['sources_pts_path'],
                                          source_pts_layer_name, "ogr")
    else:
        source_pts_layer = None

    if settings['sources_roads_path'] is not None:
        source_roads_layer_name = os.path.splitext(
            os.path.basename(settings['sources_roads_path']))[0]
        source_roads_layer = QgsVectorLayer(settings['sources_roads_path'],
                                            source_roads_layer_name, "ogr")

    else:
        source_roads_layer = None

    if settings['buildings_path'] is not None:
        obstacles_layer_name = os.path.splitext(
            os.path.basename(settings['buildings_path']))[0]
        obstacles_layer = QgsVectorLayer(settings['buildings_path'],
                                         obstacles_layer_name, "ogr")
    else:
        obstacles_layer = None

    rays_layer_path = settings['rays_path']
    diff_rays_layer_path = settings['diff_rays_path']

    # defines rays layer
    if rays_layer_path is not None:

        rays_fields = QgsFields()
        rays_fields.append(QgsField("id_ray", QVariant.Int))
        rays_fields.append(QgsField("id_rec", QVariant.Int))
        rays_fields.append(QgsField("id_emi", QVariant.Int))
        rays_fields.append(QgsField("d_rTOe", QVariant.Double, len=10, prec=2))
        rays_fields.append(
            QgsField("d_rTOe_4m", QVariant.Double, len=10, prec=2))

        if settings['period_pts_gen'] == "True" or settings[
                'period_roads_gen'] == "True":
            rays_fields.append(
                QgsField("gen_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("gen", QVariant.Double, len=5, prec=1))
        if settings['period_pts_day'] == "True" or settings[
                'period_roads_day'] == "True":
            rays_fields.append(
                QgsField("day_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("day", QVariant.Double, len=5, prec=1))
        if settings['period_pts_eve'] == "True" or settings[
                'period_roads_eve'] == "True":
            rays_fields.append(
                QgsField("eve_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("eve", QVariant.Double, len=5, prec=1))
        if settings['period_pts_nig'] == "True" or settings[
                'period_roads_nig'] == "True":
            rays_fields.append(
                QgsField("nig_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("nig", QVariant.Double, len=5, prec=1))

        rays_writer = QgsVectorFileWriter(rays_layer_path, "System",
                                          rays_fields, QgsWkbTypes.LineString,
                                          receiver_layer.crs(),
                                          "ESRI Shapefile")

    else:
        rays_writer = None

    # defines diff rays layer
    if diff_rays_layer_path is not None:

        rays_fields = QgsFields()
        rays_fields.append(QgsField("id_ray", QVariant.Int))
        rays_fields.append(QgsField("id_rec", QVariant.Int))
        rays_fields.append(QgsField("id_dif", QVariant.Int))
        rays_fields.append(QgsField("id_emi", QVariant.Int))
        rays_fields.append(QgsField("d_rTOd", QVariant.Double, len=10, prec=2))
        rays_fields.append(QgsField("d_dTOe", QVariant.Double, len=10, prec=2))
        rays_fields.append(QgsField("d_rTOe", QVariant.Double, len=10, prec=2))

        if settings['period_pts_gen'] == "True" or settings[
                'period_roads_gen'] == "True":
            rays_fields.append(
                QgsField("gen_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("gen", QVariant.Double, len=5, prec=1))
        if settings['period_pts_day'] == "True" or settings[
                'period_roads_day'] == "True":
            rays_fields.append(
                QgsField("day_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("day", QVariant.Double, len=5, prec=1))
        if settings['period_pts_eve'] == "True" or settings[
                'period_roads_eve'] == "True":
            rays_fields.append(
                QgsField("eve_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("eve", QVariant.Double, len=5, prec=1))
        if settings['period_pts_nig'] == "True" or settings[
                'period_roads_nig'] == "True":
            rays_fields.append(
                QgsField("nig_emi", QVariant.Double, len=5, prec=1))
            rays_fields.append(QgsField("nig", QVariant.Double, len=5, prec=1))

        diff_rays_writer = QgsVectorFileWriter(diff_rays_layer_path, "System",
                                               rays_fields,
                                               QgsWkbTypes.LineString,
                                               receiver_layer.crs(),
                                               "ESRI Shapefile")

    else:
        diff_rays_writer = None

    # puts the sound level in the receivers points attribute table
    # gets fields from recever point layer and initializes the final receiver_point_field_level to populate the receiver points layer attribute table
    fields_number = int(receiver_layer.fields().count())

    level_field_index = {}

    #modified version in creating fields on existing layer in qgis 3.x
    receiver_layer.startEditing()
    #level_fields = []
    if settings['period_pts_gen'] == "True" or settings[
            'period_roads_gen'] == "True":
        receiver_layer.addAttribute(
            QgsField('gen', QVariant.Double, len=5, prec=1))
        level_field_index['gen'] = fields_number
        fields_number = fields_number + 1
    if settings['period_pts_day'] == "True" or settings[
            'period_roads_day'] == "True":
        receiver_layer.addAttribute((QgsField('day',
                                              QVariant.Double,
                                              len=5,
                                              prec=1)))
        level_field_index['day'] = fields_number
        fields_number = fields_number + 1
    if settings['period_pts_eve'] == "True" or settings[
            'period_roads_eve'] == "True":
        receiver_layer.addAttribute(
            QgsField('eve', QVariant.Double, len=5, prec=1))
        level_field_index['eve'] = fields_number
        fields_number = fields_number + 1
    if settings['period_pts_nig'] == "True" or settings[
            'period_roads_nig'] == "True":
        receiver_layer.addAttribute(
            QgsField('nig', QVariant.Double, len=5, prec=1))
        level_field_index['nig'] = fields_number
        fields_number = fields_number + 1
    if settings['period_den'] == "True":
        receiver_layer.addAttribute(
            QgsField('den', QVariant.Double, len=5, prec=1))
        level_field_index['den'] = fields_number
        fields_number = fields_number + 1

    #receiver_layer.dataProvider().addAttributes( level_fields )
    receiver_layer.updateFields()

    #calculation
    receiver_feat_new_fields = calc(progress_bars, receiver_layer,
                                    source_pts_layer, source_roads_layer,
                                    settings, level_field_index,
                                    obstacles_layer, rays_writer,
                                    diff_rays_writer)

    #old way to insert data in table
    # receiver_layer.dataProvider().changeAttributeValues(receiver_feat_new_fields)

    #new way to insert data in table
    for f in receiver_layer.getFeatures():
        if 'gen' in level_field_index:
            f['gen'] = receiver_feat_new_fields[f.id()][
                level_field_index['gen']]
            #print(receiver_feat_new_fields,f.id(),f['gen'])
        if 'day' in level_field_index:
            f['day'] = receiver_feat_new_fields[f.id()][
                level_field_index['day']]
        if 'eve' in level_field_index:
            f['eve'] = receiver_feat_new_fields[f.id()][
                level_field_index['eve']]
        if 'nig' in level_field_index:
            f['nig'] = receiver_feat_new_fields[f.id()][
                level_field_index['nig']]
        if 'den' in level_field_index:
            f['den'] = receiver_feat_new_fields[f.id()][
                level_field_index['den']]
        receiver_layer.updateFeature(f)

    receiver_layer.updateExtents()

    receiver_layer.commitChanges()

    #reload all layers to see the updates of shapefile of receivers
    QgsProject.instance().reloadAllLayers()

    if rays_layer_path is not None:
        del rays_writer
        rays_layer_name = os.path.splitext(
            os.path.basename(rays_layer_path))[0]
        rays_layer = QgsVectorLayer(rays_layer_path, str(rays_layer_name),
                                    "ogr")

        QgsProject.instance().addMapLayers([rays_layer])

    if diff_rays_layer_path is not None:
        del diff_rays_writer
        diff_rays_layer_name = os.path.splitext(
            os.path.basename(diff_rays_layer_path))[0]
        diff_rays_layer = QgsVectorLayer(diff_rays_layer_path,
                                         str(diff_rays_layer_name), "ogr")

        QgsProject.instance().addMapLayers([diff_rays_layer])

        QgsProject.instance().reloadAllLayers()

    # render receivers with noise colours
    level_fields_new = list(receiver_layer.dataProvider().fields())

    if len(level_fields_new) > 0:
        receiver_layer_name = settings['receivers_name']
        layer = QgsProject.instance().mapLayersByName(receiver_layer_name)[0]
        on_ApplyNoiseSymbology.renderizeXY(
            layer, level_fields_new[len(level_fields_new) - 1].name())

    DeleteTempDir()
def main(iface):
    ### Let's go!
    print(datetime.now())

    purp_name = ['Leisure', 'Shopping', 'Services', 'Touring']
    # purp_name = ['Leisure']

    # Dictionnaries for parameters

    origins = '/tmp/origins.shp'

    for name in purp_name:
        gravity = poi_gravity_values[name]
        mode_b = mode_params_bike[name]
        mode_eb = mode_params_ebike[name]

        # 1. Join origin sizes to shortest path

        paths = '/tmp/Paths_' + name + '.shp'
        processing.run(
            "native:joinattributestable",
            {
                'INPUT': paths,
                'FIELD': 'FromFID',
                'INPUT_2': origins,
                'FIELD_2': 'ID',
                'FIELDS_TO_COPY': ['Totalt'],
                'METHOD': 0,
                'DISCARD_NONMATCHING': False,
                'PREFIX': '',
                'OUTPUT': '/tmp/WeightedPaths_' + name + '.shp',
            },
        )
        weighted_paths = '/tmp/WeightedPaths_' + name + '.shp'

        # 2. Apply distance-decay functions

        work_layer = QgsVectorLayer(weighted_paths, '', 'ogr')
        work_layer.dataProvider().addAttributes(
            [QgsField("exp", QVariant.Double, "float", 8, 3)])
        work_layer.dataProvider().addAttributes(
            [QgsField("fbike", QVariant.Double, "float", 8, 3)])
        work_layer.dataProvider().addAttributes(
            [QgsField("febike", QVariant.Double, "float", 8, 3)])
        work_layer.updateFields()

        features = work_layer.getFeatures()
        with edit(work_layer):
            for f in features:
                X = f['Distance']

                # Destination choice: exponential
                f['exp'] = math.exp(gravity * float(X) / 1000)

                # Mode choice probabilities
                f['fbike'] = sigmoid(mode_b[0], mode_b[1], mode_b[2],
                                     mode_b[3], X)
                f['febike'] = sigmoid(mode_eb[0], mode_eb[1], mode_eb[2],
                                      mode_eb[3], X)

                work_layer.updateFeature(f)

        X = processing.run(
            "native:fieldcalculator",
            {
                'INPUT': '/tmp/WeightedPaths_' + name + '.shp',
                'FIELD_NAME': 'Weight_bike',
                'FIELD_TYPE': 0,
                'FIELD_LENGTH': 0,
                'FIELD_PRECISION': 0,
                'FORMULA': 'Totalt*fbike*exp/sum(exp,FromFID)',
                'OUTPUT': 'TEMPORARY_OUTPUT',
            },
        )

        processing.run(
            "native:fieldcalculator",
            {
                'INPUT': X['OUTPUT'],
                'FIELD_NAME': 'Weight_ebike',
                'FIELD_TYPE': 0,
                'FIELD_LENGTH': 0,
                'FIELD_PRECISION': 0,
                'FORMULA': 'Totalt*febike*exp/sum(exp,FromFID)',
                'OUTPUT': '/tmp/WeightedPathsFinal_' + name + '.shp',
            },
        )
        weighted_paths_final = '/tmp/WeightedPathsFinal_' + name + '.shp'
        iface.addVectorLayer(weighted_paths_final, '', 'ogr')

    print(datetime.now())
Exemple #15
0
def get_raster_values_from_vector_layer(self):
    """
    Brief: Obtains raster layer values from point vector layer. Create memory layer or shapefile with source layer
            fields, adding new field with obtained raster value. Finally, add layer result in QGIS
    """
    # create target datamodel (fields)
    source_fields = self.qgs_vector_layer.fields()  # get QgsFields source vector layer
    str_new_fieldname = "v_raster"  # TODO: value raster, pass to constant file
    new_qgsfield = QgsField(str_new_fieldname,
                            QVariant.Double)  # new QgsField to add
    source_fields.append(new_qgsfield)  # append new QgsField to QgsFields vector source layer

    # create new vector memory layer
    source_crs = self.qgs_vector_layer.crs()  # get CRS source vector layer
    wkt_source_crs = source_crs.toWkt()  # get CRS WKT string

    str_name_memory_layer = "New memory layer"  # TODO: name memory layer, pass to constant file

    data_source = "Point?crs=" + wkt_source_crs
    layer_name = str_name_memory_layer
    provider_name = "memory"
    memory_layer = QgsVectorLayer(data_source,
                                  layer_name,
                                  provider_name)

    # add source layer fields to new memory layer
    pr_memory_layer = memory_layer.dataProvider()
    pr_memory_layer.addAttributes(source_fields)  # add datamodel to memory layer
    memory_layer.updateFields()  # tell the vector layer to fetch changes from the provider

    # add source features to new memory layer
    for feature in self.qgs_vector_layer.getFeatures():
        pr_memory_layer.addFeatures([feature])

    # gets raster value of each point in vector layer and updates the corresponding attribute in target memory layer
    memory_layer.startEditing()
    for feature in memory_layer.getFeatures():
        qgs_raster_id_result = self.qgs_raster_layer.dataProvider().identify(feature.geometry().asPoint(),
                                                                             QgsRaster.IdentifyFormatValue)
        dict_value_raster = qgs_raster_id_result.results()
        feature.setAttribute(str_new_fieldname,
                             dict_value_raster[1])
        memory_layer.updateFeature(feature)
    memory_layer.commitChanges()

    if self.dockwidget.radioButton_outputMemoryLayer.isChecked():
        QgsProject.instance().addMapLayer(memory_layer)

    if self.dockwidget.radioButton_outputShapefile.isChecked():
        # Save memory layer to file
        msg = QgsVectorFileWriter.writeAsVectorFormat(memory_layer,
                                                      self.str_path_output_shp,
                                                      "CP1250",
                                                      source_crs,
                                                      "ESRI Shapefile")
        if msg[0] == 0:  # If not error in write as vector format, add new shapefile in QGIS
            data_source = self.str_path_output_shp
            layer_name =str.split(os.path.basename(str(self.str_path_output_shp)), ".")[0]
            provider_name = "ogr"
            self.iface.addVectorLayer(data_source,
                                      layer_name,
                                      provider_name)
        else:
            print(msg)
Exemple #16
0
    def start_progress(self):
        import datetime
        start = datetime.datetime.now()
        # Check OS and dep
        if sys.platform == 'darwin':
            gdal_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/'
        else:
            gdal_os_dep = ''

        if self.dlg.canvasButton.isChecked():
            # Map Canvas
            extentCanvasCRS = self.iface.mapCanvas()
            srs = extentCanvasCRS.mapSettings().destinationCrs()
            crs = str(srs.authid())
            # old_crs = osr.SpatialReference()
            # old_crs.ImportFromEPSG(int(crs[5:]))
            can_crs = QgsCoordinateReferenceSystem(int(crs[5:]))
            # can_wkt = extentCanvasCRS.mapRenderer().destinationCrs().toWkt()
            # can_crs = osr.SpatialReference()
            # can_crs.ImportFromWkt(can_wkt)
            # Raster Layer
            dem_layer = self.layerComboManagerDEM.currentLayer()
            dem_prov = dem_layer.dataProvider()
            dem_path = str(dem_prov.dataSourceUri())
            dem_raster = gdal.Open(dem_path)
            projdsm = osr.SpatialReference(wkt=dem_raster.GetProjection())
            projdsm.AutoIdentifyEPSG()
            projdsmepsg = int(projdsm.GetAttrValue('AUTHORITY', 1))
            dem_crs = QgsCoordinateReferenceSystem(projdsmepsg)

            # dem_wkt = dem_raster.GetProjection()
            # dem_crs = osr.SpatialReference()
            # dem_crs.ImportFromWkt(dem_wkt)
            if can_crs != dem_crs:
                extentCanvas = self.iface.mapCanvas().extent()
                extentDEM = dem_layer.extent()

                transformExt = QgsCoordinateTransform(can_crs, dem_crs)
                # transformExt = osr.CoordinateTransformation(can_crs, dem_crs)

                canminx = extentCanvas.xMinimum()
                canmaxx = extentCanvas.xMaximum()
                canminy = extentCanvas.yMinimum()
                canmaxy = extentCanvas.yMaximum()

                canxymin = transformExt.TransformPoint(canminx, canminy)
                canxymax = transformExt.TransformPoint(canmaxx, canmaxy)

                extDiffminx = canxymin[0] - extentDEM.xMinimum(
                )  # If smaller than zero = warning
                extDiffminy = canxymin[1] - extentDEM.yMinimum(
                )  # If smaller than zero = warning
                extDiffmaxx = canxymax[0] - extentDEM.xMaximum(
                )  # If larger than zero = warning
                extDiffmaxy = canxymax[0] - extentDEM.yMaximum(
                )  # If larger than zero = warning

                if extDiffminx < 0 or extDiffminy < 0 or extDiffmaxx > 0 or extDiffmaxy > 0:
                    QMessageBox.warning(
                        None,
                        "Warning! Extent of map canvas is larger than raster extent.",
                        "Change to an extent equal to or smaller than the raster extent."
                    )
                    return

        # Extent
        self.yMax = self.dlg.lineEditNorth.text()
        self.yMin = self.dlg.lineEditSouth.text()
        self.xMin = self.dlg.lineEditWest.text()
        self.xMax = self.dlg.lineEditEast.text()

        if not self.DSMoutputfile:
            QMessageBox.critical(None, "Error", "Specify a raster output file")
            return

        if self.dlg.checkBoxPolygon.isChecked() and not self.OSMoutputfile:
            QMessageBox.critical(None, "Error",
                                 "Specify an output file for OSM data")
            return

        # Acquiring geodata and attributes
        dem_layer = self.layerComboManagerDEM.currentLayer()
        if dem_layer is None:
            QMessageBox.critical(None, "Error",
                                 "No valid raster layer is selected")
            return
        else:
            provider = dem_layer.dataProvider()
            filepath_dem = str(provider.dataSourceUri())
        demRaster = gdal.Open(filepath_dem)
        dem_layer_crs = osr.SpatialReference()
        dem_layer_crs.ImportFromWkt(demRaster.GetProjection())
        self.dem_layer_unit = dem_layer_crs.GetAttrValue("UNIT")
        posUnits = [
            'metre', 'US survey foot', 'meter', 'm', 'ft', 'feet', 'foot',
            'ftUS', 'International foot'
        ]  # Possible units
        if not self.dem_layer_unit in posUnits:
            QMessageBox.critical(
                None, "Error",
                "Raster projection is not in metre or foot. Please reproject.")
            return

        polygon_layer = self.layerComboManagerPolygon.currentLayer()
        osm_layer = self.dlg.checkBoxOSM.isChecked()
        if polygon_layer is None and osm_layer is False:
            QMessageBox.critical(None, "Error",
                                 "No valid building height layer is selected")
            return
        elif polygon_layer:
            vlayer = QgsVectorLayer(polygon_layer.source(), "buildings", "ogr")
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            polygon_field = self.layerComboManagerPolygonField.currentField()
            idx = vlayer.fieldNameIndex(polygon_field)
            flname = vlayer.attributeDisplayName(idx)

            if idx == -1:
                QMessageBox.critical(
                    None, "Error",
                    "An attribute with unique fields must be selected")
                return

        ### main code ###

        self.dlg.progressBar.setRange(0, 5)

        self.dlg.progressBar.setValue(1)

        if self.dlg.checkBoxOSM.isChecked():
            # TODO replace osr.CoordinateTransformation with QgsCoordinateTransform
            dem_original = gdal.Open(filepath_dem)
            dem_wkt = dem_original.GetProjection()
            ras_crs = osr.SpatialReference()
            ras_crs.ImportFromWkt(dem_wkt)
            rasEPSG = ras_crs.GetAttrValue("PROJCS|AUTHORITY", 1)
            if self.dlg.layerButton.isChecked():
                old_crs = ras_crs
            elif self.dlg.canvasButton.isChecked():
                canvasCRS = self.iface.mapCanvas()
                outputWkt = canvasCRS.mapRenderer().destinationCrs().toWkt()
                old_crs = osr.SpatialReference()
                old_crs.ImportFromWkt(outputWkt)

            wgs84_wkt = """
            GEOGCS["WGS 84",
                DATUM["WGS_1984",
                    SPHEROID["WGS 84",6378137,298.257223563,
                        AUTHORITY["EPSG","7030"]],
                    AUTHORITY["EPSG","6326"]],
                PRIMEM["Greenwich",0,
                    AUTHORITY["EPSG","8901"]],
                UNIT["degree",0.01745329251994328,
                    AUTHORITY["EPSG","9122"]],
                AUTHORITY["EPSG","4326"]]"""

            new_crs = osr.SpatialReference()
            new_crs.ImportFromWkt(wgs84_wkt)

            transform = osr.CoordinateTransformation(old_crs, new_crs)

            minx = float(self.xMin)
            miny = float(self.yMin)
            maxx = float(self.xMax)
            maxy = float(self.yMax)
            lonlatmin = transform.TransformPoint(minx, miny)
            lonlatmax = transform.TransformPoint(maxx, maxy)

            if ras_crs != old_crs:
                rasTrans = osr.CoordinateTransformation(old_crs, ras_crs)
                raslonlatmin = rasTrans.TransformPoint(float(self.xMin),
                                                       float(self.yMin))
                raslonlatmax = rasTrans.TransformPoint(float(self.xMax),
                                                       float(self.yMax))
                #else:
                #raslonlatmin = [float(self.xMin), float(self.yMin)]
                #raslonlatmax = [float(self.xMax), float(self.yMax)]

                self.xMin = raslonlatmin[0]
                self.yMin = raslonlatmin[1]
                self.xMax = raslonlatmax[0]
                self.yMax = raslonlatmax[1]

            # Make data queries to overpass-api
            urlStr = 'http://overpass-api.de/api/map?bbox=' + str(
                lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                    lonlatmax[0]) + ',' + str(lonlatmax[1])
            osmXml = urllib.urlopen(urlStr).read()
            #print urlStr

            # Make OSM building file
            osmPath = self.plugin_dir + '/temp/OSM_building.osm'
            osmFile = open(osmPath, 'w')
            osmFile.write(osmXml)
            if os.fstat(osmFile.fileno()).st_size < 1:
                urlStr = 'http://api.openstreetmap.org/api/0.6/map?bbox=' + str(
                    lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                        lonlatmax[0]) + ',' + str(lonlatmax[1])
                osmXml = urllib.urlopen(urlStr).read()
                osmFile.write(osmXml)
                #print 'Open Street Map'
                if os.fstat(osmFile.fileno()).st_size < 1:
                    QMessageBox.critical(None, "Error",
                                         "No OSM data available")
                    return

            osmFile.close()

            outputshp = self.plugin_dir + '/temp/'

            osmToShape = gdal_os_dep + 'ogr2ogr --config OSM_CONFIG_FILE "' + self.plugin_dir + '/osmconf.ini" -skipfailures -t_srs EPSG:' + str(
                rasEPSG
            ) + ' -overwrite -nlt POLYGON -f "ESRI Shapefile" "' + outputshp + '" "' + osmPath + '"'

            if sys.platform == 'win32':
                si = subprocess.STARTUPINFO()
                si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                subprocess.call(osmToShape, startupinfo=si)
            else:
                os.system(osmToShape)

            driver = ogr.GetDriverByName('ESRI Shapefile')
            driver.DeleteDataSource(outputshp + 'lines.shp')
            driver.DeleteDataSource(outputshp + 'multilinestrings.shp')
            driver.DeleteDataSource(outputshp + 'other_relations.shp')
            driver.DeleteDataSource(outputshp + 'points.shp')

            osmPolygonPath = outputshp + 'multipolygons.shp'
            vlayer = QgsVectorLayer(osmPolygonPath, 'multipolygons', 'ogr')
            polygon_layer = vlayer
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            def renameField(srcLayer, oldFieldName, newFieldName):
                ds = gdal.OpenEx(srcLayer.source(),
                                 gdal.OF_VECTOR | gdal.OF_UPDATE)
                ds.ExecuteSQL('ALTER TABLE {} RENAME COLUMN {} TO {}'.format(
                    srcLayer.name(), oldFieldName, newFieldName))
                srcLayer.reload()

            vlayer.startEditing()
            renameField(vlayer, 'building_l', 'bld_levels')
            renameField(vlayer, 'building_h', 'bld_hght')
            renameField(vlayer, 'building_c', 'bld_colour')
            renameField(vlayer, 'building_m', 'bld_materi')
            renameField(vlayer, 'building_u', 'bld_use')
            vlayer.commitChanges()

            vlayer.startEditing()
            vlayer.dataProvider().addAttributes(
                [QgsField('bld_height', QVariant.Double, 'double', 3, 2)])
            vlayer.updateFields()
            bld_lvl = vlayer.fieldNameIndex('bld_levels')
            hght = vlayer.fieldNameIndex('height')
            bld_hght = vlayer.fieldNameIndex('bld_hght')
            bld_height = vlayer.fieldNameIndex('bld_height')

            bldLvlHght = float(self.dlg.doubleSpinBoxBldLvl.value())
            illegal_chars = string.ascii_letters + "!#$%&'*+^_`|~:" + " "
            counterNone = 0
            counter = 0
            #counterWeird = 0
            for feature in vlayer.getFeatures():
                if feature[hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[hght])))
                        feature[bld_height] = float(
                            str(feature[hght]).translate(None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[bld_hght])))
                        feature[bld_height] = float(
                            str(feature[bld_hght]).translate(
                                None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_lvl]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", "", str(feature[bld_lvl])))*bldLvlHght
                        feature[bld_height] = float(
                            str(feature[bld_lvl]).translate(
                                None, illegal_chars)) * bldLvlHght
                    except:
                        counterNone += 1
                else:
                    counterNone += 1
                vlayer.updateFeature(feature)
                counter += 1
            vlayer.commitChanges()
            flname = vlayer.attributeDisplayName(bld_height)
            counterDiff = counter - counterNone

        # Zonal statistics
        vlayer.startEditing()
        zoneStat = QgsZonalStatistics(vlayer, filepath_dem, "stat_", 1,
                                      QgsZonalStatistics.Mean)
        zoneStat.calculateStatistics(None)
        vlayer.dataProvider().addAttributes(
            [QgsField('height_asl', QVariant.Double)])
        vlayer.updateFields()
        e = QgsExpression('stat_mean + ' + flname)
        e.prepare(vlayer.pendingFields())
        idx = vlayer.fieldNameIndex('height_asl')

        for f in vlayer.getFeatures():
            f[idx] = e.evaluate(f)
            vlayer.updateFeature(f)

        vlayer.commitChanges()

        vlayer.startEditing()
        idx2 = vlayer.fieldNameIndex('stat_mean')
        vlayer.dataProvider().deleteAttributes([idx2])
        vlayer.updateFields()
        vlayer.commitChanges()

        self.dlg.progressBar.setValue(2)

        # Convert polygon layer to raster

        # Define pixel_size and NoData value of new raster
        pixel_size = self.dlg.spinBox.value()  # half picture size

        # Create the destination data source

        gdalrasterize = gdal_os_dep + 'gdal_rasterize -a ' + 'height_asl' + ' -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
                        ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + ' -l "' + str(polygon_ln) + '" "' \
                         + str(polygon_layer.source()) + '" "' + self.plugin_dir + '/temp/clipdsm.tif"'

        # gdalclipdem = gdal_os_dep + 'gdalwarp -dstnodata -9999 -q -overwrite -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
        #               ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + \
        #               ' -of GTiff ' + '"' + filepath_dem + '" "' + self.plugin_dir + '/temp/clipdem.tif"'

        # Rasterize
        if sys.platform == 'win32':
            si = subprocess.STARTUPINFO()
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.call(gdalrasterize, startupinfo=si)
            # subprocess.call(gdalclipdem, startupinfo=si)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)
        else:
            os.system(gdalrasterize)
            # os.system(gdalclipdem)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)

        # Remove gdalwarp with gdal.Translate
        # bigraster = gdal.Open(filepath_dem)
        # bbox = (self.xMin, self.yMax, self.xMax, self.yMin)
        # gdal.Translate(self.plugin_dir + '/data/clipdem.tif', bigraster, projWin=bbox)

        self.dlg.progressBar.setValue(3)

        # Adding DSM to DEM
        # Read DEM
        dem_raster = gdal.Open(self.plugin_dir + '/temp/clipdem.tif')
        dem_array = np.array(dem_raster.ReadAsArray().astype(np.float))
        dsm_raster = gdal.Open(self.plugin_dir + '/temp/clipdsm.tif')
        dsm_array = np.array(dsm_raster.ReadAsArray().astype(np.float))

        indx = dsm_array.shape
        for ix in range(0, int(indx[0])):
            for iy in range(0, int(indx[1])):
                if int(dsm_array[ix, iy]) == 0:
                    dsm_array[ix, iy] = dem_array[ix, iy]

        if self.dlg.checkBoxPolygon.isChecked():
            vlayer.startEditing()
            idxHght = vlayer.fieldNameIndex('height_asl')
            idxBld = vlayer.fieldNameIndex('building')
            features = vlayer.getFeatures()
            #for f in vlayer.getFeatures():
            for f in features:
                geom = f.geometry()
                posUnitsMetre = ['metre', 'meter', 'm']  # Possible metre units
                posUnitsFt = [
                    'US survey foot', 'ft', 'feet', 'foot', 'ftUS',
                    'International foot'
                ]  # Possible foot units
                if self.dem_layer_unit in posUnitsMetre:
                    sqUnit = 1
                elif self.dem_layer_unit in posUnitsFt:
                    sqUnit = 10.76
                if int(geom.area()) > 50000 * sqUnit:
                    vlayer.deleteFeature(f.id())

                #if not f[idxHght]:
                #vlayer.deleteFeature(f.id())
                #elif not f[idxBld]:
                #vlayer.deleteFeature(f.id())
            vlayer.updateFields()
            vlayer.commitChanges()
            QgsVectorFileWriter.writeAsVectorFormat(vlayer,
                                                    str(self.OSMoutputfile),
                                                    "UTF-8", None,
                                                    "ESRI Shapefile")

        else:
            vlayer.startEditing()
            idx3 = vlayer.fieldNameIndex('height_asl')
            vlayer.dataProvider().deleteAttributes([idx3])
            vlayer.updateFields()
            vlayer.commitChanges()

        self.dlg.progressBar.setValue(4)

        # Save raster
        def saveraster(
            gdal_data, filename, raster
        ):  # gdal_data = raster extent, filename = output filename, raster = numpy array (raster to be saved)
            rows = gdal_data.RasterYSize
            cols = gdal_data.RasterXSize

            outDs = gdal.GetDriverByName("GTiff").Create(
                filename, cols, rows, int(1), gdal.GDT_Float32)
            outBand = outDs.GetRasterBand(1)

            # write the data
            outBand.WriteArray(raster, 0, 0)
            # flush data to disk, set the NoData value and calculate stats
            outBand.FlushCache()
            outBand.SetNoDataValue(-9999)

            # georeference the image and set the projection
            outDs.SetGeoTransform(gdal_data.GetGeoTransform())
            outDs.SetProjection(gdal_data.GetProjection())

        saveraster(dsm_raster, self.DSMoutputfile, dsm_array)

        # Load result into canvas
        rlayer = self.iface.addRasterLayer(self.DSMoutputfile)

        # Trigger a repaint
        if hasattr(rlayer, "setCacheImage"):
            rlayer.setCacheImage(None)
        rlayer.triggerRepaint()

        self.dlg.progressBar.setValue(5)

        #runTime = datetime.datetime.now() - start

        if self.dlg.checkBoxOSM.isChecked():
            QMessageBox.information(
                self.dlg, 'DSM Generator', 'Operation successful! ' +
                str(counterDiff) + ' building polygons out of ' +
                str(counter) + ' contained height values.')
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful! " + str(counterDiff) + " buildings out of " + str(counter) + " contained height values.", level=QgsMessageBar.INFO, duration=5)
        else:
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful!", level=QgsMessageBar.INFO, duration=5)
            QMessageBox.information(self.dlg, 'DSM Generator',
                                    'Operation successful!')

        self.resetPlugin()
Exemple #17
0
    myField5 = QgsField('BINOMIO', QVariant.String)
    myField6 = QgsField('STATUS', QVariant.String)
    myField7 = QgsField('CACs', QVariant.String)
    vlayer.dataProvider().addAttributes([myField1,myField2,myField3,myField4,myField5,myField6,myField7])
    vlayer.updateFields()

    expression1 = QgsExpression('$area')
    expression2 = QgsExpression('$perimeter')

    context = QgsExpressionContext()
    context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(vlayer))

    with edit(vlayer):
        for f in vlayer.getFeatures():
            context.setFeature(f)
            f['area_pl'] = expression1.evaluate(context)
            f['per_pl'] = expression2.evaluate(context)
            f['src'] = crs
            f['TECNICO'] = nom_tecnico
            f['BINOMIO'] = num_binomio
            f['STATUS'] = status
            vlayer.updateFeature(f)

    layer_lista.append(nombre_archivo_sext)

    print('\nPOLIGONO n°: ', nombre_archivo_ext, '\n')
    y += 1

#processing.run('qgis:mergevectorlayers', layer_lista, merge_salida)
print("\n Se cargaron todas las capas y se realizaron todos los procedimientos. \nFIN DEL PROGRAMA.\n")
Exemple #18
0
    def run(self):
        """Run method that performs all the real work"""
        # Add items to Management Practices & Soil Type
        k_lists = []
        m_lists = []

        k_lists = self.k_list()
        m_lists = self.m_list()

        self.dlg.comboBox.addItems(k_lists)
        self.dlg.comboBox_2.addItems(m_lists)

        # show dialog box
        self.dlg.show()

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            # Save paths of input directories
            selectedBoundary = self.dlg.lineEdit.text()
            selectedDEM = self.dlg.lineEdit_2.text()
            selectedRLayer = self.dlg.lineEdit_3.text()

            selectedOutput = self.dlg.lineEdit_4.text()
            for letter in selectedOutput:
                if letter == "\\":
                    selectedOutput = selectedOutput.replace(letter, "/")

            print(selectedBoundary)
            print(selectedDEM)
            print(selectedRLayer)
            print(selectedOutput)

            # Save indices for K and M
            selectedKLayer = self.dlg.comboBox.currentIndex()
            selectedMLayer = self.dlg.comboBox_2.currentIndex()

            boundary = QgsVectorLayer(selectedBoundary, 'Boundary', 'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(boundary)

            entries = []

            # Retrieve K and M values

            k_value = self.k_index(selectedKLayer)
            m_value = self.m_index(selectedMLayer)

            km_value = k_value * m_value
            km_value = str(km_value)

            # Process R index

            ## CSV to Layer
            uri = 'file:///' + selectedRLayer + '?delimiter=%s&xField=%s&yField=%s&crs=%s' % (
                ",", "x", "y", "EPSG:4326")
            rainfall_unedited = QgsVectorLayer(uri, "rainfall",
                                               "delimitedtext")
            QgsMapLayerRegistry.instance().addMapLayer(rainfall_unedited)
            spatRef = QgsCoordinateReferenceSystem(
                4326, QgsCoordinateReferenceSystem.EpsgCrsId)

            ## CSV points to editable shapefile
            rainfall_edited = QgsVectorFileWriter(
                selectedOutput + '/rainfall_edited.shp', None,
                rainfall_unedited.pendingFields(), QGis.WKBPoint, spatRef)

            pt = QgsPoint()
            outFeature = QgsFeature()

            for feat in rainfall_unedited.getFeatures():
                attrs = feat.attributes()
                pt.setX(feat['x'])
                pt.setY(feat['y'])
                outFeature.setAttributes(attrs)
                outFeature.setGeometry(QgsGeometry.fromPoint(pt))
                rainfall_edited.addFeature(outFeature)
            del rainfall_edited

            rainfall_edited2 = QgsVectorLayer(
                selectedOutput + '/rainfall_edited.shp', 'rainfall_edited',
                'ogr')

            ## Add and calculate average field
            rainfall_edited2.startEditing()

            avgField = QgsField('average', QVariant.Double)
            rainfall_edited2.dataProvider().addAttributes([avgField])
            rainfall_edited2.updateFields()
            idx = rainfall_edited2.fieldNameIndex('average')

            time_count = idx - 2
            str_output = ''
            for i in range(1, time_count + 1):
                if i == 1:
                    a = str(i)
                    str_output += 'time' + a

                else:
                    a = str(i)
                    str_output += '+ time' + a

            e = QgsExpression(str_output)
            e.prepare(rainfall_edited2.pendingFields())

            for f in rainfall_edited2.getFeatures():
                f[idx] = e.evaluate(f) / time_count
                rainfall_edited2.updateFeature(f)

            rainfall_edited2.commitChanges()

            rainfall_edited3 = QgsVectorLayer(
                selectedOutput + '/rainfall_edited.shp', 'rainfall_edited',
                'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(rainfall_edited3)

            ## Interpolating average using IDW
            ### Parameters for interpolation
            idx = rainfall_edited3.fieldNameIndex('average')

            layer_data = qgis.analysis.QgsInterpolator.LayerData()
            layer_data.vectorLayer = rainfall_edited3
            layer_data.zCoordInterpolation = False
            layer_data.interpolationAttribute = idx
            layer_data.mInputType = 1

            idw_interpolator = QgsIDWInterpolator([layer_data])

            ### Output parameter
            export_path = selectedOutput + "/interpolated_r_{}.asc".format(idx)
            rect = boundary.extent()
            res = 0.0001
            ncol = (rect.xMaximum() - rect.xMinimum()) / res
            nrows = (rect.yMaximum() - rect.yMinimum()) / res

            interpolated_r = QgsGridFileWriter(idw_interpolator,
                                               export_path, rect, int(ncol),
                                               int(nrows), res, res)
            interpolated_r.writeFile(True)

            interpolated_r2 = QgsRasterLayer(export_path, "interpolated_r")

            ## Clip output to boundary
            clippedR = processing.runandload(
                'gdalogr:cliprasterbymasklayer',
                interpolated_r2,  #INPUT <ParameterRaster>
                boundary,  #MASK <ParameterVector>
                "-9999",  #NO_DATA <ParameterString>
                False,  #ALPHA_BAND <ParameterBoolean>
                False,  #CROP_TO_CUTLINE <ParameterBoolean>
                False,  #KEEP_RESOLUTION <ParameterBoolean>
                5,  #RTYPE <ParameterSelection>
                4,  #COMPRESS <ParameterSelection>
                1,  #JPEGCOMPRESSION <ParameterNumber>
                6,  #ZLEVEL <ParameterNumber>
                1,  #PREDICTOR <ParameterNumber>
                False,  #TILED <ParameterBoolean>
                2,  #BIGTIFF <ParameterSelection>
                False,  #TFW <ParameterBoolean>
                "",  #EXTRA <ParameterString>
                selectedOutput +
                '/clip_interpolated_r.tif')  #OUTPUT <OutputRaster>

            r_layer = QgsRasterLayer(
                selectedOutput + '/clip_interpolated_r.tif', "R-index")
            boh4 = QgsRasterCalculatorEntry()
            boh4.ref = 'boh4@1'
            boh4.raster = r_layer
            boh4.bandNumber = 1
            entries.append(boh4)

            # Process S index
            ## Load DEM

            bohLayer1 = QgsRasterLayer(selectedDEM, "DEM")
            boh2 = QgsRasterCalculatorEntry()
            boh2.ref = 'boh2@1'
            boh2.raster = bohLayer1
            boh2.bandNumber = 1
            entries.append(boh2)

            ## Clip output to boundary
            clippedOutput2 = processing.runandload(
                'gdalogr:cliprasterbymasklayer',
                bohLayer1,  # INPUT <ParameterRaster>
                boundary,  # MASK <ParameterVector>
                "-9999",  # NO_DATA <ParameterString>
                False,  # ALPHA_BAND <ParameterBoolean>
                False,  # CROP_TO_CUTLINE <ParameterBoolean>
                False,  # KEEP_RESOLUTION <ParameterBoolean>
                5,  # RTYPE <ParameterSelection>
                4,  # COMPRESS <ParameterSelection>
                1,  # JPEGCOMPRESSION <ParameterNumber>
                6,  # ZLEVEL <ParameterNumber>
                1,  # PREDICTOR <ParameterNumber>
                False,  # TILED <ParameterBoolean>
                2,  # BIGTIFF <ParameterSelection>
                False,  # TFW <ParameterBoolean>
                "",  # EXTRA <ParameterString>
                selectedOutput + '/clip_dem.tif')  # OUTPUT <OutputRaster>

            bohLayer5 = QgsRasterLayer(selectedOutput + '/clip_dem.tif',
                                       "DEM-clipped")
            boh5 = QgsRasterCalculatorEntry()
            boh5.ref = 'boh5@1'
            boh5.raster = bohLayer5
            boh5.bandNumber = 1
            entries.append(boh5)

            ## GDAL algorithm for slope
            processing.runalg('gdalogr:slope', bohLayer5, 1, False, True, True,
                              111120, selectedOutput + '/slope(percent).tif')

            bohLayer6 = QgsRasterLayer(selectedOutput + '/slope(percent).tif',
                                       "slope(percent)")
            QgsMapLayerRegistry.instance().addMapLayer(bohLayer6)
            boh6 = QgsRasterCalculatorEntry()
            boh6.ref = 'boh6@1'
            boh6.raster = bohLayer6
            boh6.bandNumber = 1
            entries.append(boh6)

            # Process calculation with input extent and resolution
            calc = QgsRasterCalculator('(boh4@1 * boh6@1) *' + km_value,
                                       selectedOutput + '/soil_risk.tif',
                                       'GTiff', bohLayer6.extent(),
                                       bohLayer6.width(), bohLayer6.height(),
                                       entries)

            calc.processCalculation()
            bohLayer4 = QgsRasterLayer(selectedOutput + '/soil_risk.tif',
                                       "Soil_Risk")
            QgsMapLayerRegistry.instance().addMapLayer(bohLayer4)
    def generate_layer(self):
        """ The main function, that does all the geocoding work. """

        # disable the Button while generating
        self.setEnabled(False)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        QCoreApplication.processEvents()

        # create new memory layer
        layer = self.tableLayer.currentLayer()
        features = [f for f in layer.getFeatures()]
        mem_layer = QgsVectorLayer('Point?crs=epsg:25832',
                                   '{}_geocoded'.format(layer.name()),
                                   'memory')
        mem_layer_data = mem_layer.dataProvider()
        attr = layer.dataProvider().fields().toList()
        mem_layer_data.addAttributes(attr + [
            QgsField('lat', QVariant.Double),
            QgsField('lon', QVariant.Double)
        ])
        mem_layer.updateFields()
        mem_layer_data.addFeatures(features)
        mem_layer.startEditing()

        addr_list = []
        fid_list = []
        for feature in mem_layer.getFeatures():
            gemarkung = feature[self.gemarkungField.currentField()]
            strasse = feature[self.strasseField.currentField()]
            hausnummer = feature[self.hausnummerField.currentField()]
            if gemarkung and strasse and hausnummer:
                addr_list.append({
                    'gemarkung': gemarkung,
                    'strasse': strasse,
                    'hausnummer': str(hausnummer)
                })
                fid_list.append(feature.id())
                addr_list.append({
                    'gemeinde': gemarkung,
                    'strasse': strasse,
                    'hausnummer': str(hausnummer)
                })
                fid_list.append(feature.id())

        # basicauth:
        reply = self.geocode_addresses(addr_list)
        if reply.error() == 0:
            # No Error
            coordinates = json.loads(str(reply.content(),
                                         'utf-8')).get('coordinates')
            if not coordinates:
                iface.messageBar().pushCritical(
                    'GWS Fehler!', 'GWS unterstützt kein AlkisGeocoder!')

            for (fid, coords) in zip(fid_list, coordinates):
                if coords:
                    feature = mem_layer.getFeature(fid)
                    x = coords[0]
                    y = coords[1]
                    feature.setAttribute('lat', x)
                    feature.setAttribute('lon', y)
                    geom = QgsPointXY(x, y)
                    feature.setGeometry(QgsGeometry.fromPointXY(geom))
                    mem_layer.updateFeature(feature)

            geom_features = len(
                list(
                    filter(lambda x: x.hasGeometry(),
                           [f for f in mem_layer.getFeatures()])))
            if geom_features > 0:
                iface.messageBar().pushSuccess(
                    'Geocodierung abgeschlossen',
                    '%s von %s Features konnten geocodiert werden' %
                    (geom_features, layer.featureCount()))
                mem_layer.commitChanges()
                QgsProject.instance().addMapLayer(mem_layer)
            else:
                del mem_layer
                iface.messageBar().pushCritical(
                    'Geocodierung fehlgeschlagen',
                    'Es konnten keine Features geocodiert werden.')
        elif reply.error() == 3:
            # Host not found
            iface.messageBar().pushCritical(
                'Netzwerkfehler',
                'Host {} nicht gefunden'.format(str(self.gws_url)))
        elif reply.error() == 201:
            # Access denied (403)
            iface.messageBar().pushCritical('GWS Fehler!',
                                            'falsche Zugangsdaten')
        else:
            # Some other error
            iface.messageBar().pushCritical('Netzwerkfehler',
                                            'Code {}'.format(reply.error()))

        self.setEnabled(True)
        QApplication.setOverrideCursor(Qt.ArrowCursor)
    def compute_and_display_cadastral_vulnerability(self, cadastral_layer,
                                                    output_grid_points,
                                                    output_cadastral_points,
                                                    crop_index, crop_name,
                                                    base_path):
        cadastral_points_per_plot = {}
        for p in (output_grid_points + output_cadastral_points):
            if p.cadastral_polygon is None: continue
            if p.lulc_type not in ['agriculture', 'fallow land']: continue
            if p.cadastral_polygon.id() in cadastral_points_per_plot:
                cadastral_points_per_plot[p.cadastral_polygon.id()].append(
                    p.budget.PET_minus_AET_crop_end[crop_index])
            else:
                cadastral_points_per_plot[p.cadastral_polygon.id()] = [
                    p.budget.PET_minus_AET_crop_end[crop_index]
                ]
        for k, v in cadastral_points_per_plot.items():
            if len(v) > 0:
                cadastral_points_per_plot[k] = sum(v) / len(v)
            else:
                del cadastral_points_per_plot[k]

        # print cadastral_points_per_plot
        #	Create duplicate cadastral layer in memory
        memory_cadastral_layer = QgsVectorLayer(
            'Polygon?crs=epsg:32643',
            crop_name + ' Cadastral Level Vulnerability', 'memory')
        memory_cadastral_layer.startEditing()
        memory_cadastral_layer.dataProvider().addAttributes(
            cadastral_layer.qgsLayer.dataProvider().fields().toList())
        memory_cadastral_layer.updateFields()
        dict_new_feature_id_to_old_feature_id = {}
        for old_plot_id in cadastral_points_per_plot:
            result, output_features = memory_cadastral_layer.dataProvider(
            ).addFeatures([cadastral_layer.feature_dict[old_plot_id]])
            dict_new_feature_id_to_old_feature_id[
                output_features[0].id()] = old_plot_id
        memory_cadastral_layer.dataProvider().addAttributes(
            [QgsField('Deficit', QVariant.Double)])
        memory_cadastral_layer.updateFields()
        for new_feature in memory_cadastral_layer.getFeatures():
            new_feature['Deficit'] = cadastral_points_per_plot[
                dict_new_feature_id_to_old_feature_id[new_feature.id()]]
            memory_cadastral_layer.updateFeature(new_feature)
        memory_cadastral_layer.commitChanges()

        #	Graduated Rendering
        graduated_symbol_renderer_range_list = []
        ET_D_max = max(cadastral_points_per_plot.values())
        opacity = 1
        geometry_type = memory_cadastral_layer.geometryType()
        intervals_count = CADASTRAL_VULNERABILITY_DISPLAY_COLOUR_INTERVALS_COUNT
        dict_interval_colour = CADASTRAL_VULNERABILITY_DISPLAY_COLOURS_DICT
        for i in range(intervals_count):
            interval_min = 0 if i == 0 else (ET_D_max * float(i) /
                                             intervals_count) + 0.01
            interval_max = ET_D_max * float(i + 1) / intervals_count
            label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
            colour = QColor(*dict_interval_colour[i])
            symbol = QgsSymbolV2.defaultSymbol(geometry_type)
            symbol.setColor(colour)
            symbol.setAlpha(opacity)
            interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                symbol, label)
            graduated_symbol_renderer_range_list.append(interval_range)
        renderer = QgsGraduatedSymbolRendererV2(
            '', graduated_symbol_renderer_range_list)
        renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
        renderer.setClassAttribute('Deficit')
        memory_cadastral_layer.setRendererV2(renderer)

        QgsMapLayerRegistry.instance().addMapLayer(memory_cadastral_layer)
        memory_cadastral_layer.setCustomProperty('labeling', 'pal')
        memory_cadastral_layer.setCustomProperty('labeling/enabled', 'true')
        memory_cadastral_layer.setCustomProperty('labeling/fieldName',
                                                 'Number')
        memory_cadastral_layer.setCustomProperty('labeling/fontSize', '10')
        memory_cadastral_layer.setCustomProperty('labeling/placement', '0')

        memory_cadastral_layer.dataProvider().forceReload()
        memory_cadastral_layer.triggerRepaint()

        QgsVectorFileWriter.writeAsVectorFormat(
            memory_cadastral_layer, base_path + '/kharif_' + crop_name +
            '_cadastral_level_vulnerability.shp', "utf-8", None,
            "ESRI Shapefile")
Exemple #21
0
    def unionespacial(self, event):
        # Datos de viviendas de catastro
        bu = self.input_gml.filePath()

        # Datos de perímetros de núcleos de población EIEL
        nucleo = self.input_shp.filePath()

        # Unir aributos por localización: Viviendas y núcleos
        bu_output = 'C:/V_EIEL/viviendasclasificadas.shp'
        processing.run(
            "qgis:joinattributesbylocation", {
                'INPUT': bu,
                'JOIN': nucleo,
                'PREDICATE': 0,
                'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'],
                'METHOD': 0,
                'PREFIX': 'NU_',
                'OUTPUT': bu_output
            })

        joinat = QgsVectorLayer(bu_output, "Viviendas clasificadas nucleo",
                                "ogr")
        QgsProject.instance().addMapLayers([joinat])

        # Selecciono registros sin clasificar de la capa de viviendas clasificadas utilizando la capa núcleos

        expresion = "NU_CODIGO is NULL"
        joinat.selectByExpression(expresion, QgsVectorLayer.SetSelection)

        #Genero el buffer de la capa núcleos

        nucleo = self.input_shp.filePath()
        file_output = 'C:/V_EIEL/buffernucleo.shp'

        processing.run(
            "native:buffer", {
                'INPUT': nucleo,
                'DISTANCE': 200,
                'SEGMENTS': 10,
                'DISSOLVE': False,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 1,
                'OUTPUT': file_output
            })

        lyrBuffer = QgsVectorLayer(file_output, "Buffer nucleo", "ogr")
        QgsProject.instance().addMapLayers([lyrBuffer])

        # Unión espacial de los registros seleccionados de joinat con buffer
        bu_output_2 = 'C:/V_EIEL/viviendasclasificadas_2.shp'
        processing.run(
            "qgis:joinattributesbylocation", {
                'INPUT':
                QgsProcessingFeatureSourceDefinition(
                    'Viviendas clasificadas nucleo', True),
                'JOIN':
                lyrBuffer,
                'PREDICATE':
                0,
                'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'],
                'METHOD':
                0,
                'PREFIX':
                'NU_',
                'OUTPUT':
                bu_output_2
            })

        joinat_2 = QgsVectorLayer(bu_output_2, "Viviendas clasificadas buffer",
                                  "ogr")
        QgsProject.instance().addMapLayers([joinat_2])

        joinat.removeSelection()
        joinat.commitChanges()

        # El resto de viviendas no clasificadas mediante la union con capa buffer pasan a estar en diseminado
        joinat_2 = iface.activeLayer()

        expresion_2 = "NU_CODIGO_ is NULL"
        joinat_2.selectByExpression(expresion_2, QgsVectorLayer.SetSelection)
        joinat_2.startEditing()
        n = joinat_2.selectedFeatureCount()

        for i in range(0, n):
            diseminado = joinat_2.selectedFeatures()
            viv_diseminado = diseminado[i]
            viv_diseminado.setAttribute("NU_CODIGO_", "99")
            viv_diseminado["NU_CODIGO_"] = "99"
            joinat_2.updateFeature(viv_diseminado)
            viv_diseminado.setAttribute("NU_DENOM_1", "DISEMINADO")
            viv_diseminado["NU_DENOM_1"] = "DISEMINADO"
            joinat_2.updateFeature(viv_diseminado)

        joinat_2.commitChanges()
        joinat_2.removeSelection()

        joinat_2.startEditing()
        features = joinat_2.getFeatures()
        for feature in features:
            feature.setAttribute(feature.fieldNameIndex('NU_CODIGO'),
                                 feature['NU_CODIGO_'])
            feature.setAttribute(feature.fieldNameIndex('NU_DENOMIN'),
                                 feature['NU_DENOM_1'])
            joinat_2.updateFeature(feature)

        joinat_2.commitChanges()
        joinat_2.removeSelection()

        # Elimino los campos NU_CODIGO_ y NU_DENOM_1 para conservar la misma estructura en las dos capas joint attributes
        joinat_2.startEditing()
        joinat_2.deleteAttributes([27, 28])
        joinat_2.updateFields()
        joinat_2.commitChanges()

        # Creo la capa union de Viviendas clasificadas nucleo(solo la selección) y viviendas clasificadas buffer
        # En primer lugar extraigo las viviendas clasificadas en la union con la capa nucleos
        expresion_3 = "NU_CODIGO is not NULL"
        joinat.selectByExpression(expresion_3, QgsVectorLayer.SetSelection)
        joinat.startEditing()

        seleccion = 'C:/V_EIEL/viviendasclasificadas_seleccion.shp'
        processing.run("native:saveselectedfeatures", {
            'INPUT': joinat,
            'OUTPUT': seleccion
        })
        nucleo_seleccion = QgsVectorLayer(
            seleccion, "Viviendas clasificadas nucleo seleccion", "ogr")
        QgsProject.instance().addMapLayers([nucleo_seleccion])

        joinat.removeSelection()

        resultado = 'C:/V_EIEL/viviendasclasificadas_resultado.shp'
        processing.run("native:mergevectorlayers", {
            'LAYERS': [nucleo_seleccion, joinat_2],
            'OUTPUT': resultado
        })

        resultado_merge = QgsVectorLayer(resultado, "Viviendas clasificadas",
                                         "ogr")
        QgsProject.instance().addMapLayers([resultado_merge])

        # Suprimo del proyecto todas las capas intermedias generadas en el proceso
        QgsProject.instance().removeMapLayer(nucleo_seleccion)
        QgsProject.instance().removeMapLayer(joinat_2)
        QgsProject.instance().removeMapLayer(joinat)
        QgsProject.instance().removeMapLayer(lyrBuffer)

        #Representación categorizada de la capa resultado
        #Valores únicos
        resultado_merge = iface.activeLayer()

        valoresnucleo = []
        unico = resultado_merge.dataProvider()
        campos = unico.fields()
        id = campos.indexFromName('NU_DENOMIN')
        valoresnucleo = unico.uniqueValues(id)

        #Creación de categorías
        categorias = []
        for valornucleo in valoresnucleo:

            # inicio el valor de símbolo por defecto para la geometría tipo
            symbol = QgsSymbol.defaultSymbol(resultado_merge.geometryType())

            # configuración de capa de simbología
            layer_style = {}
            layer_style['color'] = '%d, %d, %d' % (random.randint(
                0, 256), random.randint(0, 256), random.randint(0, 256))
            layer_style['outline'] = '#000000'
            symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)

            # sustitución de simbología por defecto por simbología configurada
            if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)

            # creación de objeto renderer
            categoria = QgsRendererCategory(valornucleo, symbol,
                                            str(valornucleo))

            # generación de entrada para la lista de categorías
            categorias.append(categoria)

        renderer = QgsCategorizedSymbolRenderer('NU_DENOMIN', categorias)
        # asignación del renderer a la capa
        if renderer is not None:
            resultado_merge.setRenderer(renderer)

        resultado_merge.triggerRepaint()

        # Cálculo de estadísticas

        resultado = iface.activeLayer()
        estadisticas = 'C:/V_EIEL/estadisticas.csv'
        processing.run(
            "qgis:statisticsbycategories", {
                'CATEGORIES_FIELD_NAME': ['NU_DENOMIN', 'NU_CODIGO'],
                'INPUT': 'Viviendas clasificadas',
                'OUTPUT': 'C:/V_EIEL/estadisticas.csv',
                'VALUES_FIELD_NAME': 'numberOfDw',
            })

        # Cargo datos calculados de estadísticas de distribución de viviendas en QTableWidget tbl_resultados
        with open(estadisticas, 'r') as leer_estadisticas:
            registros = leer_estadisticas.read().splitlines()
            contar = 0  #Descarto la primera linea del archivo por contener las cabeceras de los campos
            for registro in registros:
                r = 0
                if contar > 0:
                    campos = registro.split(',')
                    #Puesto que el campo codigo se almacena con "" las elimino para que no aparezcan en la tabla
                    sc = campos[1].lstrip('"').rstrip('"')

                    #Cargo datos del csv en Qtable widget
                    self.tbl_resultados.insertRow(r)
                    self.tbl_resultados.setItem(r, 0,
                                                QTableWidgetItem(str(sc)))
                    self.tbl_resultados.setItem(
                        r, 1, QTableWidgetItem(str(campos[0])))
                    self.tbl_resultados.setItem(
                        r, 2, QTableWidgetItem(str(campos[7])))
                    r = r + 1
                contar = contar + 1

        # Rastreo de registros duplicados en capa resultado por intersectar con dos buffer o dos núcleos
        features = resultado_merge.getFeatures()
        referencias = []
        referencias_dup = []
        for f in features:
            idr = f.fieldNameIndex('reference')
            referencia = f.attribute(idr)
            if referencia not in referencias:
                referencias.append(referencia)
            else:
                referencias_dup.append(referencia)

        self.lst_duplicados.addItems(referencias_dup)
        total_duplicados = self.lst_duplicados.count()
        self.text_duplicados.append(str(total_duplicados))
Exemple #22
0
def raster_to_polygon(raster_path, out_gpkg, out_layer_name, raster_value, surface_name='valley bottom'):

    # raster_layer = QgsRasterLayer(raster_path, 'in_raster')
    out_polygon_path = os.path.join(out_gpkg, out_layer_name)

    # --------- PROCESSING -------------

    # -- DEM --
    tempdir = tempfile.TemporaryDirectory()
    temp_raster = os.path.join(tempdir.name, "less_than.tif")

    gp_calc = processing.run('gdal:rastercalculator', {'INPUT_A': raster_path,
                                                       'BAND_A': 1,
                                                       'FORMULA': f'(A <= {raster_value})',
                                                       'OUTPUT': temp_raster})  # 'raster'})

    # raster_less_than = gp_calc['OUTPUT']

    raster_less_than = QgsRasterLayer(gp_calc['OUTPUT'])

    # -- DEM to VECTOR --
    gp_raw = processing.run("gdal:polygonize",
                            {'INPUT': raster_less_than,
                             'BAND': 1,
                             'FIELD': 'DN',
                             'EIGHT_CONNECTEDNESS': False,
                             'EXTRA': '',
                             'OUTPUT': 'TEMPORARY_OUTPUT'})

    raw_vector = QgsVectorLayer(
        gp_raw['OUTPUT'], "raw_vectors", "ogr")

    # TODO remove when done
    # QgsProject.instance().addMapLayer(raw_vector)

    # -- CALCULATE AREA --
    # create a provider
    pv = raw_vector.dataProvider()

    # add the attribute and update
    pv.addAttributes([QgsField('raw_area_m', QVariant.Int), QgsField(
        'max_elev_m', QVariant.Double), QgsField('surface_name', QVariant.String)])
    raw_vector.updateFields()

    # Create a context and scope
    context = QgsExpressionContext()
    context.appendScopes(
        QgsExpressionContextUtils.globalProjectLayerScopes(raw_vector))

    # Loop through and add the areas
    delete_features = []
    with edit(raw_vector):
        # loop them
        for feature in raw_vector.getFeatures():
            if feature['DN'] != 1:
                delete_features.append(feature.id())
            else:
                context.setFeature(feature)
                feature['raw_area_m'] = QgsExpression('$area').evaluate(context)
                feature['max_elev_m'] = raster_value
                feature['surface_name'] = surface_name
                raw_vector.updateFeature(feature)
        raw_vector.dataProvider().deleteFeatures(delete_features)

    # -- BUFFER POLYGONS --
    gp_buffered = processing.run("native:buffer",
                                 {'INPUT': raw_vector,
                                  'DISTANCE': 0.000001,
                                  'SEGMENTS': 5,
                                  'END_CAP_STYLE': 0,
                                  'JOIN_STYLE': 0,
                                  'MITER_LIMIT': 2,
                                  'DISSOLVE': False,
                                  'OUTPUT': 'TEMPORARY_OUTPUT'})

    buffered_vector = gp_buffered['OUTPUT']

    # TODO remove when final
    # QgsProject.instance().addMapLayer(buffered_vector)

    # -- Simplify Polygons --
    gp_simple = processing.run("native:simplifygeometries",
                               {'INPUT': buffered_vector,
                                'METHOD': 0,
                                'TOLERANCE': simplify_tolerance,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})

    simple_vector = gp_simple['OUTPUT']  # QgsVectorLayer(
    # gp_simplify['OUTPUT'], "simplified_polygons", 'ogr')

    # -- Smooth the polygons --
    gp_smooth = processing.run("native:smoothgeometry",
                               {'INPUT': simple_vector,
                                'ITERATIONS': 1,
                                'OFFSET': smoothing_offset,
                                'MAX_ANGLE': 180,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})

    smooth_vector = gp_smooth['OUTPUT']  # QgsVectorLayer(
    # , "smoothed_polygons", 'ogr')

    gp_multi = processing.run("native:multiparttosingleparts",
                              {'INPUT': smooth_vector,
                               'OUTPUT': 'TEMPORARY_OUTPUT'})

    multi_vector = gp_multi['OUTPUT']

    # Fix any crossed geometry as final vector
    gp_fix = processing.run("native:fixgeometries",
                            {'INPUT': multi_vector,
                             'OUTPUT': 'TEMPORARY_OUTPUT'})

    final_vector = gp_fix['OUTPUT']

    # Create a context and scope
    # Understand WTF this is??
    context = QgsExpressionContext()
    context.appendScopes(
        QgsExpressionContextUtils.globalProjectLayerScopes(final_vector))

    # add an area attribute
    # create a provider
    pv = final_vector.dataProvider()

    # add the attribute and update
    pv.addAttributes([QgsField('area_m', QVariant.Int)])
    final_vector.updateFields()

    # Loop through and add the areas
    with edit(final_vector):
        # loop them
        for feature in final_vector.getFeatures():
            context.setFeature(feature)
            feature['area_m'] = QgsExpression('$area').evaluate(context)
            final_vector.updateFeature(feature)

    # -- Delete Unneeded Fields --
    pv = final_vector.dataProvider()
    pv.deleteAttributes([1, 2])
    final_vector.updateFields()

    # -- Delete small polygons --
    # data provider capabilities
    caps = final_vector.dataProvider().capabilities()

    # features and empty list of features to delete
    features = final_vector.getFeatures()
    delete_features = []

    # if the layer can have deleted features
    if caps & QgsVectorDataProvider.DeleteFeatures:
        for feature in features:
            if feature['area_m'] <= polygon_min_size:
                delete_features.append(feature.id())
        final_vector.dataProvider().deleteFeatures(delete_features)

    # TODO fix final data export
    options = QgsVectorFileWriter.SaveVectorOptions()
    options.layerName = out_layer_name
    options.driverName = 'GPKG'
    if os.path.exists(out_gpkg):
        options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
    QgsVectorFileWriter.writeAsVectorFormat(
        final_vector, out_gpkg, options)

    # open the output layer
    QgsVectorLayer(out_polygon_path, out_layer_name, 'ogr')
Exemple #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.
        ozsource = self.parameterAsSource(parameters, self.OZINPUT, context)
        ozlayer = self.parameterAsVectorLayer(parameters, self.OZINPUT,
                                              context)
        source = self.parameterAsFile(parameters, self.INPUT, context)
        update = self.parameterAsFile(parameters, self.UPDATE, 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))

        fieldnames = [field.name() for field in ozsource.fields()]
        total = 100.0 / ozsource.featureCount() if ozsource.featureCount(
        ) else 0

        with open(source) as csvfile:
            reader = csv.DictReader(csvfile, delimiter=';')
            olddata = [i for i in reader]
            roldata = sorted(list(
                i['ROL'] for i in
                olddata))  # list with language codes (within the BPI dataset)
            ulcode_source = sorted(
                list(set(i['ROL'] for i in olddata))
            )  # list with unique language codes (within the BPI dataset)
            #oz_list = sorted(list(set([i['WorldID'] for i in olddata)))        # list with the unique omega zone identifiers (within the BPI dataset)
            oz_list = sorted(list(set(i['OmegaZone'] for i in olddata)))
            oz_dict = {i['WorldID']: i['OmegaZone'] for i in olddata}
            oz_country_dict = {i['WorldID']: i['Cnty_Name'] for i in olddata}
            cname = sorted(list(set(i['Cnty_Name'] for i in olddata)))

        oz_lang_dict = {}
        with open(source) as csvfile:
            reader = csv.DictReader(csvfile, delimiter=';')
            for row in reader:
                item = oz_lang_dict.get(row['OmegaZone'], list())
                item.append(row['ROL'])
                oz_lang_dict[row['OmegaZone']] = item

        lcode_dict = {i: 0 for i in ulcode_source}
        for i in roldata:
            if i in ulcode_source:
                lcode_dict[i] += 1

        with open(update) as csvfile:
            reader = csv.DictReader(csvfile, delimiter=';')
            data = [i for i in reader]
            countries = sorted(list(set(i['Country'] for i in data)))
            lcode_update = sorted(list(set(i['Language Code'] for i in data)))
            lang_pop_dict = {i['Language Code']: i['Population'] for i in data}
            lang_lang_dict = {
                i['Language Code']: i['Language Name']
                for i in data
            }
            lang_egids_dict = {
                i['Language Code']: i['EGIDS Group']
                for i in data
            }
            lang_color_dict = {i['Language Code']: i['Color'] for i in data}

        ndict = {}
        for lang, pop in lang_pop_dict.items():
            ndict[lang] = int(pop.replace('.', ''))

        oz_update = []
        ozlang_update = {i: [] for i in oz_list}
        ozlan_update = {i: 0 for i in oz_list}
        for oz, lang in oz_lang_dict.items():
            for i in lang:
                if i in lcode_update:
                    oz_update.append(oz)
                    ozlang_update[oz].append(i)
                    ozlan_update[oz] += ndict[i] / lcode_dict[i]

        ozset_update = sorted(list(set(oz_update)))

        # Send some information to the user
        desdict = dict(
            sorted(ozlan_update.items(),
                   key=lambda item: item[1],
                   reverse=True))
        #feedback.pushInfo('{}'.format(desdict))

        lcode_output = []
        nlcode_dict = {i: 0 for i in lcode_update}
        for i in roldata:
            if i in lcode_update:
                lcode_output.append(i)
                nlcode_dict[i] += 1

        nolang = []
        for key, value in nlcode_dict.items():
            if value == 0:
                nolang.append(key)

        crs = ozlayer.crs().authid()
        temp = QgsVectorLayer('Polygon?crs=' + crs, 'temp', 'memory')
        pr = temp.dataProvider()
        pr.addAttributes([
            QgsField("OBJECTID_1", QVariant.Int),
            QgsField("OBJECTID", QVariant.Int),
            QgsField("OZ ID", QVariant.String),
            QgsField("Omega Zone", QVariant.String),
            QgsField("World ABC", QVariant.String),
            QgsField("Province", QVariant.String),
            QgsField("Country", QVariant.String),
            QgsField("Region", QVariant.String),
            QgsField("Population", QVariant.Double),
            QgsField("Number UBL", QVariant.Int),
            QgsField("Population UBL", QVariant.Int),
            QgsField("Perc_Pop UBL", QVariant.Double),
            QgsField("Language Details", QVariant.String),
            QgsField("Color", QVariant.String)
        ])
        temp.updateFields()

        fieldsout = QgsFields()
        fieldsout.append(QgsField("OBJECTID_1", QVariant.Int))
        fieldsout.append(QgsField("OBJECTID", QVariant.Int))
        fieldsout.append(QgsField('OZ ID', QVariant.String))
        fieldsout.append(QgsField('Omega Zone', QVariant.String))
        fieldsout.append(QgsField("World ABC", QVariant.String))
        fieldsout.append(QgsField("Province", QVariant.String))
        fieldsout.append(QgsField("Country", QVariant.String))
        fieldsout.append(QgsField("Region", QVariant.String))
        fieldsout.append(QgsField('Population', QVariant.Double))
        fieldsout.append(QgsField('Number UBL', QVariant.Int))
        fieldsout.append(QgsField('Population UBL', QVariant.Int))
        fieldsout.append(QgsField('Perc_Pop UBL', QVariant.Double))
        fieldsout.append(QgsField('Language Details', QVariant.String))
        fieldsout.append(QgsField('Color', QVariant.String))

        (sink, dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT,
            context,
            fieldsout,  #temp.fields(),
            ozsource.wkbType(),
            ozsource.sourceCrs())

        lang_tpop_dict = {i: 0 for i in lcode_update}
        for feat in ozlayer.getFeatures():
            f = QgsFeature()
            f.setGeometry(feat.geometry())
            f.setFields(fieldsout)
            f["OBJECTID_1"] = feat["OBJECTID_1"]
            f["OBJECTID"] = feat["OBJECTID"]
            f["OZ ID"] = feat["WorldID"]
            f["Omega Zone"] = feat["Zone_Name"]
            f["World ABC"] = feat["World"]
            f["Province"] = feat["Adm1_Name"]
            f["Country"] = feat["Cnty_Name"]
            f["Region"] = feat["RegionYWAM"]
            f["Population"] = feat["Population"]
            f["Number UBL"] = 0
            f["Population UBL"] = 0
            f["Perc_Pop UBL"] = 0
            f["Language Details"] = ""
            f["Color"] = ""
            color = 0
            if f["Omega Zone"] in ozset_update:
                for i in ozlang_update[f["Omega Zone"]]:
                    f["Number UBL"] += 1
                    lang_tpop_dict[i] += f["Population"]
                    color = int(lang_color_dict[i])
                    if color > 0:
                        f["Color"] = f["Country"]
            pr.addFeature(f)
        temp.updateExtents()

        temp.startEditing()
        for feat in temp.getFeatures():
            pop_noOBT_oz = 0
            lpe_string = ""
            if feat["Omega Zone"] in ozset_update:
                langpop = {i: 0 for i in ozlang_update[feat["Omega Zone"]]}
                for i in ozlang_update[feat["Omega Zone"]]:
                    try:
                        ppopoz_lang = feat["Population"] / lang_tpop_dict[i]
                        pop_noOBT_oz += ndict[i] * ppopoz_lang
                        pop_lang_oz = int(ndict[i] * ppopoz_lang)
                        langpop[i] = pop_lang_oz
                    except ZeroDivisionError:
                        pass
                sdict = dict(
                    sorted(langpop.items(),
                           key=lambda item: item[1],
                           reverse=True))
                n = 0
                for key, value in sdict.items():
                    n += 1
                    if feat["Language Details"] == "":
                        feat["Language Details"] += lang_lang_dict[
                            key] + ";" + str(
                                value) + ";" + lang_egids_dict[key]
                    else:
                        feat["Language Details"] += ";" + lang_lang_dict[
                            key] + ";" + str(
                                value) + ";" + lang_egids_dict[key]
                if pop_noOBT_oz > 0:
                    feat["Population UBL"] = round(pop_noOBT_oz, 0)
                    feat["Perc_Pop UBL"] = round(
                        pop_noOBT_oz / feat["Population"] * 100, 1)
            temp.updateFeature(feat)
        temp.commitChanges()

        sec_countries = ()

        for feat in temp.getFeatures():
            if feat["Country"] in sec_countries:
                feat["Number UBL"] = None
                feat["Population UBL"] = None
                feat["Perc_Pop UBL"] = None
                feat["Language Details"] = None
                feat["Color"] = None
            sink.addFeature(feat, QgsFeatureSink.FastInsert)

        return {}
Exemple #24
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        demLayer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM,
                                               context)

        # If DEM layer 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 demLayer is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT_DEM))

        outDBF = self.parameterAsOutputLayer(parameters, self.OUTPUT_DBF,
                                             context)

        # If output DBF 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 outDBF is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT_DBF))

        # Run the script
        stats = demLayer.dataProvider().bandStatistics(1)
        demMinimum = stats.minimumValue
        demMaximum = stats.maximumValue
        print("min:", demMinimum, "m")
        print("max:", demMaximum, "m")
        demRange = demMaximum - demMinimum
        print("Elevation Difference:", demRange, "m")
        increment = demRange / 10.0
        print("Increment:", increment)
        i = 0
        dbfList = []
        for level in self.frange(demMinimum, demMaximum + 1, increment):
            outTable = os.path.join(os.path.dirname(outDBF),
                                    "volume" + str(round(level * 100.0)))
            outTableDbf = str(outTable) + ".dbf"
            processing.run(
                "native:rastersurfacevolume", {
                    'INPUT': demLayer,
                    'BAND': 1,
                    'LEVEL': level,
                    'METHOD': 1,
                    'OUTPUT_HTML_FILE': 'TEMPORARY_OUTPUT',
                    'OUTPUT_TABLE': outTable + ".shp"
                })

            dbfTable = QgsVectorLayer(outTable + ".dbf", outTable, "ogr")
            for feature in dbfTable.getFeatures():
                VolumeKm3 = abs(feature["Volume"]) / 1000000000.0

            pr = dbfTable.dataProvider()
            pr.addAttributes([
                QgsField("Level", QVariant.Double),
                QgsField("VolAbsKm3", QVariant.Double)
            ])
            dbfTable.updateFields()
            dbfTable.startEditing()
            for f in dbfTable.getFeatures():
                f["Level"] = level
                f["VolAbsKm3"] = VolumeKm3
                dbfTable.updateFeature(f)
            dbfTable.commitChanges()

            dbfList.append(outTableDbf)

        volumetable = processing.run("native:mergevectorlayers", {
            'LAYERS': dbfList,
            'CRS': None,
            'OUTPUT': outDBF
        })

        # Return the results of the algorithm.
        outFile = os.path.splitext(outDBF)[0] + ".dbf"
        return {self.OUTPUT_DBF: outFile}
Exemple #25
0
    with edit(shp_layer):
        for f in shp_layer.getFeatures():
            context.setFeature(f)
            f['NOMBRE'] = nombre_Carpeta
            f['CURP'] = curp_def
            if len(nombre_archivo_sext) == 22:
                f['POLIGONO'] = 1
            elif len(nombre_archivo_sext) > 22:
                f['POLIGONO'] = int(numero_pol)
            else:
                f['POLIGONO'] = 0
            f['AREA'] = expression1.evaluate(context)
            f['PERIMETRO'] = expression2.evaluate(context)

            shp_layer.updateFeature(f)

    layer = qgis.utils.iface.activeLayer()
    res = layer.dataProvider().deleteAttributes([0])
    layer.updateFields()
    layer.commitChanges()

    to_be_deleted = project.mapLayersByName(name_vl)[0]
    project.removeMapLayer(to_be_deleted.id())

    print('\nPOLIGONO n°: ', nombre_archivo_ext, '\n')
    print('\nPOLIGONO ELABORADO n°: ' '\n')

print(
    "\n Se cargaron todas las capas y se realizaron todos los procedimientos. \nFIN DEL PROGRAMA.\n"
)
Exemple #26
0
 bar.update(bar_counter)
 
 # add new field
 if school_level not in [field.name() for field in attendance_areas_layer.fields()]:
     attendance_areas_layer.dataProvider().addAttributes([QgsField(school_level, QVariant.String)])
     attendance_areas_layer.updateFields()
     
 # start applying changes
 attendance_areas_layer.startEditing()
 
 # find attendance areas within voronoi polygons
 for attendance_area in attendance_areas_layer.getFeatures():
     for voronoi_polygon in voronoi_layer.getFeatures():
         if attendance_area.geometry().within(voronoi_polygon.geometry()):
             attendance_area[school_level] = voronoi_polygon['Name']
             attendance_areas_layer.updateFeature(attendance_area)
             break
 
 # define and populate attendance areas where schools physically reside (do not give away home area)
 home_areas = {}
 
 for school in schools_layer.getFeatures(request=QgsFeatureRequest(QgsExpression("\"Level\" = '%s'" % (school_level)))):
     for attendance_area in attendance_areas_layer.getFeatures():
         if school.geometry().within(attendance_area.geometry()):
             home_areas[school['Name']] = attendance_area['PLAN_ID']
             attendance_area[school_level] = school['Name']
             attendance_areas_layer.updateFeature(attendance_area)
 
 # commit applied changes
 attendance_areas_layer.commitChanges()
 
Exemple #27
0
    def save_hazard_data(self):
        hazard_geojson = PetaJakartaAPI.get_aggregate_report(
            self.duration, self.level)

        if not hazard_geojson:
            raise PetaJakartaAPIError("Can't access PetaJakarta REST API")

        with open(self.hazard_path, 'w+') as f:
            f.write(hazard_geojson)

        # Save the layer as shp
        file_info = QFileInfo(self.hazard_path)
        hazard_layer = QgsVectorLayer(self.hazard_path, file_info.baseName(),
                                      'ogr', False)

        target_name = 'flood_data.shp'
        self.hazard_path = os.path.join(self.report_path, target_name)
        QgsVectorFileWriter.writeAsVectorFormat(hazard_layer, self.hazard_path,
                                                'CP1250', None,
                                                'ESRI Shapefile')

        file_info = QFileInfo(self.hazard_path)
        hazard_layer = QgsVectorLayer(self.hazard_path, file_info.baseName(),
                                      'ogr')

        hazard_layer.startEditing()
        field = QgsField('flooded', QVariant.Int)
        hazard_layer.dataProvider().addAttributes([field])
        hazard_layer.commitChanges()
        idx = hazard_layer.fieldNameIndex('flooded')
        expression = QgsExpression('count > 0')
        expression.prepare(hazard_layer.pendingFields())

        hazard_layer.startEditing()
        for feature in hazard_layer.getFeatures():
            feature[idx] = expression.evaluate(feature)
            hazard_layer.updateFeature(feature)

        hazard_layer.commitChanges()

        # writing keywords
        keyword_io = KeywordIO()

        keywords = {
            'field': 'flooded',
            'hazard': 'flood',
            'hazard_category': 'single_event',
            'keyword_version': '3.3',
            'layer_geometry': 'polygon',
            'layer_mode': 'classified',
            'layer_purpose': 'hazard',
            'title': 'Flood',
            'value_map': '{"wet": [1], "dry": [0]}',
            'vector_hazard_classification': 'flood_vector_hazard_classes'
        }

        keyword_io.write_keywords(hazard_layer, keywords)

        # archiving hazard layer
        with ZipFile(self.hazard_zip_path, 'w') as zf:
            for root, dirs, files in os.walk(self.report_path):
                for f in files:
                    _, ext = os.path.splitext(f)
                    if 'flood_data' in f:
                        filename = os.path.join(root, f)
                        zf.write(filename, arcname=f)
Exemple #28
0
class FMSFDataFilter():
    def __init__(self, file_path, resource_type=""):

        self.file_path = file_path
        self.resource_type = resource_type
        self.layer_name = ""
        self.in_layer = None
        self.siteid_index = None
        self.out_layer = None
        self.out_layer_dp = None
        self.use_ids = set()

        logger.debug(self.resource_type.upper())
        QgsMessageLog.logMessage(self.resource_type.upper(), "fmsf2hms")

        def initialize_layers():

            self.layer_name = os.path.splitext(os.path.basename(
                self.file_path))[0]
            self.in_layer = QgsVectorLayer(self.file_path,
                                           self.layer_name + " - FMSF", "ogr")

            self.siteid_index = self.in_layer.fields().names().index("SITEID")

            self.out_layer_name = self.layer_name + " - Intermediate Layer"

            geom_name = QgsWkbTypes.displayString(self.in_layer.wkbType())
            self.out_layer = QgsVectorLayer(geom_name,
                                            self.out_layer_name,
                                            "memory",
                                            crs=self.in_layer.crs())
            self.out_layer_dp = self.out_layer.dataProvider()
            self.out_layer_dp.addAttributes(
                [i for i in self.in_layer.fields()])

            # add the extra OWNERSHIP field that will be populated separately
            self.out_layer_dp.addAttributes(
                [QgsField("OWNERSHIP", QVariant.String)])
            self.out_layer.updateFields()

            msg = "layers initialized"
            logger.debug(msg)
            QgsMessageLog.logMessage(msg, "fmsf2hms")

        initialize_layers()

    def add_input_to_map(self):
        QgsProject.instance().addMapLayer(self.in_layer)

    def add_output_to_map(self):
        QgsProject.instance().addMapLayer(self.out_layer)

    def compare_ids_against_hms(self, lookup, compare_to_use_ids=False):

        msg = "comparing ids against HMS ids..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

        start = datetime.now()
        hms_siteids = set([i[0] for i in lookup[self.resource_type]])

        if compare_to_use_ids is True:
            self.use_ids = self.use_ids - hms_siteids
        else:
            for feature in self.in_layer.getFeatures():
                siteid = feature.attributes()[self.siteid_index]
                if siteid not in hms_siteids:
                    self.use_ids.add(siteid)

        msg = f"  - done in {datetime.now() - start}. use_ids total: {len(self.use_ids)}"
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def find_lighthouses(self):

        msg = "finding lighthouses..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

        start = datetime.now()
        for feature in self.in_layer.getFeatures():
            if "Lighthouse" in feature.attributes():
                self.use_ids.add(feature.attributes()[self.siteid_index])

        msg = f"  - done in {datetime.now() - start}. use_ids total: {len(self.use_ids)}"
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def compare_to_shapefile(self):

        msg = "comparing to clip shapefile..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        clip_shp = os.path.join(DATADIR, "structure_filter.gpkg")
        clipped = processing.run(
            "native:clip", {
                'INPUT': self.in_layer,
                'OVERLAY': f'{clip_shp}|layername=structure_filter',
                'OUTPUT': 'TEMPORARY_OUTPUT'
            })['OUTPUT']

        for feature in clipped.getFeatures():
            siteid = feature.attributes()[self.siteid_index]
            self.use_ids.add(siteid)

        msg = f"  - done in {datetime.now() - start}. use_ids total: {len(self.use_ids)}"
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def compare_to_idlist(self, csv_file):

        msg = "comparing to input siteid list..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        with open(csv_file, newline="") as openf:
            reader = csv.DictReader(openf)
            for row in reader:
                self.use_ids.add(row['SITEID'])

        msg = f"  - done in {datetime.now() - start}. use_ids total: {len(self.use_ids)}"
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def remove_destroyed_structures(self):

        msg = "removing destroyed structures..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        des_structures = list()
        dfield = self.out_layer.fields().names().index("DESTROYED")
        for feature in self.in_layer.getFeatures():
            if feature.attributes()[dfield] == "YES":
                des_structures.append(feature.attributes()[self.siteid_index])

        self.use_ids = self.use_ids - set(des_structures)

        msg = f"  - done in {datetime.now() - start}. use_ids total: {len(self.use_ids)}"
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def write_siteids_to_out_layer(self):

        msg = f"writing {len(self.use_ids)} use_ids to out_layer..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        dupes_removed = 0
        for feature in self.in_layer.getFeatures():
            siteid = feature.attributes()[self.siteid_index]
            if siteid in self.use_ids:

                # this proved to be the most effective geometry fixing, remaking
                # the geometry and removing duplicate nodes from it. the native
                # fixgeometries function is still called later though.
                old_geom = feature.geometry().asWkt()
                new_geom = QgsGeometry().fromWkt(old_geom)
                dupes = new_geom.removeDuplicateNodes()
                if dupes is True:
                    dupes_removed += 1
                feature.setGeometry(new_geom)

                self.out_layer_dp.addFeature(feature)
                self.use_ids.remove(siteid)

        self.out_layer.updateExtents()

        msg = f"  - removed {dupes_removed} duplicate nodes during iteration."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

        msg = f"  - done in {datetime.now() - start}."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

        self.fix_geometry()

    def fix_geometry(self):

        msg = f"running native:fixgeometries..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        fixed_results = processing.run("native:fixgeometries", {
            'INPUT': self.out_layer,
            'OUTPUT': 'TEMPORARY_OUTPUT'
        })

        fixed_results['OUTPUT'].setName(self.out_layer.name())
        self.out_layer = fixed_results['OUTPUT']

        msg = f"  - done in {datetime.now() - start}."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")

    def add_owner_type(self, ownership_csv):

        msg = f"adding owner type to output layer..."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
        start = datetime.now()

        owner_value_lookup = {
            'CITY': "City",
            'COUN': "County",
            'STAT': "State",
            'FEDE': "Federal",
            'PULO': "Local government",
            'PRIV': "Private-individual",
            'CORP': "Private-corporate-for profit",
            'CONP': "Private-corporate-nonprofit",
            'FORE': "Foreign",
            'NAAM': "Native American",
            'MULT': "Multiple categories of ownership",
            'UNSP': "Unspecified by Surveyor",
            'PUUN': "Public-unspecified",
            'PRUN': "Private-unspecified",
            'OTHR': "Other",
            'UNKN': "Unknown"
        }

        owner_info = {}
        with open(ownership_csv, "r") as opencsv:
            reader = csv.DictReader(opencsv)
            for row in reader:
                siteid, owner = row['SiteID'].rstrip(), row['OwnType'].rstrip()
                if owner in owner_value_lookup:
                    owner_info[siteid] = owner_value_lookup[owner]
                elif owner in owner_value_lookup.values():
                    owner_info[siteid] = owner
                else:
                    msg = f" - siteid: {siteid}; unexpected ownership: {owner}"
                    logger.debug(msg)
                    QgsMessageLog.logMessage(msg, "fmsf2hms")

        own_field_index = self.out_layer.fields().names().index("OWNERSHIP")
        with edit(self.out_layer):
            for feature in self.out_layer.getFeatures():
                siteid = feature.attributes()[self.siteid_index]
                if siteid in owner_info:
                    feature["OWNERSHIP"] = owner_info[siteid]
                    self.out_layer.updateFeature(feature)

        msg = f"  - done in {datetime.now() - start}."
        logger.debug(msg)
        QgsMessageLog.logMessage(msg, "fmsf2hms")
Exemple #29
0
    def create_mesure_layer(self):
        """ Create an temporary point layer in the Qgis canvas """
        try:
            QApplication.setOverrideCursor(
                Qt.WaitCursor)  ## Start the 'wait' cursor
            if self.list_mesures:

                vl = QgsVectorLayer("Linestring?crs=" + self.selected_epsg,
                                    self.layer_name, "memory")
                pr = vl.dataProvider()

                # add fields
                pr.addAttributes([
                    QgsField("station", QVariant.String),
                    QgsField("st_num", QVariant.Int),
                    QgsField("st_y", QVariant.Double, "double", 12, 4),
                    QgsField("st_x", QVariant.Double, "double", 12, 4),
                    QgsField("st_h", QVariant.Double, "double", 10, 4),
                    QgsField("st_hi", QVariant.Double),
                    QgsField("vise", QVariant.String),
                    QgsField("vise_y", QVariant.Double, "double", 12, 4),
                    QgsField("vise_x", QVariant.Double, "double", 12, 4),
                    QgsField("vise_h", QVariant.Double, "double", 10, 4),
                    QgsField("vise_hs", QVariant.Double),
                    QgsField("vise_category", QVariant.Int),
                    QgsField("dhz", QVariant.Double),
                    QgsField("dh", QVariant.Double)
                ])
                vl.updateFields(
                )  # tell the vector layer to fetch changes from the provider

                # add features
                for item in self.list_mesures:
                    st_y = float(item[2])
                    st_x = float(item[3])
                    vise_y = float(item[7])
                    vise_x = float(item[8])
                    fet = QgsFeature()
                    fet.setGeometry(
                        QgsGeometry.fromPolyline(
                            [QgsPoint(st_y, st_x),
                             QgsPoint(vise_y, vise_x)]))
                    fet.setAttributes(list(item))
                    pr.addFeatures([fet])

                # Calculate the "dhz" and "dh" columns
                expression1 = QgsExpression(
                    "round((sqrt((st_y - vise_y)^2 + (st_x - vise_x)^2)), 3)")
                expression2 = QgsExpression(
                    "round((vise_h + vise_hs - st_h - st_hi), 3)")
                context = QgsExpressionContext()
                context.appendScopes(
                    QgsExpressionContextUtils.globalProjectLayerScopes(vl))

                vl.startEditing()
                for f in vl.getFeatures():
                    context.setFeature(f)
                    f["dhz"] = expression1.evaluate(context)
                    f["dh"] = expression2.evaluate(context)
                    vl.updateFeature(f)
                vl.commitChanges()

                # add preconfigured qgis.qml style file
                plugin_folder = os.path.dirname(os.path.dirname(__file__))
                qml_file = Path(plugin_folder) / "qml" / self.qml_style_mesure
                if qml_file.is_file(
                ):  # Test if file exist, avoid error if he is missing
                    vl.loadNamedStyle(str(qml_file))

                # update layer's extent when new features have been added
                vl.updateExtents()

                # zoom to the layer extent
                canvas = iface.mapCanvas()
                canvas.setExtent(vl.extent())

                # Show in project
                self.rmv_old_qgs_mesure_layer()
                QgsProject.instance().addMapLayer(vl)
        except:
            print(
                "Mesures -> Failed to create a new measurements Qgis layer (def create_mesure_layer)"
            )
            QApplication.restoreOverrideCursor()  ## Stop the 'wait' cursor
        finally:
            QApplication.restoreOverrideCursor()  ## Stop the 'wait' cursor
Exemple #30
0
class EliminadorMMC:
    """ MMC Deletion class """
    def __init__(self, municipi_id, coast=False):
        # Common
        self.arr_nom_municipis = np.genfromtxt(DIC_NOM_MUNICIPIS,
                                               dtype=None,
                                               encoding=None,
                                               delimiter=';',
                                               names=True)
        self.arr_lines_data = np.genfromtxt(DIC_LINES,
                                            dtype=None,
                                            encoding=None,
                                            delimiter=';',
                                            names=True)
        # ADT PostGIS connection
        self.pg_adt = PgADTConnection(HOST, DBNAME, USER, PWD, SCHEMA)
        self.pg_adt.connect()
        # ###
        # Input dependant that don't need data from the layers
        self.municipi_id = int(municipi_id)
        self.coast = coast
        self.municipi_codi_ine = self.get_municipi_codi_ine(self.municipi_id)
        self.municipi_lines = self.get_municipi_lines(
        )  # Get a list with all the lines ID
        if self.coast:
            self.municipi_coast_line = self.get_municipi_coast_line()
        # Input layers
        self.input_points_layer, self.input_lines_layer, self.input_polygons_layer, self.input_coast_lines_layer, self.input_full_bt5_table, self.input_points_table, self.input_line_table, self.input_coast_line_table = (
            None, ) * 8

    def get_municipi_codi_ine(self, municipi_id):
        """
        Get the municipi INE ID
        :param municipi_id -> ID of the municipi which to obtain its INE ID
        :return: codi_ine -> INE ID of the municipi
        """
        muni_data = self.arr_nom_municipis[np.where(
            self.arr_nom_municipis['id_area'] == f'"{municipi_id}"')]
        if muni_data:
            codi_ine = muni_data['codi_ine_muni'][0].strip('"')

            return codi_ine

    def get_municipi_lines(self):
        """
        Get all the municipal boundary lines that make the input municipi
        :return lines_muni_list -> List with all the boundary lines that make the municipi
        """
        lines_muni_1 = self.arr_lines_data[np.where(
            self.arr_lines_data['CODIMUNI1'] == self.municipi_id)]
        lines_muni_2 = self.arr_lines_data[np.where(
            self.arr_lines_data['CODIMUNI2'] == self.municipi_id)]
        lines_muni_1_list = lines_muni_1['IDLINIA'].tolist()
        lines_muni_2_list = lines_muni_2['IDLINIA'].tolist()

        lines_muni_list = lines_muni_1_list + lines_muni_2_list

        return lines_muni_list

    def check_mm_exists(self, municipi_codi_ine, layer='postgis'):
        """
        Check if the input municipi exists as a Municipal Map into the database or into the input polygon layer.
        :param municipi_codi_ine -> Municipi INE ID of the municipi to check if exists its MM
        :param layer -> Layer into check if the MM exists
        :return Boolean True/False -> Boolean that means if the MM exists into the given layer or not
        """
        mapa_muni_table, expression = None, None
        if layer == 'postgis':
            mapa_muni_table = self.pg_adt.get_table('mapa_muni_icc')
            expression = f'"codi_muni"=\'{municipi_codi_ine}\' and "vig_mm" is True'
        elif layer == 'input':
            mapa_muni_table = self.input_polygons_layer
            expression = f'"CodiMuni"=\'{municipi_codi_ine}\''

        mapa_muni_table.selectByExpression(expression,
                                           QgsVectorLayer.SetSelection)
        count = mapa_muni_table.selectedFeatureCount()
        if count == 0:
            return False
        else:
            return True

    def get_municipi_coast_line(self):
        """
        Get the municipi coast line, if exists
        :return coast_line_id -> ID of the coast boundary line
        """
        coast_line_id = ''
        for line_id in self.municipi_lines:
            line_data = self.arr_lines_data[np.where(
                self.arr_lines_data['IDLINIA'] == line_id)]
            if line_data['LIMCOSTA'] == 'S':
                coast_line_id = line_id

        return coast_line_id

    def remove_municipi_data(self):
        """
        Main entry point. This function removes all the data of the municipi that the user wants to remove
        from the database.
        """
        self.set_layers()
        self.remove_polygons()
        self.remove_lines_layer()
        self.remove_lines_table()
        self.remove_points_layer()
        self.remove_points_table()
        if self.coast:
            self.remove_coast_line_layer()
            self.remove_coast_lines_table()
            self.remove_full_bt5m()

    def set_layers(self):
        """ Set the paths of the working vector layers """
        directory_list = os.listdir(ELIMINADOR_WORK_DIR)
        directory_path = os.path.join(ELIMINADOR_WORK_DIR, directory_list[0])
        shapefiles_list = os.listdir(directory_path)

        for shapefile in shapefiles_list:
            if '-fita-' in shapefile and shapefile.endswith('.shp'):
                self.input_points_layer = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-liniaterme-' in shapefile and shapefile.endswith('.shp'):
                self.input_lines_layer = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-poligon-' in shapefile and shapefile.endswith('.shp'):
                self.input_polygons_layer = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-liniacosta-' in shapefile and shapefile.endswith('.shp'):
                self.input_coast_lines_layer = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-liniacostataula-' in shapefile and shapefile.endswith(
                    '.dbf'):
                self.input_coast_line_table = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-tallfullbt5m-' in shapefile and shapefile.endswith('.dbf'):
                self.input_full_bt5_table = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-liniatermetaula-' in shapefile and shapefile.endswith(
                    '.dbf'):
                self.input_line_table = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))
            elif '-fitataula-' in shapefile and shapefile.endswith('.dbf'):
                self.input_points_table = QgsVectorLayer(
                    os.path.join(directory_path, shapefile))

    def remove_polygons(self):
        """ Remove the municipi's polygons from the database """
        self.input_polygons_layer.selectByExpression(
            f'"CodiMuni"=\'{self.municipi_codi_ine}\'',
            QgsVectorLayer.SetSelection)
        with edit(self.input_polygons_layer):
            for polygon in self.input_polygons_layer.getSelectedFeatures():
                self.input_polygons_layer.deleteFeature(polygon.id())

    def remove_coast_line_layer(self):
        """ Remove the municipi's coast lines from the database's layer """
        # 5065
        self.input_coast_lines_layer.selectByExpression(
            f'"IdLinia"={self.municipi_coast_line}',
            QgsVectorLayer.SetSelection)
        with edit(self.input_coast_lines_layer):
            for line in self.input_coast_lines_layer.getSelectedFeatures():
                self.input_coast_lines_layer.deleteFeature(line.id())

    def remove_full_bt5m(self):
        """ Remove the municipi's BT5M full from the database's table """
        self.input_full_bt5_table.selectByExpression(
            f'"IdLinia"={self.municipi_coast_line}',
            QgsVectorLayer.SetSelection)
        with edit(self.input_full_bt5_table):
            for line in self.input_full_bt5_table.getSelectedFeatures():
                self.input_full_bt5_table.deleteFeature(line.id())

    def remove_points_layer(self):
        """
        Remove the municipi's points from the database's layer
        Atenció: en alguns casos no esborra correctament les fites 3 termes.
        """
        point_id_remove_list = self.get_points_to_remove()
        with edit(self.input_points_layer):
            for point_id in point_id_remove_list:
                self.input_points_layer.selectByExpression(
                    f'"IdFita"=\'{point_id}\'', QgsVectorLayer.SetSelection)
                for feature in self.input_points_layer.getSelectedFeatures():
                    self.input_points_layer.deleteFeature(feature.id())

        box = QMessageBox()
        box.setIcon(QMessageBox.Warning)
        box.setText(
            "Enrecorda't de revisar que s'han esborrat\ncorrectament totes les fites 3 termes."
        )
        box.exec_()

    def get_points_to_remove(self):
        """
        Get the points that the class has to remove, in order to avoid removing points that have to exists
        due they also pertain to another municipi that have MM.
        :return point_id_remove_list -> List with the ID of all the points to remove from the points layer
        """
        fita_mem_layer = self.pg_adt.get_layer('v_fita_mem', 'id_fita')
        point_id_remove_list = []
        delete_lines_list, edit_lines_dict = self.get_lines_to_manage()

        for line_id in delete_lines_list:
            fita_mem_layer.selectByExpression(f'"id_linia"=\'{line_id}\'',
                                              QgsVectorLayer.SetSelection)
            for feature in fita_mem_layer.getSelectedFeatures():
                # Check that the point has correctly filled the coordinates fields
                if feature['point_x'] and feature['point_y']:
                    point_id_fita = coordinates_to_id_fita(
                        feature['point_x'], feature['point_y'])
                    if feature['num_termes'] == 'F2T':
                        point_id_remove_list.append(point_id_fita)
                    elif feature['num_termes'] != 'F2T' and feature[
                            'num_termes']:
                        '''
                        No es pot fer una selecció espacial fita - linia de terme, de manera que no es 
                        pot comprovar de manera 100% fiable si una fita 3 termes té una línia veïna amb MM o no.
                        El que es fa és el següent:
                            1. Per cada línia veïna, saber si cap dels municipis de la línia de terme té MM al MMC.
                            2. Si en té, no s'elimina la fita 3 termes.
                        '''
                        neighbor_lines = self.get_neighbor_lines(line_id)
                        neighbor_mm = False
                        for neighbor_line in neighbor_lines:
                            # Get neighbors municipis
                            neighbor_municipi_1_codi_ine, neighbor_municipi_2_codi_ine = self.get_neighbors_ine(
                                neighbor_line)
                            # Check if any of neighbors has MM
                            neighbor_municipi_1_mm = self.check_mm_exists(
                                neighbor_municipi_1_codi_ine, 'input')
                            neighbor_municipi_2_mm = self.check_mm_exists(
                                neighbor_municipi_2_codi_ine, 'input')
                            if (neighbor_municipi_1_mm
                                    or neighbor_municipi_2_mm
                                ) and not neighbor_mm:
                                neighbor_mm = True

                        # If there is not any neighbor municipi with MM, remove the point
                        if not neighbor_mm:
                            point_id_remove_list.append(point_id_fita)

        return point_id_remove_list

    def remove_points_table(self):
        """ Remove the municipi's points from the database's table """
        for line_id in self.municipi_lines:
            with edit(self.input_points_table):
                line_id_txt = line_id_2_txt(line_id)
                self.input_points_table.selectByExpression(
                    f'"IdLinia"=\'{line_id_txt}\'',
                    QgsVectorLayer.SetSelection)
                for feature in self.input_points_table.getSelectedFeatures():
                    self.input_points_table.deleteFeature(feature.id())

    def get_neighbor_lines(self, line_id):
        """
        Get the neighbor lines from the given boundary line
        :param line_id -> ID of the line to obtain its neighbor boundary lines
        :return neighbor_lines -> List with the line ID of the neighbor lines
        """
        neighbor_lines = []
        linia_veina_table = self.pg_adt.get_table('linia_veina')
        linia_veina_table.selectByExpression(f'"id_linia"=\'{line_id}\'',
                                             QgsVectorLayer.SetSelection)
        for line in linia_veina_table.getSelectedFeatures():
            neighbor_lines.append(int(line['id_linia_veina']))

        return neighbor_lines

    def remove_lines_layer(self):
        """ Remove the municipi's boundary lines from the database's layer """
        # Remove boundary lines
        delete_lines_list, edit_lines_dict = self.get_lines_to_manage()
        if delete_lines_list:
            with edit(self.input_lines_layer):
                for line_id in delete_lines_list:
                    self.input_lines_layer.selectByExpression(
                        f'"IdLinia"=\'{line_id}\'',
                        QgsVectorLayer.SetSelection)
                    for line in self.input_lines_layer.getSelectedFeatures():
                        self.input_lines_layer.deleteFeature(line.id())

        # Edit boundary lines
        if edit_lines_dict:
            with edit(self.input_lines_layer):
                for line_id, dates in edit_lines_dict.items():
                    neighbor_valid_de, neighbor_data_alta, neighbor_ine = dates
                    self.input_lines_layer.selectByExpression(
                        f'"IdLinia"=\'{line_id}\'',
                        QgsVectorLayer.SetSelection)
                    for line in self.input_lines_layer.getSelectedFeatures():
                        if line['ValidDe'] < neighbor_valid_de:
                            line['ValidDe'] = neighbor_valid_de
                            self.input_lines_layer.updateFeature(line)
                        if line['DataAlta'] < neighbor_data_alta:
                            line['DataAlta'] = neighbor_data_alta
                            self.input_lines_layer.updateFeature(line)

    def get_lines_to_manage(self):
        """
        Get a list with the line id of the lines to remove and a dict with the line id and some dates of the lines
        to edit
        :return delete_lines_list -> List with the line ID of the lines to remove
        :return edit_lines_dict -> List with the line ID and the Valid De, Data Alta and INE ID of the neighbor municipi
        """
        delete_lines_list = []
        edit_lines_dict = {}
        for line_id in self.municipi_lines:
            # Check if the other municipi has a considered MM
            neighbor_ine = self.get_neighbor_ine(line_id)
            neighbor_mm = self.check_mm_exists(neighbor_ine, 'input')
            line_id_txt = line_id_2_txt(line_id)
            # If the neighbor municipi doesn't have a considered MM, directly remove the boundary line
            # If it has, create a dictionary with its Data Alta and Valid De to check if it has to replace the dates
            if not neighbor_mm:
                delete_lines_list.append(line_id_txt)
            else:
                neighbor_data_alta, neighbor_valid_de = self.get_neighbor_dates(
                    neighbor_ine)
                edit_lines_dict[line_id_txt] = [
                    neighbor_valid_de, neighbor_data_alta, neighbor_ine
                ]

        return delete_lines_list, edit_lines_dict

    def get_neighbor_municipi(self, line_id):
        """
        Get the ID of the neighbor municipi
        :return neighbor_municipi_id -> ID of the neighbor municipi
        """
        line_data = self.arr_lines_data[np.where(
            self.arr_lines_data['IDLINIA'] == line_id)]
        neighbor_municipi_id = ''
        if line_data['CODIMUNI1'] == self.municipi_id:
            neighbor_municipi_id = line_data['CODIMUNI2'][0]
        elif line_data['CODIMUNI2'] == self.municipi_id:
            neighbor_municipi_id = line_data['CODIMUNI1'][0]

        return neighbor_municipi_id

    def get_neighbors_municipis(self, line_id):
        """
        Get the IDs of both municipis than share a boundary line
        :return neighbor_municipi_1_id -> ID of the first neighbor municipi
        :return neighbor_municipi_2_id -> ID of the second neighbor municipi
        """
        line_data = self.arr_lines_data[np.where(
            self.arr_lines_data['IDLINIA'] == line_id)]
        neighbor_municipi_1_id, neighbor_municipi_2_id = line_data[
            'CODIMUNI1'][0], line_data['CODIMUNI2'][0]

        return neighbor_municipi_1_id, neighbor_municipi_2_id

    def get_neighbor_ine(self, line_id):
        """
        Get the INE ID of the neighbor municipi
        :return neighbor_municipi_codi_ine -> INE ID of the neighbor municipi
        """
        neighbor_municipi_id = self.get_neighbor_municipi(line_id)
        neighbor_municipi_codi_ine = self.get_municipi_codi_ine(
            neighbor_municipi_id)

        return neighbor_municipi_codi_ine

    def get_neighbors_ine(self, line_id):
        """
        Get the INE IDs of both municipis than share a boundary line
        :return neighbor_municipi_1_codi_ine -> INE ID of the first neighbor municipi
        :return neighbor_municipi_2_codi_ine -> INE ID of the second neighbor municipi
        """
        neighbor_municipi_1_id, neighbor_municipi_2_id = self.get_neighbors_municipis(
            line_id)
        neighbor_municipi_1_codi_ine = self.get_municipi_codi_ine(
            neighbor_municipi_1_id)
        neighbor_municipi_2_codi_ine = self.get_municipi_codi_ine(
            neighbor_municipi_2_id)

        return neighbor_municipi_1_codi_ine, neighbor_municipi_2_codi_ine

    def get_neighbor_dates(self, neighbor_ine):
        """
        Get the Data Alta and Valid De dates of the neighbor municipi
        :return data_alta -> Data Alta of the neighbor municipi
        :return valid_de -> Valid De of the neighbor municipi
        """
        self.input_polygons_layer.selectByExpression(
            f'"CodiMuni"=\'{neighbor_ine}\'', QgsVectorLayer.SetSelection)
        data_alta, valid_de = None, None
        for polygon in self.input_polygons_layer.getSelectedFeatures():
            data_alta = polygon['DataAlta']
            valid_de = polygon['ValidDe']

        return data_alta, valid_de

    def remove_lines_table(self):
        """ Remove the municipi's boundary lines from the database's table """
        with edit(self.input_line_table):
            for line in self.municipi_lines:
                line_txt = line_id_2_txt(line)
                self.input_line_table.selectByExpression(
                    f'"IdLinia"={line_txt} and "CodiMuni" = \'{self.municipi_codi_ine}\'',
                    QgsVectorLayer.SetSelection)
                for feature in self.input_line_table.getSelectedFeatures():
                    self.input_line_table.deleteFeature(feature.id())

    def remove_coast_lines_table(self):
        """ Remove the municipi's boundary coast line from the database's table """
        with edit(self.input_coast_line_table):
            self.input_coast_line_table.selectByExpression(
                f'"IdLinia"={self.municipi_coast_line}')
            for feature in self.input_coast_line_table.getSelectedFeatures():
                self.input_coast_line_table.deleteFeature(feature.id())