diff --git a/FarmmapsApiSamples.sln b/FarmmapsApiSamples.sln
index e44d74d..49b0a34 100644
--- a/FarmmapsApiSamples.sln
+++ b/FarmmapsApiSamples.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30320.27
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33122.133
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FarmmapsNbs", "FarmmapsNbs\FarmmapsNbs.csproj", "{E08EF7E9-F09E-42D8-825C-164E458C78F4}"
EndProject
@@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Secrets", "Secrets\Secrets.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FarmmapsCleanUp", "FarmmapsCleanUp\FarmmapsCleanUp.csproj", "{5E4387F9-5953-4A9B-BCA5-DF3964EED3CB}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FarmmapsKPI", "FarmmapsKPI\FarmmapsKPI.csproj", "{14575235-9867-4CE5-A22F-3F9FE002FF42}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -81,6 +83,10 @@ Global
{5E4387F9-5953-4A9B-BCA5-DF3964EED3CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E4387F9-5953-4A9B-BCA5-DF3964EED3CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E4387F9-5953-4A9B-BCA5-DF3964EED3CB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {14575235-9867-4CE5-A22F-3F9FE002FF42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {14575235-9867-4CE5-A22F-3F9FE002FF42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {14575235-9867-4CE5-A22F-3F9FE002FF42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {14575235-9867-4CE5-A22F-3F9FE002FF42}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/FarmmapsKPI/FarmmapsKPI.csproj b/FarmmapsKPI/FarmmapsKPI.csproj
new file mode 100644
index 0000000..bdd33b9
--- /dev/null
+++ b/FarmmapsKPI/FarmmapsKPI.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git a/FarmmapsKPI/KPIApplication.cs b/FarmmapsKPI/KPIApplication.cs
new file mode 100644
index 0000000..0e8bac8
--- /dev/null
+++ b/FarmmapsKPI/KPIApplication.cs
@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Threading.Tasks;
+using FarmmapsApi;
+using FarmmapsApi.Models;
+using FarmmapsApi.Services;
+using FarmmapsKPI.Models;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using static FarmmapsApiSamples.Constants;
+
+namespace FarmmapsKPI
+{
+ public class KPIApplication : IApplication
+ {
+ //private const string DownloadFolder = "Downloads";
+ private const string SettingsFile = "settings.json";
+
+ private readonly ILogger _logger;
+ private readonly FarmmapsApiService _farmmapsApiService;
+ private readonly KPIService _dataDownloadService;
+ private readonly GeneralService _generalService;
+
+ private Settings _settings;
+
+ public KPIApplication(ILogger logger, FarmmapsApiService farmmapsApiService,
+ GeneralService generalService, KPIService dataDownloadService)
+ {
+ _logger = logger;
+ _farmmapsApiService = farmmapsApiService;
+ _generalService = generalService;
+ _dataDownloadService = dataDownloadService;
+ }
+
+ public async Task RunAsync()
+ {
+ var fieldsInputJson = File.ReadAllText("KPIInput.json");
+
+ List fieldsInputs = JsonConvert.DeserializeObject>(fieldsInputJson);
+
+ // !! 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 fieldsInputs)
+ {
+ try
+ {
+ await Process(roots, input);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex.Message);
+ }
+ }
+ }
+
+ private async Task Process(List roots, KPIInput input)
+ {
+ string downloadFolder = input.DownloadFolder;
+ if (string.IsNullOrEmpty(downloadFolder)) {
+ downloadFolder = "Downloads";
+ }
+ if (!Directory.Exists(downloadFolder))
+ Directory.CreateDirectory(downloadFolder);
+
+ // !!specify if you are using an already created cropfield:
+ bool useCreatedCropfield = input.UseCreatedCropfield;
+ var cropYear = input.CropYear;
+ var fieldName = input.fieldName;
+ //bool storeSatelliteStatistics = input.StoreSatelliteStatisticsSingleImage;
+ //bool storeSatelliteStatisticsCropYear = input.StoreSatelliteStatisticsCropYear;
+ //List SatelliteBands = new List(1) { input.SatelliteBand };
+ //string headerLineStats = $"FieldName,satelliteDate,satelliteBand,max,min,mean,mode,median,stddev,minPlus,curtosis,maxMinus,skewness,variance,populationCount,variationCoefficient,confidenceIntervalLow, confidenceIntervalHigh,confidenceIntervalErrorMargin" + Environment.NewLine;
+
+
+ string settingsfile = $"Settings_{fieldName}.json";
+
+ LoadSettings(settingsfile);
+
+ var uploadedRoot = roots.SingleOrDefault(r => r.Name == "USER_IN");
+ if (uploadedRoot == null)
+ {
+ _logger.LogError("Could not find a needed root item");
+ return;
+ }
+
+ var myDriveRoot = roots.SingleOrDefault(r => r.Name == "USER_FILES");
+ 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,
+ $"DataCropfield {input.OutputFileName}", cropYear, 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);
+ }
+
+ //Get croprecordings
+ if (input.GetCropRecordings)
+ {
+ var crprecItem = input.CrprecItem;
+ _logger.LogInformation($"Trying to get crop recordings of croprecording: {crprecItem}");
+
+ var cropRec = await _farmmapsApiService.GetItemChildrenAsync(crprecItem, CROPREC_ITEMTYPE);
+ if (cropRec == null)
+ {
+ _logger.LogError("Something went wrong while obtaining the croprecordings");
+ return;
+ }
+
+ var cropRecPath = Path.Combine(downloadFolder, $"croprecordings_{crprecItem}.json");
+ _logger.LogInformation($"Found {cropRec.Count} crop recordings");
+ var count = 0;
+ await Task.Delay(500);
+ foreach (var item in cropRec)
+ {
+ Console.WriteLine($"Crop recording #{count}: {item.Name}");
+ File.AppendAllText(cropRecPath, item.Data +Environment.NewLine);
+ count++;
+ }
+ _logger.LogInformation($"Downloaded file {cropRecPath}");
+ }
+ else
+ {
+ //todo set croprecordings from file
+ }
+
+ // Get KPI data
+
+ //_logger.LogInformation("Calculate KPI map for field");
+ //var KPIItem = await _generalService.RunKPITask(cropfieldItem);
+ var KPIItem = null;
+ if (KPIItem == null)
+ {
+ _logger.LogError("Something went wrong while obtaining the KPI map");
+ return;
+ }
+
+ //_logger.LogInformation("Downloading KPI map");
+ //await _farmmapsApiService.DownloadItemAsync(KPIItem.Code,
+ // Path.Combine(downloadFolder, $"{input.OutputFileName}_KPI.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);
+
+ }
+
+ }
+}
diff --git a/FarmmapsKPI/KPIInput.json b/FarmmapsKPI/KPIInput.json
new file mode 100644
index 0000000..84d35e8
--- /dev/null
+++ b/FarmmapsKPI/KPIInput.json
@@ -0,0 +1,34 @@
+[
+ {
+ "UseCreatedCropfield": false,
+ "outputFileName": "TestData",
+ "fieldName": "TestField",
+ "DownloadFolder": "Downloads", //"C:\\workdir\\groenmonitor\\", // "Downloads", -> if you just put "Downloads" the program will download to somewhere in ..\FarmMapsApiClient_WURtest\FarmmapsDataDownload\bin\Debug\netcoreapp3.1\Downloads\
+ "GetCropRecordings": true,
+ "CrprecItem": "...", //item code of de crop recording parrent - can be found by opening the crop recording page of a field.
+ "GetShadowData": false,
+ "GetSatelliteData": false,
+ "SatelliteBand": "wdvi", // "natural", "ndvi" or "wdvi"
+ "StoreSatelliteStatisticsSingleImage": false,
+ "StoreSatelliteStatisticsCropYear": false,
+ "GetVanDerSatData": false,
+ "StoreVanDerSatStatistics": false,
+ "CropYear": 2020,
+ "geometryJson": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [ 4.960707146896585, 52.800583669708487 ],
+ [ 4.960645975538824, 52.800470217610922 ],
+ [ 4.962140695752897, 52.799177147194797 ],
+ [ 4.967523821195745, 52.801502400041208 ],
+ [ 4.966336768950911, 52.802543735879809 ],
+ [ 4.961711880764330, 52.801009996856429 ],
+ [ 4.960707146896585, 52.800583669708487 ]
+ ]
+ ]
+ }
+ }
+
+
+]
\ No newline at end of file
diff --git a/FarmmapsKPI/KPIService.cs b/FarmmapsKPI/KPIService.cs
new file mode 100644
index 0000000..ce88acd
--- /dev/null
+++ b/FarmmapsKPI/KPIService.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
+using FarmmapsApi.Models;
+using FarmmapsApi.Services;
+using FarmmapsKPI.Models;
+using Microsoft.Extensions.Logging;
+using static FarmmapsApi.Extensions;
+using static FarmmapsApiSamples.Constants;
+
+namespace FarmmapsKPI
+{
+ public class KPIService
+ {
+ private readonly ILogger _logger;
+ private readonly FarmmapsApiService _farmmapsApiService;
+ private readonly GeneralService _generalService;
+
+ public KPIService(ILogger logger, FarmmapsApiService farmmapsApiService,
+ GeneralService generalService)
+ {
+ _logger = logger;
+ _farmmapsApiService = farmmapsApiService;
+ _generalService = generalService;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/FarmmapsKPI/Models/CropRecordings.cs b/FarmmapsKPI/Models/CropRecordings.cs
new file mode 100644
index 0000000..61e667f
--- /dev/null
+++ b/FarmmapsKPI/Models/CropRecordings.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FarmmapsKPI.Models
+{
+ internal class CropRecordings
+ {
+ }
+}
diff --git a/FarmmapsKPI/Models/KPIInput.cs b/FarmmapsKPI/Models/KPIInput.cs
new file mode 100644
index 0000000..63e5c68
--- /dev/null
+++ b/FarmmapsKPI/Models/KPIInput.cs
@@ -0,0 +1,28 @@
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace FarmmapsKPI.Models
+{
+ public class KPIInput
+ {
+ public bool UseCreatedCropfield { get; set; }
+ public string File { get; set; }
+ public string InputVariable { get; set; }
+ public string OutputFileName { get; set; }
+ public string DownloadFolder { get; set; }
+ public int CropYear { get; set; }
+ public JObject GeometryJson { get; set; }
+ public string InputLayerName { get; set; }
+ public string fieldName { get; set; }
+ public bool GetSatelliteData { get; set; }
+ public bool GetVanDerSatData { get; set; }
+ public string SatelliteBand { get; set; }
+ public bool StoreSatelliteStatisticsSingleImage { get; set; }
+ public bool StoreSatelliteStatisticsCropYear { get; set; }
+ public bool StoreVanDerSatStatistics { get; set; }
+ public bool GetShadowData { get; set; }
+ public bool GetCropRecordings { get; set; }
+ public string CrprecItem { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/FarmmapsKPI/Models/Settings.cs b/FarmmapsKPI/Models/Settings.cs
new file mode 100644
index 0000000..bd7ff29
--- /dev/null
+++ b/FarmmapsKPI/Models/Settings.cs
@@ -0,0 +1,11 @@
+namespace FarmmapsKPI
+{
+ public class Settings
+ {
+ public string CropfieldItemCode { get; set; }
+ //public string SatelliteTaskCode { get; set; }
+ //public string VanDerSatTaskCode { get; set; }
+ //public string WatBalTaskCode { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/FarmmapsKPI/Program.cs b/FarmmapsKPI/Program.cs
new file mode 100644
index 0000000..9e8e737
--- /dev/null
+++ b/FarmmapsKPI/Program.cs
@@ -0,0 +1,21 @@
+using System.Threading.Tasks;
+using FarmmapsApi;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace FarmmapsKPI
+{
+ class Program : FarmmapsProgram
+ {
+ private static async Task Main(string[] args)
+ {
+ await new Program().Start(args);
+ }
+
+ protected override void Configure(IServiceCollection serviceCollection)
+ {
+ serviceCollection.AddLogging()
+ .AddTransient();
+ }
+ }
+}