using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using FarmmapsApi; using FarmmapsApi.Models; using FarmmapsApi.Services; using FarmmapsHaulmkilling.Models; using FarmmapsZonering.Models; using FarmmapsZonering.Services; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using static FarmmapsApiSamples.Constants; namespace FarmmapsZonering { public class ZoneringApplication : IApplication { private const string DownloadFolder = "Downloads"; private const string SettingsFile = "settings.json"; private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; private readonly GeneralService _generalService; private readonly ZoneringService _zoneringService; private Settings _settings; public ZoneringApplication(ILogger logger, FarmmapsApiService farmmapsApiService, GeneralService generalService, ZoneringService zoneringService) { _logger = logger; _farmmapsApiService = farmmapsApiService; _generalService = generalService; _zoneringService = zoneringService; } public async Task RunAsync() { if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); // Read input data from separate file var zoneringInputJson = File.ReadAllText("ZoneringInput.json"); List zoneringInputs = JsonConvert.DeserializeObject>(zoneringInputJson); // !! 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 zoneringInputs) { try { await ZoningAsync(roots, input); } catch (Exception ex) { _logger.LogError(ex.Message); } } } private async Task ZoningAsync(List roots, ZoneringInput input) { var myDrive = roots.SingleOrDefault(r => r.Name == "My drive"); if (myDrive == null) { _logger.LogError("Could not find a needed root item"); return; } bool useCreatedCropfield = true; bool GetWatBal = input.GetWatBal; bool getVanDerSat = true;// input.GetVanDerSat; bool StoreVanDerSatStatistics = true;// input.storeVanDerSatStatistics; var FieldName = input.fieldName; string settingsfile = $"Settings_{FieldName}.json"; // Load settings from previous cropfield LoadSettings(settingsfile); var uploadedRoot = roots.SingleOrDefault(r => r.Name == "Uploaded"); if (uploadedRoot == null) { _logger.LogError("Could not find a needed root item"); return; } Item cropfieldItem; if (string.IsNullOrEmpty(_settings.CropfieldItemCode)) { _logger.LogInformation("Creating cropfield"); //var cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDrive.Code, input.CropFieldName, input.cropYear //$"VRA Poten cropfield {input.OutputFileName}", //input.GeometryJson.ToString(Formatting.None)); cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDrive.Code, "Perceel mestsilo", 2020, @"{ ""type"": ""Polygon"", ""coordinates"": [ [ [ 6.48270347, 53.25953201 ], [ 6.48257178, 53.25858122 ], [ 6.48781397, 53.25797859 ], [ 6.48793320, 53.25928036 ], [ 6.48270347, 53.25953201 ] ] ] }"); _settings.CropfieldItemCode = cropfieldItem.Code; SaveSettings(settingsfile); //cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDrive.Code, "Cropfield VRA Zonering", 2020, // @"{ ""type"": ""Polygon"", ""coordinates"": [ [ [ 5.670991253771027, 52.796788997702613 ], [ 5.671526456638633, 52.797291618546666 ], [ 5.671275936147413, 52.797422436717852 ], [ 5.671959173850738, 52.798269302728798 ], [ 5.670649634919365, 52.798778791408822 ], [ 5.671503682048522, 52.799591206957416 ], [ 5.675159003761311, 52.798193567415474 ], [ 5.673029579585948, 52.796024727480535 ], [ 5.670991253771027, 52.796788997702613 ] ] ] }"); //_settings.CropfieldItemCode = cropfieldItem.Code; //SaveSettings(); } else { _logger.LogInformation("Cropfield already exists trying to get"); cropfieldItem = await _farmmapsApiService.GetItemAsync(_settings.CropfieldItemCode); } if (GetWatBal==true) { ////Run watbal //if (useCreatedCropfield == false || string.IsNullOrEmpty(_settings.WatBalTaskCode)) { // var WatBalTaskCode = await _generalService.RunWatBalTask(cropfieldItem); // _settings.WatBalTaskCode = WatBalTaskCode; // SaveSettings(settingsfile); //} //// Get watbal data //Item WatBalItem = await _generalService.FindWatBalItem(cropfieldItem, _settings.WatBalTaskCode, FieldName, StoreStatistics); } if (getVanDerSat==true) { // check if vandersat task not yet done, do here and save taskcode if (useCreatedCropfield == false || string.IsNullOrEmpty(_settings.VanDerSatTaskCode)) { var VanDerSatTaskCode = await _generalService.RunVanDerSatTask(cropfieldItem); _settings.VanDerSatTaskCode = VanDerSatTaskCode; SaveSettings(settingsfile); } // Select a particular image item from VanDerSat Item VanDerSatItem = await _generalService.FindVanDerSatItem(cropfieldItem, _settings.VanDerSatTaskCode, FieldName, StoreVanDerSatStatistics); // download the geotiff _logger.LogInformation("Downloading geotiff file"); await _farmmapsApiService.DownloadItemAsync(VanDerSatItem.Code, Path.Combine(DownloadFolder, $"nbs_VanDerSatGeotiff_{input.OutputFileName}.zip")); } var inputOneItem = await _generalService.UploadDataAsync(uploadedRoot, GEOTIFF_PROCESSED_ITEMTYPE, Path.Combine("Data", "data_9001.tif"), "data_9001"); if (inputOneItem == null) { _logger.LogError("Could not find item for uploaded data"); return; } var inputTwoItem = await _generalService.UploadDataAsync(uploadedRoot, GEOTIFF_PROCESSED_ITEMTYPE, Path.Combine("Data", "data_times_two_4326.tiff"), "data_times_two_4326"); if (inputTwoItem == null) { _logger.LogError("Could not find item for uploaded data"); return; } //Formule kan meerdere inputs aan // Met blokhaken en een nummer specificeer je een input: //[0], [10]. etc... // Aan de hand van de volgorde van input wordt momenteel bepaald welk nummer bij welk input hoort. //[0] is dus de eerst tiff opgegeven.Als het goed is maakt het nummer nu niks uit, dus als er 2 inputs zijn en in de formule staan[0] en[10] dan zal die nog steeds werken. //De volgorde van de tiff kun je verslepen, bij de formule inputs kun je de input van het ene[0] slot naar het andere slepen[10] //Functies: abs, min en max //Constanten: pi en e //if ([0] -[1])/ ([0] +[1]) < 0 then 0 //else if ([0] -[1])/ ([0] +[1]) > 1 then 1 //else ([0] -[1]) / ([0] +[1]) var outputItem = await _zoneringService.CreateApplicationMapAsync(cropfieldItem, "[0] >= 1.28 then [1] else 0", new Output() { Name = "Test", Unit = "index", Quantity = "kg" }, new InputParameter() { ItemCode = inputOneItem.Code, LayerName = inputOneItem.Data["layers"][0]["name"].ToString() }, new InputParameter() { ItemCode = inputOneItem.Code, LayerName = inputOneItem.Data["layers"][0]["name"].ToString() }); _logger.LogInformation("Downloading output"); await _farmmapsApiService.DownloadItemAsync(outputItem.Code, Path.Combine(DownloadFolder, $"Test.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); } } }