diff --git a/ISOv4Plugin/ExtensionMethods/ExtensionMethods.cs b/ISOv4Plugin/ExtensionMethods/ExtensionMethods.cs index 66a5615..0949024 100644 --- a/ISOv4Plugin/ExtensionMethods/ExtensionMethods.cs +++ b/ISOv4Plugin/ExtensionMethods/ExtensionMethods.cs @@ -95,6 +95,13 @@ public static bool ReverseEquals(this string s1, string s2) return true; } + /// + /// Matches NumericRepresentation by code, accounting for null representation code + /// + public static bool ContainsCode(this ApplicationDataModel.Representations.Representation representation, string code) + { + return representation?.Code != null && representation.Code.Contains(code); + } /// /// Looks up unit, converts and loads representation diff --git a/ISOv4Plugin/Mappers/PartfieldMapper.cs b/ISOv4Plugin/Mappers/PartfieldMapper.cs index 8887a59..ffa211a 100644 --- a/ISOv4Plugin/Mappers/PartfieldMapper.cs +++ b/ISOv4Plugin/Mappers/PartfieldMapper.cs @@ -90,11 +90,16 @@ public ISOPartfield ExportField(Field adaptField) //Boundary PolygonMapper polygonMapper = new PolygonMapper(TaskDataMapper); - FieldBoundary boundary = DataModel.Catalog.FieldBoundaries.SingleOrDefault(b => b.FieldId == adaptField.Id.ReferenceId); + + var boundaries = DataModel.Catalog.FieldBoundaries.Where(b => b.FieldId == adaptField.Id.ReferenceId).ToList(); + var boundary = boundaries.FirstOrDefault(b=> b.Id.ReferenceId == adaptField.ActiveBoundaryId) ?? boundaries.FirstOrDefault(); if (boundary != null) { - IEnumerable isoPolygons = polygonMapper.ExportMultipolygon(boundary.SpatialData, ISOEnumerations.ISOPolygonType.PartfieldBoundary); - isoField.Polygons.AddRange(isoPolygons); + if (boundary.SpatialData != null) + { + IEnumerable isoPolygons = polygonMapper.ExportMultipolygon(boundary.SpatialData, ISOEnumerations.ISOPolygonType.PartfieldBoundary); + isoField.Polygons.AddRange(isoPolygons); + } } //Guidance diff --git a/ISOv4Plugin/Mappers/TimeLogMapper.cs b/ISOv4Plugin/Mappers/TimeLogMapper.cs index f0eccf2..13a39bb 100644 --- a/ISOv4Plugin/Mappers/TimeLogMapper.cs +++ b/ISOv4Plugin/Mappers/TimeLogMapper.cs @@ -33,6 +33,8 @@ internal TimeLogMapper(TaskDataMapper taskDataMapper) : base(taskDataMapper, "TL { } + private static readonly DateTime _firstDayOf1980 = new DateTime(1980, 1, 1, 0, 0, 0, DateTimeKind.Local); + #region Export private Dictionary _dataLogValueOrdersByWorkingDataID; public IEnumerable ExportTimeLogs(IEnumerable operationDatas, string dataPath) @@ -150,7 +152,6 @@ private class BinaryWriter { // ATTENTION: CoordinateMultiplier and ZMultiplier also exist in Import\SpatialRecordMapper.cs! private const double CoordinateMultiplier = 0.0000001; private const double ZMultiplier = 0.001; // In ISO the PositionUp value is specified in mm. - private readonly DateTime _januaryFirst1980 = new DateTime(1980, 1, 1); private readonly IEnumeratedValueMapper _enumeratedValueMapper; private readonly INumericValueMapper _numericValueMapper; @@ -193,7 +194,7 @@ private void WriteSpatialRecord(SpatialRecord spatialRecord, List m var millisecondsSinceMidnight = (UInt32)new TimeSpan(0, spatialRecord.Timestamp.Hour, spatialRecord.Timestamp.Minute, spatialRecord.Timestamp.Second, spatialRecord.Timestamp.Millisecond).TotalMilliseconds; memoryStream.Write(BitConverter.GetBytes(millisecondsSinceMidnight), 0, 4); - var daysSinceJanOne1980 = (UInt16)(spatialRecord.Timestamp - (_januaryFirst1980)).TotalDays; + var daysSinceJanOne1980 = (UInt16)(spatialRecord.Timestamp - _firstDayOf1980).TotalDays; memoryStream.Write(BitConverter.GetBytes(daysSinceJanOne1980), 0, 2); //Position @@ -409,8 +410,7 @@ protected IEnumerable ImportTimeLog(ISOTask loggedTask, ISOTimeLo operationData.GetDeviceElementUses = x => operationData.DeviceElementUses.Where(s => s.Depth == x).ToList(); operationData.PrescriptionId = prescriptionID; operationData.OperationType = GetOperationTypeFromProductCategory(productIDs) ?? - GetOperationTypeFromWorkingDatas(workingDatas) ?? - GetOperationTypeFromLoggingDevices(time); + OverrideOperationTypeFromWorkingDatas(GetOperationTypeFromLoggingDevices(time), workingDatas); operationData.ProductIds = productIDs; if (!useDeferredExecution) { @@ -428,22 +428,25 @@ protected IEnumerable ImportTimeLog(ISOTask loggedTask, ISOTimeLo return null; } - private OperationTypeEnum? GetOperationTypeFromWorkingDatas(List workingDatas) + private OperationTypeEnum OverrideOperationTypeFromWorkingDatas(OperationTypeEnum deviceOperationType, List workingDatas) { //Harvest/ForageHarvest omitted intentionally to be determined from machine type vs. working data - if (workingDatas.Any(w => w.Representation.Code.Contains("Seed"))) + if (workingDatas.Any(w => w.Representation.ContainsCode("Seed"))) { return OperationTypeEnum.SowingAndPlanting; } - else if (workingDatas.Any(w => w.Representation.Code.Contains("Tillage"))) + else if (workingDatas.Any(w => w.Representation.ContainsCode("Tillage"))) { return OperationTypeEnum.Tillage; } - if (workingDatas.Any(w => w.Representation.Code.Contains("AppRate"))) + if (workingDatas.Any(w => w.Representation.ContainsCode("AppRate"))) { - return OperationTypeEnum.Unknown; //We can't differentiate CropProtection from Fertilizing, but prefer unkonwn to letting implement type set to SowingAndPlanting + if (deviceOperationType != OperationTypeEnum.Fertilizing && deviceOperationType != OperationTypeEnum.CropProtection) + { + return OperationTypeEnum.Unknown; //We can't differentiate CropProtection from Fertilizing, but prefer unknown to letting implement type set to SowingAndPlanting + } } - return null; + return deviceOperationType; } private List> SplitElementsByProductProperties(Dictionary> productAllocations, HashSet loggedDeviceElementIds, ISODevice dvc) @@ -682,9 +685,6 @@ private void AddProductAllocationsForDeviceElement(Dictionary t.ClientNAMEMachineType >= 2 && t.ClientNAMEMachineType <= 11); + DeviceOperationType deviceType = representedTypes.FirstOrDefault(t => t.ClientNAMEMachineType >= 2 && t.ClientNAMEMachineType <= 11 && + t.OperationType != OperationTypeEnum.Unknown); + if (deviceType != null) { //2-11 represent known types of operations @@ -752,8 +754,6 @@ internal static Dictionary ReadImplementGeometryValues(IEnumerable ReadImplementGeometryValues(string filePath, ISOTime templateTime, IEnumerable desiredDLVIndices, int version, IList errors) { Dictionary output = new Dictionary();