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 = false; bool GetWatBal = input.GetWatBal; bool getVanDerSat = input.GetVanDerSat; bool StoreVanDerSatStatistics = input.storeVanDerSatStatistics; var FieldName = input.CropFieldName; 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) || input.CreateNewCropfield == true) { _logger.LogInformation("Creating cropfield"); cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDrive.Code, input.CropFieldName, input.CropYear, input.GeometryJson.ToString(Formatting.None)); _settings.CropfieldName = cropfieldItem.Name; _settings.CropfieldItemCode = cropfieldItem.Code; SaveSettings(settingsfile); } 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", $"{input.InputItemOne}"), Path.GetFileNameWithoutExtension($"{input.InputItemOne}")); 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", $"{input.InputItemTwo}"), Path.GetFileNameWithoutExtension($"{input.InputItemTwo}")); if (inputTwoItem == null) { _logger.LogError("Could not find item for uploaded data"); return; } var outputItem = await _zoneringService.CreateApplicationMapAsync(cropfieldItem, input.Formula, new Output() { Name = input.CalculatedLayerName, Quantity = input.CalculatedQuantity, Unit = input.CalculatedUnit, }, new InputParameter() { ItemCode = inputOneItem.Code, LayerName = inputOneItem.Data["layers"][0]["name"].ToString() }, new InputParameter() { ItemCode = inputTwoItem.Code, LayerName = inputTwoItem.Data["layers"][0]["name"].ToString() }); _logger.LogInformation("Downloading output"); _logger.LogInformation($"outputitem: {outputItem} with code {outputItem.Code} and date {outputItem.DataDate}"); //_logger.LogInformation($"Data: {outputItem.Data}"); await _farmmapsApiService.DownloadItemAsync(outputItem.Code, Path.Combine(DownloadFolder, $"{input.OutputFileName}.zoning.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); } } }