Skip to content

Prediction

Classes to perform multidiversity index prediction.

BaseDataManager

Base class for data management. Contain layers to extract features needed for computation.

compute() abstractmethod

Compute sample from data layer and output a set of variables as Sample.

Source code in niva/core/prediction/data_manager.py
25
26
27
28
@abstractmethod
def compute(self) -> Sample:
    """Compute sample from data layer and output a set of variables as Sample."""
    pass

filter_iacs(layer)

Filter IACS on Niva.ID fields.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

IACS layer.

required

Returns:

Type Description
qgis.core.QgsVectorLayer

Filtered IACS.

Source code in niva/core/prediction/data_manager.py
30
31
32
33
34
35
36
37
38
39
40
41
42
def filter_iacs(self, layer: QgsVectorLayer) -> QgsVectorLayer:
    """Filter IACS on Niva.ID fields.

    Args:
        layer (QgsVectorLayer): IACS layer.

    Returns:
        Filtered IACS.
    """
    filtered = layer.materialize(
        QgsFeatureRequest().setFilterExpression(f'"ID.NIVA" < 41')
    )
    return filtered

GridDataManager() dataclass

Bases: niva.core.prediction.data_manager.BaseDataManager

DataManager for grid based predictor.

compute(cell) abstractmethod

Compute a sample from cell geometry selection.

Parameters:

Name Type Description Default
cell qgis.core.QgsGeometry

Cell to compute metrics on.

required

Returns:

Type Description
niva.core.sample.Sample

Sample of variables.

Source code in niva/core/prediction/data_manager.py
49
50
51
52
53
54
55
56
57
58
59
@abstractmethod
def compute(self, cell: QgsGeometry) -> Sample:
    """Compute a sample from cell geometry selection.

    Args:
        cell (QgsGeometry): Cell to compute metrics on.

    Returns:
        Sample of variables.
    """
    pass

crop_feat(feature, geometry)

Crop a feat with intersection geometry.

Parameters:

Name Type Description Default
feature qgis.core.QgsFeature

Fetaure to crop.

required
geometry qgis.core.QgsGeometry

Geometry to compute intersection.

required

Returns:

Type Description
typing.List[qgis.core.QgsFeature]

Cropped feature.

Source code in niva/core/prediction/data_manager.py
61
62
63
64
65
66
67
68
69
70
71
72
def crop_feat(self, feature: QgsFeature, geometry: QgsGeometry) -> List[QgsFeature]:
    """Crop a feat with intersection geometry.

    Args:
        feature (QgsFeature): Fetaure to crop.
        geometry (QgsGeometry): Geometry to compute intersection.

    Returns:
        Cropped feature.
    """
    feature.setGeometry(feature.geometry().intersection(geometry))
    return feature

get_features(layer, index, cell, crop=True)

Gather all features from a layer that intersect a geometry/cell.

Parameters:

Name Type Description Default
layer qgis.core.QgsVectorLayer

Layer to gather features from.

required
cell qgis.core.QgsGeometry

Geometry to gather feats.

required
crop bool, **optional**

If True, crop feats to geometry. Defaults to False.

True

Returns:

Type Description
typing.List[qgis.core.QgsFeature]

List of geometries extracted.

Source code in niva/core/prediction/data_manager.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def get_features(
    self,
    layer: QgsVectorLayer,
    index: QgsSpatialIndex,
    cell: QgsGeometry,
    crop=True,
) -> List[QgsFeature]:
    """Gather all features from a layer that intersect a geometry/cell.

    Args:
        layer (QgsVectorLayer): Layer to gather features from.
        cell (QgsGeometry): Geometry to gather feats.
        crop (bool, **optional**): If True, crop feats to geometry. Defaults to False.

    Returns:
        List of geometries extracted.
    """
    features_ids = index.intersects(cell.boundingBox())
    features: List[QgsFeature] = layer.getFeatures(features_ids)
    features: List[QgsFeature] = [
        f for f in features if f.geometry().intersects(cell)
    ]
    if crop:
        features = [self.crop_feat(f, cell) for f in features]
    return features

T1GridDataManager(*, iacs, artificial, naa=None) dataclass

Bases: niva.core.prediction.data_manager.GridDataManager

Data manager for Contra Tier 1 with grid based predictions.

Parameters:

Name Type Description Default
iacs qgis.core.QgsVectorLayer

Layer of IACS data. Warning: Provide IACS with Niva.ID field.

required
artificial qgis.core.QgsVectorLayer

