Skip to content

Commit e373a99

Browse files
committed
Add MCDA module for spatial multi-criteria decision analysis (#1030)
New xrspatial.mcda subpackage covering the four stages of raster MCDA: Standardize (6 value functions): linear, sigmoidal, gaussian, triangular, piecewise, categorical Weight derivation: AHP eigenvector method with consistency ratio, rank-order weighting (ROC, rank sum, reciprocal of ranks) Combination methods: WLC, WPM, OWA, fuzzy overlay (AND/OR/sum/product/gamma), boolean overlay Validation: Constraint masking, one-at-a-time and Monte Carlo sensitivity analysis All operations are element-wise or reductions across layers, so they work on numpy, cupy, dask+numpy, and dask+cupy without ArrayTypeFunctionMapping dispatch. No new dependencies. 148 tests covering correctness, edge cases (degenerate triangles, inf/NaN propagation, single-criterion datasets, AHP validation, dask graph safety, weight boundary clamping, MC reproducibility), and a full end-to-end suitability workflow. Includes docs reference page, README feature matrix section, and user guide notebook (35_MCDA.ipynb).
1 parent f9d1eb3 commit e373a99

File tree

12 files changed

+3367
-0
lines changed

12 files changed

+3367
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,23 @@ write_vrt('mosaic.vrt', ['tile1.tif', 'tile2.tif']) # generate VRT
441441

442442
-------
443443

444+
### **Multi-Criteria Decision Analysis (MCDA)**
445+
446+
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
447+
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
448+
| [Standardize](xrspatial/mcda/standardize.py) | Converts criterion rasters to 0-1 suitability scale (linear, sigmoidal, gaussian, triangular, piecewise, categorical) | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
449+
| [AHP Weights](xrspatial/mcda/weights.py) | Derives criterion weights from pairwise comparisons using the Saaty eigenvector method with consistency ratio | Saaty 1980 | ✅️ | ✅️ | ✅️ | ✅️ |
450+
| [Rank Weights](xrspatial/mcda/weights.py) | Derives weights from a rank ordering (ROC, rank sum, reciprocal) | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
451+
| [WLC](xrspatial/mcda/combine.py) | Weighted Linear Combination (fully compensatory weighted sum) | Malczewski 2006 | ✅️ | ✅️ | ✅️ | ✅️ |
452+
| [WPM](xrspatial/mcda/combine.py) | Weighted Product Model (multiplicative, penalizes low scores) | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
453+
| [OWA](xrspatial/mcda/combine.py) | Ordered Weighted Averaging with tunable risk attitude | Yager 1988 | ✅️ | ✅️ | ✅️ | ✅️ |
454+
| [Fuzzy Overlay](xrspatial/mcda/combine.py) | Combines criteria using fuzzy set operators (AND, OR, sum, product, gamma) | Eastman 1999 | ✅️ | ✅️ | ✅️ | ✅️ |
455+
| [Boolean Overlay](xrspatial/mcda/combine.py) | Combines binary criterion masks using AND/OR logic | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
456+
| [Constrain](xrspatial/mcda/constrain.py) | Masks exclusion zones from a suitability surface | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
457+
| [Sensitivity](xrspatial/mcda/sensitivity.py) | Assesses weight stability via one-at-a-time or Monte Carlo perturbation | Standard | ✅️ | ✅️ | ✅️ | ✅️ |
458+
459+
-------
460+
444461
### **Pathfinding**
445462

446463
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |

docs/source/reference/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Reference
1515
focal
1616
hydrology
1717
interpolation
18+
mcda
1819
morphology
1920
multispectral
2021
pathfinding

docs/source/reference/mcda.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.. _reference.mcda:
2+
3+
*********************************************
4+
Multi-Criteria Decision Analysis (MCDA)
5+
*********************************************
6+
7+
Standardize
8+
===========
9+
.. autosummary::
10+
:toctree: _autosummary
11+
12+
xrspatial.mcda.standardize.standardize
13+
14+
Weights
15+
=======
16+
.. autosummary::
17+
:toctree: _autosummary
18+
19+
xrspatial.mcda.weights.ahp_weights
20+
xrspatial.mcda.weights.rank_weights
21+
22+
Combination
23+
===========
24+
.. autosummary::
25+
:toctree: _autosummary
26+
27+
xrspatial.mcda.combine.wlc
28+
xrspatial.mcda.combine.wpm
29+
xrspatial.mcda.combine.owa
30+
xrspatial.mcda.combine.fuzzy_overlay
31+
xrspatial.mcda.combine.boolean_overlay
32+
33+
Constraints
34+
===========
35+
.. autosummary::
36+
:toctree: _autosummary
37+
38+
xrspatial.mcda.constrain.constrain
39+
40+
Sensitivity
41+
===========
42+
.. autosummary::
43+
:toctree: _autosummary
44+
45+
xrspatial.mcda.sensitivity.sensitivity

0 commit comments

Comments
 (0)