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 FarmmapsPoten.Models; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using static FarmmapsApiSamples.Constants; namespace FarmmapsVRApoten { public class PotenApplication : IApplication { private const string DownloadFolder = "Downloads"; private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; private readonly PotenService _potenService; private readonly GeneralService _generalService; public PotenApplication(ILogger logger, FarmmapsApiService farmmapsApiService, GeneralService generalService, PotenService potenService) { _logger = logger; _farmmapsApiService = farmmapsApiService; _generalService = generalService; _potenService = potenService; } public async Task RunAsync() { // read field data from separate json file var VRAPotenInputJson = File.ReadAllText("PotenInput.json"); List potenInputs = JsonConvert.DeserializeObject>(VRAPotenInputJson); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); // !! 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 potenInputs) { try { await Process(roots, input); } catch (Exception ex) { _logger.LogError(ex.Message); } } } private async Task Process(List roots, PotenInput input) { var meanDensity = input.MeanDensity; var variation = input.Variation; var fieldName = input.FieldName; bool useShadow = input.UseShadow; bool countPerArea = input.CountPerArea; var myDrive = roots.SingleOrDefault(r => r.Name == "My drive"); if (myDrive == null) { _logger.LogError("Could not find a needed root item"); return; } var uploadedRoot = roots.SingleOrDefault(r => r.Name == "Uploaded"); if (uploadedRoot == null) { _logger.LogError("Could not find a needed root item"); return; } _logger.LogInformation("Creating cropfield"); var cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDrive.Code, $"VRA Poten cropfield {input.OutputFileName}", input.PlantingYear, input.GeometryJson.ToString(Formatting.None)); //Item cropfieldItem; // _logger.LogInformation("Cropfield already exists, trying to get it"); //cropfieldItem = await _farmmapsApiService.GetItemAsync("2927b80f63b946afb36821470b9c5c23"); //Calculating shadow map if (useShadow) { _logger.LogInformation("Calculate shadow map for field"); var shadowItem = await _generalService.RunShadowTask(cropfieldItem); if (shadowItem == null) { _logger.LogError("Something went wrong while obtaining the shadow map"); return; } _logger.LogInformation("Downloading shadow map"); await _farmmapsApiService.DownloadItemAsync(shadowItem.Code, Path.Combine(DownloadFolder, $"{input.OutputFileName}.shadow.zip")); } _logger.LogInformation("Looking for local data to use"); var localDataAvailable = input.File; var geotiffItem = (Item)null; if (String.IsNullOrEmpty(localDataAvailable)) { _logger.LogInformation("Could not find item for uploaded data, using BOFEK"); //Retreiving BOFEK _logger.LogInformation("Get BOFEK for field"); var bofekItem = await _generalService.RunBofekTask(cropfieldItem); if (bofekItem == null) { _logger.LogError("Something went wrong while obtaining the BOFEK data"); return; } _logger.LogInformation("Downloading Bofek map"); await _farmmapsApiService.DownloadItemAsync(bofekItem.Code, Path.Combine(DownloadFolder, $"{input.OutputFileName}.BOFEK.zip")); } else if (input.File.Contains(".tif") || input.File.Contains(".geotiff")) { _logger.LogInformation("input = tiff data"); var dataPath = Path.Combine("Data", input.File); geotiffItem = await _generalService.UploadDataAsync(uploadedRoot, GEOTIFF_PROCESSED_ITEMTYPE, dataPath, Path.GetFileNameWithoutExtension(input.File)); if (geotiffItem == null) { _logger.LogError("Could not find item for uploaded data"); return; } } else { var isGeoJson = input.File.Contains("json"); var dataPath = Path.Combine("Data", input.File); var shapeItem = isGeoJson ? await _generalService.UploadDataAsync(uploadedRoot, SHAPE_PROCESSED_ITEMTYPE, dataPath, Path.GetFileNameWithoutExtension(input.File)) : await _generalService.UploadZipWithShapeAsync(uploadedRoot, dataPath, Path.GetFileNameWithoutExtension(input.File), input.GeometryJson.ToString(Formatting.None)); if (shapeItem == null) { _logger.LogError("Something went wrong while searching for the shape file"); return; } // transform shape to geotiff as VRA poten only supports tiff input item _logger.LogInformation($"Converting shape to geotiff"); geotiffItem = await _generalService.ShapeToGeotiff(shapeItem); if (geotiffItem == null) { _logger.LogError("Something went wrong with shape to geotiff transformation"); return; } _logger.LogInformation("Downloading geotiff file"); await _farmmapsApiService.DownloadItemAsync(geotiffItem.Code, Path.Combine(DownloadFolder, $"VRApoten_inputGeotiff_{input.OutputFileName}.zip")); } // create appliance map _logger.LogInformation("Calculating application map"); // INPUT IS NEEDED as GEOTIFF var applianceMapItem = await _potenService.CalculateApplicationMapAsync(cropfieldItem, geotiffItem, meanDensity, variation, countPerArea, useShadow); if (applianceMapItem == null) { return; } _logger.LogInformation("Downloading application map"); await _farmmapsApiService.DownloadItemAsync(applianceMapItem.Code, Path.Combine(DownloadFolder, $"VRApoten_appliancemap_{input.OutputFileName}.zip")); string finalOutput = Path.Combine(DownloadFolder, $"VRApoten_appliancemap_{input.OutputFileName}.zip"); _logger.LogInformation(File.Exists(finalOutput) ? "Download application map completed." : "Something went wrong while downloading."); if(input.GenerateTaskmap) { //GEOTIFF TO Taskmap _logger.LogInformation($"Converting geotiff to taskmap"); var taskmap = (Item)null; if (input.OutputType == "isoxml") { taskmap = await _generalService.CreateTaskmap(cropfieldItem: cropfieldItem, tiffItem: applianceMapItem, outputType: input.OutputType, cellWidth: input.CellWidth, cellHeight: input.CellHeight, startPoint: input.StartPoint.ToString(Formatting.None), ddiCode: input.DdiCode, centered: input.Centered, endPoint: input.EndPoint.ToString(Formatting.None), angle: input.Angle, precision: input.Precision, cropTypeName: null, costumerName: null, ProductGroupName: null, productName : null, resolution: null, unitScale: null, maximumClasses: input.MaximumClasses); } else { taskmap = await _generalService.CreateTaskmap(cropfieldItem: cropfieldItem, tiffItem: applianceMapItem, outputType: input.OutputType, cellWidth: input.CellWidth, cellHeight: input.CellHeight, startPoint: input.StartPoint.ToString(Formatting.None), centered: input.Centered, endPoint: input.EndPoint.ToString(Formatting.None), angle: input.Angle, precision: input.Precision, maximumClasses: input.MaximumClasses); } if (taskmap == null) { _logger.LogError("Something went wrong with geotiff to taskmap transformation"); return; } _logger.LogInformation("Downloading taskmap"); await _farmmapsApiService.DownloadItemAsync(taskmap.Code, Path.Combine(DownloadFolder, $"VRApoten_taskmap_{input.OutputFileName}.zip")); } } } }