Layer of artificial data.

required
naa qgis.core.QgsVectorLayer

Layer of NAA data.

None

Attributes:

Name Type Description
iacs qgis.core.QgsVectorLayer

Layer of IACS data.

artificial qgis.core.QgsVectorLayer

Layer of artificial data.

naa Union[qgis.core.QgsVectorLayer, None]

Layer of NAA data or None if not passed to constructor.

iacs_index qgis.core.QgsSpatialIndex

Spatial index for layer iacs.

artificial_index qgis.core.QgsSpatialIndex

Spatial index for layer artificial.

naa_index qgis.core.QgsSpatialIndex

Spatial index for layer naa.

compute(cell)

Compute metrics and build sample for cell.

Parameters:

Name Type Description Default
cell qgis.core.QgsGeometry

Cell geometry to compute metric on.

required

Returns:

Type Description
niva.core.sample.T1Sample

Tier 1 sample for cell.

Source code in niva/core/prediction/data_manager.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
def compute(self, cell: QgsGeometry) -> T1Sample:
    """Compute metrics and build sample for cell.

    Args:
        cell (QgsGeometry): Cell geometry to compute metric on.

    Returns:
        Tier 1 sample for cell.
    """
    # Gather features
    iacs_feats = self.get_features(self.iacs, self.iacs_index, cell)
    artificial_feats = self.get_features(
        self.artificial, self.artificial_index, cell, crop=False
    )
    # Group geometries
    iacs = QgsGeometry.unaryUnion([f.geometry() for f in iacs_feats])
    artificial = QgsGeometry.unaryUnion([f.geometry() for f in artificial_feats])
    # get buildings with aoe geometry
    buildings = self._get_buildings(artificial_feats)
    # if naa apply geometries transformations.
    if self.naa:
        naa_feats = self.get_features(self.naa, self.naa_index, cell)
        naa_union = QgsGeometry.unaryUnion([f.geometry() for f in naa_feats])
        naa_union = naa_union.difference(artificial)
        iacs = iacs.difference(naa_union)
        buildings = buildings.difference(naa_union)
    else:
        naa_union = QgsGeometry.fromWkt("POLYGON EMPTY")

    artificial = QgsGeometry.unaryUnion([artificial, buildings])
    if not naa_union.isEmpty():
        artificial = artificial.difference(naa_union)
    artificial = artificial.intersection(cell)

    # compute metrics
    snc = semi_natural_cover(artificial, iacs, cell.area())
    mfs = mean_field_size(iacs_feats)
    rich, simpson = diversity(iacs_feats)

    return T1Sample(richness=rich, simpson=simpson, snc=snc, mfs=mfs)

Predictor(context=QgsProcessingContext(), feedback=QgsProcessingFeedback(), *args, **kwargs)

Bases: niva.core.mixins.QgsLogicMixin

Base predictor class.

Source code in niva/core/mixins.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def __init__(
    self,
    context: QgsProcessingContext = QgsProcessingContext(),
    feedback: QgsProcessingFeedback = QgsProcessingFeedback(),
    *args,
    **kwargs,
):
    """
    Args:
        context (QgsProcessingContext, **optional**): Context to use within the class.
        feedback (QgsProcessingFeedback, **optional**): Feedback to use within the class.
    """
    self.context = context
    self.feedback = feedback
    super().__init__(*args, **kwargs)

run() abstractmethod

Run the prediction and output a QgsVectorLayer with predictions.

Source code in niva/core/prediction/predictor.py
15
16
17
18
@abstractmethod
def run(self) -> QgsVectorLayer:
    """Run the prediction and output a QgsVectorLayer with predictions."""
    pass

GridPredictor(tree, data_manager, grid, *args, **kwargs)

Bases: niva.core.prediction.predictor.Predictor

Base predictor class for grid predictions.

Attributes:

Name Type Description
tree niva.core.contra.ContraTree

ContratTree for prediction.

data_manager niva.core.prediction.data_manager.BaseDataManager

Data manager.

grid qgis.core.QgsVectorLayer

Grdi to predict on.

Parameters:

Name Type Description Default
tree niva.core.contra.ContraTree

ContratTree for prediction.

required
data_manager niva.core.prediction.data_manager.BaseDataManager

Data manager.

required
grid qgis.core.QgsVectorLayer

Grdi to predict on.

