using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading.Tasks; using FarmmapsApi; using FarmmapsApi.Models; using FarmmapsApi.Services; using FarmmapsKPI.Models; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using static FarmmapsApiSamples.Constants; namespace FarmmapsKPI { public class KPIApplication : IApplication { //private const string DownloadFolder = "Downloads"; private const string SettingsFile = "settings.json"; private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; private readonly KPIService _dataDownloadService; private readonly GeneralService _generalService; private Settings _settings; public KPIApplication(ILogger logger, FarmmapsApiService farmmapsApiService, GeneralService generalService, KPIService dataDownloadService) { _logger = logger; _farmmapsApiService = farmmapsApiService; _generalService = generalService; _dataDownloadService = dataDownloadService; } public async Task RunAsync() { var fieldsInputJson = File.ReadAllText("KPIInput.json"); List fieldsInputs = JsonConvert.DeserializeObject>(fieldsInputJson); // !! this call is needed the first time an api is called with a fresh clientid and secret !! await _farmmapsApiService.GetCurrentUserCodeAsync(); var roots = await _farmmapsApiService.GetCurrentUserRootsAsync(); foreach (var input in fieldsInputs) { try { await Process(roots, input); } catch (Exception ex) { _logger.LogError(ex.Message); } } } private async Task Process(List roots, KPIInput input) { string downloadFolder = input.DownloadFolder; if (string.IsNullOrEmpty(downloadFolder)) { downloadFolder = "Downloads"; } if (!Directory.Exists(downloadFolder)) Directory.CreateDirectory(downloadFolder); // !!specify if you are using an already created cropfield: bool useCreatedCropfield = input.UseCreatedCropfield; var cropYear = input.CropYear; var fieldName = input.fieldName; //bool storeSatelliteStatistics = input.StoreSatelliteStatisticsSingleImage; //bool storeSatelliteStatisticsCropYear = input.StoreSatelliteStatisticsCropYear; //List SatelliteBands = new List(1) { input.SatelliteBand }; //string headerLineStats = $"FieldName,satelliteDate,satelliteBand,max,min,mean,mode,median,stddev,minPlus,curtosis,maxMinus,skewness,variance,populationCount,variationCoefficient,confidenceIntervalLow, confidenceIntervalHigh,confidenceIntervalErrorMargin" + Environment.NewLine; string settingsfile = $"Settings_{fieldName}.json"; LoadSettings(settingsfile); var uploadedRoot = roots.SingleOrDefault(r => r.Name == "USER_IN"); if (uploadedRoot == null) { _logger.LogError("Could not find a needed root item"); return; } var myDriveRoot = roots.SingleOrDefault(r => r.Name == "USER_FILES"); if (myDriveRoot == null) { _logger.LogError("Could not find a needed root item"); return; } // Use already created cropfield or create new one, added a Data input, with field specific data for the KPI calculation Item cropfieldItem; //1 useCreatedCropfield = false -> get new //2 useCreatedCropfield = true && CropfieldItemCode = "" or absent -> read from settings json //2 useCreatedCropfield = true && CropfieldItemCode like "deb48a74c5b54299bb852f17288010e9" in KPIinput -> use this one if (useCreatedCropfield == false || string.IsNullOrEmpty(_settings.CropfieldItemCode)) { _logger.LogInformation("Creating cropfield, writting to settings file"); cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDriveRoot.Code, $"DataCropfield {input.OutputFileName}", cropYear, input.GeometryJson.ToString(Formatting.None), input.Data.ToString(Formatting.None)); _settings.CropfieldItemCode = cropfieldItem.Code; SaveSettings(settingsfile); } else if (string.IsNullOrEmpty(input.CropfieldItemCode)) { _logger.LogInformation("CropfieldItemCode not in json input, reading from settings json"); cropfieldItem = await _farmmapsApiService.GetItemAsync(_settings.CropfieldItemCode); } else { _logger.LogInformation("CropfieldItemCode not in json input, reading from settings json"); cropfieldItem = await _farmmapsApiService.GetItemAsync(input.CropfieldItemCode); } //Get croprecordings if (input.GetCropRecordings) { var crprecItem = input.CrprecItem; _logger.LogInformation($"Trying to get crop recordings of croprecording: {crprecItem}"); var cropRec = await _farmmapsApiService.GetItemChildrenAsync(crprecItem, CROPREC_ITEMTYPE); if (cropRec == null) { _logger.LogError("Something went wrong while obtaining the croprecordings"); return; } var cropRecPath = Path.Combine(downloadFolder, $"croprecordings_{crprecItem}.json"); _logger.LogInformation($"Found {cropRec.Count} crop recordings"); var count1 = 0; await Task.Delay(500); foreach (var item in cropRec) { Console.WriteLine($"Crop recording #{count1}: {item.Name}"); File.AppendAllText(cropRecPath, item.Data +Environment.NewLine); count1++; } _logger.LogInformation($"Downloaded file {cropRecPath}"); } else { //todo set croprecordings from file } // Get KPI data for saving it in a file, here the generalsedrvice is called to get the KPI data _logger.LogInformation($"Trying to get the cropfielditem: {cropfieldItem.Code}"); var KPIItem = await _generalService.GetKpiItemsForCropField(cropfieldItem); var KPIItemPath = Path.Combine(downloadFolder, $"KPIItems_{cropfieldItem.Code}.json"); _logger.LogInformation($"Found {KPIItem.Count} KPI items"); var count = 0; await Task.Delay(50); foreach (var item in KPIItem) { Console.WriteLine($"KPI item #{count}: {item.Name}"); File.AppendAllText(KPIItemPath, item.Data + Environment.NewLine); count++; } _logger.LogInformation($"Downloaded file {KPIItemPath}"); //////////// //_logger.LogInformation("Calculate KPI map for field"); //var KPIItem = await _generalService.GetKpiItemsForCropField(cropfieldItem);// hier dus verwijzen naar de KPI task //if ((object)null == null) //{ // _logger.LogError("Something went wrong while obtaining the KPI map"); // return; // } //_logger.LogInformation("Downloading KPI map"); //await _farmmapsApiService.DownloadItemAsync(KPIItem.Code, // Path.Combine(downloadFolder, $"{input.OutputFileName}_KPI.zip")); } // Functions to save previously created cropfields private void LoadSettings(string file) { if (File.Exists(file)) { var jsonText = File.ReadAllText(file); _settings = JsonConvert.DeserializeObject(jsonText); } else { _settings = new Settings(); } } private void SaveSettings(string file) { if (_settings == null) return; var json = JsonConvert.SerializeObject(_settings); File.WriteAllText(file, json); } private void SaveInfo(string file) { if (_settings == null) return; var json = JsonConvert.SerializeObject(_settings); File.WriteAllText(file, json); } } }