Chapter 26: Land Use and Cover Change Modeling¶
Part V — Domain Modeling: Land Use & Coastal Systems
Implemented by the disslucc-continuous and disslucc-discrete packages.
Watch out
This chapter is a draft, deliberately written ahead of the underlying DisSLUCC packages settling — student work on both is still in progress and the API is likely to shift. Treat this as a base to revise once that work stabilizes, not a final reference; the CLI commands shown were not re-verified end to end against the currently installed packages.
Learning Objectives¶
By the end of this chapter you will be able to:
- Explain what DisSLUCC means as a family, not a single package
- Choose between continuous and discrete allocation for a given research question
- Describe the Demand/Potential/Allocation loop every LUCC model in the ecosystem shares
- Know how each package validates itself against its TerraME/LUCCME predecessor
# Standard imports — add chapter-specific imports below
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Every model since Chapter 23 has been a paradigm demonstration — Predator-Prey, Game of Life, a handful of agents. This chapter is the first full domain application: land use and cover change, the process that originally motivated LUCCME at INPE/CCST, and the process DisSModel's own migration story (Chapter 32) keeps returning to as its central example.
What DisSLUCC Is¶
DisSLUCC isn't one package — it's the name for two libraries that implement spatially explicit land-use and cover change modeling on top of dissmodel, mirroring two allocation philosophies LUCCME itself historically supported:
| Approach | Package | Style | Unit of allocation |
|---|---|---|---|
| Continuous | disslucc-continuous |
LUCCME-like | area/percentage per cell |
| Discrete | disslucc-discrete |
CLUE-S-like | one land use per cell |
Both depend on dissmodel as an ordinary package dependency, following the same additive philosophy Chapter 33 described for every satellite package in the ecosystem — neither modifies the core.
Theory: Demand, Potential, Allocation¶
Every LUCC model in this chapter, continuous or discrete, runs the identical three-part loop each time step — the same structure LUCCME itself established:
- Demand ("how much?") — the area changing class this step. It can come from a historical trend, a constructed scenario, an economic model, or simply a precomputed table read from a CSV.
- Potential ("where?") — a suitability map built from driving-factor layers: distance to roads, distance to ports, protected-area status, soil fertility. This is a regression problem — predicting suitability from spatial covariates — with those covariates typically prepared upstream by
disscube's derivation pipeline (Chapter 30). - Allocation — spatially distributing the demanded change according to the potential map, by rank ordering, competition, or another strategy.
Is a land-change model a cellular automaton? By Chapter 24's own six-element definition — grid, neighborhood, finite states, transition rules, initial state, discrete time — yes, formally. The difference from dissmodel-ca's models is one of emphasis and disciplinary origin (economic geography, not physics), not underlying mechanism.
Continuous Allocation: disslucc-continuous¶
disslucc-continuous answers "how much does this cell's land use change" — the right choice whenever a cell can legitimately hold more than one land use at once (a partially-deforested cell, a partially-urbanized one). Potential comes from PotentialLinearRegression, one regression per land-use type, each with its own intercept and driving-factor coefficients; allocation comes from AllocationClueLike, distributing demand across cells according to that potential map, subject to per-class minimum/maximum bounds.
from disslucc_continuous import (
DemandPreComputedValues, load_demand_csv,
PotentialLinearRegression, RegressionSpec,
AllocationClueLike, AllocationSpec,
)
demand = DemandPreComputedValues(
annual_demand=load_demand_csv("demand.csv", ["forest", "dev", "other"]),
land_use_types=["forest", "dev", "other"],
)
potential = PotentialLinearRegression(
gdf=gdf,
land_use_types=["forest", "dev", "other"],
land_use_no_data="other",
potential_data=[[
RegressionSpec(const=0.74, betas={"dist_roads": -0.22, "protected": 0.18}),
RegressionSpec(const=0.27, betas={"dist_roads": -9.9e-7}),
RegressionSpec(const=0.0),
]],
)
Validation follows the same benchmark pattern Chapter 32 already described for the ecosystem generally: a dedicated benchmark executor runs vector and raster substrates side by side and checks both against a TerraME/LUCCME reference dataset, asserting mean absolute error and root-mean-square error stay under a configurable tolerance — never trusting a production run without that check passing first.
Discrete Allocation: disslucc-discrete¶
disslucc-discrete answers a different question: "which single land use dominates this cell" — a CLUE-S-style allocation, right whenever ground-truth is itself categorical (a classified land-cover map, not a fractional-cover raster). Potential here comes from PotentialDLogisticRegression instead of a linear one — a logistic regression predicts which class a cell most likely belongs to, not how much of a fractional quantity it holds — and allocation runs through a competition-based AllocationDClueSLike. Configuration lives entirely in a TOML file rather than inline Python — land-use types, per-class regression coefficients, elasticities, and the allowed transition matrix:
[model]
land_use_types = ["forest", "dev", "other"]
region_attr = "region"
[[model.potential]]
const = -2.34
elasticity = 0.0
[model.potential.betas]
soil_decl = -0.03
dist_road = 3.10
[model.allocation]
max_difference = 10.0
max_iteration = 1000
factor_iteration = 0.0001
disslucc-discrete's validation reaches the strongest bar anywhere in this book: not a tolerance band, but exact cell-level parity against a TerraME/LuccME reference dataset — 100% accuracy, Cohen's κ = 1.0, F1 = 1.0, checked automatically in continuous integration. That exactness is possible specifically because the output is categorical — a cell either matches its reference class or it doesn't, with no "close enough" in between the way a continuous percentage would have.
Choosing Between Continuous and Discrete¶
Both packages implement the identical Demand/Potential/Allocation loop with different algorithms at each step — the decision between them is about your data, not architecture:
disslucc-continuous |
disslucc-discrete |
|
|---|---|---|
| Potential | linear regression | logistic regression |
| Allocation | CLUE-like, per-class bounds | competition-based CLUE-S |
| Validation | MAE/RMSE tolerance vs. reference | exact cell-level parity vs. reference |
The fastest way to decide: look at your calibration and validation data first. If it's expressed as a class label per cell, disslucc-discrete is the model that can be checked against it exactly. If it's expressed as an area or percentage per cell, disslucc-continuous is the only one that represents it without lossy discretization forced on it first.
Calibration, Validation, and Goodness-of-Fit¶
The MAE/RMSE/parity checks above are engineering validation — confirming a Python port matches a TerraME reference run. That's a different question from scientific validation: fitting a model to real-world observed data by splitting a timeline into a calibration period (used to fit parameters) and a held-out validation period, checked only after fitting.
A cell-by-cell comparison between a simulated map and an observed one is often too strict a bar even for scientific validation — two reasonable model runs can disagree pixel-for-pixel while still being "equally good" at the pattern level. A multiscale comparison — checking agreement in successively larger windows (3×3, then 5×5, then 9×9, and so on) — is the standard alternative: two maps might show weak agreement at the finest resolution but strong agreement once compared at a coarser one, which is real, usable information a strict pixel match would have discarded entirely.
Exercises¶
- Match the package to the question. For each research question, name which package fits and why: (a) "how does the percentage of forest cover in each cell change over the next 20 years," (b) "which cells convert from forest to pasture by 2030."
- Why two different regressions?
PotentialLinearRegressionandPotentialDLogisticRegressionboth take driving-factor coefficients (betas) per land-use type. From the model names alone, explain why one needs a linear regression and the other a logistic one — what is each one actually trying to predict? - Tolerance vs. exact parity. Explain, in your own words, why a tolerance-based check makes sense for
disslucc-continuous's validation but not fordisslucc-discrete's. - Multiscale comparison, by hand. Sketch, conceptually, how you'd compute a 3×3-window agreement score between two categorical land-use grids of the same shape — what would you compare within each window, and how would you turn that into a single agreement number for the whole grid?
# Your code here
Summary¶
Key concepts introduced¶
- DisSLUCC as two packages, not one, sharing the identical Demand/Potential/Allocation loop LUCCME originally established
disslucc-continuous: fractional, per-cell land-use change, validated by MAE/RMSE tolerance against a TerraME/LUCCME referencedisslucc-discrete: categorical, one-class-per-cell allocation, validated by exact cell-level parity — the strongest equivalence claim in the ecosystem, possible because the output is categorical- Choosing between them by looking at your own calibration/validation data's type first, not by architectural preference
- Engineering validation (matching a TerraME reference) versus scientific validation (calibration/validation split against real-world data), and multiscale comparison as an alternative to an overly strict pixel-for-pixel match
Chapter 27 stays in domain-application territory but moves from land far inland to the coastline itself — a coupled flood and mangrove-migration model, run on both substrates and validated two different ways at once.
Further Reading¶
- Verburg, P. H. et al. (2002). "Modeling the spatial dynamics of regional land use: the CLUE-S model." Environmental Management, 30(3), 391-405
- Verburg, P. H. et al. (2006). "Downscaling of land use change scenarios to assess the dynamics of European landscapes." Agriculture, Ecosystems & Environment, 114(1), 39-56
- Costanza, R. (1989). "Model goodness of fit: a multiple resolution procedure." Ecological Modelling, 47(3-4), 199-215 — the multiscale comparison method this chapter's validation section draws on
- LuccME documentation (INPE): http://www.dpi.inpe.br/luccme/
- disslucc-continuous and disslucc-discrete on GitHub: https://github.com/DisSModel