Update NBS taskmap generator
This commit is contained in:
		| @@ -1,24 +0,0 @@ | |||||||
| <Project Sdk="Microsoft.NET.Sdk"> |  | ||||||
|  |  | ||||||
|     <PropertyGroup> |  | ||||||
|         <OutputType>Exe</OutputType> |  | ||||||
|         <TargetFramework>netcoreapp3.0</TargetFramework> |  | ||||||
|     </PropertyGroup> |  | ||||||
|  |  | ||||||
|     <ItemGroup> |  | ||||||
|       <None Update="appsettings.json"> |  | ||||||
|         <CopyToOutputDirectory>Always</CopyToOutputDirectory> |  | ||||||
|       </None> |  | ||||||
|       <None Update="Data\**\*"> |  | ||||||
|         <CopyToOutputDirectory>Always</CopyToOutputDirectory> |  | ||||||
|       </None> |  | ||||||
|       <None Update="NitrogenInput.json"> |  | ||||||
|         <CopyToOutputDirectory>Always</CopyToOutputDirectory> |  | ||||||
|       </None> |  | ||||||
|     </ItemGroup> |  | ||||||
|  |  | ||||||
|     <ItemGroup> |  | ||||||
|       <ProjectReference Include="..\FarmmapsApi\FarmmapsApi.csproj" /> |  | ||||||
|     </ItemGroup> |  | ||||||
|  |  | ||||||
| </Project> |  | ||||||
| @@ -1,336 +0,0 @@ | |||||||
| 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 FarmmapsNbs.Models; |  | ||||||
| using Microsoft.Extensions.Logging; |  | ||||||
| using Newtonsoft.Json; |  | ||||||
| using Newtonsoft.Json.Linq; |  | ||||||
| using static FarmmapsApiSamples.Constants; |  | ||||||
|  |  | ||||||
| namespace FarmmapsNbs |  | ||||||
| { |  | ||||||
|     public class NbsApplication : IApplication |  | ||||||
|     { |  | ||||||
|         private const string DownloadFolder = "Downloads"; |  | ||||||
|         private const string SettingsFile = "settings.json"; |  | ||||||
|  |  | ||||||
|         private readonly ILogger<NbsApplication> _logger; |  | ||||||
|         private readonly FarmmapsApiService _farmmapsApiService; |  | ||||||
|         private readonly NitrogenService _nitrogenService; |  | ||||||
|         private readonly GeneralService _generalService; |  | ||||||
|  |  | ||||||
|         private Settings _settings; |  | ||||||
|  |  | ||||||
|         public NbsApplication(ILogger<NbsApplication> logger, FarmmapsApiService farmmapsApiService, |  | ||||||
|             GeneralService generalService, NitrogenService nitrogenService) |  | ||||||
|         { |  | ||||||
|             _logger = logger; |  | ||||||
|             _farmmapsApiService = farmmapsApiService; |  | ||||||
|             _generalService = generalService; |  | ||||||
|             _nitrogenService = nitrogenService; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public async Task RunAsync() |  | ||||||
|         { |  | ||||||
|             var nitrogenInputJson = File.ReadAllText("InputData-NBS.json"); //NitrogenInput.json |  | ||||||
|             List<NitrogenInput> nitrogenInputs = JsonConvert.DeserializeObject<List<NitrogenInput>>(nitrogenInputJson); |  | ||||||
|              |  | ||||||
|             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 nitrogenInputs) |  | ||||||
|             { |  | ||||||
|                 try |  | ||||||
|                 { |  | ||||||
|                     await Process(roots, input); |  | ||||||
|                 } |  | ||||||
|                 catch (Exception ex) |  | ||||||
|                 { |  | ||||||
|                     _logger.LogError(ex.Message); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         private async Task Process(List<UserRoot> roots, NitrogenInput input) |  | ||||||
|         { |  | ||||||
|              |  | ||||||
|             // !!specify if you are using an already created cropfield: |  | ||||||
|             bool useCreatedCropfield = input. UseCreatedCropfield; |  | ||||||
|             var plantingDate = input.PlantingDate; |  | ||||||
|             var FieldName = input.fieldName; |  | ||||||
|             bool StoreStatistics = input.storeSatelliteStatistics; |  | ||||||
|             var measurementDate = input.MeasurementDate; |  | ||||||
|             string settingsfile = $"Settings_{FieldName}.json"; |  | ||||||
|  |  | ||||||
|             LoadSettings(settingsfile); |  | ||||||
|  |  | ||||||
|             var uploadedRoot = roots.SingleOrDefault(r => r.Name == "Uploaded"); |  | ||||||
|             if (uploadedRoot == null) |  | ||||||
|             { |  | ||||||
|                 _logger.LogError("Could not find a needed root item"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             var myDriveRoot = roots.SingleOrDefault(r => r.Name == "My drive"); |  | ||||||
|             if (myDriveRoot == null) |  | ||||||
|             { |  | ||||||
|                 _logger.LogError("Could not find a needed root item"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|                            |  | ||||||
|             // Use already created cropfield or create new one |  | ||||||
|             Item cropfieldItem; |  | ||||||
|             if (useCreatedCropfield == false || string.IsNullOrEmpty(_settings.CropfieldItemCode)) |  | ||||||
|             { |  | ||||||
|                 _logger.LogInformation("Creating cropfield"); |  | ||||||
|                 cropfieldItem = await _generalService.CreateCropfieldItemAsync(myDriveRoot.Code, |  | ||||||
|                     $"VRA NBS cropfield {input.OutputFileName}", plantingDate.Year, input.GeometryJson.ToString(Formatting.None)); |  | ||||||
|                 _settings.CropfieldItemCode = cropfieldItem.Code; |  | ||||||
|                 SaveSettings(settingsfile); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 _logger.LogInformation("Cropfield already exists, trying to get it"); |  | ||||||
|                 cropfieldItem = await _farmmapsApiService.GetItemAsync(_settings.CropfieldItemCode); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             var geotiffItem = (Item)null; |  | ||||||
|  |  | ||||||
|             // No file input, use most recent satellite image |  | ||||||
|             if (string.IsNullOrEmpty(input.File)) { |  | ||||||
|                 _logger.LogInformation("No specific data given, retrieving most recent satellite image"); |  | ||||||
|  |  | ||||||
|                 // check if satellite task not yet done, do here and save taskcode |  | ||||||
|                 if (useCreatedCropfield == false || string.IsNullOrEmpty(_settings.SatelliteTaskCode)) { |  | ||||||
|                     var satelliteTaskCode = await _generalService.RunSatelliteTask(cropfieldItem); |  | ||||||
|                     _settings.SatelliteTaskCode = satelliteTaskCode; |  | ||||||
|                     SaveSettings(settingsfile); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                 // Select a particular satellite item from satelliteTask |  | ||||||
|                 Item satalliteItem = await _generalService.FindSatelliteItem(cropfieldItem, _settings.SatelliteTaskCode, FieldName, StoreStatistics); |  | ||||||
|  |  | ||||||
|                 var satelliteBand = satalliteItem.Data["layers"][0]["name"]; |  | ||||||
|                 var satelliteStatistics = satalliteItem.Data["layers"][0]["renderer"]["band"]["statistics"]; |  | ||||||
|                 Console.WriteLine($"Satellite image date: {satalliteItem.DataDate}"); |  | ||||||
|                 //Console.WriteLine($"Satellite image statistics for band {satelliteBand}: {satelliteStatistics}"); |  | ||||||
|  |  | ||||||
|                 //Store data to csv  |  | ||||||
|                 if (StoreStatistics==true) { |  | ||||||
|                     var SatelliteFile = $"C:\\Akkerweb\\DataSatellite_{FieldName}.csv"; |  | ||||||
|                     var NewLineField = $"\"Field\":{FieldName}" + Environment.NewLine; |  | ||||||
|                     var NewLineDate = $"\"date\":{satalliteItem.DataDate}" + Environment.NewLine; |  | ||||||
|                     var i = 0; |  | ||||||
|                     foreach (var item in satelliteStatistics) { |  | ||||||
|                         //var NewLines2; |  | ||||||
|                         if (i == 0) { |  | ||||||
|                             File.AppendAllText(SatelliteFile, NewLineDate); |  | ||||||
|                             i++; |  | ||||||
|                         } |  | ||||||
|                         File.AppendAllText(SatelliteFile, $"{item}" + Environment.NewLine); |  | ||||||
|  |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                 // must be wdvi[1] |  | ||||||
|                 var inputType = (satalliteItem.Data["layers"] as JArray)?[1]["name"].ToString(); |  | ||||||
|                 if (string.IsNullOrEmpty(inputType)) { |  | ||||||
|                     _logger.LogError("Could not get the input type name from the satellite item"); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 // download the geotiff |  | ||||||
|                 var SatelliteImageDate = (DateTime)satalliteItem.DataDate; |  | ||||||
|                 var SatelliteDate = SatelliteImageDate.ToString("yyyyMMdd"); |  | ||||||
|                 _logger.LogInformation("Downloading geotiff file"); |  | ||||||
|                 await _farmmapsApiService.DownloadItemAsync(satalliteItem.Code, |  | ||||||
|                     Path.Combine(DownloadFolder, $"nbs_inputSatelliteGeotiff_{input.OutputFileName}_{inputType}_{SatelliteDate}.zip")); |  | ||||||
|  |  | ||||||
|                 // overwrite measurement date by date of satellite item |  | ||||||
|                 measurementDate = satalliteItem.DataDate.Value; |  | ||||||
|  |  | ||||||
|                 geotiffItem = satalliteItem; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             // (geo)tiff input: |  | ||||||
|             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; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // json/shape input |  | ||||||
|             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)); |  | ||||||
|  |  | ||||||
|                 if (shapeItem == null) { |  | ||||||
|                     _logger.LogError("Could not find item for uploaded data"); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 _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, $"{input.OutputFileName}.input_geotiff.zip")); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             //// 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, StoreStatistics); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             //// download the geotiff |  | ||||||
|             //_logger.LogInformation("Downloading geotiff file"); |  | ||||||
|             //await _farmmapsApiService.DownloadItemAsync(VanDerSatItem.Code, |  | ||||||
|             //    Path.Combine(DownloadFolder, $"nbs_VanDerSatGeotiff_{input.OutputFileName}.zip")); |  | ||||||
|  |  | ||||||
|             _logger.LogInformation($"Calculating targetN with targetYield: {input.TargetYield}"); |  | ||||||
|             var targetNItem = await _nitrogenService.CreateTargetNItem(cropfieldItem); |  | ||||||
|             var targetNData = await _nitrogenService.CalculateTargetN(cropfieldItem, targetNItem, plantingDate, |  | ||||||
|                 measurementDate, input.PotatoPurposeType, input.TargetYield); |  | ||||||
|  |  | ||||||
|             if (targetNData == null) { |  | ||||||
|                 _logger.LogError("Something went wrong with TargetN calculation"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             _logger.LogInformation($"TargetN: {targetNData.TargetN}"); |  | ||||||
|             ////Option to manually adjust the Target N, for test purposes only! |  | ||||||
|             //targetNData.TargetN = 225; |  | ||||||
|             //_logger.LogInformation($"TargetN adjusted: {targetNData.TargetN}"); |  | ||||||
|  |  | ||||||
|             var targetNDataPath = Path.Combine(DownloadFolder, $"{input.OutputFileName}.targetn.json"); |  | ||||||
|             await File.WriteAllTextAsync(targetNDataPath, JsonConvert.SerializeObject(targetNData, Formatting.Indented)); |  | ||||||
|  |  | ||||||
|             _logger.LogInformation("Calculating uptake map"); |  | ||||||
|             var uptakeMapItem = |  | ||||||
|                 await _nitrogenService.CalculateUptakeMap(cropfieldItem, geotiffItem, plantingDate, |  | ||||||
|                     measurementDate, input.InputVariable, input.InputLayerName); |  | ||||||
|             if (uptakeMapItem == null) { |  | ||||||
|                 _logger.LogError("Something went wrong with creating the uptakeMap"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             _logger.LogInformation("Downloading uptake map"); |  | ||||||
|             await _farmmapsApiService.DownloadItemAsync(uptakeMapItem.Code, |  | ||||||
|                 Path.Combine(DownloadFolder, $"{input.OutputFileName}.uptake.zip")); |  | ||||||
|             _logger.LogInformation("UptakeMap downloaded to {0}", Path.Combine(DownloadFolder, $"{input.OutputFileName}.uptake.zip")); |  | ||||||
|  |  | ||||||
|             _logger.LogInformation("Calculating application map"); |  | ||||||
|             var applicationMapItem = |  | ||||||
|                 await _nitrogenService.CalculateApplicationMap(cropfieldItem, geotiffItem, plantingDate, |  | ||||||
|                     measurementDate, input.InputVariable, targetNData.TargetN, input.InputLayerName); |  | ||||||
|  |  | ||||||
|             if (applicationMapItem == null) { |  | ||||||
|                 _logger.LogError("Something went wrong with creating the applicationMap"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             _logger.LogInformation("Downloading application map"); |  | ||||||
|             await _farmmapsApiService.DownloadItemAsync(applicationMapItem.Code, |  | ||||||
|                 Path.Combine(DownloadFolder, $"{input.OutputFileName}.application.zip")); |  | ||||||
|             _logger.LogInformation("Application map can be found in {0}", Path.Combine(DownloadFolder, $"{input.OutputFileName}.application.zip")); |  | ||||||
|  |  | ||||||
|             //transforming tiff to shape |  | ||||||
|             var tiffItem = applicationMapItem; |  | ||||||
|  |  | ||||||
|             if (tiffItem == null) { |  | ||||||
|                 _logger.LogError("Could not find item for uploaded data"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             //_logger.LogInformation($"Converting geotiff to shape"); |  | ||||||
|             //var taskmap = await _generalService.GeotiffToShape(tiffItem); |  | ||||||
|             //if (taskmap == null) { |  | ||||||
|             //    _logger.LogError("Something went wrong with geotiff to shape transformation"); |  | ||||||
|             //    return; |  | ||||||
|             //} |  | ||||||
|  |  | ||||||
|             //ApplicationMap (GEOTIFF) To Taskmap |  | ||||||
|             _logger.LogInformation($"Converting geotiff to taskmap"); |  | ||||||
|             var taskmap = await _generalService.CreateTaskmap(cropfieldItem, tiffItem, input.CellWidth, input.CellHeight, input.StartPoint.ToString(Formatting.None), |  | ||||||
|                 input.EndPoint.ToString(Formatting.None), input.Angle); |  | ||||||
|             if (taskmap == null) |  | ||||||
|             { |  | ||||||
|                 _logger.LogError("Something went wrong with geotiff to shape transformation"); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             _logger.LogInformation("Downloading taskmap"); |  | ||||||
|             await _farmmapsApiService.DownloadItemAsync(taskmap.Code, |  | ||||||
|                 Path.Combine(DownloadFolder, $"{input.OutputFileName}.taskmap.zip")); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         // Functions to save previously created cropfields |  | ||||||
|         private void LoadSettings(string file) |  | ||||||
|         { |  | ||||||
|             if (File.Exists(file)) |  | ||||||
|             { |  | ||||||
|                 var jsonText = File.ReadAllText(file); |  | ||||||
|                 _settings = JsonConvert.DeserializeObject<Settings>(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); |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
		Reference in New Issue
	
	Block a user