Skip to content

Vector layer

Import
from pyqgis_wrapper.layer import VectorLayerBuilder, VectorLayerManager

VectorLayerBuilder()

Bases: pyqgis_wrapper.layer.base.LayerBuilder[qgis.core.QgsVectorLayer]

Class that handle layer creation. Either form an existing layer with various degree of copying (fields, feature) or from scratch

It can be written to a file or stay in memory

Source code in pyqgis_wrapper/layer/vector_layer.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def __init__(self):
    super().__init__()
    self._geometry_type: Optional[QgsWkbTypes] = None
    self._fields: Optional[QgsFields] = None
    self._request: Optional[QgsFeatureRequest] = None
    self._copy_feat: bool = False
    self._multi_layer_extension: Set[str] = {
        "gpkg",
        "fgb",
        "gdb",
        "sqlite",
        "sql",
        "ods",
        "xlsx",
    }  # Infered from _valid_extension

get_geometry_type property

Get the geometry type

Returns:

Type Description
QgsWkbTypes

Type of geometry used for the layer creation

get_fields property

Fields getter. Allow to add the fields to QgsFeature that'll be added to the created layer

Returns:

Type Description
QgsFields

Fields of the created layer

set_geometry(geom_type)

Set the geometry type for the output layer.

Parameters:

Name Type Description Default
geom_type typing.Union[str, int]

