2020-04-08 09:43:53 +00:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Threading.Tasks ;
using FarmmapsApi.Models ;
using Google.Apis.Upload ;
using Microsoft.Extensions.Logging ;
2020-04-08 18:23:22 +00:00
using Newtonsoft.Json.Linq ;
2020-04-08 09:43:53 +00:00
using static FarmmapsApi . Extensions ;
using static FarmmapsApiSamples . Constants ;
namespace FarmmapsApi.Services
{
2021-01-28 14:08:32 +00:00
public class GeneralService {
2020-04-08 09:43:53 +00:00
private readonly ILogger < GeneralService > _logger ;
private readonly FarmmapsApiService _farmmapsApiService ;
2021-01-28 14:08:32 +00:00
public GeneralService ( ILogger < GeneralService > logger , FarmmapsApiService farmmapsApiService ) {
2020-04-08 09:43:53 +00:00
_logger = logger ;
_farmmapsApiService = farmmapsApiService ;
}
2020-08-19 11:40:42 +00:00
public async Task < Item > CreateCropfieldItemAsync ( string parentItemCode , string name , int year ,
2021-01-28 14:08:32 +00:00
string fieldGeomJson , string data = "{}" ) {
2020-04-08 18:23:22 +00:00
var currentYear = new DateTime ( year , 1 , 1 ) ;
2021-01-28 14:08:32 +00:00
var cropfieldItemRequest = new ItemRequest ( ) {
2020-04-08 18:23:22 +00:00
ParentCode = parentItemCode ,
ItemType = CROPFIELD_ITEMTYPE ,
Name = name ,
DataDate = currentYear ,
DataEndDate = currentYear . AddYears ( 1 ) . AddDays ( - 1 ) ,
2020-10-03 10:04:15 +00:00
Data = JObject . Parse ( data ) ,
2020-04-08 18:23:22 +00:00
Geometry = JObject . Parse ( fieldGeomJson )
} ;
return await _farmmapsApiService . CreateItemAsync ( cropfieldItemRequest ) ;
}
2020-08-19 11:40:42 +00:00
2021-04-12 15:01:17 +00:00
public async Task < Item > UploadDataAsync ( UserRoot root , string itemType , string filePath , string itemName , string geoJsonString = null )
{
2021-02-12 16:10:25 +00:00
var startUpload = DateTime . UtcNow . AddSeconds ( - 3 ) ;
2021-04-12 15:01:17 +00:00
var result = await _farmmapsApiService . UploadFile ( filePath , root . Code , geoJsonString ,
2021-07-08 15:18:12 +00:00
progress = >
{
_logger . LogInformation ( $"Status: {progress.Status} - BytesSent: {progress.BytesSent}" ) ;
if ( progress . Status = = UploadStatus . Failed & & progress . Exception ! = null )
_logger . LogError ( progress . Exception . Message ? ? "No further error" ) ;
} ) ;
2020-04-08 09:43:53 +00:00
if ( result . Progress . Status = = UploadStatus . Failed )
return null ;
2020-08-19 11:40:42 +00:00
return await FindChildItemAsync ( root . Code , itemType , itemName ,
i = > i . Created > = startUpload & &
2020-04-08 09:43:53 +00:00
i . Name . ToLower ( ) . Contains ( itemName . ToLower ( ) ) ) ;
}
2021-04-11 15:22:19 +00:00
public async Task < Item > UploadZipWithShapeAsync ( UserRoot root , string filePath , string itemName , string geoJsonString = null )
2020-04-08 09:43:53 +00:00
{
2021-04-12 15:01:17 +00:00
var startUpload = DateTime . UtcNow . AddSeconds ( - 3 ) ;
var result = await _farmmapsApiService . UploadFile ( filePath , root . Code , geoJsonString ,
2020-04-08 09:43:53 +00:00
progress = > _logger . LogInformation ( $"Status: {progress.Status} - BytesSent: {progress.BytesSent}" ) ) ;
if ( result . Progress . Status = = UploadStatus . Failed )
return null ;
2020-10-06 13:50:05 +00:00
return await FindChildItemAsync ( root . Code , SHAPE_PROCESSED_ITEMTYPE , itemName ,
i = > i . Created > = startUpload & &
2021-01-28 14:08:32 +00:00
i . Name . ToLower ( ) . Contains ( itemName . ToLower ( ) ) ) ; ;
2020-04-08 09:43:53 +00:00
}
2021-07-01 10:47:04 +00:00
public async Task < Item > ShapeToGeotiff ( Item shapeItem , int resolution = 1 , params string [ ] inputLayerNames )
2020-04-08 09:43:53 +00:00
{
2021-03-09 13:15:32 +00:00
var startUpload = DateTime . UtcNow . AddSeconds ( - 3 ) ;
2021-07-08 15:18:12 +00:00
var taskStatus = await RunAndWaitForTask ( shapeItem , "vnd.farmmaps.task.shapetogeotiff" , request = >
2021-07-01 10:47:04 +00:00
{
request . attributes [ "resolution" ] = resolution . ToString ( ) ;
if ( inputLayerNames . Length > 0 )
2021-07-02 08:34:30 +00:00
request . attributes [ "inputLayers" ] = $"[{string.Join(" , ", inputLayerNames.Select(v => $" \ "{v}\"" ) ) } ] ";
2021-07-01 10:47:04 +00:00
} ) ;
2020-04-28 08:06:41 +00:00
2021-07-08 15:18:12 +00:00
if ( taskStatus . State = = ItemTaskState . Error )
return null ;
2021-03-09 13:15:32 +00:00
return await FindChildItemAsync ( shapeItem . ParentCode , GEOTIFF_PROCESSED_ITEMTYPE , shapeItem . Name ,
i = > i . Created > = startUpload & &
i . Name . ToLower ( ) . Contains ( shapeItem . Name . ToLower ( ) ) ) ;
2020-04-28 08:06:41 +00:00
}
2020-08-19 11:40:42 +00:00
public async Task < Item > GeotiffToShape ( Item tiffItem )
{
var taskmapRequest = new TaskRequest { TaskType = TASKMAP_TASK } ;
2021-02-12 16:10:25 +00:00
taskmapRequest . attributes [ "cellWidth" ] = "3" ;
taskmapRequest . attributes [ "cellHeight" ] = "1" ;
taskmapRequest . attributes [ "angle" ] = "0" ;
2020-08-19 11:40:42 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( tiffItem . Code , taskmapRequest ) ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2020-08-19 11:40:42 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( tiffItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on converting geotiff to shape; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( tiffItem . Code , itemTaskCode ) ;
2021-01-28 14:08:32 +00:00
if ( itemTask . State = = ItemTaskState . Error ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
2021-03-01 13:04:18 +00:00
//the taskmap is a child of the input tiff *** Update feb 2021: it is a child of the cropfield.
2020-08-19 11:40:42 +00:00
var itemName = "Taskmap" ;
2021-02-12 16:10:25 +00:00
var taskMapItem = await FindChildItemAsync ( tiffItem . ParentCode ,
2020-08-19 11:40:42 +00:00
SHAPE_PROCESSED_ITEMTYPE , itemName ) ;
2021-01-28 14:08:32 +00:00
if ( taskMapItem = = null ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( "Could not find the shape taskmap as a child item under the input" ) ;
2021-02-12 16:10:25 +00:00
return null ;
}
return taskMapItem ;
}
// Create taskmap based on width, height and direction
2021-04-07 09:10:47 +00:00
2021-04-07 08:38:42 +00:00
public async Task < Item > CreateTaskmap ( Item cropfieldItem , Item tiffItem , string outputType , string cellWidth , string cellHeight ,
2021-07-01 10:54:06 +00:00
string startPoint , string inputLayerName = null , string ddiCode = "0001" , string centered = "false" , string endPoint = null , string angle = null , string precision = null ,
2021-04-07 08:38:42 +00:00
string cropTypeName = null , string costumerName = null , string ProductGroupName = null , string productName = null ,
2021-05-12 06:06:30 +00:00
string resolution = "3" , string unitScale = null , string maximumClasses = null )
2021-04-07 08:38:42 +00:00
2021-04-07 09:10:47 +00:00
2021-02-12 16:10:25 +00:00
{
var taskmapRequest = new TaskRequest { TaskType = TASKMAP_TASK } ;
2021-07-01 10:54:06 +00:00
taskmapRequest . attributes [ "inputLayerName" ] = inputLayerName ;
2021-02-12 16:10:25 +00:00
taskmapRequest . attributes [ "inputCode" ] = tiffItem . Code ;
2021-04-07 08:38:42 +00:00
taskmapRequest . attributes [ "operation" ] = outputType ; // Currently onlye "shape" supported, if ISOXML is supported this should be an input
2021-02-12 16:10:25 +00:00
taskmapRequest . attributes [ "cellWidth" ] = cellWidth ; //metres
taskmapRequest . attributes [ "cellHeight" ] = cellHeight ; //metres
taskmapRequest . attributes [ "startPoint" ] = startPoint ; // Coordinates WGS84
2021-03-01 15:31:31 +00:00
taskmapRequest . attributes [ "centered" ] = centered ;
2021-04-07 08:38:42 +00:00
if ( outputType = = "isoxml" ) taskmapRequest . attributes [ "ddiCode" ] = ddiCode ; // ddi is obligatory for isoxml, if not given set to 0001
2021-02-12 16:10:25 +00:00
if ( angle = = null ) taskmapRequest . attributes [ "endPoint" ] = endPoint ; // Coordinates WGS84
if ( endPoint = = null ) taskmapRequest . attributes [ "angle" ] = angle ; // degrees between 0.0 and 360.0
2021-04-12 12:22:24 +00:00
2021-02-12 16:10:25 +00:00
2021-04-07 08:38:42 +00:00
// Optional attributes
2021-04-12 12:22:24 +00:00
if ( precision ! = null ) taskmapRequest . attributes [ "precision" ] = precision ;
2021-04-07 08:38:42 +00:00
if ( cropTypeName ! = null ) taskmapRequest . attributes [ "cropTypeName" ] = cropTypeName ;
if ( costumerName ! = null ) taskmapRequest . attributes [ "costumerName" ] = costumerName ;
if ( ProductGroupName ! = null ) taskmapRequest . attributes [ "ProductGroupName" ] = ProductGroupName ;
if ( productName ! = null ) taskmapRequest . attributes [ "productName" ] = productName ;
if ( resolution ! = null ) taskmapRequest . attributes [ "resolution" ] = resolution ;
if ( unitScale ! = null ) taskmapRequest . attributes [ "unitScale" ] = unitScale ;
if ( maximumClasses ! = null ) taskmapRequest . attributes [ "maximumClasses" ] = maximumClasses ; // Can be used for shapefile too
2021-02-15 16:06:09 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
2021-02-12 16:10:25 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2021-02-15 16:06:09 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-02-12 16:10:25 +00:00
_logger . LogInformation ( $"Waiting on conversion to Taskmap; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
2021-02-15 16:06:09 +00:00
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-02-12 16:10:25 +00:00
if ( itemTask . State = = ItemTaskState . Error )
{
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
//the taskmap is a child of the input tiff
var itemName = "Taskmap" ;
2021-04-12 12:22:24 +00:00
Item taskMapItem = null ;
if ( outputType = = "isoxml" ) { taskMapItem = await FindChildItemAsync ( tiffItem . ParentCode ,
ISOXML_PROCESSED_ITEMTYPE , itemName ) ;
}
else if ( outputType = = "shape" ) {
taskMapItem = await FindChildItemAsync ( tiffItem . ParentCode ,
2021-04-21 08:17:24 +00:00
2021-06-09 09:53:14 +00:00
SHAPE_PROCESSED_ITEMTYPE , outputType ) ;
2021-04-12 12:22:24 +00:00
}
else
{
_logger . LogError ( "OutputType not specified, could not determine if output should be shape or ISOXML" ) ;
taskMapItem = null ;
}
2021-02-12 16:10:25 +00:00
if ( taskMapItem = = null )
{
2021-06-09 09:53:14 +00:00
_logger . LogError ( "Could not find the shape/isoxml taskmap as a child item under the cropfield" ) ;
2020-08-19 11:40:42 +00:00
return null ;
}
return taskMapItem ;
}
public async Task < ItemTaskStatus > RunAndWaitForTask ( Item subjectItem , string taskIdentifier ,
2021-01-28 14:08:32 +00:00
Action < TaskRequest > configureCallback = null , int retrySeconds = 3 ) {
var taskRequest = new TaskRequest ( ) {
2020-04-28 08:06:41 +00:00
TaskType = taskIdentifier
2020-04-08 09:43:53 +00:00
} ;
2020-04-28 08:06:41 +00:00
configureCallback ? . Invoke ( taskRequest ) ;
2020-08-19 11:40:42 +00:00
2020-04-28 08:06:41 +00:00
var taskCode = await _farmmapsApiService . QueueTaskAsync ( subjectItem . Code , taskRequest ) ;
2020-04-08 09:43:53 +00:00
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( retrySeconds ) , async ( tokenSource ) = > {
2020-04-28 08:06:41 +00:00
_logger . LogInformation ( $"Checking {taskIdentifier} task status" ) ;
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( subjectItem . Code , taskCode ) ;
2020-04-08 09:43:53 +00:00
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
2020-08-19 11:40:42 +00:00
2020-04-28 08:06:41 +00:00
_logger . LogInformation ( $"{taskIdentifier} finished" ) ;
2020-08-19 11:40:42 +00:00
2020-04-28 08:06:41 +00:00
return await _farmmapsApiService . GetTaskStatusAsync ( subjectItem . Code , taskCode ) ;
2020-04-08 09:43:53 +00:00
}
public async Task < Item > FindChildItemAsync ( string parentCode , string itemType , string containsName ,
2021-01-28 14:08:32 +00:00
Func < Item , bool > filter = null , int maxTries = 10 ) {
2020-04-08 09:43:53 +00:00
Item dataItem = null ;
int tries = 0 ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 3 ) , async source = > {
2020-04-08 09:43:53 +00:00
_logger . LogInformation ( $"Trying to get {containsName} data" ) ;
var uploadedFilesChildren = await _farmmapsApiService . GetItemChildrenAsync ( parentCode , itemType ) ;
2020-10-06 13:50:05 +00:00
Func < Item , bool > func = filter ? ? ( i = > i . Name . ToLower ( ) . Contains ( containsName . ToLower ( ) ) ) ;
dataItem = uploadedFilesChildren . FirstOrDefault ( func ) ;
2021-01-28 14:08:32 +00:00
if ( dataItem ! = null | | tries = = maxTries ) {
2020-04-08 09:43:53 +00:00
source . Cancel ( ) ;
2021-06-09 09:53:14 +00:00
}
2020-04-08 09:43:53 +00:00
tries + + ;
} ) ;
2021-01-28 14:08:32 +00:00
if ( dataItem = = null ) {
2020-04-08 09:43:53 +00:00
_logger . LogError ( "dataItem not found" ) ;
return null ;
}
_logger . LogInformation ( $"Found {containsName} item" ) ;
return dataItem ;
}
2020-08-19 11:40:42 +00:00
2021-01-28 14:08:32 +00:00
public async Task < Item > RunBofekTask ( Item cropfieldItem ) {
var taskmapRequest = new TaskRequest { TaskType = BOFEK_TASK } ;
2020-08-19 11:40:42 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2020-08-19 11:40:42 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on retreiving BOFEK data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-01-28 14:08:32 +00:00
if ( itemTask . State = = ItemTaskState . Error ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
//the BOFEK data is a child of the cropfield
var itemName = "bofek" ;
var bofekItem = await FindChildItemAsync ( cropfieldItem . Code ,
SHAPE_PROCESSED_ITEMTYPE , itemName ) ;
2021-01-28 14:08:32 +00:00
if ( bofekItem = = null ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( "Could not find the BOFEK data as a child item under the cropfield" ) ;
return null ;
}
return bofekItem ;
}
2023-03-31 09:02:06 +00:00
public async Task < Item > RunKPITask ( Item cropfieldItem ) // dit is dus nieuw om de KPI task te runnen
{
2023-04-06 14:11:37 +00:00
var taskmapRequest = new TaskRequest { TaskType = KPI_TASK } ; //hier KPI request van maken
taskmapRequest . attributes [ "processAggregateKpi" ] = "false" ; // zo de properties meegeven?, moet dit niet bij de KPIinput?
taskmapRequest . attributes [ "year" ] = "2022" ;
2023-03-31 09:02:06 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on retreiving KPI data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
if ( itemTask . State = = ItemTaskState . Error )
{
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
//hier nog definieren waar in de hierarchie een KPI item is?
2023-04-06 14:11:37 +00:00
//the kpi data is a child of the cropfield --> is dit wel zo?
2023-04-03 11:03:10 +00:00
var itemName = "kpi" ;
2023-03-31 09:13:51 +00:00
var KPIItem = await FindChildItemAsync ( cropfieldItem . Code ,
2023-04-03 11:03:10 +00:00
CROPFIELD_ITEMTYPE , itemName ) ; //hier moet ik dus verwijzen naar waar het KPIItem zit? ik gok dat het een cropfield item type is.-> of onderdeel van een croppingscheme? net toegevoegd.
2023-03-31 09:13:51 +00:00
if ( KPIItem = = null )
{
2023-04-03 11:03:10 +00:00
_logger . LogError ( "could not find the KPI data as a child item under the cropfield" ) ;
2023-03-31 09:13:51 +00:00
return null ;
}
2023-03-31 09:02:06 +00:00
2023-03-31 09:13:51 +00:00
return KPIItem ;
2023-03-31 09:02:06 +00:00
}
2021-01-28 14:08:32 +00:00
public async Task < Item > RunAhnTask ( Item cropfieldItem ) {
var taskmapRequest = new TaskRequest { TaskType = AHN_TASK } ;
2020-08-19 11:40:42 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2020-08-19 11:40:42 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on retreiving AHN data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-01-28 14:08:32 +00:00
if ( itemTask . State = = ItemTaskState . Error ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
//the AHN data is a child of the cropfield
var itemName = "ahn" ;
var ahnItem = await FindChildItemAsync ( cropfieldItem . Code ,
GEOTIFF_PROCESSED_ITEMTYPE , itemName ) ;
2021-01-28 14:08:32 +00:00
if ( ahnItem = = null ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( "Could not find the AHN data as a child item under the cropfield" ) ;
return null ;
}
return ahnItem ;
}
2021-01-28 14:08:32 +00:00
public async Task < Item > RunShadowTask ( Item cropfieldItem ) {
var taskmapRequest = new TaskRequest { TaskType = SHADOW_TASK } ;
2020-08-19 11:40:42 +00:00
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2020-08-19 11:40:42 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on calculation shadow data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-01-28 14:08:32 +00:00
if ( itemTask . State = = ItemTaskState . Error ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( $"Something went wrong with task execution: {itemTask.Message}" ) ;
return null ;
}
//the shadow data is a child of the cropfield
var itemName = "shadow" ;
var shadowItem = await FindChildItemAsync ( cropfieldItem . Code ,
GEOTIFF_PROCESSED_ITEMTYPE , itemName ) ;
2021-01-28 14:08:32 +00:00
if ( shadowItem = = null ) {
2020-08-19 11:40:42 +00:00
_logger . LogError ( "Could not find the shadow data as a child item under the cropfield" ) ;
return null ;
}
return shadowItem ;
}
2020-12-11 13:02:01 +00:00
2021-01-28 14:08:32 +00:00
public async Task < string > RunSatelliteTask ( Item cropfieldItem ) {
2020-12-11 13:02:01 +00:00
_logger . LogInformation ( "Gathering satellite information for cropfield, this might take a while!" ) ;
var taskmapRequest = new TaskRequest { TaskType = SATELLITE_TASK } ;
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
2021-01-28 14:08:32 +00:00
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
2020-12-11 13:02:01 +00:00
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on satellite data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
2021-01-28 14:08:32 +00:00
2020-12-11 13:02:01 +00:00
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
2021-01-28 14:08:32 +00:00
if ( itemTask . State = = ItemTaskState . Error ) {
2020-12-11 13:02:01 +00:00
_logger . LogError ( $"Something went wrong when trying to process satellite data; {itemTask.Message}" ) ;
}
return itemTask . Code ;
}
2021-05-26 08:16:29 +00:00
public async Task < Item > FindSatelliteItem ( Item cropfieldItem , string satelliteTaskCode ) {
2020-12-11 13:02:01 +00:00
var taskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , satelliteTaskCode ) ;
var temporalItem = await FindChildItemAsync ( cropfieldItem . Code , TEMPORAL_ITEMTYPE ,
"Cropfield Satellite items" , item = > item . SourceTask = = SATELLITE_TASK & &
taskStatus . Finished > = item . Created & &
taskStatus . Finished < = item . Created . Value . AddHours ( 1 ) ) ;
2021-01-28 14:08:32 +00:00
if ( temporalItem = = null ) {
2020-12-11 13:02:01 +00:00
_logger . LogError ( "Temporal item not found" ) ;
}
var satelliteTiffs = await _farmmapsApiService . GetItemChildrenAsync ( temporalItem . Code ) ;
2021-05-12 11:05:17 +00:00
2021-05-26 08:16:29 +00:00
_logger . LogInformation ( "Available satellite images:" ) ;
var count = 0 ;
TimeSpan . FromSeconds ( 0.5 ) ;
foreach ( var item in satelliteTiffs ) {
2021-05-12 11:05:17 +00:00
2021-05-26 08:16:29 +00:00
Console . WriteLine ( $"Satellite image #{count}: {item.DataDate}" ) ;
count + + ;
2020-12-11 13:02:01 +00:00
}
2021-01-28 14:08:32 +00:00
2021-05-26 08:16:29 +00:00
_logger . LogInformation ( "Enter satellite image number for NBS application" ) ;
int element = Int32 . Parse ( Console . ReadLine ( ) ) ;
var selectedSatelliteItem = satelliteTiffs [ element ] ;
2020-12-11 13:02:01 +00:00
2021-05-26 08:16:29 +00:00
if ( selectedSatelliteItem = = null )
{
2020-12-11 13:02:01 +00:00
_logger . LogError ( "Satellite item not found" ) ;
}
2021-05-26 08:16:29 +00:00
return selectedSatelliteItem ;
2020-12-11 13:02:01 +00:00
}
2021-05-26 08:16:29 +00:00
public async Task < List < Item > > FindSatelliteItems ( Item cropfieldItem , string satelliteTaskCode )
2021-05-18 16:19:28 +00:00
{
var taskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , satelliteTaskCode ) ;
2021-05-26 08:16:29 +00:00
if ( taskStatus . State = = ItemTaskState . Error )
2021-05-18 16:19:28 +00:00
{
2021-05-26 08:16:29 +00:00
_logger . LogWarning ( taskStatus . Message ) ;
return null ;
}
else
{
// find satellite data geotiffs
var temporalItem = await FindChildItemAsync ( cropfieldItem . Code , TEMPORAL_ITEMTYPE ,
"Cropfield Satellite items" , item = > item . SourceTask = = SATELLITE_TASK & &
taskStatus . Finished > = item . Created & &
taskStatus . Finished < = item . Created . Value . AddHours ( 1 ) ) ;
if ( temporalItem = = null )
{
_logger . LogWarning ( "Temporal item not found" ) ;
return null ;
}
else
{
var satelliteTiffs = await _farmmapsApiService . GetItemChildrenAsync ( temporalItem . Code ) ;
return satelliteTiffs ;
}
2021-05-18 16:19:28 +00:00
}
2021-05-26 08:16:29 +00:00
}
public async Task < string > DownloadSatelliteStats ( List < Item > satelliteTiffs , string fieldName = null , List < string > satelliteBands = null , string downloadFolder = null )
{
2021-05-18 16:19:28 +00:00
2021-05-26 08:16:29 +00:00
string satelliteDataStatisticsFile = Path . Combine ( downloadFolder , $"satelliteStats_{fieldName}.csv" ) ;
File . Delete ( satelliteDataStatisticsFile ) ; // Delete the SatelliteFile file if exists
string headerLineStats = $"FieldName,satelliteDate,satelliteBand,max,min,mean,mode,median,stddev,minPlus,curtosis,maxMinus,skewness,variance,populationCount,variationCoefficient,confidenceIntervalLow, confidenceIntervalHigh,confidenceIntervalErrorMargin" + Environment . NewLine ;
File . AppendAllText ( satelliteDataStatisticsFile , headerLineStats ) ;
2021-05-28 15:25:31 +00:00
foreach ( var satelliteTiff in satelliteTiffs )
{
List < JToken > layers = satelliteTiff . Data [ "layers" ] . Children ( ) . ToList ( ) ;
foreach ( JToken layer in layers )
2021-05-26 08:16:29 +00:00
{
2021-05-28 15:25:31 +00:00
DateTime satelliteImageDate = ( DateTime ) satelliteTiff . DataDate ;
string satelliteBand = layer [ "name" ] . ToString ( ) ;
if ( satelliteBands . Contains ( satelliteBand ) )
2021-05-26 08:16:29 +00:00
{
2021-05-28 15:25:31 +00:00
JToken satelliteStatisticsJtoken = layer [ "renderer" ] [ "band" ] [ "statistics" ] ;
2021-05-26 08:16:29 +00:00
if ( satelliteStatisticsJtoken = = null )
{
2021-05-28 15:25:31 +00:00
_logger . LogWarning ( $"{satelliteImageDate.ToString(" yyyy - MM - dd ")} no statistics found for satelliteBand '{satelliteBand}'" ) ;
2021-05-26 08:16:29 +00:00
}
else
{
SatelliteStatistics satelliteStatistics = satelliteStatisticsJtoken . ToObject < SatelliteStatistics > ( ) ;
satelliteStatistics . fieldName = fieldName ;
satelliteStatistics . satelliteDate = satelliteImageDate ;
2021-05-28 15:25:31 +00:00
satelliteStatistics . satelliteBand = satelliteBand ;
2021-05-26 08:16:29 +00:00
File . AppendAllText ( satelliteDataStatisticsFile , $"" +
$"{satelliteStatistics.fieldName}," +
$"{satelliteStatistics.satelliteDate.ToString(" yyyy - MM - dd ")}," +
$"{satelliteStatistics.satelliteBand}," +
$"{satelliteStatistics.max}," +
$"{satelliteStatistics.min}," +
$"{satelliteStatistics.mean}," +
$"{satelliteStatistics.mode}," +
$"{satelliteStatistics.median}," +
$"{satelliteStatistics.stddev}," +
$"{satelliteStatistics.minPlus}," +
$"{satelliteStatistics.curtosis}," +
$"{satelliteStatistics.maxMinus}," +
$"{satelliteStatistics.skewness}," +
$"{satelliteStatistics.variance}," +
$"{satelliteStatistics.populationCount}," +
$"{satelliteStatistics.variationCoefficient}," +
$"{satelliteStatistics.confidenceIntervalLow}," +
$"{satelliteStatistics.confidenceIntervalHigh}," +
$"{satelliteStatistics.confidenceIntervalErrorMargin}" +
Environment . NewLine ) ;
}
}
}
2021-05-28 15:25:31 +00:00
}
2021-05-26 08:16:29 +00:00
return satelliteDataStatisticsFile ;
}
public async Task < List < SatelliteStatistics > > ListSatelliteStatistics ( Item satelliteTiff , List < string > satelliteBands = null , string fieldName = null )
{
SatelliteStatistics satelliteStatistics ;
List < SatelliteStatistics > listSatelliteStatistics = new List < SatelliteStatistics > ( ) ;
2021-05-28 15:25:31 +00:00
List < JToken > layers = satelliteTiff . Data [ "layers" ] . Children ( ) . ToList ( ) ;
foreach ( JToken layer in layers )
2021-05-26 08:16:29 +00:00
{
2021-05-28 15:25:31 +00:00
DateTime satelliteImageDate = ( DateTime ) satelliteTiff . DataDate ;
string satelliteBand = layer [ "name" ] . ToString ( ) ;
//_logger.LogInformation($"Date '{satelliteImageDate.ToString("yyyy-MM-dd")}': satelliteBand: {satelliteBand}");
if ( satelliteBands . Contains ( satelliteBand ) )
2021-05-26 08:16:29 +00:00
{
2021-05-28 15:25:31 +00:00
JToken satelliteStatisticsJtoken = layer [ "renderer" ] [ "band" ] [ "statistics" ] ;
if ( satelliteStatisticsJtoken = = null )
{
_logger . LogWarning ( $"{satelliteImageDate.ToString(" yyyy - MM - dd ")} no statistics found for satelliteBand '{satelliteBand}'" ) ;
//Console.WriteLine($"Available data: {item.Data}");
}
else
{
//_logger.LogInformation($"Adding satelliteStatistics to listSatelliteStatistics");
satelliteStatistics = satelliteStatisticsJtoken . ToObject < SatelliteStatistics > ( ) ;
satelliteStatistics . fieldName = fieldName ;
satelliteStatistics . satelliteDate = satelliteImageDate ;
satelliteStatistics . satelliteBand = satelliteBand ;
listSatelliteStatistics . Add ( satelliteStatistics ) ;
}
2021-05-26 08:16:29 +00:00
}
2021-05-28 15:25:31 +00:00
//else
//{
// _logger.LogInformation($"this satelliteBand is not in your list satelliteBands");
//}
2021-05-26 08:16:29 +00:00
}
return listSatelliteStatistics ;
2021-05-18 16:19:28 +00:00
}
2021-05-26 08:16:29 +00:00
2021-01-28 14:08:32 +00:00
//VanDerSat
public async Task < string > RunVanDerSatTask ( Item cropfieldItem ) {
_logger . LogInformation ( "Gathering VanDerSat information for cropfield, this might take a while!" ) ;
var taskmapRequest = new TaskRequest { TaskType = VANDERSAT_TASK } ;
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on VanDerSat data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
if ( itemTask . State = = ItemTaskState . Error ) {
_logger . LogError ( $"Something went wrong when trying to process VanDerSat data; {itemTask.Message}" ) ;
}
return itemTask . Code ;
}
public async Task < Item > FindVanDerSatItem ( Item cropfieldItem , string VanDerSatTaskCode , string FieldName , bool StoreStatistics ) {
var taskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , VanDerSatTaskCode ) ;
2020-12-11 13:02:01 +00:00
2021-01-28 14:08:32 +00:00
// find VanDerSat data temporal
var temporalItem = await FindChildItemAsync ( cropfieldItem . Code , TEMPORAL_ITEMTYPE , "Van der Sat" ) ;
if ( temporalItem = = null ) {
_logger . LogError ( "Temporal item not found" ) ;
}
2020-12-11 13:02:01 +00:00
2021-01-28 14:08:32 +00:00
var VanDerSatiffs = await _farmmapsApiService . GetItemChildrenAsync ( temporalItem . Code ) ;
_logger . LogInformation ( "Available VanDerSat images:" ) ;
var count = 0 ;
TimeSpan . FromSeconds ( 0.5 ) ;
foreach ( var item in VanDerSatiffs ) {
//Console.WriteLine($"Van der Sat image #{count}: {item.DataDate}");
//if (count == 0 ) {
// Console.WriteLine($"vandersat image #{count}: {item.Data}");
//}
if ( StoreStatistics = = true ) {
var VanDerSatBand = item . Data [ "layers" ] [ 0 ] [ "name" ] ;
var VanderSatFile = $"C:\\Akkerweb\\{FieldName}_{VanDerSatBand}.csv" ;
var NewLineField = $"Field,Date,Mean,Min,Max,Standard deviation, ConfidenceInterval low, ConfidenceInterval high" + Environment . NewLine ;
if ( count = = 0 ) {
File . AppendAllText ( VanderSatFile , NewLineField ) ;
var numbervandersat = VanDerSatiffs . Count ;
Console . WriteLine ( $"{numbervandersat} Van der Sat images found" ) ;
}
var VanderSatStatistics = item . Data [ "layers" ] [ 0 ] [ "renderer" ] [ "band" ] [ "statistics" ] ;
var VanDerSatImageDate = ( DateTime ) item . DataDate ;
var VanderSatDate = VanDerSatImageDate . ToString ( "yyyy-MM-dd" ) ;
var NewLineDate = $"\" date \ ":{VanderSatDate}" + Environment . NewLine ;
if ( VanderSatStatistics = = null ) {
Console . WriteLine ( $"{VanderSatDate} no statistics found" ) ;
//Console.WriteLine($"Available data: {item.Data}");
} else {
File . AppendAllText ( VanderSatFile , $"{FieldName},{VanderSatDate},{VanderSatStatistics[" mean "]},{VanderSatStatistics[" min "]},{VanderSatStatistics[" max "]},{VanderSatStatistics[" stddev "]},{VanderSatStatistics[" confidenceIntervalLow "]},{VanderSatStatistics[" confidenceIntervalHigh "]}" + Environment . NewLine ) ;
}
}
count + + ;
}
//_logger.LogInformation("Enter VanDerSat image number");
//int element = Int32.Parse(Console.ReadLine());
int element = 0 ;
var selectedVanDerSatItem = VanDerSatiffs [ element ] ;
if ( selectedVanDerSatItem = = null ) {
_logger . LogError ( "VanDerSat item not found" ) ;
}
return selectedVanDerSatItem ;
}
2021-04-13 08:54:04 +00:00
public async Task < string > RunWatBalTask ( Item cropfieldItem ) {
_logger . LogInformation ( "Gathering WatBal information for cropfield, this might take a while!" ) ;
var taskmapRequest = new TaskRequest { TaskType = WATBAL_TASK } ;
string itemTaskCode = await _farmmapsApiService . QueueTaskAsync ( cropfieldItem . Code , taskmapRequest ) ;
await PollTask ( TimeSpan . FromSeconds ( 5 ) , async ( tokenSource ) = > {
var itemTaskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
_logger . LogInformation ( $"Waiting on VanDerSat data; status: {itemTaskStatus.State}" ) ;
if ( itemTaskStatus . IsFinished )
tokenSource . Cancel ( ) ;
} ) ;
var itemTask = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , itemTaskCode ) ;
if ( itemTask . State = = ItemTaskState . Error ) {
_logger . LogError ( $"Something went wrong when trying to process WatBal data; {itemTask.Message}" ) ;
}
return itemTask . Code ;
}
2021-01-28 14:08:32 +00:00
public async Task < Item > FindWatBalItem ( Item cropfieldItem , string WatBalTaskCode , string FieldName , bool StoreStatistics ) {
var taskStatus = await _farmmapsApiService . GetTaskStatusAsync ( cropfieldItem . Code , WatBalTaskCode ) ;
// find WatBal data temporal
2021-04-13 08:54:04 +00:00
var temporalItem = await FindChildItemAsync ( cropfieldItem . Code , TEMPORAL_ITEMTYPE , "Watbal" ,
item = > item . SourceTask = = WATBAL_TASK & & taskStatus . Finished > = item . Created & & taskStatus . Finished < = item . Created . Value . AddHours ( 1 ) ) ;
2021-01-28 14:08:32 +00:00
if ( temporalItem = = null ) {
_logger . LogError ( "Temporal item not found" ) ;
}
var WatBalData = await _farmmapsApiService . GetItemChildrenAsync ( temporalItem . Code ) ;
_logger . LogInformation ( "Available WatBal Data:" ) ;
var count = 0 ;
TimeSpan . FromSeconds ( 0.5 ) ;
foreach ( var item in WatBalData ) {
Console . WriteLine ( $"WatBal data #{count}: {item.DataDate}" ) ;
if ( count = = 0 ) {
Console . WriteLine ( $"WatBalData #{count}: {item.Data}" ) ;
}
count + + ;
}
int element = 0 ;
var selectedWatBalItem = WatBalData [ element ] ;
if ( selectedWatBalItem = = null ) {
_logger . LogError ( "WatBal item not found" ) ;
}
return selectedWatBalItem ;
}
2020-04-08 09:43:53 +00:00
}
}