required
Source code in niva/core/prediction/predictor.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def __init__(
    self,
    tree: ContraTree,
    data_manager: BaseDataManager,
    grid: QgsVectorLayer,
    *args,
    **kwargs,
):
    """
    Args:
        tree (ContraTree): ContratTree for prediction.
        data_manager (BaseDataManager): Data manager.
        grid (QgsVectorLayer): Grdi to predict on.
    """

    self.data_manager = data_manager
    self.tree = tree
    self.grid = grid
    super().__init__(*args, **kwargs)

run()

Run the predictions by iterating over each grid cells.

Returns:

Type Description
qgis.core.QgsVectorLayer

Prediction layer.

Source code in niva/core/prediction/predictor.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def run(self) -> QgsVectorLayer:
    """Run the predictions by iterating over each grid cells.

    Returns:
        Prediction layer.
    """
    predictions = []
    total = self.grid.featureCount()
    for i, cell in enumerate(self.grid.getFeatures()):
        sample = self.data_manager.compute(cell.geometry())
        sample.mdi, sample.novelty, sample.branch = self.tree.predict(sample)
        pred_feat = sample.to_feature()
        pred_feat.setGeometry(cell.geometry())
        predictions.append(pred_feat)
        self.feedback.setProgress((i / total) * 100)
        self.cancel()

    output = QgsVectorLayer(
        f"Polygon?crs={self.grid.crs().authid()}", "predictions", "memory"
    )
    output.dataProvider().addAttributes(list(predictions[0].fields()))
    output.updateFields()
    output.dataProvider().addFeatures(predictions)
    return output

NivaMdi

Base class for Niva's prediction.

predict_mdi() abstractmethod

Predict Niva MultiDiversityIndex.

Source code in niva/core/prediction/predictor.py
79
80
81
82
@abstractmethod
def predict_mdi(self):
    """Predict Niva MultiDiversityIndex."""
    pass

NivaMdiGridT1(grid, iacs, artificial, naa=None, tree_name='T1', *args, **kwargs)

Bases: niva.core.prediction.predictor.NivaMdi, niva.core.mixins.QgsLogicMixin

Manage Niva prediction for Tier 1 on a grid.

Parameters:

Name Type Description Default
grid qgis.core.QgsVectorLayer

Grid layer to predict on.

required
iacs qgis.core.QgsVectorLayer

IACS layer with Niva.ID field.

required
artificial qgis.core.QgsVectorLayer

Artificial layer.

required
naa Union[QgsVectorLayer, None], **optional**

NAA layer. Defaults to None.

None
tree_name str, **optional**

Name of tree config into ContraTreeFactory. Defaults to "T1".

'T1'

Attributes:

Name Type Description
tree niva.core.contra.ContraTree

Contra decision tree to use for prediction.

data_manager niva.core.prediction.data_manager.T1GridDataManager

Data manager for grid T1.

predictor niva.core.prediction.predictor.GridPredictor

Predictor to use for T1 grid prediction.

Source code in niva/core/prediction/predictor.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def __init__(
    self,
    grid: QgsVectorLayer,
    iacs: QgsVectorLayer,
    artificial: QgsVectorLayer,
    naa: Union[QgsVectorLayer, None] = None,
    tree_name: str = "T1",
    *args,
    **kwargs,
):
    """
    Args:
        grid (QgsVectorLayer): Grid layer to predict on.
        iacs (QgsVectorLayer): IACS layer with Niva.ID field.
        artificial (QgsVectorLayer): Artificial layer.
        naa (Union[QgsVectorLayer, None], **optional**): NAA layer. Defaults to None.
        tree_name (str, **optional**): Name of tree config into ContraTreeFactory. Defaults to "T1".

    Attributes:
        tree (ContraTree): Contra decision tree to use for prediction.
        data_manager (T1GridDataManager): Data manager for grid T1.
        predictor (GridPredictor): Predictor to use for T1 grid prediction.
    """
    self.tree = ContraTreeFactory.build(tree_name)
    layers = [artificial, iacs, grid]
    if naa:
        layers.append(naa)
    self.data_manager = T1GridDataManager(iacs=iacs, artificial=artificial, naa=naa)
    self.predictor = GridPredictor(
        tree=self.tree, data_manager=self.data_manager, grid=grid, *args, **kwargs
    )

predict_mdi()

Run prediction.

Returns:

Type Description
qgis.core.QgsVectorLayer

Prediction layer.

Source code in niva/core/prediction/predictor.py
120
121
122
123
124
125
126
def predict_mdi(self) -> QgsVectorLayer:
    """Run prediction.

    Returns:
        Prediction layer.
    """
    return self.predictor.run()