added vrapoten and changed some nbs stuff
This commit is contained in:
		
							
								
								
									
										21
									
								
								FarmmapsPoten/FarmmapsPoten.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								FarmmapsPoten/FarmmapsPoten.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>netcoreapp3.1</TargetFramework> | ||||
|   </PropertyGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<None Update="appsettings.json"> | ||||
| 			<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 		</None> | ||||
| 		<None Update="Data\**\*"> | ||||
| 			<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 		</None> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
|     <ProjectReference Include="..\FarmmapsApi\FarmmapsApi.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										18
									
								
								FarmmapsPoten/Models/PotenInput.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								FarmmapsPoten/Models/PotenInput.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| using System; | ||||
| using Newtonsoft.Json.Linq; | ||||
|  | ||||
| namespace FarmmapsPoten.Models | ||||
| { | ||||
|     public class PotenInput | ||||
|     { | ||||
|         public bool UseShadow { get; set; } | ||||
|  | ||||
|         public string File { get; set; } | ||||
|         public string OutputFileName { get; set; } | ||||
|         public string FieldName { get; set; } | ||||
|         public int PlantingYear { get; set; } | ||||
|         public string MeanDensity { get; set; } | ||||
|         public string Variation { get; set; } | ||||
|         public JObject GeometryJson { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										196
									
								
								FarmmapsPoten/PotenApplication.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								FarmmapsPoten/PotenApplication.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| 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<PotenApplication> _logger; | ||||
|         private readonly FarmmapsApiService _farmmapsApiService; | ||||
|         private readonly PotenService _potenService; | ||||
|         private readonly GeneralService _generalService; | ||||
|  | ||||
|  | ||||
|         public PotenApplication(ILogger<PotenApplication> 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<PotenInput> potenInputs = JsonConvert.DeserializeObject<List<PotenInput>>(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<UserRoot> roots, PotenInput input) | ||||
|         { | ||||
|             var meanDensity = input.MeanDensity; | ||||
|             var variation = input.Variation; | ||||
|             var fieldName = input.FieldName; | ||||
|             bool useShadow = input.UseShadow; | ||||
|  | ||||
|             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)); | ||||
|  | ||||
|             //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 | ||||
|             { | ||||
|                 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("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); | ||||
|  | ||||
|             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."); | ||||
|  | ||||
|             _logger.LogInformation($"Converting geotiff to shape"); | ||||
|             var taskmap = await _generalService.GeotiffToShape(applianceMapItem); | ||||
|             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, $"VRApoten_taskmap_{input.OutputFileName}.zip")); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										91
									
								
								FarmmapsPoten/PotenService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								FarmmapsPoten/PotenService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| using System; | ||||
| using System.Globalization; | ||||
| using System.Threading.Tasks; | ||||
| using FarmmapsApi.Models; | ||||
| using FarmmapsApi.Services; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Newtonsoft.Json; | ||||
| using static FarmmapsApi.Extensions; | ||||
| using static FarmmapsApiSamples.Constants; | ||||
|  | ||||
|  | ||||
| namespace FarmmapsVRApoten | ||||
| { | ||||
|     public class PotenService | ||||
|     { | ||||
|         private readonly ILogger<PotenService> _logger; | ||||
|         private readonly FarmmapsApiService _farmmapsApiService; | ||||
|         private readonly GeneralService _generalService; | ||||
|  | ||||
|         public PotenService(ILogger<PotenService> logger, FarmmapsApiService farmmapsApiService, | ||||
|             GeneralService generalService) | ||||
|         { | ||||
|             _logger = logger; | ||||
|             _farmmapsApiService = farmmapsApiService; | ||||
|             _generalService = generalService; | ||||
|         } | ||||
|  | ||||
|         public async Task<Item> CalculateApplicationMapAsync(Item cropfieldItem, Item inputItem,string meanDensity, string variation) | ||||
|         { | ||||
|             var potenApplicationMapRequest = new TaskRequest()  { TaskType = VRAPLANTING_TASK }; | ||||
|             if (inputItem != null) {potenApplicationMapRequest.attributes["inputCode"] = inputItem.Code; } | ||||
|             potenApplicationMapRequest.attributes["meanDensity"] = meanDensity; | ||||
|             potenApplicationMapRequest.attributes["variation"] = variation; | ||||
|  | ||||
|             //var taskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, potenApplicationMapRequest); | ||||
|             //await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) => | ||||
|             //{ | ||||
|             //    _logger.LogInformation("Checking VRAPoten task status"); | ||||
|             //    var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, taskCode); | ||||
|             //    // Code  | ||||
|             //    if (itemTaskStatus.IsFinished) | ||||
|             //        tokenSource.Cancel(); | ||||
|             //}); | ||||
|  | ||||
|  | ||||
|  | ||||
|             var taskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, potenApplicationMapRequest); | ||||
|             _logger.LogInformation($"itemTaskCode: {taskCode}"); | ||||
|             _logger.LogInformation($"potenTaskmapRequest: {potenApplicationMapRequest}"); | ||||
|             _logger.LogInformation($"potenTaskmapRequest type: {potenApplicationMapRequest.TaskType}"); | ||||
|             _logger.LogInformation($"cropfieldItemCode: {cropfieldItem.Code}"); | ||||
|  | ||||
|  | ||||
|  | ||||
|             await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) => { | ||||
|                 var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, taskCode); | ||||
|                 _logger.LogInformation($"Waiting on calculation of application map; Status: {itemTaskStatus.State}"); | ||||
|                 if (itemTaskStatus.IsFinished) | ||||
|                     tokenSource.Cancel(); | ||||
|             }); | ||||
|  | ||||
|  | ||||
|  | ||||
|             var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, taskCode); | ||||
|             if (itemTask.State == ItemTaskState.Error) | ||||
|             { | ||||
|                 _logger.LogError($"Something went wrong with task execution: {itemTask.Message}"); | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             var itemName = $"VRAPoten"; | ||||
|             var applianceMapItem = await _generalService.FindChildItemAsync(cropfieldItem.Code, | ||||
|                 GEOTIFF_PROCESSED_ITEMTYPE, itemName, | ||||
|                 i => i.Updated >= itemTask.Finished.GetValueOrDefault(DateTime.UtcNow) && | ||||
|                             i.Name.ToLower().Contains(itemName.ToLower())); | ||||
|  | ||||
|             if (applianceMapItem == null) | ||||
|             { | ||||
|                 _logger.LogError("Could not find the VRAPoten geotiff child item under cropfield"); | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             return applianceMapItem; | ||||
|  | ||||
|         }    | ||||
|  | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										23
									
								
								FarmmapsPoten/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								FarmmapsPoten/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| using System.Threading.Tasks; | ||||
| using FarmmapsApi; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| namespace FarmmapsVRApoten | ||||
| { | ||||
|     class Program : FarmmapsProgram<PotenApplication> | ||||
|     { | ||||
|         private static async Task Main(string[] args) | ||||
|         { | ||||
|             await new Program().Start(args); | ||||
|         } | ||||
|  | ||||
|         protected override void Configure(IServiceCollection serviceCollection) | ||||
|         { | ||||
|             serviceCollection.AddLogging(opts => opts | ||||
|                     .AddConsole() | ||||
|                     .AddFilter("System.Net.Http", LogLevel.Warning)) | ||||
|                 .AddTransient<PotenService>(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user