private void ExportDeviceProperty(ISODeviceElement deviceElement, NumericRepresentationValue representationValue, int objectID) { ISODeviceProperty dpt = new ISODeviceProperty(); dpt.ObjectID = (uint)objectID; switch (representationValue.Representation.Code) { case "0043": case "0046": dpt.DDI = representationValue.Representation.Code; dpt.Designator = "Width"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetInline": dpt.DDI = "0086"; dpt.Designator = "XOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetLateral": dpt.DDI = "0087"; dpt.Designator = "YOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; case "vrOffsetVertical": dpt.DDI = "0088"; dpt.Designator = "ZOffset"; dpt.Value = representationValue.AsIntViaMappedDDI(RepresentationMapper); break; } if (!string.IsNullOrEmpty(dpt.DDI)) { deviceElement.Device.DeviceProperties.Add(dpt); deviceElement.DeviceObjectReferences.Add(new ISODeviceObjectReference() { DeviceObjectId = (uint)objectID }); } }
public DeviceElementHierarchy(ISODeviceElement deviceElement, int depth, RepresentationMapper representationMapper, HashSet <int> crawledElements = null, DeviceElementHierarchy parent = null) { RepresentationMapper = representationMapper; //This Hashset will track that we don't build infinite hierarchies. //The plugin does not support peer control at this time. _crawledElements = crawledElements; if (_crawledElements == null) { _crawledElements = new HashSet <int>(); } if (_crawledElements.Add((int)deviceElement.DeviceElementObjectId)) { Type = deviceElement.DeviceElementType; DeviceElement = deviceElement; Depth = depth; Order = (int)deviceElement.DeviceElementNumber; //Using this number as analagous to this purpose. The ISO spec requires these numbers increment from left to right as in ADAPT. (See ISO11783-10:2015(E) B.3.2 Element number) //DeviceProperty assigned Widths & Offsets //DeviceProcessData assigned values will be assigned as the SectionMapper reads timelog data. //Width ISODeviceProperty widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0046"); if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0046"; } else { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0043"); if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0043"; } } //Offsets ISODeviceProperty xOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0086"); if (xOffsetProperty != null) { XOffset = xOffsetProperty.Value; } ISODeviceProperty yOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0087"); if (yOffsetProperty != null) { YOffset = yOffsetProperty.Value; } ISODeviceProperty zOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0088"); if (zOffsetProperty != null) { ZOffset = zOffsetProperty.Value; } //Children IEnumerable <ISODeviceElement> childDeviceElements = deviceElement.Device.DeviceElements.Where(det => det.ParentObjectId == deviceElement.DeviceElementObjectId);// && det.DeviceElementType == ISOEnumerations.ISODeviceElementType.Section); if (childDeviceElements.Any()) { int childDepth = depth + 1; Children = new List <DeviceElementHierarchy>(); foreach (ISODeviceElement det in childDeviceElements) { DeviceElementHierarchy child = new DeviceElementHierarchy(det, childDepth, representationMapper, _crawledElements, this); Children.Add(child); } } //Parent Parent = parent; } }
public DeviceHierarchyElement(ISODeviceElement deviceElement, int depth, RepresentationMapper representationMapper, bool mergeSingleBinsIntoBoom, Dictionary <string, List <string> > missingGeometryDefinitions, HashSet <int> crawledElements = null, DeviceHierarchyElement parent = null) { RepresentationMapper = representationMapper; MergedElements = new List <ISODeviceElement>(); //This Hashset will track that we don't build infinite hierarchies. //The plugin does not support peer control at this time. _crawledElements = crawledElements; if (_crawledElements == null) { _crawledElements = new HashSet <int>(); } if (_crawledElements.Add((int)deviceElement.DeviceElementObjectId)) { Type = deviceElement.DeviceElementType; DeviceElement = deviceElement; Depth = depth; Order = (int)deviceElement.DeviceElementNumber; //Using this number as analagous to this purpose. The ISO spec requires these numbers increment from left to right as in ADAPT. (See ISO11783-10:2015(E) B.3.2 Element number) //DeviceProperty assigned Widths & Offsets //DeviceProcessData assigned values will be assigned as the SectionMapper reads timelog data. //Width ISODeviceProperty widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0046"); //Max width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0046"; } else { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0044"); //Default working width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0044"; } if (widthProperty == null) { widthProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0043"); //Actual working width if (widthProperty != null) { Width = widthProperty.Value; WidthDDI = "0043"; } } } if (Width == null) { //We are missing a width DPT. Log it (0046 as a substitute here for any valid width) for possible retrieval from the TLG binaries. AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0046"); } //Offsets ISODeviceProperty xOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0086"); if (xOffsetProperty != null) { XOffset = xOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0086"); } ISODeviceProperty yOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0087"); if (yOffsetProperty != null) { YOffset = yOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0087"); } ISODeviceProperty zOffsetProperty = deviceElement.DeviceProperties.FirstOrDefault(dpt => dpt.DDI == "0088"); if (zOffsetProperty != null) { ZOffset = zOffsetProperty.Value; } else { AddMissingGeometryDefinition(missingGeometryDefinitions, deviceElement.DeviceElementId, "0088"); } //Children IEnumerable <ISODeviceElement> childDeviceElements = deviceElement.Device.DeviceElements.Where(det => det.ParentObjectId == deviceElement.DeviceElementObjectId && det.ParentObjectId != det.DeviceElementObjectId); //Do not create children for an element classified as its own parent if (childDeviceElements.Any()) { int childDepth = depth + 1; Children = new List <DeviceHierarchyElement>(); foreach (ISODeviceElement childDeviceElement in childDeviceElements) { //If there is a single bin child of the boom (usually alongside sections), //we can logically combine the bin and boom to have a clean hierarchy //where sections are the direct children of the element containing the rates. //We currently use an import property (MergeSingleBinsIntoBoom) to enable this functionality. //Note that if there are any duplicate DDIs on both the Bin and Boom (non-standard per Annex F.3), //the FirstOrDefault() logic in the setter methods in the SpatialRecordMapper will prefer the Boom and suppress the Bin data. if (mergeSingleBinsIntoBoom && (DeviceElement.DeviceElementType == ISODeviceElementType.Device || DeviceElement.DeviceElementType == ISODeviceElementType.Function) && childDeviceElement.DeviceElementType == ISODeviceElementType.Bin && childDeviceElements.Count(c => c.DeviceElementType == ISODeviceElementType.Bin) == 1) { //Set the element into the MergedElements list MergedElements.Add(childDeviceElement); //Set its children as children of the boom foreach (ISODeviceElement binChild in childDeviceElement.ChildDeviceElements.Where(det => det.ParentObjectId == childDeviceElement.DeviceElementObjectId && det.ParentObjectId != det.DeviceElementObjectId)) { Children.Add(new DeviceHierarchyElement(binChild, childDepth, representationMapper, mergeSingleBinsIntoBoom, missingGeometryDefinitions, _crawledElements, this)); } //This functionality will not work in the ADAPT framework today for multiple bins on one boom (i.e., ISO 11783-10:2015(E) F.23 & F.33). //For these, we will fall back to the more basic default functionality in HandleBinDeviceElements() //where we separate bins and sections into different depths within the ADAPT device hierarchy. //Plugin implementers will need to rationalize the separate bins to the single boom, //with the rate for each bin associated to the corresponding DeviceElement in the ADAPT model. //Were this multi-bin/single boom DDOP common, we could perhaps extend the WorkingData(?) class with some new piece of information //To differentiate like data elements from different bins and thereby extend the merge functionality to this case. } else { //Add the child device element DeviceHierarchyElement child = new DeviceHierarchyElement(childDeviceElement, childDepth, representationMapper, mergeSingleBinsIntoBoom, missingGeometryDefinitions, _crawledElements, this); Children.Add(child); } } } //Parent Parent = parent; } }