Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
landscape.jl 12.91 KiB
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file manages the landscape maps that underlie the model.
###

using Printf

## IMPORTANT: do not change the order of this enum, or initlandscape() will break!
"The land cover classes encoded in the Mundialis Sentinel data."
@enum LandCover nodata forest grass water builtup soil agriculture

# TODO: check names and order of enum
# TODO: note where values come from
## IMPORTANT: do not change the order of this enum, or initlandscape() will break!
"The soil type"
@enum SoilType begin
    soiltype_nodata = 0       # 0
    soiltype_sand             # 1
    soiltype_loamy_sand       # 2
    soiltype_sandy_loam       # 3
    soiltype_loam             # 4
    soiltype_silt_loam        # 5
    soiltype_silt             # 6
    soiltype_sandy_clay_loam  # 7
    soiltype_clay_loam        # 8
    soiltype_silty_clay_loam  # 9
    soiltype_sandy_clay       # 10
    soiltype_silty_clay       # 11
    soiltype_clay             # 12
    soiltype_unknown          # 13  TODO: invented this to get a type 13
end

"The types of management event that can be simulated"
@enum Management tillage sowing fertiliser pesticide harvesting


"""
    Pixel

A pixel is a simple data structure to combine land use and ownership information
in a single object. The model landscape consists of a matrix of pixels.
(Note: further landscape information may be added here in future.)
"""
mutable struct Pixel
    landcover::LandCover          # land cover class at this position
    soiltype::SoilType            # soil type class at this position
    fieldid::Union{Missing,Int64} # ID of the farmplot (if any) at this position
    events::Vector{Management}    # management events that have been applied to this pixel
    animals::Vector{Int64}        # IDs of animals currently at this position
    territories::Vector{String}   # IDs of animals that claim this pixel as part of their territory
end

Pixel(landcover::LandCover, soiltype::SoilType, fieldid::Union{Missing,Int64}) =
    Pixel(landcover, soiltype, fieldid, Vector{Management}(), Vector{Int64}(), Vector{String}())
Pixel(landcover::LandCover, fieldid::Union{Missing,Int64}) =
    Pixel(landcover, soiltype_nodata, fieldid)
Pixel(landcover::LandCover) = Pixel(landcover, missing)

showlandscape(mat::T) where T <: AbstractMatrix{Pixel} = showlandscape(stdout, mat)

function showlandscape(io::IO, mat::T) where T <: AbstractMatrix{Pixel}
    println(io, "Matrix{Pixel}:")

    println(io, "  LandCover:")
    nrow, ncol = size(mat)
    max_fieldid = maximum(skipmissing(map(x -> getfield(x, :fieldid), mat)); init=0)
    for i in axes(mat, 1)
        print(io, "    ")
        for j in axes(mat, 2)
            charid = uppercase(first(string(mat[i, j].landcover)))