### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe. ### ### This file contains code for the fields that farmers manage. ### mutable struct FarmPlot{T} <: ModelAgent const id::Int64 pixels::Vector{Tuple{Int64, Int64}} cropstate :: T end croptype(f::FarmPlot{T}) where {T} = croptype(f.cropstate) cropname(f::FarmPlot{T}) where {T} = cropname(croptype(f)) cropheight(f::FarmPlot{T}) where {T} = cropheight(f.cropstate) cropcover(f::FarmPlot{T}) where {T} = cropcover(f.cropstate) cropyield(f::FarmPlot{T}) where {T} = cropyield(f.cropstate) """ stepagent!(farmplot, model) Update a farm plot by one day. """ function stepagent!(farmplot::FarmPlot{T}, model::SimulationModel) where T stepagent!(farmplot.cropstate, model) end """ sow!(farmplot, model, cropname) Sow the specified crop on the farmplot. """ function sow!(farmplot::FarmPlot, model::SimulationModel, cropname::String) #XXX test if the crop is sowable? createevent!(model, farmplot.pixels, sowing) sow!(farmplot.cropstate, model, cropname) end """ harvest!(farmplot, model) Harvest the crop of this farmplot. """ function harvest!(farmplot::FarmPlot{T}, model::SimulationModel) where T createevent!(model, farmplot.pixels, harvesting) harvest!(farmplot.cropstate, model) # TODO: multiply with area to return units of `g` end ## UTILITY FUNCTIONS """ averagefieldsize(model) Calculate the average field size in hectares for the model landscape. """ function averagefieldsize(model::SimulationModel) conversionfactor = 100 #our pixels are currently 10x10m, so 100 pixels per hectare sizes::Vector{Float64} = [] for fp in model.farmplots push!(sizes, size(fp.pixels)[1]/conversionfactor) end round(sum(sizes)/size(sizes)[1], digits=2) end """ croptype(model, position) Return the crop at this position, or nothing if there is no crop here (utility wrapper). """ function croptype(pos::Tuple{Int64,Int64}, model::SimulationModel) ismissing(model.landscape[pos...].fieldid) ? nothing : croptype(model.farmplots[model.landscape[pos...].fieldid]) end """ cropname(model, position) Return the name of the crop at this position, or an empty string if there is no crop here (utility wrapper). """ function cropname(pos::Tuple{Int64,Int64}, model::SimulationModel) field = model.landscape[pos...].fieldid ismissing(field) ? "" : cropname(model.farmplots[field]) end """ cropheight(model, position) Return the height of the crop at this position, or nothing if there is no crop here (utility wrapper). """ function cropheight(pos::Tuple{Int64,Int64}, model::SimulationModel) ismissing(model.landscape[pos...].fieldid) ? 0.0cm : # TODO: 0.0cm correct here? cropheight(model.farmplots[model.landscape[pos...].fieldid]) end """ cropcover(model, position) Return the crop cover of the crop at this position, or nothing if there is no crop here (utility wrapper). """ function cropcover(pos::Tuple{Int64,Int64}, model::SimulationModel) ismissing(model.landscape[pos...].fieldid) ? 0.0 : # TODO: 0.0 correct here? cropcover(model.farmplots[model.landscape[pos...].fieldid]) end