All checks were successful
FarmMaps.Develop/CarbonLib/pipeline/head This commit looks good
1945 lines
100 KiB
C#
1945 lines
100 KiB
C#
using Base.Core.Common;
|
|
using Base.Core.Common.Geometry;
|
|
using CarbonService.Models;
|
|
using FarmMapsAPI.Carbon.Models;
|
|
using NetTopologySuite.Geometries;
|
|
using OSGeo.OGR;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace FarmMapsAPI.Carbon
|
|
{
|
|
public class CarbonCalculation
|
|
{
|
|
private readonly string configPath;
|
|
|
|
private SetsForDataTransformation dataTransformationSet;
|
|
private GIS_Soils_Sets gisSoilSet;
|
|
private CropSets cropSet;
|
|
private ParameterSet parameterSet;
|
|
private FarmInputsetsModel farmInputSet;
|
|
|
|
private List<CropYieldModel> cropYieldConfig;
|
|
private List<ManCcontModel> manCcontConfig;
|
|
private List<CropPropertyModel> cropPropertyConfig;
|
|
private List<YieldGreenManureModel> yieldGreenManureConfig;
|
|
private List<CropCoverMonthsModel> cropCoverMonthConfig;
|
|
|
|
private List<MappingCropFarmmapsMiterraRothC> mappingCropFarmmapsMiterraRothC;
|
|
private List<MappingGreenManureFarmmapsMiterraRothC> mappingGreenManureFarmmapsMiterraRothC;
|
|
|
|
public CarbonCalculation(string configPath)
|
|
{
|
|
this.configPath = configPath;
|
|
|
|
var dataTransformationSetFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "SetsForDataTransformation.json"));
|
|
var gisSoilFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "GIS_Soil_Sets.json"));
|
|
var cropSetFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "CropSets.json"));
|
|
var parameterRothCFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "ParametersRothC.json"));
|
|
var farmInputSetFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "Farm_input_sets.json"));
|
|
|
|
var cropYieldFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "CropYield.json"));
|
|
var manCcontFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "ManCcont.json"));
|
|
var cropPropertyFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "CropProperties.json"));
|
|
var yieldGreenManureFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "YieldGreenManure.json"));
|
|
var cropCoverMonthFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "CropCoverMonth.json"));
|
|
|
|
var mappingCropFarmmapsMiterraFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "Mapping", "MappingCropsFarmmapsMiterraRothC.json"));
|
|
var mappingGreenManureFarmmapsMiterraFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "Mapping", "MappingGreenManureFarmmapsMiterraRothC.json"));
|
|
|
|
// sets
|
|
//var regionSet = GamsSets.ReadSets<RegionSets>(regionSetFile);
|
|
dataTransformationSet = GamsSets.ReadSets<SetsForDataTransformation>(dataTransformationSetFile);
|
|
gisSoilSet = GamsSets.ReadSets<GIS_Soils_Sets>(gisSoilFile);
|
|
cropSet = GamsSets.ReadSets<CropSets>(cropSetFile);
|
|
parameterSet = GamsSets.ReadSets<ParameterSet>(parameterRothCFile);
|
|
farmInputSet = GamsSets.ReadSets<FarmInputsetsModel>(farmInputSetFile);
|
|
|
|
cropYieldConfig = GamsSets.ReadSets<List<CropYieldModel>>(cropYieldFile);
|
|
manCcontConfig = GamsSets.ReadSets<List<ManCcontModel>>(manCcontFile);
|
|
cropPropertyConfig = GamsSets.ReadSets<List<CropPropertyModel>>(cropPropertyFile);
|
|
yieldGreenManureConfig = GamsSets.ReadSets<List<YieldGreenManureModel>>(yieldGreenManureFile);
|
|
cropCoverMonthConfig = GamsSets.ReadSets<List<CropCoverMonthsModel>>(cropCoverMonthFile);
|
|
|
|
// mapping
|
|
mappingCropFarmmapsMiterraRothC = GamsSets.ReadSets<List<MappingCropFarmmapsMiterraRothC>>(mappingCropFarmmapsMiterraFile);
|
|
mappingGreenManureFarmmapsMiterraRothC = GamsSets.ReadSets<List<MappingGreenManureFarmmapsMiterraRothC>>(mappingGreenManureFarmmapsMiterraFile);
|
|
}
|
|
|
|
public string Validate(CarbonRequest farmInput)
|
|
{
|
|
var postalCodePresent = dataTransformationSet.KNMI_zone_Reg.Any(x => x.Reg.Any(y => y == farmInput.PostalCode));
|
|
if (!postalCodePresent)
|
|
{
|
|
return $"Unknown postalcode (reg) {farmInput.PostalCode}";
|
|
}
|
|
|
|
var allCrops = farmInput.CropFields.SelectMany(s => s.HistoricalCropData.SelectMany(x => x.Crops)).Distinct();
|
|
foreach (var crop in allCrops)
|
|
{
|
|
if (string.IsNullOrEmpty(crop.Crop))
|
|
{
|
|
return "Missing crop";
|
|
}
|
|
var cropPresent = cropPropertyConfig.Any(x => x.Name.ToLower() == crop.Crop.ToLower());
|
|
if (!cropPresent)
|
|
{
|
|
return $"Unknown crop {crop.Crop}";
|
|
}
|
|
}
|
|
|
|
|
|
var allSoils = farmInput.CropFields.Select(s => s.SoilType);
|
|
foreach (var soil in allSoils)
|
|
{
|
|
if (!gisSoilSet.SoilType.Any(x => x == soil))
|
|
{
|
|
return $"Unknown soil {soil}";
|
|
}
|
|
}
|
|
|
|
var allGreenManure = farmInput.CropFields.SelectMany(s => s.GreenManures.SelectMany(x=>x.GreenManureTypes)).Distinct();
|
|
foreach (var greenManure in allGreenManure)
|
|
{
|
|
if (!yieldGreenManureConfig.Any(x=>x.ManureName.ToLower() == greenManure.Type.ToLower()))
|
|
{
|
|
return $"Unknown green manure {greenManure.Type}";
|
|
}
|
|
}
|
|
|
|
var allOrgManure = farmInput.CropFields.SelectMany(x => x.HistoricalCropData.SelectMany(s => s.Crops.Where(w=>w.OrganicManures != null).SelectMany(y=>y.OrganicManures.Select(r=>r.Type)))).Distinct();
|
|
foreach (var orgManure in allOrgManure)
|
|
{
|
|
if (!manCcontConfig.Any(x=>x.ManCcont == orgManure))
|
|
{
|
|
return $"Unknown organic manure {orgManure}";
|
|
}
|
|
}
|
|
|
|
//var allYears
|
|
return null;
|
|
}
|
|
|
|
public CarbonRequest MapFarmMapsToMiterra(FarmMapsCarbonRequest farmInput)
|
|
{
|
|
var mappedInput = new CarbonRequest();
|
|
mappedInput.PostalCode = farmInput.PostalCode;
|
|
mappedInput.CropFields = new List<CropField>();
|
|
foreach (var cropField in farmInput.CropFields)
|
|
{
|
|
var mappedCropData = new List<HistoricalCropData>();
|
|
var greenManures = new List<GreenManure>();
|
|
mappedInput.CropFields.Add(new CropField
|
|
{
|
|
Name = cropField.Name,
|
|
Area = cropField.Area,
|
|
HistoricalCropData = mappedCropData,
|
|
SoilType = MapSoil(cropField.SoilType),
|
|
SoilProperty = new SoilProperty { Clay_Content = cropField.SoilProperty.Clay_Content, OM_Const = cropField.SoilProperty.OM_Const },
|
|
GreenManures = greenManures
|
|
});
|
|
foreach (var crops in cropField.HistoricalCropData)
|
|
{
|
|
foreach (var cropYear in crops.Crops)
|
|
{
|
|
if (!string.IsNullOrEmpty(cropYear.MiterraCropName))
|
|
{
|
|
mappedCropData.Add(new HistoricalCropData
|
|
{
|
|
Year = crops.Year,
|
|
Crops = new List<OrgManureApplied> {
|
|
new OrgManureApplied {
|
|
Crop = cropYear.MiterraCropName,
|
|
CropRes = cropYear.CropRes,
|
|
OrganicManures =
|
|
cropYear.OrganicManures.Where(y=>y.Quantity > 0 && !string.IsNullOrEmpty(y.Type)).Select(x => new OrganicManureType { Type = x.Type, Quantity = x.Quantity }).ToList(),
|
|
CropYield = cropYear.CropYield } }
|
|
});
|
|
}
|
|
else
|
|
{
|
|
var cropMapping = mappingCropFarmmapsMiterraRothC.FirstOrDefault(x => x.CropCode == cropYear.CropCode);
|
|
if (cropMapping != null)
|
|
{
|
|
var orgManure = new List<OrganicManureType>();
|
|
if (cropYear.OrganicManures != null)
|
|
{
|
|
foreach (var manure in cropYear.OrganicManures)
|
|
{
|
|
if (!string.IsNullOrEmpty(manure.Type) && manure.Quantity > 0)
|
|
{
|
|
orgManure.Add(new OrganicManureType { Type = manure.Type, Quantity = manure.Quantity });
|
|
}
|
|
}
|
|
}
|
|
var crop = mappedCropData.SingleOrDefault(x => x.Year == crops.Year);
|
|
if (crop == null)
|
|
{
|
|
mappedCropData.Add(new HistoricalCropData { Year = crops.Year, Crops = new List<OrgManureApplied> { new OrgManureApplied { Crop = cropMapping.MiterraRothCCrop, OrganicManures = orgManure, CropYield = cropYear.CropYield, CropRes = cropYear.CropRes } } });
|
|
}
|
|
else
|
|
{
|
|
crop.Crops.Add(new OrgManureApplied { Crop = cropMapping.MiterraRothCCrop, OrganicManures = orgManure, CropYield = cropYear.CropYield, CropRes = cropYear.CropRes });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mappedCropData.Add(new HistoricalCropData { Year = crops.Year, Crops = new List<OrgManureApplied> { new OrgManureApplied { Crop = cropYear.CropCode, OrganicManures = null, CropYield = cropYear.CropYield, CropRes = cropYear.CropRes } } });
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var cropYear in crops.GreenManures)
|
|
{
|
|
if (string.IsNullOrEmpty(cropYear.CropCode))
|
|
{
|
|
continue;
|
|
}
|
|
var greenManure = cropYear.CropCode;// mappingGreenManureFarmmapsMiterraRothC.FirstOrDefault(x => x.CropCode == cropYear.CropCode && x.PurposeCode == "118");
|
|
var manureYear = greenManures.SingleOrDefault(x => x.Year == crops.Year);
|
|
if (manureYear == null)
|
|
{
|
|
greenManures.Add(new GreenManure { Year = crops.Year, GreenManureTypes = new List<GreenManureType> { new GreenManureType { Type = greenManure, Quality = cropYear.Quality == QualityFarmMaps.Good ? Quality.Good : cropYear.Quality == QualityFarmMaps.Bad ? Quality.Bad : Quality.Average } } });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return mappedInput;
|
|
}
|
|
|
|
public double? GetCropYield(string cropCode, int year, int postalCode)
|
|
{
|
|
string provinceCode = GetProvinceCode(dataTransformationSet, postalCode);
|
|
//var cropMapping = mappingCropFarmmapsMiterraRothC.FirstOrDefault(x => x.CropCode == cropCode);
|
|
//if (cropMapping == null)
|
|
//{
|
|
// return 0;
|
|
//}
|
|
//var crpYield = cropYieldConfig.SingleOrDefault(x => x.CropName.ToLower() == cropMapping.MiterraRothCCrop.ToLower());
|
|
var crpYield = cropYieldConfig.SingleOrDefault(x => x.CropName.ToLower() == cropCode.ToLower());
|
|
var crpYieldProvince = crpYield.Yields.SingleOrDefault(x => x.ProvinceCode == provinceCode);
|
|
var cropYield = crpYieldProvince.YearData.SingleOrDefault(x => x.Year == year)?.YieldValue;
|
|
return cropYield;
|
|
}
|
|
|
|
public CarbonSummary Calculate(CarbonRequest farmInput)
|
|
{
|
|
var knmiFile = Helper.GetPlatformIndependentDirectoryPath(Path.Combine(configPath, "KNMI_data.csv"));
|
|
|
|
// soilTypeData (external input)
|
|
var soilTypeData = GetSoilTypeData(farmInput);
|
|
|
|
//soilPropertiesField (external input)
|
|
var soilPropertiesField = GetSoilPropertiesField(farmInput);
|
|
|
|
// HistoricalCropData (external input)
|
|
var historicalCropdata = GetHistoricalCropdata(farmInput);
|
|
|
|
// cropAreaSheet (external input)
|
|
var cropAreaField = GetCropAreaField(farmInput);
|
|
|
|
|
|
//////////////////////////////////////////////
|
|
// precalculations
|
|
//////////////////////////////////////////////
|
|
|
|
|
|
//soilPropSoilType
|
|
var soilPropSoilType = GetSoilPropSoilType(soilTypeData, soilPropertiesField);
|
|
|
|
//soilPropertiesField (again)
|
|
foreach (var item in soilPropertiesField)
|
|
{
|
|
var soilProps = soilPropSoilType.Keys.Where(x => x.Item1 == item.Key).ToList();
|
|
var sumCorr = 0.0;
|
|
foreach (var soilProp in soilProps)
|
|
{
|
|
sumCorr += soilPropSoilType[soilProp].OM_Corr;
|
|
}
|
|
item.Value.OM_Corr = sumCorr;
|
|
}
|
|
|
|
// soilBulkDensities
|
|
Dictionary<string, SoilBulkDensityType> soilBulkDensities = GetSoilBulkDensities(soilPropertiesField, soilTypeData, soilPropSoilType);
|
|
|
|
foreach (var soilBulkDensity in soilBulkDensities)
|
|
{
|
|
if (soilPropSoilType.ContainsKey((soilBulkDensity.Key, "Klei")))
|
|
{
|
|
soilPropSoilType[(soilBulkDensity.Key, "Klei")].Bulk_Density = (1.0 / soilBulkDensity.Value.Clay);
|
|
}
|
|
if (soilPropSoilType.ContainsKey((soilBulkDensity.Key, "Zand")))
|
|
{
|
|
soilPropSoilType[(soilBulkDensity.Key, "Zand")].Bulk_Density = (1.0 / soilBulkDensity.Value.Sand);
|
|
}
|
|
}
|
|
|
|
foreach (var item in soilPropertiesField)
|
|
{
|
|
var soilProps = soilPropSoilType.Keys.Where(x => x.Item1 == item.Key).ToList();
|
|
var sumBulkDensity = 0.0;
|
|
foreach (var soilProp in soilProps)
|
|
{
|
|
sumBulkDensity += soilPropSoilType[soilProp].Bulk_Density;
|
|
}
|
|
item.Value.Bulk_Density = sumBulkDensity;
|
|
}
|
|
// finish precalculations
|
|
|
|
|
|
//////////////////////////////////////////
|
|
// loop rothc
|
|
//////////////////////////////////////////
|
|
|
|
var soc_Field = new Dictionary<string, List<YearColumnValue>>();
|
|
var year = GetYears(farmInputSet, farmInput);
|
|
|
|
var cropAreaField1 = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var carbonInputs = new GamsThreeKeyParameter();
|
|
var soc_Balance = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var socIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var cropAreaFarm = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
// start loop year
|
|
foreach (var loopYear in year)
|
|
{
|
|
var historicalCropYearKeys = historicalCropdata.Keys.Where(k => k.Item2 == loopYear).Distinct().ToList();
|
|
foreach (var historicalCropYearKey in historicalCropYearKeys)
|
|
{
|
|
foreach (var historicalCropKeyValue in historicalCropdata[historicalCropYearKey])
|
|
{
|
|
if (cropAreaField1.ContainsKey(historicalCropYearKey))
|
|
{
|
|
cropAreaField1[historicalCropYearKey].Add(new ColumnValue(historicalCropKeyValue, cropAreaField[historicalCropYearKey.Item1]));
|
|
}
|
|
else
|
|
{
|
|
cropAreaField1.Add(historicalCropYearKey, new List<ColumnValue> { new ColumnValue(historicalCropKeyValue, cropAreaField[historicalCropYearKey.Item1]) });
|
|
}
|
|
}
|
|
}
|
|
|
|
// cropAreaFarm
|
|
var croplist = new List<ColumnValue>();
|
|
foreach (var field in farmInput.CropFields.Select(s => s.Name))
|
|
{
|
|
croplist.AddRange(cropAreaField1[(field, loopYear)]);
|
|
}
|
|
cropAreaFarm.Add(("Farmname", loopYear), croplist);
|
|
|
|
Dictionary<string, List<ClimateVariable>> climateVariable = GetClimateVariable(knmiFile, dataTransformationSet, gisSoilSet, loopYear, farmInput);
|
|
|
|
// Crop and soil areas
|
|
// soilArea keys: (fieldname, year, soil)
|
|
var soilArea = new Dictionary<(string, int, string), List<ColumnValue>>();
|
|
foreach (var cropArea in cropAreaField1)
|
|
{
|
|
foreach (var soilType in soilTypeData[cropArea.Key.Item1])
|
|
{
|
|
foreach (var crparea in cropArea.Value)
|
|
{
|
|
var key = (cropArea.Key.Item1, loopYear, crparea.Key);
|
|
if (soilArea.ContainsKey(key))
|
|
{
|
|
soilArea[key].Add(new ColumnValue(soilType, crparea.Value));
|
|
}
|
|
else
|
|
{
|
|
soilArea.Add(key, new List<ColumnValue> { new ColumnValue(soilType, crparea.Value) });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Mineral soils
|
|
var mineralSoilArea = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var cropArea in cropAreaField1)
|
|
{
|
|
foreach (var soilType in soilTypeData[cropArea.Key.Item1])
|
|
{
|
|
if (!gisSoilSet.MineralSoils.Contains(soilType))
|
|
{
|
|
continue;
|
|
}
|
|
var total = 0.0;
|
|
foreach (var crparea in cropArea.Value)
|
|
{
|
|
total += crparea.Value;
|
|
var key = (cropArea.Key.Item1, loopYear);
|
|
if (mineralSoilArea.ContainsKey(key))
|
|
{
|
|
var miniralSoil = mineralSoilArea[key].FirstOrDefault(x => x.Key == crparea.Key);
|
|
if (miniralSoil == null)
|
|
{
|
|
mineralSoilArea[key].Add(new ColumnValue(crparea.Key, crparea.Value));
|
|
}
|
|
else
|
|
{
|
|
miniralSoil.Value += crparea.Value;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mineralSoilArea.Add(key, new List<ColumnValue> { new ColumnValue(crparea.Key, crparea.Value) });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// carbon input
|
|
|
|
// This part had organic manure per year per cropfield
|
|
var carbonInputManure2 = new Dictionary<(string, string), List<ColumnValue>>();
|
|
var carbonInputCompost2 = new Dictionary<(string, string), ColumnValue>();
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
foreach (var cropData in field.HistoricalCropData.Where(x => x.Year == loopYear).SelectMany(s => s.Crops))
|
|
{
|
|
if (cropData.OrganicManures == null)
|
|
{
|
|
continue;
|
|
}
|
|
foreach (var compost in cropData.OrganicManures)
|
|
{
|
|
if (farmInputSet.ManureSources_liv.Any(x => x.ManureSource_liv.ToUpper() == compost.Type.ToUpper()))
|
|
{
|
|
var result = compost.Quantity * manCcontConfig.SingleOrDefault(x => x.ManCcont.ToUpper() == compost.Type.ToUpper())?.Value ?? 0;
|
|
if (carbonInputManure2.ContainsKey((field.Name, cropData.Crop)))
|
|
{
|
|
carbonInputManure2[(field.Name, cropData.Crop)].Add(new ColumnValue(compost.Type, result));
|
|
}
|
|
else
|
|
{
|
|
carbonInputManure2.Add((field.Name, cropData.Crop), new List<ColumnValue> { new ColumnValue(compost.Type, result) });
|
|
}
|
|
}
|
|
else if (farmInputSet.composts.Any(x => x.compost.ToUpper() == compost.Type.ToUpper()))
|
|
{
|
|
var result = compost.Quantity * manCcontConfig.SingleOrDefault(x => x.ManCcont.ToUpper() == compost.Type.ToUpper())?.Value ?? 0;
|
|
if (carbonInputCompost2.ContainsKey((field.Name, cropData.Crop)))
|
|
{
|
|
carbonInputCompost2[(field.Name, cropData.Crop)] = new ColumnValue(compost.Type, result);
|
|
}
|
|
else
|
|
{
|
|
carbonInputCompost2.Add((field.Name, cropData.Crop), new ColumnValue(compost.Type, result));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CarbonInputCompost
|
|
|
|
// cropYield
|
|
var yieldField = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var fieldYear in cropAreaField1)
|
|
{
|
|
string provinceCode = GetProvinceCode(dataTransformationSet, farmInput.PostalCode);
|
|
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in fieldYear.Value)
|
|
{
|
|
var crpYield = cropYieldConfig.SingleOrDefault(x => x.CropName.ToLower() == item.Key.ToLower());
|
|
if (crpYield != null)
|
|
{
|
|
double yieldValue = 0;
|
|
var yieldProvinceYear = crpYield.Yields.Single(x => x.ProvinceCode == provinceCode).YearData.FirstOrDefault(y => y.Year == loopYear);
|
|
if (yieldProvinceYear == null)
|
|
{
|
|
yieldValue = 0;
|
|
}
|
|
else
|
|
{
|
|
yieldValue = yieldProvinceYear.YieldValue;
|
|
}
|
|
valueList.Add(new ColumnValue(crpYield.CropName, yieldValue));
|
|
}
|
|
}
|
|
yieldField.Add(fieldYear.Key, valueList);
|
|
|
|
var farmfield = farmInput.CropFields.SingleOrDefault(x => x.Name == fieldYear.Key.Item1);
|
|
var crop = farmfield.HistoricalCropData.SingleOrDefault(x => x.Year == fieldYear.Key.Item2);
|
|
foreach (var cropItem in crop.Crops)
|
|
{
|
|
if (cropItem.CropYield.HasValue)
|
|
{
|
|
valueList.SingleOrDefault(x => x.Key.ToLower() == cropItem.Crop.ToLower()).Value = cropItem.CropYield.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
// DM_Yield_Field
|
|
// dm_Yield_Field key: (field, year)
|
|
var dm_Yield_Field = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var yieldFieldYear in yieldField)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var value in yieldFieldYear.Value)
|
|
{
|
|
var newValue = value.Value * 0.001;
|
|
var dmValue = cropPropertyConfig.SingleOrDefault(x => x.Name == value.Key)?.DM_content ?? 0;
|
|
newValue = newValue * dmValue;
|
|
valueList.Add(new ColumnValue(value.Key, newValue));
|
|
}
|
|
dm_Yield_Field.Add(yieldFieldYear.Key, valueList);
|
|
}
|
|
|
|
var harvestIndexField = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var dmField in dm_Yield_Field)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in dmField.Value)
|
|
{
|
|
var newValue = 0.0;
|
|
switch (item.Key)
|
|
{
|
|
// maybe in json strawcrops?
|
|
case "Maize":
|
|
newValue = 0.024 * item.Value + 0.228;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Corn_Cob_mix":
|
|
newValue = 0.024 * item.Value + 0.228;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Winter_wheat":
|
|
newValue = 0.0246 * item.Value + 0.3192;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Summer_wheat":
|
|
newValue = 0.0246 * item.Value + 0.3192;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Summer_barley":
|
|
newValue = 0.0256 * item.Value + 0.3727;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "winter_barley":
|
|
newValue = 0.0256 * item.Value + 0.3727;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Rapeseed":
|
|
newValue = 0.008 * item.Value + 0.3037;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Rye":
|
|
newValue = 0.0256 * item.Value + 0.3727;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "oats":
|
|
newValue = 0.0256 * item.Value + 0.3727;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Sunflower":
|
|
newValue = 0.0077 * item.Value + 0.3045;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
case "Other_cereals":
|
|
newValue = 0.0256 * item.Value + 0.3727;
|
|
valueList.Add(new ColumnValue(item.Key, newValue));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (valueList.Count > 0)
|
|
{
|
|
harvestIndexField.Add(dmField.Key, valueList);
|
|
}
|
|
}
|
|
|
|
// AboveGroundResidues
|
|
var aboveGroundResidues = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var stubbleChaff = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var strawYield = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var harvestField in harvestIndexField)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
var valueListStubbleChaff = new List<ColumnValue>();
|
|
var valueListStrawYield = new List<ColumnValue>();
|
|
foreach (var harvestValue in harvestField.Value)
|
|
{
|
|
var dm_YieldValue = dm_Yield_Field[harvestField.Key].SingleOrDefault(x => x.Key == harvestValue.Key);
|
|
var result = (dm_YieldValue.Value / harvestValue.Value) - dm_YieldValue.Value;
|
|
valueList.Add(new ColumnValue(harvestValue.Key, result));
|
|
valueListStubbleChaff.Add(new ColumnValue(harvestValue.Key, result * parameterSet.StubbleFraction));
|
|
valueListStrawYield.Add(new ColumnValue(harvestValue.Key, result * (1 - parameterSet.StubbleFraction)));
|
|
}
|
|
aboveGroundResidues.Add(harvestField.Key, valueList);
|
|
stubbleChaff.Add(harvestField.Key, valueListStubbleChaff);
|
|
strawYield.Add(harvestField.Key, valueListStrawYield);
|
|
}
|
|
|
|
|
|
// BelowGroundCarbonInput
|
|
// (field, year) --> crop,value
|
|
var belowGroundCarbonInput = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var stubbleC in stubbleChaff)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var stubbleKeyValue in stubbleC.Value)
|
|
{
|
|
var dmYieldValue = dm_Yield_Field[stubbleC.Key].Single(s => s.Key.ToLower() == stubbleKeyValue.Key.ToLower());
|
|
var strawYieldValue = strawYield[stubbleC.Key].Single(s => s.Key.ToLower() == stubbleKeyValue.Key.ToLower());
|
|
var dmContentStraw = cropSet.StrawCrops.Single(s => s.StrawCrop.ToLower() == stubbleKeyValue.Key.ToLower());
|
|
|
|
var result = ((dmYieldValue.Value + ((stubbleKeyValue.Value + strawYieldValue.Value) * dmContentStraw.DM_Content)) * parameterSet.CarbonBiomass) / ((1 / parameterSet.FracBelowGroundCinput) - 1);
|
|
valueList.Add(new ColumnValue(stubbleKeyValue.Key, result));
|
|
}
|
|
belowGroundCarbonInput.Add(stubbleC.Key, valueList);
|
|
}
|
|
|
|
// CarbonInputs
|
|
// (field, year, crop)
|
|
// what to do with carbon residues??
|
|
// other cereals?? (has value in cInputCropRes and is strawCrop)
|
|
foreach (var cropArea in cropAreaField1.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
foreach (var crop in cropArea.Value)
|
|
{
|
|
var cInputCropRes = cropPropertyConfig.SingleOrDefault(s => s.Name.ToLower() == crop.Key.ToLower())?.C_input_CropRes ?? 0.0;
|
|
if (cInputCropRes > 0)
|
|
{
|
|
carbonInputs.AddValue((cropArea.Key.Item1, cropArea.Key.Item2, crop.Key), "CarbonResidues", cInputCropRes);
|
|
|
|
}
|
|
|
|
if (cropSet.StrawCrops.Any(x => x.StrawCrop.ToLower() == crop.Key.ToLower()))
|
|
{
|
|
var belowGroundCarbon = belowGroundCarbonInput[cropArea.Key].SingleOrDefault(x => x.Key.ToLower() == crop.Key.ToLower());
|
|
var below2 = GetColumnValueForKey(belowGroundCarbonInput, cropArea.Key, crop.Key);
|
|
var stubble = GetColumnValueForKey(stubbleChaff, cropArea.Key, crop.Key);
|
|
var dm_contentStraw = cropSet.StrawCrops.SingleOrDefault(x => x.StrawCrop.ToLower() == crop.Key.ToLower())?.DM_Content ?? 0;
|
|
var strawYld = strawYield[cropArea.Key].SingleOrDefault(x => x.Key.ToLower() == crop.Key.ToLower())?.Value ?? 0;
|
|
var fracR = cropPropertyConfig.SingleOrDefault(x => x.Name.ToLower() == crop.Key.ToLower())?.FracR ?? 0.0;
|
|
|
|
var field = farmInput.CropFields.SingleOrDefault(x => x.Name == cropArea.Key.Item1);
|
|
var crop_res = field.HistoricalCropData.SingleOrDefault(x => x.Year == loopYear).Crops[0].CropRes ? 0 : 1;
|
|
|
|
//var result = belowGroundCarbon.Value + (stubble * dm_contentStraw * parameterSet.CarbonBiomass) + ((1 - fracR) * strawYld * dm_contentStraw * parameterSet.CarbonBiomass);
|
|
var result = belowGroundCarbon.Value + (stubble * dm_contentStraw * parameterSet.CarbonBiomass) + (crop_res * strawYld * dm_contentStraw * parameterSet.CarbonBiomass);
|
|
|
|
//check if key exists (from if condition (in case of other cereals))
|
|
if (result > 12000)
|
|
{
|
|
result = 12000;
|
|
}
|
|
carbonInputs.AddOrUpdateValue((cropArea.Key.Item1, cropArea.Key.Item2, crop.Key), "CarbonResidues", result);
|
|
}
|
|
}
|
|
}
|
|
|
|
// CarbonInputGreenManure
|
|
var carbonInputGreenManure = GetCarbonInputGreenManure(loopYear, farmInput, yieldGreenManureConfig);
|
|
|
|
|
|
//Total carbon input[in ton C / ha] from manure, compost, crop residues and green manure
|
|
// CarbonInputs(field, year, crop,'CarbonResidues')$(CarbonInputs(field, year,crop,'CarbonResidues')>12000) = 12000;???
|
|
|
|
foreach (var carbon in carbonInputManure2)
|
|
{
|
|
var sumCarbonInputManure = carbon.Value.Sum(x => x.Value);
|
|
var carbonKeyInput = carbonInputs.TrippleKeyParam.Where(x => x.Key.Item1 == carbon.Key.Item1 && x.Key.Item3.ToLower() == carbon.Key.Item2.ToLower() && x.Key.Item2 == loopYear).Select(s => s.Key).ToList();
|
|
|
|
foreach (var carbonKey in carbonKeyInput)
|
|
{
|
|
carbonInputs.AddValue(carbonKey, "CarbonManure", sumCarbonInputManure);
|
|
}
|
|
}
|
|
|
|
foreach (var carbonManure in carbonInputGreenManure.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var sum = carbonManure.Value.Sum(x => x.Value);
|
|
foreach (var item in historicalCropdata[carbonManure.Key])
|
|
{
|
|
carbonInputs.AddValue((carbonManure.Key.Item1, carbonManure.Key.Item2, item), "CarbonGreenManure", sum);
|
|
}
|
|
}
|
|
|
|
foreach (var carbon in carbonInputCompost2)
|
|
{
|
|
foreach (var historicData in historicalCropdata.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var historicDataItem = historicData.Value.SingleOrDefault(x => x.ToLower() == carbon.Key.Item2.ToLower());
|
|
if (historicDataItem != null)
|
|
{
|
|
carbonInputs.AddValueSkipIfColumnExists((historicData.Key.Item1, historicData.Key.Item2, historicDataItem), "CarbonCompost", carbon.Value.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
// TempModFactor
|
|
var tempModFactor = new Dictionary<string, List<ColumnValue>>();
|
|
foreach (var climateVar in climateVariable)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
var count = 1;
|
|
foreach (var temperature in climateVar.Value)
|
|
{
|
|
var temp = 47.9 / (1 + Math.Exp(106.0 / (temperature.Temperature + 18.3)));
|
|
valueList.Add(new ColumnValue($"M{count}", temp));
|
|
count++;
|
|
}
|
|
tempModFactor.Add(climateVar.Key, valueList);
|
|
}
|
|
|
|
// CoverModFactor
|
|
// input sheet
|
|
var coverModFactor = new Dictionary<string, List<ColumnValue>>();
|
|
|
|
foreach (var crpCover in cropCoverMonthConfig)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
for (int i = 1; i < 13; i++)
|
|
{
|
|
if (crpCover.CoverMonths.Contains($"M{i}"))
|
|
{
|
|
valueList.Add(new ColumnValue($"M{i}", 0.6));
|
|
}
|
|
else
|
|
{
|
|
valueList.Add(new ColumnValue($"M{i}", 1.0));
|
|
}
|
|
}
|
|
coverModFactor.Add(crpCover.CropName, valueList);
|
|
}
|
|
|
|
// SMDMax (kan buiten yearLoop)
|
|
// field, crop
|
|
var smdMax = new Dictionary<string, double>();
|
|
foreach (var soil in soilPropertiesField)
|
|
{
|
|
var result = -(20 + (1.3 * soil.Value.Clay_Content) - (0.01 * Math.Pow(soil.Value.Clay_Content, 2))) * (parameterSet.LayerDepth / 23);
|
|
smdMax.Add(soil.Key, result);
|
|
}
|
|
|
|
// SMDaccMonthi (kan buiten yearLoop ??)
|
|
var smdAccMonthi = new Dictionary<string, List<ColumnValue>>();
|
|
|
|
foreach (var climateItem in climateVariable)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
for (int i = 0; i < climateItem.Value.Count; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
var result = climateItem.Value[i].Precipitation - climateItem.Value[i].Evapotranspiration;
|
|
result = result < 0 ? result : 0;
|
|
result = result < smdMax[climateItem.Key] ? smdMax[climateItem.Key] : result;
|
|
valueList.Add(new ColumnValue("M1", result));
|
|
}
|
|
else
|
|
{
|
|
var result = climateItem.Value[i].Precipitation - climateItem.Value[i].Evapotranspiration + valueList.SingleOrDefault(x => x.Key == $"M{i}").Value;
|
|
result = result < 0 ? result : 0;
|
|
result = result < smdMax[climateItem.Key] ? smdMax[climateItem.Key] : result;
|
|
valueList.Add(new ColumnValue($"M{i + 1}", result));
|
|
}
|
|
}
|
|
smdAccMonthi.Add(climateItem.Key, valueList);
|
|
}
|
|
|
|
//MoistureModFactor
|
|
var moistureModFactor = new Dictionary<string, List<ColumnValue>>();
|
|
|
|
foreach (var fieldSmdAccMonthi in smdAccMonthi)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var smdAccMonth in fieldSmdAccMonthi.Value)
|
|
{
|
|
if (smdAccMonth.Value > 0.444 * smdMax[fieldSmdAccMonthi.Key])
|
|
{
|
|
valueList.Add(new ColumnValue(smdAccMonth.Key, 1));
|
|
}
|
|
else
|
|
{
|
|
var result = (0.2 + 0.8 * ((smdMax[fieldSmdAccMonthi.Key] - smdAccMonth.Value) / (smdMax[fieldSmdAccMonthi.Key] - 0.444 * smdMax[fieldSmdAccMonthi.Key])));
|
|
valueList.Add(new ColumnValue(smdAccMonth.Key, result));
|
|
}
|
|
}
|
|
moistureModFactor.Add(fieldSmdAccMonthi.Key, valueList);
|
|
}
|
|
|
|
|
|
// TempCoverMoistureModFactorAverage
|
|
var tempCoverMoistureModFactorAverage = new Dictionary<string, List<ColumnValue>>();
|
|
|
|
foreach (var field in moistureModFactor.Select(s => s.Key))
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var coverMod in coverModFactor)
|
|
{
|
|
var result = 0.0;
|
|
foreach (var monthValue in coverMod.Value)
|
|
{
|
|
var covermodValue = monthValue.Value;
|
|
var tempModValue = tempModFactor[field].SingleOrDefault(x => x.Key == monthValue.Key).Value;
|
|
var moistureModValue = moistureModFactor[field].SingleOrDefault(x => x.Key == monthValue.Key).Value;
|
|
result += covermodValue * tempModValue * moistureModValue;
|
|
}
|
|
result = (1.0 / 12.0) * result;
|
|
valueList.Add(new ColumnValue(coverMod.Key, result));
|
|
}
|
|
tempCoverMoistureModFactorAverage.Add(field, valueList);
|
|
}
|
|
|
|
//step1
|
|
|
|
//SOCini
|
|
|
|
if (loopYear == year.First())
|
|
{
|
|
foreach (var field in cropAreaField1.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
var result = parameterSet.LayerDepth * soilPropertiesField[field.Key.Item1].Bulk_Density * soilPropertiesField[field.Key.Item1].OM_Corr * 0.54;
|
|
foreach (var crop in field.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(crop.Key, result));
|
|
}
|
|
socIni.Add(field.Key, valueList);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var fieldItem in soc_Field)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
var prev = fieldItem.Value.SingleOrDefault(x => x.Key == loopYear - 1);
|
|
if (prev == null)
|
|
{
|
|
continue;
|
|
}
|
|
foreach (var cropItem in historicalCropdata[(fieldItem.Key, loopYear)])
|
|
{
|
|
valueList.Add(new ColumnValue(cropItem, prev.Value));
|
|
}
|
|
socIni.Add((fieldItem.Key, loopYear), valueList);
|
|
}
|
|
}
|
|
|
|
//step 2
|
|
|
|
// RPM_in_residues
|
|
// DPM_in_residues
|
|
var rpm_in_residues = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var dpm_in_residues = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var carbonInput in carbonInputs.TrippleKeyParam.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var carbonResidues = carbonInput.Value.SingleOrDefault(x => x.Key == "CarbonResidues")?.Value ?? 0;
|
|
var carbonGreenManure = carbonInput.Value.SingleOrDefault(x => x.Key == "CarbonGreenManure")?.Value ?? 0;
|
|
var resultRpm = 0.0;
|
|
var resultDpm = 0.0;
|
|
if (cropSet.Perennial.Any(x=>x.ToLower() == carbonInput.Key.Item3.ToLower()))
|
|
{
|
|
resultRpm = (carbonResidues) * 0.6;
|
|
resultDpm = (carbonResidues) * 0.4;
|
|
}
|
|
else
|
|
{
|
|
resultRpm = (carbonResidues + carbonGreenManure) * 0.41;
|
|
resultDpm = (carbonResidues + carbonGreenManure) * 0.59;
|
|
}
|
|
|
|
if (rpm_in_residues.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
rpm_in_residues[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultRpm));
|
|
}
|
|
else
|
|
{
|
|
rpm_in_residues.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultRpm) });
|
|
}
|
|
if (dpm_in_residues.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
dpm_in_residues[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultDpm));
|
|
}
|
|
else
|
|
{
|
|
dpm_in_residues.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultDpm) });
|
|
}
|
|
}
|
|
|
|
// DPM_in_Manure
|
|
// RPM_in_manure
|
|
// HUM_in_manure
|
|
var dpm_in_Manure = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpm_in_manure = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var hum_in_manure = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var carbonInput in carbonInputs.TrippleKeyParam.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var carbonManure = carbonInput.Value.SingleOrDefault(x => x.Key == "CarbonManure")?.Value ?? 0;
|
|
var resultRpm = (carbonManure) * 0.49;
|
|
var resultDpm = (carbonManure) * 0.49;
|
|
var resultHum = (carbonManure) * 0.02;
|
|
|
|
if (rpm_in_manure.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
rpm_in_manure[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultRpm));
|
|
}
|
|
else
|
|
{
|
|
rpm_in_manure.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultRpm) });
|
|
}
|
|
if (dpm_in_Manure.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
dpm_in_Manure[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultDpm));
|
|
}
|
|
else
|
|
{
|
|
dpm_in_Manure.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultDpm) });
|
|
}
|
|
if (hum_in_manure.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
hum_in_manure[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultHum));
|
|
}
|
|
else
|
|
{
|
|
hum_in_manure.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultHum) });
|
|
}
|
|
}
|
|
|
|
// DPM_compost
|
|
// RPM_compost
|
|
// HUM_compost
|
|
var dpm_compost = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpm_compost = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var hum_compost = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var carbonInput in carbonInputs.TrippleKeyParam.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var carbonCompost = carbonInput.Value.SingleOrDefault(x => x.Key == "CarbonCompost")?.Value ?? 0;
|
|
var resultRpm = (carbonCompost) * 0.70;
|
|
var resultDpm = (carbonCompost) * 0.15;
|
|
var resultHum = (carbonCompost) * 0.15;
|
|
|
|
if (rpm_compost.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
rpm_compost[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultRpm));
|
|
}
|
|
else
|
|
{
|
|
rpm_compost.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultRpm) });
|
|
}
|
|
if (dpm_compost.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
dpm_compost[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultDpm));
|
|
}
|
|
else
|
|
{
|
|
dpm_compost.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultDpm) });
|
|
}
|
|
if (hum_compost.ContainsKey((carbonInput.Key.Item1, carbonInput.Key.Item2)))
|
|
{
|
|
hum_compost[(carbonInput.Key.Item1, carbonInput.Key.Item2)].Add(new ColumnValue(carbonInput.Key.Item3, resultHum));
|
|
}
|
|
else
|
|
{
|
|
hum_compost.Add((carbonInput.Key.Item1, carbonInput.Key.Item2), new List<ColumnValue> { new ColumnValue(carbonInput.Key.Item3, resultHum) });
|
|
}
|
|
}
|
|
|
|
// DPM_in
|
|
// RPM_in
|
|
// HUM_in
|
|
var dpm_in = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpm_in = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var hum_in = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var dpmitem in dpm_in_Manure)
|
|
{
|
|
foreach (var item in dpmitem.Value)
|
|
{
|
|
var valueDpmManure = item.Value;
|
|
var valueDpmResidues = dpm_in_residues[dpmitem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var valueDpmCompost = dpm_compost[dpmitem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = valueDpmManure + valueDpmResidues + valueDpmCompost;
|
|
|
|
if (dpm_in.ContainsKey(dpmitem.Key))
|
|
{
|
|
dpm_in[dpmitem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
dpm_in.Add(dpmitem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var rpmitem in rpm_in_manure)
|
|
{
|
|
foreach (var item in rpmitem.Value)
|
|
{
|
|
var valueRpmManure = item.Value;
|
|
var valueRpmResidues = rpm_in_residues[rpmitem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var valueRpmCompost = rpm_compost[rpmitem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = valueRpmManure + valueRpmResidues + valueRpmCompost;
|
|
|
|
if (rpm_in.ContainsKey(rpmitem.Key))
|
|
{
|
|
rpm_in[rpmitem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
rpm_in.Add(rpmitem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var humitem in hum_in_manure)
|
|
{
|
|
foreach (var item in humitem.Value)
|
|
{
|
|
var valueHumManure = item.Value;
|
|
var valueHumCompost = hum_compost[humitem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = valueHumManure + valueHumCompost;
|
|
|
|
if (hum_in.ContainsKey(humitem.Key))
|
|
{
|
|
hum_in[humitem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
hum_in.Add(humitem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
//step 3
|
|
|
|
//DPMini
|
|
var dpmIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var dpmItem in dpm_in)
|
|
{
|
|
foreach (var item in dpmItem.Value)
|
|
{
|
|
var tempCover = tempCoverMoistureModFactorAverage[dpmItem.Key.Item1].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
var result = (item.Value / tempCover) / parameterSet.kDPM;
|
|
if (dpmIni.ContainsKey(dpmItem.Key))
|
|
{
|
|
dpmIni[dpmItem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
dpmIni.Add(dpmItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
//RPMini
|
|
var rpmIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var rpmItem in rpm_in)
|
|
{
|
|
foreach (var item in rpmItem.Value)
|
|
{
|
|
var tempCover = tempCoverMoistureModFactorAverage[rpmItem.Key.Item1].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
var result = (item.Value / tempCover) / parameterSet.kRPM;
|
|
if (rpmIni.ContainsKey(rpmItem.Key))
|
|
{
|
|
rpmIni[rpmItem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
rpmIni.Add(rpmItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
//IOMini
|
|
var iomIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var socItem in socIni)
|
|
{
|
|
foreach (var item in socItem.Value)
|
|
{
|
|
var result = 0.049 * Math.Pow(item.Value, 1.139);
|
|
if (iomIni.ContainsKey(socItem.Key))
|
|
{
|
|
iomIni[socItem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
iomIni.Add(socItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
// BIOplusHUM_ini
|
|
var bioPlusHUM_ini = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var socItem in socIni.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
foreach (var item in socItem.Value)
|
|
{
|
|
var socIniValue = item.Value;
|
|
var dpmIniValue = dpmIni[socItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var rpmIniValue = rpmIni[socItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var iomIniValue = iomIni[socItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = socIniValue - (dpmIniValue + rpmIniValue + iomIniValue);
|
|
|
|
if (bioPlusHUM_ini.ContainsKey(socItem.Key))
|
|
{
|
|
bioPlusHUM_ini[socItem.Key].Add(new ColumnValue(item.Key, result));
|
|
}
|
|
else
|
|
{
|
|
bioPlusHUM_ini.Add(socItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, result) });
|
|
}
|
|
}
|
|
}
|
|
|
|
// BIOini
|
|
// HUMini
|
|
var bioIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var humIni = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var bioPlusItem in bioPlusHUM_ini)
|
|
{
|
|
foreach (var item in bioPlusItem.Value)
|
|
{
|
|
var bioIniValue = item.Value / (1 + 0.66 / 0.02);
|
|
var humIniValue = item.Value / (1 + 0.02 / 0.66);
|
|
|
|
if (bioIni.ContainsKey(bioPlusItem.Key))
|
|
{
|
|
bioIni[bioPlusItem.Key].Add(new ColumnValue(item.Key, bioIniValue));
|
|
}
|
|
else
|
|
{
|
|
bioIni.Add(bioPlusItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, bioIniValue) });
|
|
}
|
|
if (humIni.ContainsKey(bioPlusItem.Key))
|
|
{
|
|
humIni[bioPlusItem.Key].Add(new ColumnValue(item.Key, humIniValue));
|
|
}
|
|
else
|
|
{
|
|
humIni.Add(bioPlusItem.Key, new List<ColumnValue> { new ColumnValue(item.Key, humIniValue) });
|
|
}
|
|
}
|
|
}
|
|
|
|
//step 4
|
|
|
|
// DPMdec_fraction
|
|
// RPMdec_fraction
|
|
// BIOdec_fraction
|
|
// HUMdec_fraction
|
|
var dpmDec_fraction = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpmDec_fraction = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var bioDec_fraction = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var humDec_fraction = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var tempCover in tempCoverMoistureModFactorAverage)
|
|
{
|
|
foreach (var item in tempCover.Value)
|
|
{
|
|
var dpmDecValue = 1 - Math.Exp(-(item.Value * parameterSet.kDPM / 12));
|
|
var rpmDecValue = 1 - Math.Exp(-(item.Value * parameterSet.kRPM / 12));
|
|
var bioDecValue = 1 - Math.Exp(-(item.Value * 0.66 / 12));
|
|
var humDecValue = 1 - Math.Exp(-(item.Value * 0.02 / 12));
|
|
|
|
if (dpmDec_fraction.ContainsKey((tempCover.Key, loopYear)))
|
|
{
|
|
dpmDec_fraction[(tempCover.Key, loopYear)].Add(new ColumnValue(item.Key, dpmDecValue));
|
|
}
|
|
else
|
|
{
|
|
dpmDec_fraction.Add((tempCover.Key, loopYear), new List<ColumnValue> { new ColumnValue(item.Key, dpmDecValue) });
|
|
}
|
|
|
|
if (rpmDec_fraction.ContainsKey((tempCover.Key, loopYear)))
|
|
{
|
|
rpmDec_fraction[(tempCover.Key, loopYear)].Add(new ColumnValue(item.Key, rpmDecValue));
|
|
}
|
|
else
|
|
{
|
|
rpmDec_fraction.Add((tempCover.Key, loopYear), new List<ColumnValue> { new ColumnValue(item.Key, rpmDecValue) });
|
|
}
|
|
|
|
if (bioDec_fraction.ContainsKey((tempCover.Key, loopYear)))
|
|
{
|
|
bioDec_fraction[(tempCover.Key, loopYear)].Add(new ColumnValue(item.Key, bioDecValue));
|
|
}
|
|
else
|
|
{
|
|
bioDec_fraction.Add((tempCover.Key, loopYear), new List<ColumnValue> { new ColumnValue(item.Key, bioDecValue) });
|
|
}
|
|
|
|
if (humDec_fraction.ContainsKey((tempCover.Key, loopYear)))
|
|
{
|
|
humDec_fraction[(tempCover.Key, loopYear)].Add(new ColumnValue(item.Key, humDecValue));
|
|
}
|
|
else
|
|
{
|
|
humDec_fraction.Add((tempCover.Key, loopYear), new List<ColumnValue> { new ColumnValue(item.Key, humDecValue) });
|
|
}
|
|
}
|
|
}
|
|
|
|
// step 5
|
|
|
|
// CO2LostRatio
|
|
var co2LostRatio = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var soilProperty in soilPropertiesField)
|
|
{
|
|
var result = 1.67 * (1.85 + 1.60 * Math.Exp(-0.0786 * soilProperty.Value.Clay_Content));
|
|
var data1 = cropAreaField1[(soilProperty.Key, loopYear)];
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in data1)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
co2LostRatio.Add((soilProperty.Key, loopYear), valueList);
|
|
}
|
|
|
|
// CO2LostRate
|
|
var co2LostRate = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var co2 in co2LostRatio)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in co2.Value)
|
|
{
|
|
var result = item.Value / (1 + item.Value);
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
co2LostRate.Add(co2.Key, valueList);
|
|
}
|
|
|
|
// step 6
|
|
|
|
// DPM
|
|
// RPM
|
|
// BIO
|
|
// HUM
|
|
|
|
var dpm = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpm = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var bio = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var hum = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var dpmItem in dpmIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in dpmItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
dpm.Add(dpmItem.Key, valueList);
|
|
}
|
|
|
|
foreach (var rpmItem in rpmIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in rpmItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
rpm.Add(rpmItem.Key, valueList);
|
|
}
|
|
|
|
foreach (var bioItem in bioIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in bioItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
bio.Add(bioItem.Key, valueList);
|
|
}
|
|
|
|
foreach (var humItem in humIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in humItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
hum.Add(humItem.Key, valueList);
|
|
}
|
|
|
|
// ToSOM
|
|
var toSOM = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var dpmItem in dpm)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in dpmItem.Value)
|
|
{
|
|
var result = 0.0;
|
|
for (int i = 0; i < 12; i++)
|
|
{
|
|
var dpmValue = item.Value;
|
|
var dpm_inValue = dpm_in[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var dpmDec_FractionValue = dpmDec_fraction[dpmItem.Key].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
|
|
var temp1 = (dpmValue + (dpm_inValue / 12)) * dpmDec_FractionValue;
|
|
|
|
var rpmValue = rpm[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var rpm_InValue = rpm_in[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var rpmDec_FractionValue = rpmDec_fraction[dpmItem.Key].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
|
|
var temp2 = (rpmValue + (rpm_InValue / 12)) * rpmDec_FractionValue;
|
|
|
|
var bioValue = bio[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var bioDec_FractionValue = bioDec_fraction[dpmItem.Key].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
|
|
var humValue = hum[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var hum_InValue = hum_in[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var humDec_FractionValue = humDec_fraction[dpmItem.Key].SingleOrDefault(x => x.Key.ToLower() == item.Key.ToLower())?.Value ?? 0;
|
|
|
|
var co2 = co2LostRate[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
|
|
result = ((dpmValue + (dpm_inValue / 12)) * dpmDec_FractionValue + (rpmValue + (rpm_InValue / 12)) * rpmDec_FractionValue + (bioValue * bioDec_FractionValue) + ((humValue + (hum_InValue / 12)) * humDec_FractionValue)) * (1 - co2);
|
|
|
|
item.Value = (dpmValue + (dpm_inValue / 12)) * (1 - dpmDec_FractionValue);
|
|
rpm[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key).Value = (rpmValue + (rpm_InValue / 12)) * (1 - rpmDec_FractionValue);
|
|
bio[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key).Value = bioValue * (1 - bioDec_FractionValue) + result * 0.46;
|
|
hum[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key).Value = (humValue + (hum_InValue / 12)) * (1 - humDec_FractionValue) + result * 0.54;
|
|
}
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
toSOM.Add(dpmItem.Key, valueList);
|
|
}
|
|
|
|
// SOC
|
|
var soc = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var dpmItem in dpm)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in dpmItem.Value)
|
|
{
|
|
if (!mineralSoilArea.ContainsKey(dpmItem.Key))
|
|
{
|
|
continue;
|
|
}
|
|
var dpmValue = item.Value;
|
|
var rpmValue = rpm[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var bioValue = bio[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var humValue = hum[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var iomValue = iomIni[dpmItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
|
|
var result = dpmValue + rpmValue + bioValue + humValue + iomValue;
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
soc.Add(dpmItem.Key, valueList);
|
|
}
|
|
|
|
// step 7
|
|
// DPMss
|
|
// RPMss
|
|
// IOMss
|
|
|
|
var dpmSs = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var rpmSs = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var iomSs = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
foreach (var dpmItem in dpmIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in dpmItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
dpmSs.Add(dpmItem.Key, valueList);
|
|
}
|
|
|
|
foreach (var rpmItem in rpmIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in rpmItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
rpmSs.Add(rpmItem.Key, valueList);
|
|
}
|
|
|
|
foreach (var iomItem in iomIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in iomItem.Value)
|
|
{
|
|
valueList.Add(new ColumnValue(item.Key, item.Value));
|
|
}
|
|
iomSs.Add(iomItem.Key, valueList);
|
|
}
|
|
|
|
// BIOss
|
|
// HUMss
|
|
var bioSs = new Dictionary<(string, int), List<ColumnValue>>();
|
|
var humSs = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var co2Lost in co2LostRatio)
|
|
{
|
|
var valueListBio = new List<ColumnValue>();
|
|
var valueListHum = new List<ColumnValue>();
|
|
foreach (var item in co2Lost.Value)
|
|
{
|
|
var co2Value = item.Value;
|
|
var tempCoverValue = 0.0;
|
|
if (tempCoverMoistureModFactorAverage.ContainsKey(co2Lost.Key.Item1))
|
|
{
|
|
tempCoverValue = tempCoverMoistureModFactorAverage[co2Lost.Key.Item1].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
}
|
|
if (co2Value * tempCoverValue * parameterSet.kBIO > 0)
|
|
{
|
|
var sumCarbon = carbonInputs.TrippleKeyParam[(co2Lost.Key.Item1, co2Lost.Key.Item2, item.Key)].Sum(x => x.Value);
|
|
var result = sumCarbon * 0.46 / (co2Value * tempCoverValue * parameterSet.kBIO);
|
|
valueListBio.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
if (co2Value * tempCoverValue * parameterSet.kHUM > 0)
|
|
{
|
|
var sumCarbon = carbonInputs.TrippleKeyParam[(co2Lost.Key.Item1, co2Lost.Key.Item2, item.Key)].Sum(x => x.Value);
|
|
var result = sumCarbon * 0.54 / (co2Value * tempCoverValue * parameterSet.kHUM);
|
|
valueListHum.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
}
|
|
bioSs.Add(co2Lost.Key, valueListBio);
|
|
humSs.Add(co2Lost.Key, valueListHum);
|
|
}
|
|
|
|
// SOC_SteadyState
|
|
var soc_SteadyState = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var dpms in dpmSs)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
|
|
foreach (var item in dpms.Value)
|
|
{
|
|
var dpmSValue = item.Value;
|
|
var rpmSValue = rpmSs[dpms.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var bioSValue = bioSs[dpms.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var humSValue = humSs[dpms.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var iomSValue = iomSs[dpms.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
|
|
var result = dpmSValue + rpmSValue + bioSValue + humSValue + iomSValue;
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
soc_SteadyState.Add(dpms.Key, valueList);
|
|
}
|
|
|
|
// SOC_Field
|
|
foreach (var item in soc.Where(x => x.Key.Item2 == loopYear))
|
|
{
|
|
var result = item.Value.Sum(x => x.Value);
|
|
if (soc_Field.ContainsKey(item.Key.Item1))
|
|
{
|
|
soc_Field[item.Key.Item1].Add(new YearColumnValue(loopYear, result));
|
|
}
|
|
else
|
|
{
|
|
soc_Field.Add(item.Key.Item1, new List<YearColumnValue> { new YearColumnValue(loopYear, result) });
|
|
}
|
|
}
|
|
|
|
// SOC_Balance
|
|
foreach (var socItem in soc)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in socItem.Value)
|
|
{
|
|
var socValue = item.Value;
|
|
var socIniValue = socIni[socItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = socValue - socIniValue;
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
soc_Balance.Add(socItem.Key, valueList);
|
|
}
|
|
|
|
// SOC_Relative
|
|
var soc_Relative = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var socItem in socIni)
|
|
{
|
|
var valueList = new List<ColumnValue>();
|
|
foreach (var item in socItem.Value)
|
|
{
|
|
var socIniValue = item.Value;
|
|
var socBalanceValue = soc_Balance[socItem.Key].SingleOrDefault(x => x.Key == item.Key)?.Value ?? 0;
|
|
var result = socBalanceValue / socIniValue;
|
|
valueList.Add(new ColumnValue(item.Key, result));
|
|
}
|
|
soc_Relative.Add(socItem.Key, valueList);
|
|
}
|
|
}
|
|
//end loopYear
|
|
|
|
|
|
// SOC_output.gms
|
|
// SOC_Summary
|
|
var carbonSummary = new CarbonSummary();
|
|
var cropFieldSummary = new List<CropFieldSummary>();
|
|
carbonSummary.CropField = cropFieldSummary;
|
|
|
|
var soc_Summary = new Dictionary<(string, int), List<ColumnValue>>();
|
|
foreach (var item in cropAreaField1)
|
|
{
|
|
var sum = item.Value.Sum(x => x.Value);
|
|
soc_Summary.Add(item.Key, new List<ColumnValue> { new ColumnValue("Total_crop_area", sum) });
|
|
}
|
|
|
|
foreach (var item in cropAreaField1)
|
|
{
|
|
var sum = item.Value.Sum(x => x.Value);
|
|
var crpField = cropFieldSummary.SingleOrDefault(x => x.Name == item.Key.Item1);
|
|
if (crpField == null)
|
|
{
|
|
cropFieldSummary.Add(new CropFieldSummary { Name = item.Key.Item1, Summary = new List<YearSummary> { new YearSummary { Year = item.Key.Item2, Total_crop_area = sum } } });
|
|
}
|
|
else
|
|
{
|
|
crpField.Summary.Add(new YearSummary { Year = item.Key.Item2, Total_crop_area = sum });
|
|
}
|
|
}
|
|
|
|
var allFields = carbonInputs.TrippleKeyParam.Keys.Select(x => x.Item1).Distinct();
|
|
var allYears = carbonInputs.TrippleKeyParam.Keys.Select(x => x.Item2).Distinct();
|
|
|
|
foreach (var fieldLoop in allFields)
|
|
{
|
|
foreach (var yLoop in allYears)
|
|
{
|
|
var sumCarbonManure = 0.0;
|
|
var sumCarbonResidues = 0.0;
|
|
var sumCarbonGreenManure = 0.0;
|
|
var sumCarbonCompost = 0.0;
|
|
foreach (var item in carbonInputs.TrippleKeyParam.Where(x => x.Key.Item1 == fieldLoop && x.Key.Item2 == yLoop))
|
|
{
|
|
sumCarbonManure += item.Value.SingleOrDefault(x => x.Key == "CarbonManure")?.Value ?? 0;
|
|
sumCarbonResidues += item.Value.SingleOrDefault(x => x.Key == "CarbonResidues")?.Value ?? 0;
|
|
sumCarbonGreenManure += item.Value.SingleOrDefault(x => x.Key == "CarbonGreenManure")?.Value ?? 0;
|
|
sumCarbonCompost += item.Value.SingleOrDefault(x => x.Key == "CarbonCompost")?.Value ?? 0;
|
|
}
|
|
soc_Summary[(fieldLoop, yLoop)].Add(new ColumnValue("SOC_CarbonManure", sumCarbonManure));
|
|
soc_Summary[(fieldLoop, yLoop)].Add(new ColumnValue("SOC_CarbonResidues", sumCarbonResidues));
|
|
soc_Summary[(fieldLoop, yLoop)].Add(new ColumnValue("SOC_CarbonGreenManure", sumCarbonGreenManure));
|
|
soc_Summary[(fieldLoop, yLoop)].Add(new ColumnValue("SOC_CarbonCompost", sumCarbonCompost));
|
|
|
|
var crpField = cropFieldSummary.Single(x => x.Name == fieldLoop);
|
|
var summary = crpField.Summary.Single(x => x.Year == yLoop);
|
|
summary.SOC_CarbonManure = sumCarbonManure;
|
|
summary.SOC_CarbonResidues = sumCarbonResidues;
|
|
summary.SOC_CarbonGreenManure = sumCarbonGreenManure;
|
|
summary.SOC_CarbonCompost = sumCarbonCompost;
|
|
}
|
|
}
|
|
|
|
foreach (var item in soc_Balance)
|
|
{
|
|
var sum = item.Value.Sum(x => x.Value);
|
|
soc_Summary[item.Key].Add(new ColumnValue("Balance", sum));
|
|
|
|
var crpField = cropFieldSummary.Single(x => x.Name == item.Key.Item1);
|
|
var summary = crpField.Summary.Single(x => x.Year == item.Key.Item2);
|
|
summary.Balance = sum;
|
|
}
|
|
|
|
foreach (var item in socIni)
|
|
{
|
|
var sum = item.Value.Sum(x => x.Value);
|
|
soc_Summary[item.Key].Add(new ColumnValue("Initial", sum));
|
|
|
|
var crpField = cropFieldSummary.Single(x => x.Name == item.Key.Item1);
|
|
var summary = crpField.Summary.Single(x => x.Year == item.Key.Item2);
|
|
summary.Initial = sum;
|
|
}
|
|
|
|
foreach (var item in soilPropertiesField)
|
|
{
|
|
var result = item.Value.Bulk_Density;
|
|
foreach (var lYear in allYears)
|
|
{
|
|
soc_Summary[(item.Key, lYear)].Add(new ColumnValue("Bulk_Density", result));
|
|
}
|
|
}
|
|
|
|
foreach (var item in soilPropertiesField)
|
|
{
|
|
var result = item.Value.Bulk_Density;
|
|
foreach (var lYear in allYears)
|
|
{
|
|
var summaries = cropFieldSummary.Single(x => x.Name == item.Key);
|
|
var summary = summaries.Summary.Single(x => x.Year == lYear);
|
|
summary.Bulk_Density = result;
|
|
}
|
|
}
|
|
|
|
foreach (var item in socIni)
|
|
{
|
|
var crpField = cropFieldSummary.Single(x => x.Name == item.Key.Item1);
|
|
var summary = crpField.Summary.Single(x => x.Year == item.Key.Item2);
|
|
summary.Crop = item.Value[0].Key;
|
|
}
|
|
|
|
foreach (var item in soc_Summary)
|
|
{
|
|
var balanceValue = item.Value.SingleOrDefault(x => x.Key == "Balance")?.Value ?? 0;
|
|
var initValue = item.Value.SingleOrDefault(x => x.Key == "Initial")?.Value ?? 0;
|
|
var bulkValue = item.Value.SingleOrDefault(x => x.Key == "Bulk_Density")?.Value ?? 0;
|
|
|
|
double result = 0;
|
|
if (bulkValue > 0)
|
|
{
|
|
result = (balanceValue + initValue) / parameterSet.LayerDepth / bulkValue;
|
|
}
|
|
|
|
item.Value.Add(new ColumnValue("IniCcontent", result));
|
|
|
|
var carbonManure = item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonManure")?.Value ?? 0;
|
|
var carbonResidues = item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonResidues")?.Value ?? 0;
|
|
var carbonGreenManure = item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonGreenManure")?.Value ?? 0;
|
|
var carbonCompost = item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonCompost")?.Value ?? 0;
|
|
var emision = -1 * (carbonManure + carbonResidues + carbonGreenManure + carbonCompost - balanceValue);
|
|
item.Value.Add(new ColumnValue("Emision", emision));
|
|
}
|
|
|
|
foreach (var item in cropFieldSummary)
|
|
{
|
|
foreach (var crpSummary in item.Summary)
|
|
{
|
|
var result = (crpSummary.Balance + crpSummary.Initial) / parameterSet.LayerDepth / crpSummary.Bulk_Density;
|
|
crpSummary.IniCcontent = result;
|
|
}
|
|
}
|
|
|
|
foreach (var item in soc_Summary)
|
|
{
|
|
var iniValue = item.Value.SingleOrDefault(x => x.Key == "IniCcontent")?.Value ?? 0;
|
|
var balanceValue = item.Value.SingleOrDefault(x => x.Key == "Balance")?.Value ?? 0;
|
|
|
|
var resultOmIni = iniValue / 0.54;
|
|
var resultCo2 = balanceValue * (44.0 / 12.0);
|
|
|
|
item.Value.Add(new ColumnValue("OM_ini", resultOmIni));
|
|
item.Value.Add(new ColumnValue("CO2seq", resultCo2));
|
|
}
|
|
|
|
foreach (var summaries in cropFieldSummary)
|
|
{
|
|
foreach (var item in summaries.Summary)
|
|
{
|
|
var iniValue = item.IniCcontent;
|
|
var balanceValue = item.Balance;
|
|
|
|
var manure = item.SOC_CarbonManure;
|
|
var residues = item.SOC_CarbonResidues;
|
|
var greenManure = item.SOC_CarbonGreenManure;
|
|
var compost = item.SOC_CarbonCompost;
|
|
|
|
item.OM_ini = iniValue / 0.54;
|
|
item.CO2seq = balanceValue * (44.0 / 12.0);
|
|
|
|
var emision = -1 * (manure + residues + greenManure + compost - balanceValue);
|
|
item.Emision = emision;
|
|
}
|
|
}
|
|
|
|
|
|
// SOC_Summary_Farm
|
|
var soc_Summary_Farm = new List<FarmYearSummary>();
|
|
//carbonSummary.FarmSummary = soc_Summary_Farm;
|
|
foreach (var item in cropAreaFarm)
|
|
{
|
|
var sum = item.Value.Sum(x => x.Value);
|
|
//soc_Summary_Farm.Add(item.Key, new List<ColumnValue> { new ColumnValue("Total_crop_area", sum) });
|
|
soc_Summary_Farm.Add(new FarmYearSummary { Year = item.Key.Item2, Total_crop_area = sum });
|
|
}
|
|
|
|
foreach (var farm in cropAreaFarm)
|
|
{
|
|
var sumCarbonMan = 0.0;
|
|
var sumCarbonRes = 0.0;
|
|
var sumCarbonGreenMan = 0.0;
|
|
var sumCarbonCom = 0.0;
|
|
var sumEmision = 0.0;
|
|
|
|
var sumBal = 0.0;
|
|
var sumIni = 0.0;
|
|
var sumInicc = 0.0;
|
|
|
|
foreach (var item in soc_Summary.Where(x=>x.Key.Item2 == farm.Key.Item2))
|
|
{
|
|
var cropfieldArea = item.Value.SingleOrDefault(x => x.Key == "Total_crop_area")?.Value ?? 0;
|
|
sumCarbonMan += item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonManure")?.Value ?? 0;
|
|
sumCarbonRes += item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonResidues")?.Value ?? 0;
|
|
sumCarbonGreenMan += item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonGreenManure")?.Value ?? 0;
|
|
sumCarbonCom += item.Value.SingleOrDefault(x => x.Key == "SOC_CarbonCompost")?.Value ?? 0;
|
|
sumEmision += item.Value.SingleOrDefault(x => x.Key == "Emision")?.Value ?? 0;
|
|
|
|
sumBal += item.Value.SingleOrDefault(x => x.Key == "Balance")?.Value * cropfieldArea ?? 0;
|
|
sumIni += item.Value.SingleOrDefault(x => x.Key == "Initial")?.Value ?? 0;
|
|
sumInicc += item.Value.SingleOrDefault(x => x.Key == "IniCcontent")?.Value ?? 0;
|
|
}
|
|
var farmArea = soc_Summary_Farm.SingleOrDefault(x => x.Year == farm.Key.Item2);
|
|
if (farmArea != null && farmArea.Total_crop_area > 0)
|
|
{
|
|
var resultCarbonMan = sumCarbonMan / farmArea.Total_crop_area;
|
|
var resultCarbonRes = sumCarbonRes / farmArea.Total_crop_area;
|
|
var resultCarbonGreenMan = sumCarbonGreenMan / farmArea.Total_crop_area;
|
|
var resultCarboncom = sumCarbonCom / farmArea.Total_crop_area;
|
|
var resultEmision = sumEmision / farmArea.Total_crop_area;
|
|
|
|
var resultBal = sumBal / farmArea.Total_crop_area;
|
|
var resultIni = sumIni / farmArea.Total_crop_area;
|
|
var resultiniCc = sumInicc / farmArea.Total_crop_area;
|
|
var resultOm_Ini = resultiniCc / 0.54;
|
|
var resultCo2 = resultBal * (44.0 / 12.0);
|
|
var resultCo2Tot = resultCo2 * farmArea.Total_crop_area;
|
|
|
|
farmArea.SOC_CarbonManure = resultCarbonMan;
|
|
farmArea.SOC_CarbonResidues = resultCarbonRes;
|
|
farmArea.SOC_CarbonGreenManure = resultCarbonGreenMan;
|
|
farmArea.SOC_CarbonCompost = resultCarboncom;
|
|
|
|
farmArea.Balance = resultBal;
|
|
farmArea.Initial = resultIni;
|
|
farmArea.IniCcontent = resultiniCc;
|
|
farmArea.OM_ini = resultOm_Ini;
|
|
farmArea.CO2seq = resultCo2;
|
|
farmArea.CO2seq_total = resultCo2Tot;
|
|
farmArea.Emision = resultEmision;
|
|
}
|
|
}
|
|
return carbonSummary;
|
|
}
|
|
|
|
private double GetColumnValueForKey(Dictionary<(string, int), List<ColumnValue>> input, (string, int) key, string column)
|
|
{
|
|
return input[key].SingleOrDefault(x => x.Key.ToLower() == column.ToLower())?.Value ?? 0;
|
|
}
|
|
|
|
private List<int> GetYears(FarmInputsetsModel farmInputSet, CarbonRequest farmInput)
|
|
{
|
|
// assume for all cropfields the same years apply
|
|
return farmInput.CropFields.First().HistoricalCropData.Select(x => x.Year).Distinct().OrderBy(o=>o).ToList();
|
|
}
|
|
|
|
private Dictionary<string, List<string>> GetSoilTypeData(CarbonRequest farmInput)
|
|
{
|
|
var soilTypeData = new Dictionary<string, List<string>>();
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
soilTypeData.Add(field.Name, new List<string> { field.SoilType });
|
|
}
|
|
return soilTypeData;
|
|
}
|
|
|
|
private Dictionary<string, SoilPropertyType> GetSoilPropertiesField(CarbonRequest farmInput)
|
|
{
|
|
var soilPropertiesField = new Dictionary<string, SoilPropertyType>();
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
soilPropertiesField.Add(field.Name, new SoilPropertyType { OM_Cont = field.SoilProperty.OM_Const.Value, Clay_Content = field.SoilProperty.Clay_Content.Value, OM_Corr = field.SoilProperty.OM_Const.Value <= 20 ? field.SoilProperty.OM_Const.Value : 0 });
|
|
}
|
|
|
|
return soilPropertiesField;
|
|
}
|
|
|
|
private Dictionary<(string, string), SoilPropertyType> GetSoilPropSoilType(Dictionary<string, List<string>> soilTypeData, Dictionary<string, SoilPropertyType> soilPropertiesField)
|
|
{
|
|
var soilPropSoilType = new Dictionary<(string, string), SoilPropertyType>();
|
|
foreach (var item in soilTypeData)
|
|
{
|
|
foreach (var item2 in item.Value)
|
|
{
|
|
soilPropSoilType.Add((item.Key, item2), new SoilPropertyType { Bulk_Density = soilPropertiesField[item.Key].Bulk_Density, Clay_Content = soilPropertiesField[item.Key].Clay_Content, OM_Cont = soilPropertiesField[item.Key].OM_Cont, OM_Corr = soilPropertiesField[item.Key].OM_Corr }); // soilPropertiesField[item.Key]);
|
|
}
|
|
}
|
|
return soilPropSoilType;
|
|
}
|
|
|
|
private Dictionary<(string, int), List<string>> GetHistoricalCropdata(CarbonRequest farmInput)
|
|
{
|
|
var historicalCropData = new Dictionary<(string, int), List<string>>();
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
foreach (var cropYear in field.HistoricalCropData)
|
|
{
|
|
historicalCropData.Add((field.Name, cropYear.Year), cropYear.Crops.Select(x => x.Crop).ToList());
|
|
}
|
|
}
|
|
return historicalCropData;
|
|
}
|
|
|
|
|
|
private Dictionary<string, double> GetCropAreaField(CarbonRequest farmInput)
|
|
{
|
|
var cropAreaField = new Dictionary<string, double>();
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
cropAreaField.Add(field.Name, field.Area);
|
|
}
|
|
return cropAreaField;
|
|
}
|
|
|
|
private Dictionary<string, SoilBulkDensityType> GetSoilBulkDensities(Dictionary<string, SoilPropertyType> soilPropertiesField, Dictionary<string, List<string>> soilTypeData, Dictionary<(string, string), SoilPropertyType> soilPropSoilType)
|
|
{
|
|
var soilBulkDensities = new Dictionary<string, SoilBulkDensityType>();
|
|
foreach (var item in soilPropertiesField)
|
|
{
|
|
soilBulkDensities.Add(item.Key, new SoilBulkDensityType());
|
|
if (soilTypeData[item.Key].Any(x => x == "Klei"))
|
|
{
|
|
var soilBulkDensityKey = soilPropSoilType.Keys.Single(x => x.Item1 == item.Key && x.Item2 == "Klei");
|
|
var clay = (0.6117 + (0.003601 * item.Value.Clay_Content)) +
|
|
(0.002172 * soilPropSoilType[soilBulkDensityKey].OM_Corr * soilPropSoilType[soilBulkDensityKey].OM_Corr) +
|
|
(0.01715 * Math.Log(soilPropSoilType[soilBulkDensityKey].OM_Corr));
|
|
soilBulkDensities[item.Key].Clay = clay;
|
|
}
|
|
if (soilTypeData[item.Key].Any(x => x == "Zand"))
|
|
{
|
|
var soilBulkDensityKey = soilPropSoilType.Keys.Single(x => x.Item1 == item.Key && x.Item2 == "Zand");
|
|
soilBulkDensities[item.Key].Sand = 0.667 + (0.021 * soilPropSoilType[soilBulkDensityKey].OM_Corr);
|
|
}
|
|
}
|
|
return soilBulkDensities;
|
|
}
|
|
|
|
private static Dictionary<string, List<ClimateVariable>> GetClimateVariable(string knmiFile, SetsForDataTransformation dataTransformationSet, GIS_Soils_Sets gisSoilSet, int loopYear, CarbonRequest farmInput)
|
|
{
|
|
var data = new List<string>();
|
|
using (StreamReader r = new StreamReader(knmiFile))
|
|
{
|
|
string line;
|
|
while ((line = r.ReadLine()) != null)
|
|
{
|
|
data.Add(line);
|
|
}
|
|
}
|
|
|
|
|
|
var farmPostalCode = farmInput.PostalCode;
|
|
if (farmInput.geometry != null)
|
|
{
|
|
// determine poatalcode from geometry
|
|
string res = GetPostalCodeFromGeometry(farmInput.geometry);
|
|
farmPostalCode = 8211;
|
|
}
|
|
|
|
var farmZone = dataTransformationSet.KNMI_zone_Reg.SingleOrDefault(x => x.Reg.Contains(farmPostalCode)).KNMI_zone;
|
|
// climate (zone, month, year)
|
|
var climate = new Dictionary<(string, string, int), ClimateVariable>();
|
|
|
|
foreach (var row in data)
|
|
{
|
|
if (string.IsNullOrEmpty(row) || row.Split(';').Length == 0 || string.IsNullOrEmpty(row.Split(';')[0]))
|
|
{
|
|
continue;
|
|
}
|
|
var rowArr = row.Split(';');
|
|
climate.Add((rowArr[0], rowArr[1], int.Parse(rowArr[2])), new ClimateVariable(double.Parse(rowArr[3], CultureInfo.InvariantCulture), double.Parse(rowArr[4], CultureInfo.InvariantCulture), double.Parse(rowArr[5], CultureInfo.InvariantCulture)));
|
|
}
|
|
|
|
var climateVariable = new Dictionary<string, List<ClimateVariable>>();
|
|
|
|
foreach (var field in farmInput.CropFields.Select(s=>s.Name))
|
|
{
|
|
var monthClimateList = new List<ClimateVariable>();
|
|
foreach (var month in gisSoilSet.AllMonths)
|
|
{
|
|
var climateYear = loopYear > 2020 || loopYear < 2011 ? 2012 : loopYear;
|
|
var monthData = climate.Single(x => x.Key.Item1 == farmZone && x.Key.Item2 == month && x.Key.Item3 == climateYear).Value;
|
|
var newMonthData = new ClimateVariable(monthData.Temperature, monthData.Precipitation, monthData.Evapotranspiration * 1.25);
|
|
monthClimateList.Add(newMonthData);
|
|
}
|
|
climateVariable.Add(field, monthClimateList);
|
|
}
|
|
|
|
return climateVariable;
|
|
}
|
|
|
|
private string GetProvinceCode(SetsForDataTransformation dataTransformationSet, int postalCode)
|
|
{
|
|
// get number of postalcode based on geometry?
|
|
var farm_reg = dataTransformationSet.NUTS0NUTSII.SingleOrDefault(s => s.reg.Any(x => x == postalCode));
|
|
if (farm_reg == null)
|
|
{
|
|
throw new Exception($"reg {postalCode} not found");
|
|
}
|
|
var provinceCode = farm_reg.prov;
|
|
return provinceCode;
|
|
}
|
|
|
|
private Dictionary<(string, int), List<ColumnValue>> GetCarbonInputGreenManure(int loopYear, CarbonRequest farmInput, List<YieldGreenManureModel> yieldGreenManureConfig)
|
|
{
|
|
var carbonInputGreenManure = new Dictionary<(string, int), List<ColumnValue>>();
|
|
|
|
if (farmInput == null)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
foreach (var field in farmInput.CropFields)
|
|
{
|
|
foreach (var manures in field.GreenManures)
|
|
{
|
|
foreach (var manure in manures.GreenManureTypes)
|
|
{
|
|
var manureQ = yieldGreenManureConfig.SingleOrDefault(x => x.ManureName.ToLower() == manure.Type.ToLower());
|
|
//double manureQuality = manure.Quality == "Goed" ? manureQ.GoodQuality : manure.Quality == "Matig" ? manureQ.AverageQuality : manure.Quality == "Slecht" ? manureQ.BadQuality : 0;
|
|
double manureQuality2 = manure.Quality == Quality.Good ? manureQ.GoodQuality : manure.Quality == Quality.Average ? manureQ.AverageQuality : manure.Quality == Quality.Bad ? manureQ.BadQuality : 0;
|
|
if (manureQuality2 > 0)
|
|
{
|
|
//var yieldGreenManureRow = yieldGreenManureSheet.Rows.SingleOrDefault(x => x.Cells[0] != null && x.Cells[0].Text.ToString() == manure.Type).Cells[qColumn].Value;
|
|
carbonInputGreenManure.Add((field.Name, manures.Year), new List<ColumnValue> { new ColumnValue(manure.Type, manureQuality2) });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return carbonInputGreenManure;
|
|
}
|
|
|
|
private static string GetPostalCodeFromGeometry(NetTopologySuite.Geometries.Geometry geometry)
|
|
{
|
|
//// Set crs default geometry factory to EPSG:4326
|
|
NetTopologySuite.NtsGeometryServices.Instance = new NetTopologySuite.NtsGeometryServices(NetTopologySuite.Geometries.Implementation.CoordinateArraySequenceFactory.Instance,
|
|
new PrecisionModel(PrecisionModels.Floating), 4326);
|
|
// Register all vector drivers
|
|
Ogr.RegisterAll();
|
|
|
|
// item.geometry is always in WGS84 so reproject to EPSG:28992
|
|
var localReference = new LocalReference("EPSG:28992");
|
|
var localGeometry = localReference.ToLocalPolygon(geometry as Polygon);
|
|
|
|
// get postal code from shape file
|
|
// open shape file
|
|
using (var postalcodes = Ogr.Open("config/PC4/PC4.shp", 0))
|
|
{
|
|
// get first layer
|
|
var pc4Layer = postalcodes.GetLayerByIndex(0);
|
|
|
|
// set spatial filter to geometry ( only intersecting features are retrieved )
|
|
pc4Layer.SetSpatialFilter(localGeometry.Centroid.ToOGRGeometry());
|
|
|
|
// get next feature
|
|
var pc4Feature = pc4Layer.GetNextFeature();
|
|
|
|
// if feature retrieved get the PC4 attribute from it
|
|
if (pc4Feature is object)
|
|
{
|
|
return pc4Feature.GetFieldAsString("PC4");
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
private string MapSoil(string soil)
|
|
{
|
|
switch (soil)
|
|
{
|
|
case "6":
|
|
case "7":
|
|
return "Klei";
|
|
case "1":
|
|
return "Zand";
|
|
default:
|
|
return "Loss";
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|