Accepts (case don't matter): 'Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon' Accepts following enum/WkbType : 1: QgsWkbTypes.Point, 2: QgsWkbTypes.LineString, 3: QgsWkbTypes.Polygon, 4: QgsWkbTypes.MultiPoint, 5: QgsWkbTypes.MultiLineString, 6: QgsWkbTypes.MultiPolygon,

required

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def set_geometry(self, geom_type: Union[str, int]) -> VectorLayerBuilder:
    """
    Set the geometry type for the output layer.


    :param geom_type: Accepts (case don't matter):
            'Point', 'MultiPoint',
            'LineString', 'MultiLineString',
            'Polygon', 'MultiPolygon'
        Accepts following enum/WkbType :
        1: QgsWkbTypes.Point,
        2: QgsWkbTypes.LineString,
        3: QgsWkbTypes.Polygon,
        4: QgsWkbTypes.MultiPoint,
        5: QgsWkbTypes.MultiLineString,
        6: QgsWkbTypes.MultiPolygon,
    :type geom_type: Union[str, int]

    :return: self
    :rtype: VectorLayerBuilder
    """
    geom_map = {
        "point": QgsWkbTypes.Point,
        "multipoint": QgsWkbTypes.MultiPoint,
        "linestring": QgsWkbTypes.LineString,
        "multilinestring": QgsWkbTypes.MultiLineString,
        "polygon": QgsWkbTypes.Polygon,
        "multipolygon": QgsWkbTypes.MultiPolygon,
    }

    # For validation of enum to not allow random int input
    wkbType_map = [
        QgsWkbTypes.Point,
        QgsWkbTypes.LineString,
        QgsWkbTypes.Polygon,
        QgsWkbTypes.MultiPoint,
        QgsWkbTypes.MultiLineString,
        QgsWkbTypes.MultiPolygon,
    ]

    if isinstance(geom_type, str):
        key = geom_type.lower()
        if key not in geom_map:
            raise ValueError(
                f"Unsupported geometry type string: '{geom_type}'. \
                Must be one of {list(geom_map.keys())}."
            )

        self._geometry_type = geom_map[key]
    # Can be directly a WkbType enum
    elif isinstance(geom_type, int):
        if geom_type not in wkbType_map:
            raise ValueError(
                f"Unsupported WKB enum value: '{QgsWkbTypes.Type(geom_type)}'. \
                Must be one of {wkbType_map}."
            )

        self._geometry_type = QgsWkbTypes.Type(geom_type)

    else:
        raise TypeError(
            f"Invalid type for geometry: {type(geom_type).__name__}. "
            f"Expected str or int (QgsWkbTypes)."
        )
    return self

set_fields(fields)

Set fields for the output layer

Parameters:

Name Type Description Default
fields qgis.core.QgsFields

Fields to be set

required

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def set_fields(self, fields: QgsFields) -> VectorLayerBuilder:
    """
    Set fields for the output layer

    :param fields: Fields to be set
    :type fields: QgsFields

    :return: self
    :rtype: VectorLayerBuilder
    """
    if not isinstance(fields, QgsFields):
        raise TypeError(f"Expected QgsFields, got {type(fields).__name__}")

    self._fields = fields
    return self

set_request(request)

Spatial or attribute request to create a subset of feature when calling from_layer with copy_feat = True

Parameters:

Name Type Description Default
request qgis.core.QgsFeatureRequest

description

required

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
224
225
226
227
228
229
230
231
232
233
234
235
236
def set_request(self, request: QgsFeatureRequest) -> VectorLayerBuilder:
    """
    Spatial or attribute request to create a subset of feature
    when calling from_layer with copy_feat = True

    :param request: _description_
    :type request: QgsFeatureRequest

    :return: self
    :rtype: VectorLayerBuilder
    """
    self._request = request
    return self

from_layer(layer, copy_feat=True, copy_fields=True, request=None)

Duplicate a layer at various degree If you want more flexibility in layer creation you should call configure instead

Once you set the wanted parameters you can call build method to create the layer

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to duplicate

required
copy_feat bool

Copy feature in the new layer, defaults to True

True
copy_fields bool

Copy fields in the new layer, defaults to True You can get the QgsFields object with the get_fields property in case you want to add new features to the layer

True
request typing.Optional[qgis.core.QgsFeatureRequest]

Spatial or attributary request to select a subset of features to copy, defaults to None

None

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
def from_layer(
    self,
    layer: QgsVectorLayer,
    copy_feat: bool = True,
    copy_fields: bool = True,
    request: Optional[QgsFeatureRequest] = None,
) -> VectorLayerBuilder:
    """
    Duplicate a layer at various degree
    If you want more flexibility in layer creation you should call configure instead

    Once you set the wanted parameters you can call build method to create the layer

    :param layer: Layer to duplicate
    :type layer: QgsVectorLayer
    :param copy_feat: Copy feature in the new layer, defaults to True
    :type copy_feat: bool, optional
    :param copy_fields: Copy fields in the new layer, defaults to True
    You can get the QgsFields object with the `get_fields` property in case
    you want to add new features to the layer
    :type copy_fields: bool, optional
    :param request: Spatial or attributary request to select a
    subset of features to copy, defaults to None
    :type request: Optional[QgsFeatureRequest], optional

    :return: self
    :rtype: VectorLayerBuilder
    """
    if not isinstance(layer, QgsVectorLayer):
        raise TypeError(
            f"Parameter layer expected a QgsVectorLayer, got '{type(layer)}'."
        )
    else:
        if not layer.isValid():
            raise ValueError(f"{layer} is not a valid QgsVectorLayer.")

    if copy_feat:
        self._src_layer = layer
        self._copy_feat = True
        if request is not None:
            self.set_request(request)
    if copy_fields:
        self.set_fields(layer.fields())

    self.set_geometry(layer.wkbType())
    self.set_crs(layer.crs())

    return self

configure(crs, geometry, fields=None)

Configure layer creation from scratch

Parameters:

Name Type Description Default
crs typing.Union[str, int, qgis.core.QgsCoordinateReferenceSystem]

Crs of the layer to create

required
geometry str

Geometry type of the layer to create Accepts (case don't matter): 'Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon'

required
fields typing.Optional[qgis.core.QgsFields]

Fields to add to the new layer, defaults to None

None

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
def configure(
    self,
    crs: Union[str, int, QgsCoordinateReferenceSystem],
    geometry: str,
    fields: Optional[QgsFields] = None,
) -> VectorLayerBuilder:
    """
    Configure layer creation from scratch

    :param crs: Crs of the layer to create
    :type crs: Union[str, int, QgsCoordinateReferenceSystem]
    :param geometry: Geometry type of the layer to create
    Accepts (case don't matter):
            'Point', 'MultiPoint',
            'LineString', 'MultiLineString',
            'Polygon', 'MultiPolygon'
    :type geometry: str
    :param fields: Fields to add to the new layer, defaults to None
    :type fields: Optional[QgsFields], optional

    :return: self
    :rtype: VectorLayerBuilder
    """
    self.set_crs(crs)
    self.set_geometry(geometry)

    if fields is not None:
        self.set_fields(fields)

    return self

build()

Build a layer form the parameters set by from_layer or configure method. If a path was provided the new layer will be saved on a file

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
def build(self) -> VectorLayerBuilder:
    """
    Build a layer form the parameters set by from_layer or configure method.
    If a path was provided the new layer will be saved on a file

    :return: self
    :rtype: VectorLayerBuilder
    """
    self._validate_parameters()

    uri = f"{QgsWkbTypes.displayString(self.get_geometry_type)}?crs={self._crs.authid()}"

    self._layer = QgsVectorLayer(uri, "newLayer", "memory")

    if self._fields is not None:
        self._layer.dataProvider().addAttributes(self._fields)
        self._layer.updateFields()

    if not self._copy_feat and self._request is not None:
        self.logger.info("'copy_feat' is set to False, request will be ignored.")
    elif self._copy_feat:
        if self._request is not None:
            iterator = self._src_layer.getFeatures(self._request)
        else:
            iterator = self._src_layer.getFeatures()

        if not "fid" in self._layer.fields().names():
            features = [feature for feature in iterator]
        else:
            fid_idx = self._layer.fields().indexFromName("fid")
            features = []
            for idx, feature in enumerate(iterator, 1):
                if "fid" not in feature.fields().names():
                    attr = feature.attributes()
                    attr.insert(fid_idx, idx)
                    feature.setAttributes(attr)
                else:
                    feature["fid"] = idx

                features.append(feature)

        self._layer.dataProvider().addFeatures(features)

    return self

save(path, layer_name=None, extension='gpkg', provider='ogr', overwrite=False, append_layer=False)

Writes layer to a file

Parameters:

Name Type Description Default
path typing.Union[str, pathlib.Path]

Output path to write to

required
layer_name typing.Optional[str]

Name of the layer. If None it'll be infered by the file name. If append_layer is True and layer name already exists or is None then a random one will be created, defaults to None The layer name is ignored if the extension does not support multi layer

None
extension str

The file extension to use when saving the layer, defaults to "gpkg". If the path includes an extension, it will take precedence over this parameter. Accepted extensions : 'gpkg', 'shp', '000', 'csv', 'dgn', 'dxf', 'fgb', 'gdb', 'geojson', 'geojsonl', 'geojsons', 'gml', 'gpx', 'gxt', 'ili', 'itf', 'json', 'kml', 'ods', 'sql', 'sqlite', 'tab', 'txt', 'xlsx', 'xml', 'xtf'

'gpkg'
provider str

Provider used to load the QgsVectorLayer. Defaults to 'ogr'. Most extension is handled by the default provider. However, if the specified provider does not match the file format (e.g., using "ogr" for a format that requires a different provider), the resulting layer will be invalid and an error will be raised when calling the load() method.

'ogr'
overwrite bool

If True will erase existing file or layer, defaults to False

False
append_layer bool

If True will append the layer to an existing file if the format allows it, defaults to False

False

Returns:

Type Description
VectorLayerBuilder

self

Source code in pyqgis_wrapper/layer/vector_layer.py
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
def save(
    self,
    path: Union[str, Path],
    layer_name: Optional[str] = None,
    extension: str = "gpkg",
    provider: str = "ogr",
    overwrite: bool = False,
    append_layer: bool = False,
) -> VectorLayerBuilder:
    """
    Writes layer to a file

    :param path: Output path to write to
    :type path:  Union[str, Path], optional
    :param layer_name: Name of the layer. If None it'll be infered by the file name.
    If append_layer is True and layer name already exists or is None
    then a random one will be created, defaults to None
    The layer name is ignored if the extension does not support multi layer
    :type layer_name: Optional[str], optional
    :param extension: The file extension to use when saving the layer, defaults to "gpkg".
    If the path includes an extension, it will take precedence over this parameter.
    Accepted extensions :
        'gpkg', 'shp', '000', 'csv', 'dgn', 'dxf', 'fgb', 'gdb', 'geojson',
        'geojsonl', 'geojsons', 'gml', 'gpx', 'gxt', 'ili', 'itf', 'json',
        'kml', 'ods', 'sql', 'sqlite', 'tab', 'txt', 'xlsx', 'xml', 'xtf'
    :type extension: str, optional
    :param provider: Provider used to load the QgsVectorLayer. Defaults to 'ogr'.
    Most extension is handled by the default provider. However, if the
    specified provider does not match the file format (e.g., using "ogr" for a format
    that requires a different provider), the resulting layer will be invalid and an
    error will be raised when calling the `load()` method.
    :type provider: str, optional
    :param overwrite: If True will erase existing file or layer, defaults to False
    :type overwrite: bool
    :param append_layer: If True will append the layer to an existing file
    if the format allows it, defaults to False
    :type append_layer: bool

    :return: self
    :rtype: VectorLayerBuilder
    """
    path, extension = self._validate_output(path, extension)
    save_options = self._build_options(
        path, layer_name, extension, overwrite, append_layer
    )

    # Will be used if i want to define reprojection
    transform_context = QgsCoordinateTransformContext()

    error, _, _, error_str = QgsVectorFileWriter.writeAsVectorFormatV3(
        self._layer, path, transform_context, save_options
    )  # Second output seems to be always empty and third is the input path
    # instead of the filename so i prefer to keep my input parameter

    if error != QgsVectorFileWriter.NoError:
        message = f"Failed to save layer: {error_str}."
        raise IOError(message)  # Should be catch by logger in higher level

    self.logger.info(f"Layer successfully saved to {path}")

    self._layer = self._load_layer(
        path, save_options.layerName, extension, provider
    )

    return self

VectorLayerManager(edit_session=False)

Handles

  • adding and removing fields in a QgsVectorLayer,
  • modifying attributes
  • adding or removing feature

Support working directly on the dataprovider or with the edit session. Does not own the logic, instead delegate to lower level manager. Please note that working directly on the provider provide less safeguarding and do not keep track of previous changes.

Parameters:

Name Type Description Default
edit_session bool

Use edit session from QGIS or work directly on the file, defaults to False. Can be changed by calling edit_session

False
Source code in pyqgis_wrapper/layer/vector_layer.py
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self._field = VectorLayerFieldManager(edit_session)
    self._attribute = VectorLayerAttributeManager(edit_session)
    self._feature = VectorLayerFeatureManager(edit_session)
    self._geometry = VectorLayerGeometryManager(edit_session)

    self.edit_session = edit_session

edit_session property writable

Getter for edit_session

Returns:

Type Description
bool

edit_session value

VectorLayerBaseManager(edit_session=False)

Bases: abc.ABC

Base handler for QgsVectorLayer

Parameters:

Name Type Description Default
edit_session bool

Use edit session from QGIS or work directly on the file, defaults to False. Can be changed by calling edit_session

False
Source code in pyqgis_wrapper/layer/vector_layer.py
583
584
585
586
587
588
589
590
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self.edit_session = edit_session
    self.logger = create_child_logger(__name__)

edit_session property writable

Getter for edit_session

Returns:

Type Description
bool

edit_session value

exit_edit_mode(layer, strategy=EditStrategy.ROLLBACK)

Attempts to exit edit mode on the given layer using the provided strategy.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to check

required
strategy pyqgis_wrapper.layer.vector_layer.EditStrategy

Either ROLLBACK or COMMIT

pyqgis_wrapper.layer.vector_layer.EditStrategy.ROLLBACK

Returns:

Type Description
bool

True if the layer edit state has changed

Source code in pyqgis_wrapper/layer/vector_layer.py
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
def exit_edit_mode(
    self, layer: QgsVectorLayer, strategy: EditStrategy = EditStrategy.ROLLBACK
) -> bool:
    """
    Attempts to exit edit mode on the given layer using the provided strategy.

    :param layer: Layer to check
    :type layer: QgsVectorLayer
    :param strategy: Either ROLLBACK or COMMIT
    :type strategy: EditStrategy

    :return: True if the layer edit state has changed
    :rtype: bool
    """
    success = False
    if layer.isEditable():  # True if layer is in edit mode
        success = strategy.apply(layer)
        if not success:
            raise LayerEditionError(
                f"Could not exit edition mode for layer {layer.name()}."
            )
    return success

VectorLayerFieldManager(edit_session=False)

Bases: pyqgis_wrapper.layer.vector_layer.VectorLayerBaseManager

Handles adding and removing fields in a QgsVectorLayer, Support working directly on the dataprovider or with the edit session.

Source code in pyqgis_wrapper/layer/vector_layer.py
583
584
585
586
587
588
589
590
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self.edit_session = edit_session
    self.logger = create_child_logger(__name__)

add(layer, field_input)

Add a QgsField or QgsFields to the given QgsVectorLayer.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

The layer to add the field(s) to

required
field_or_fields typing.Union[qgis.core.QgsField, qgis.core.QgsFields]

A single QgsField or multiple QgsFields

required

Returns:

Type Description
Union[int, Dict[str, int]]

Index of the added field, or dict of {field names: indexes}

Source code in pyqgis_wrapper/layer/vector_layer.py
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
def add(
    self, layer: QgsVectorLayer, field_input: Union[QgsFields, QgsField]
) -> Union[int, Dict[str, int]]:
    """
    Add a QgsField or QgsFields to the given QgsVectorLayer.

    :param layer: The layer to add the field(s) to
    :type layer: QgsVectorLayer
    :param field_or_fields: A single QgsField or multiple QgsFields
    :type field_or_fields: Union[QgsField, QgsFields]

    :return: Index of the added field, or dict of {field names: indexes}
    :rtype: Union[int, Dict[str, int]]
    """
    if isinstance(field_input, QgsField):
        return self._add_field(layer, field_input)

    elif isinstance(field_input, QgsFields):
        return self._add_fields(layer, field_input)

    else:
        raise TypeError(
            f"field_input must be a QgsField or QgsFields, got {type(field_input)}."
        )

delete(layer, field_names)

Delete one or more fields from the given QgsVectorLayer.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

The layer to delete the field(s) from

required
field_names typing.Union[str, typing.List[str]]

Name of the field or list of field names to delete

required

Returns:

Type Description
bool

True if the field(s) were successfully deleted

Source code in pyqgis_wrapper/layer/vector_layer.py
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
def delete(self, layer: QgsVectorLayer, field_names: Union[str, List[str]]) -> bool:
    """
    Delete one or more fields from the given QgsVectorLayer.

    :param layer: The layer to delete the field(s) from
    :type layer: QgsVectorLayer
    :param field_names: Name of the field or list of field names to delete
    :type field_names: Union[str, List[str]]

    :return: True if the field(s) were successfully deleted
    :rtype: bool
    """
    if isinstance(field_names, str):
        return self._delete_field(layer, field_names)

    elif isinstance(field_names, list):
        return self._delete_fields(layer, field_names)

    else:
        raise TypeError(
            f"field_names must be a string or list of strings, got {type(field_names)}."
        )

VectorLayerFeatureManager(edit_session=False)

Bases: pyqgis_wrapper.layer.vector_layer.VectorLayerBaseManager

Handles adding and removing feature in a QgsVectorLayer, Support working directly on the dataprovider or with the edit session.

Source code in pyqgis_wrapper/layer/vector_layer.py
583
584
585
586
587
588
589
590
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self.edit_session = edit_session
    self.logger = create_child_logger(__name__)

add(layer, feature_input)

Add a feature or an iterable of feature to the layer

Example : - Deleted feature n°1. - Added feature with a setId(1) -> Internal id is feature n°2

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to add the feature to

required
feature_input typing.Union[qgis.core.QgsFeature, typing.Iterable[qgis.core.QgsFeature]]

Feature(s) that will be added

required

Returns:

Type Description
bool

True if successfully added

Source code in pyqgis_wrapper/layer/vector_layer.py
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
def add(
    self,
    layer: QgsVectorLayer,
    feature_input: Union[QgsFeature, Iterable[QgsFeature]],
) -> bool:
    """
    Add a feature or an iterable of feature to the layer

    Example :
        - Deleted feature n°1.
        - Added feature with a setId(1) -> Internal id is feature n°2

    :param layer: Layer to add the feature to
    :type layer: QgsVectorLayer
    :param feature_input: Feature(s) that will be added
    :type feature_input: Union[QgsFeature, Iterable[QgsFeature]]

    :return: True if successfully added
    :rtype: bool
    """
    feature_input = self._update_fids(layer, feature_input)

    if isinstance(feature_input, QgsFeature):
        return self._add_feature(layer, feature_input)

    elif self._is_iterable(feature_input):
        return self._add_features(layer, feature_input)

    else:
        raise TypeError(
            f"feature_input must be a QgsFeature or an iterable of QgsFeature, got {type(feature_input)}."
        )

delete(layer, fid_input)

Delete a feature or a list of feature by their ids.

Please be aware that if you delete a feature the next feature that'll be added will have an internal id incremented by one.

Example : - Deleted feature n°1. - Added feature with a setId(1) -> Internal id is feature n°2

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to delete the features from

required
fid_input typing.Union[int, typing.List[int]]

Feature id or a list of features id to be deleted from the layer

required

Returns:

Type Description
bool

True if successfully deleted

Source code in pyqgis_wrapper/layer/vector_layer.py
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
def delete(self, layer: QgsVectorLayer, fid_input: Union[int, List[int]]) -> bool:
    """
    Delete a feature or a list of feature by their ids.

    Please be aware that if you delete a feature the next feature
    that'll be added will have an internal id incremented by one.

    Example :
        - Deleted feature n°1.
        - Added feature with a setId(1) -> Internal id is feature n°2

    :param layer: Layer to delete the features from
    :type layer: QgsVectorLayer
    :param fid_input: Feature id or a list of features id to be deleted from the layer
    :type fid_input: Union[int, List[int]]

    :return: True if successfully deleted
    :rtype: bool
    """
    if isinstance(fid_input, int):
        return self._delete_feature(layer, fid_input)

    elif isinstance(fid_input, list):
        return self._delete_features(layer, fid_input)

    else:
        raise TypeError(
            f"fid_input must be an int or a list of int, got {type(fid_input)}."
        )

update(layer, feature_input)

Update a feature or an iterable of features in a layer.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to update the feature(s) from.

required
feature_input typing.Union[qgis.core.QgsFeature, typing.Iterable[qgis.core.QgsFeature]]

Feature or iterable of features with matching feature.id() to update

required

Returns:

Type Description
bool

True if successfully updated.

Source code in pyqgis_wrapper/layer/vector_layer.py
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
def update(
    self,
    layer: QgsVectorLayer,
    feature_input: Union[QgsFeature, Iterable[QgsFeature]],
) -> bool:
    """
    Update a feature or an iterable of features in a layer.

    :param layer: Layer to update the feature(s) from.
    :type layer: QgsVectorLayer
    :param feature_input: Feature or iterable of features with matching feature.id() to update
    :type feature_input: Union[QgsFeature, Iterable[QgsFeature]]

    :return: True if successfully updated.
    :rtype: bool
    """
    if isinstance(feature_input, QgsFeature):
        return self._update_feature(layer, feature_input)

    elif self._is_iterable(feature_input):
        return self._update_features(layer, feature_input)

    else:
        raise TypeError(
            f"feature_input must be a QgsFeature or an iterable of QgsFeature, got {type(feature_input)}."
        )

VectorLayerAttributeManager(edit_session=False)

Bases: pyqgis_wrapper.layer.vector_layer.VectorLayerBaseManager

Handles adding and removing attribute for specific feature in a QgsVectorLayer, Support working directly on the dataprovider or with the edit session.

Source code in pyqgis_wrapper/layer/vector_layer.py
583
584
585
586
587
588
589
590
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self.edit_session = edit_session
    self.logger = create_child_logger(__name__)

update(layer, attr_map)

Update attributes from feature(s).

In edit session QGIS will cast str, float and bool to int if able

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer containing the features whose attributes will be updated

required
attr_map typing.Dict[int, typing.Dict[int, typing.Any]]

Dictionary in the form {fid: {field_idx: new_value, ...}, ...}

required

Returns:

Type Description
bool

True if successfully updated

Source code in pyqgis_wrapper/layer/vector_layer.py
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
def update(
    self, layer: QgsVectorLayer, attr_map: Dict[int, Dict[int, Any]]
) -> bool:
    """
    Update attributes from feature(s).

    In edit session QGIS will cast str, float and bool to int if able

    :param layer: Layer containing the features whose attributes will be updated
    :type layer: QgsVectorLayer
    :param attr_map: Dictionary in the form {fid: {field_idx: new_value, ...}, ...}
    :type attr_map: Dict[int, Dict[int, Any]]

    :return: True if successfully updated
    :rtype: bool
    """
    if not isinstance(attr_map, dict):
        raise TypeError(f"attr_map must be a dict, got {type(attr_map)}.")

    is_single_attr = len(attr_map) == 1 and len(next(iter(attr_map.values()))) == 1

    if is_single_attr:
        return self._change_attribute_value(layer, attr_map)

    elif not is_single_attr:
        return self._change_attribute_values(layer, attr_map)

    else:
        raise ValueError(
            "Unexpected error. "
            "Please encure attr_map is a dict in the form "
            "{fid: {field_idx: new_value, ...}, ...}"
        )

VectorLayerGeometryManager(edit_session=False)

Bases: pyqgis_wrapper.layer.vector_layer.VectorLayerBaseManager

Handles adding and removing geometry for specific feature in a QgsVectorLayer, Support working directly on the dataprovider or with the edit session.

Source code in pyqgis_wrapper/layer/vector_layer.py
583
584
585
586
587
588
589
590
def __init__(self, edit_session: bool = False):
    """
    :param edit_session: Use edit session from QGIS or work directly on the
    file, defaults to False. Can be changed by calling `edit_session`
    :type edit_session: bool, optional
    """
    self.edit_session = edit_session
    self.logger = create_child_logger(__name__)

update(layer, geom_map)

Update geometries from feature(s)

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer containing the features whose geometries will be updated

required
attr_map typing.Dict[int, qgis.core.QgsGeometry]

Dictionary in the form {fid: QgsGeometry, ...}

required

Returns:

Type Description
bool

True if successfully updated

Source code in pyqgis_wrapper/layer/vector_layer.py
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
def update(self, layer: QgsVectorLayer, geom_map: Dict[int, Any]) -> bool:
    """
    Update geometries from feature(s)

    :param layer: Layer containing the features whose geometries will be updated
    :type layer: QgsVectorLayer
    :param attr_map: Dictionary in the form {fid: QgsGeometry, ...}
    :type attr_map: Dict[int, QgsGeometry]

    :return: True if successfully updated
    :rtype: bool
    """
    if not isinstance(geom_map, dict):
        raise TypeError(f"geom_map must be a dict, got {type(geom_map)}.")

    is_single = len(geom_map) == 1

    if is_single:
        return self._change_geometry(layer, geom_map)

    elif not is_single:
        return self._change_geometries(layer, geom_map)

    else:
        raise ValueError(f"Unknown update_type: '{type(geom_map)}'.")

EditStrategy

Bases: str, enum.Enum

Class to store edit strategy and eventually apply it.