예제 #1
0
        private List <DeviceElementUse> GetAllSections(OperationData operationData)
        {
            var deviceElementUses = new List <DeviceElementUse>();

            if (operationData.GetDeviceElementUses != null)
            {
                int maximumDepth = 0;                   // @ToDo ILaR: operationData.MaxDepth;

                if (_properties.MaximumMappingDepth != null)
                {
                    if (_properties.MaximumMappingDepth >= -1 || _properties.MaximumMappingDepth <= operationData.MaxDepth)
                    {
                        maximumDepth = (int)_properties.MaximumMappingDepth;
                    }
                }

                for (var i = 0; i <= maximumDepth; i++)
                {
                    var dvcElemUses = operationData.GetDeviceElementUses(i);
                    if (dvcElemUses != null)
                    {
                        deviceElementUses.AddRange(dvcElemUses);
                    }
                }
            }

            return(deviceElementUses);
        }
        private Dictionary <string, WorkingData> GetWorkingDataDictionary(OperationData operation, Catalog catalog)
        {
            Dictionary <string, WorkingData> workingDataDictionary = new Dictionary <string, WorkingData>();

            for (int i = 0; i <= operation.MaxDepth; i++)
            {
                IEnumerable <DeviceElementUse> deviceElementUses = operation.GetDeviceElementUses(i);
                foreach (DeviceElementUse deviceElementUse in deviceElementUses)
                {
                    DeviceElementConfiguration config = catalog.DeviceElementConfigurations.FirstOrDefault(c => c.Id.ReferenceId == deviceElementUse.DeviceConfigurationId);
                    string deviceName = deviceElementUse.Id.ReferenceId.ToString();
                    if (config != null)
                    {
                        deviceName = config.Id.ReferenceId + "_" + config.Description;
                    }

                    IEnumerable <WorkingData> workingDatas = deviceElementUse.GetWorkingDatas();
                    foreach (WorkingData workingData in workingDatas)
                    {
                        if (workingData.Representation != null)
                        {
                            string key = $"{deviceElementUse.Depth}.{deviceElementUse.Order}:__{deviceName}_{workingData.Representation.Code}";
                            if (!workingDataDictionary.ContainsKey(key))
                            {
                                workingDataDictionary.Add(key, workingData);
                            }
                        }
                    }
                }
            }
            return(workingDataDictionary);
        }
        private static Dictionary <int, IEnumerable <WorkingData> > GetWorkingData(OperationData operationData)
        {
            var workingDataWithDepth = new Dictionary <int, IEnumerable <WorkingData> >();

            for (var i = 0; i <= operationData.MaxDepth; i++)
            {
                var meters = operationData.GetDeviceElementUses(i).SelectMany(x => x.GetWorkingDatas()).Where(x => x.Representation != null);

                workingDataWithDepth.Add(i, meters);
            }
            return(workingDataWithDepth);
        }
예제 #4
0
        public static List <DeviceElementUse> GetAllSections(this OperationData operationData)
        {
            if (operationData.GetDeviceElementUses == null)
            {
                return(new List <DeviceElementUse>());
            }

            var allSections = new List <DeviceElementUse>();

            for (var i = 0; i <= operationData.MaxDepth; i++)
            {
                var sections = operationData.GetDeviceElementUses(i);
                if (sections != null)
                {
                    allSections.AddRange(sections);
                }
            }

            return(allSections);
        }
예제 #5
0
        private static Dictionary <int, IEnumerable <DeviceElementUse> > GetAllDeviceElementUses(OperationData operationData)
        {
            if (operationData == null)
            {
                return(null);
            }

            var sections = new Dictionary <int, IEnumerable <DeviceElementUse> >();

            for (var depth = 0; depth <= operationData.MaxDepth; depth++)
            {
                if (operationData.GetDeviceElementUses == null)
                {
                    continue;
                }

                var levelSections = operationData.GetDeviceElementUses(depth);
                sections.Add(depth, levelSections);
            }

            return(sections);
        }
        private static void GetHarvestData(OperationData opData, Catalog catalog)
        {
            WorkingData distanceMeter = null;
            WorkingData moistureMeter = null;
            WorkingData wetMassMeter  = null;
            WorkingData dryYieldMeter = null;

            IEnumerable <DeviceElementUse> machineDEUs = opData.GetDeviceElementUses(0);

            foreach (DeviceElementUse deu in machineDEUs)
            {
                IEnumerable <WorkingData> workingDatas = deu.GetWorkingDatas();
                foreach (WorkingData meter in workingDatas)
                {
                    switch (meter.Representation.Code)
                    {
                    case "vrDistanceTraveled":
                        distanceMeter = meter;
                        break;

                    case "vrHarvestMoisture":
                        moistureMeter = meter;
                        break;

                    case "vrYieldWetMass":
                        wetMassMeter = meter;
                        break;

                    case "vrYieldVolume":
                        dryYieldMeter = meter;
                        break;
                    }
                }
            }

            // Active width is kept on Level 1 which indicates the header
            WorkingData widthMeter = null;
            IEnumerable <DeviceElementUse> headDEUs = opData.GetDeviceElementUses(1);

            foreach (DeviceElementUse deu in headDEUs)
            {
                IEnumerable <WorkingData> workingDatas = deu.GetWorkingDatas();
                foreach (WorkingData meter in workingDatas)
                {
                    switch (meter.Representation.Code)
                    {
                    case "vrEquipmentWidth":
                        widthMeter = meter;
                        break;
                    }
                }
            }

            double totalArea       = 0;
            double totalWetMass    = 0;
            double totalDryBushels = 0;
            double totalMoisture   = 0;

            // Loop through all the spatial records to get total area, wet mass, and moisture.
            IEnumerable <SpatialRecord> spatialRecords = opData.GetSpatialRecords();

            foreach (SpatialRecord spatialRecord in spatialRecords)
            {
                // Calculate the area
                NumericRepresentationValue distance = spatialRecord.GetMeterValue(distanceMeter) as NumericRepresentationValue;
                NumericRepresentationValue width    = spatialRecord.GetMeterValue(widthMeter) as NumericRepresentationValue;

                double distanceFt = distance.Value.Value;
                double widthFt    = width.Value.Value;

                double squareFeet = distanceFt * widthFt;
                double acres      = squareFeet / SQUARE_FEET_PER_ACRE;
                totalArea += acres;

                NumericRepresentationValue wetMass = spatialRecord.GetMeterValue(wetMassMeter) as NumericRepresentationValue;

                double wetMassLbs = wetMass.Value.Value;    // lbs
                totalWetMass += wetMassLbs;

                NumericRepresentationValue moisture = spatialRecord.GetMeterValue(moistureMeter) as NumericRepresentationValue;

                double moisturePct = moisture.Value.Value;  // %
                totalMoisture += moisturePct * wetMassLbs;  // Only used for calculating weighted average

                NumericRepresentationValue dryVol = spatialRecord.GetMeterValue(dryYieldMeter) as NumericRepresentationValue;

                double dryVolBu = dryVol.Value.Value;    // bu
                totalDryBushels += dryVolBu;
            }

            double averageMoisture = totalMoisture / totalWetMass;

            string result = String.Format("Area: {0:F2}\tWetMass: {1:F2}\tMoisture: {2:F2}\tDryBushels: {3:F2}", totalArea, totalWetMass, averageMoisture, totalDryBushels);

            Console.WriteLine(result);
        }
        private static void GetAsAppliedData(OperationData opData, Catalog catalog)
        {
            WorkingData areaMeter    = null;
            WorkingData appRateMeter = null;
            IEnumerable <DeviceElementUse> headDEUs = opData.GetDeviceElementUses(1);

            foreach (DeviceElementUse deu in headDEUs)
            {
                IEnumerable <WorkingData> workingDatas = deu.GetWorkingDatas();
                foreach (WorkingData meter in workingDatas)
                {
                    switch (meter.Representation.Code)
                    {
                    case "vrDeltaArea":
                        areaMeter = meter;
                        break;

                    case "vrAppRateVolumeActual":
                        appRateMeter = meter;
                        break;
                    }
                }
            }

            double totalArea   = 0;
            double totalAmount = 0;

            string rateUnits = "";

            // Loop through all the spatial records to get total area and total amount
            IEnumerable <SpatialRecord> spatialRecords = opData.GetSpatialRecords();

            foreach (SpatialRecord spatialRecord in spatialRecords)
            {
                // Calculate the area
                NumericRepresentationValue area = spatialRecord.GetMeterValue(areaMeter) as NumericRepresentationValue;

                double acres = area.Value.Value;
                totalArea += acres;

                NumericRepresentationValue appRate = spatialRecord.GetMeterValue(appRateMeter) as NumericRepresentationValue;
                rateUnits = appRate.Value.UnitOfMeasure.Code;

                double rate   = appRate.Value.Value; // gal/ac
                double amount = rate * acres;        // gal
                totalAmount += amount;
            }

            double averageRate = totalAmount / totalArea;

            Console.WriteLine("Application Summary:");

            string result = String.Format("Area: {0:F2}\tAmount: {1:F2}\tRate: {2:F2} {3}", totalArea, totalAmount, averageRate, rateUnits);

            Console.WriteLine(result);

            if (opData.ProductIds.Count > 0)
            {
                Console.WriteLine("Product Details:");
                Product product = catalog.Products.Find(x => x.Id.ReferenceId == opData.ProductIds[0]);

                result = String.Format("Product Description: {0}", product.Description);
                Console.WriteLine(result);

                if (product.ProductComponents.Count > 0)
                {
                    Console.WriteLine("Product Components:");

                    // Calculate the total rates for each type of ProductComponent in the MixProduct
                    double volumeTotalRate = 0;
                    double massTotalRate   = 0;
                    foreach (ProductComponent component in product.ProductComponents)
                    {
                        if (component.Quantity.Value.UnitOfMeasure.Dimension == UnitOfMeasureDimensionEnum.Volume)
                        {
                            // gal
                            volumeTotalRate += component.Quantity.Value.Value;
                        }
                        else if (component.Quantity.Value.UnitOfMeasure.Dimension == UnitOfMeasureDimensionEnum.Mass)
                        {
                            // lb
                            massTotalRate += component.Quantity.Value.Value;
                        }
                    }

                    // Determine the correct total applied date for the MixProduct
                    double totalRate = volumeTotalRate;
                    if (totalRate == 0)
                    {
                        // The volumeTotalRate will be 0 for dry product mixes
                        totalRate = massTotalRate;
                    }

                    // Calculate the total units of tank mix actually applied to the field.
                    //  This is important to be able to determine the actual proportion of each ProductComponent
                    double totalUnitsOfMixProduct = totalAmount / volumeTotalRate;

                    foreach (ProductComponent component in product.ProductComponents)
                    {
                        Product componentProduct = catalog.Products.Find(x => x.Id.ReferenceId == component.IngredientId);
                        double  componentRate    = component.Quantity.Value.Value;

                        // Calculate the total amount of the product component
                        double componentAmount     = totalUnitsOfMixProduct * componentRate;
                        double componentActualRate = componentAmount / totalArea;

                        result = String.Format("Component: {0}\tAmount: {1:F2}\tRate: {2:F2} {3}/ac", componentProduct.Description, componentAmount, componentActualRate, component.Quantity.Value.UnitOfMeasure.Code);
                        Console.WriteLine(result);
                    }
                }
            }
        }
        private static void GetPlantingData(OperationData opData, Catalog catalog)
        {
            // Get the distance meter from the Machine/Vehicle level
            WorkingData distanceMeter = null;

            IEnumerable <DeviceElementUse> machineDEUs = opData.GetDeviceElementUses(0);

            foreach (DeviceElementUse deu in machineDEUs)
            {
                IEnumerable <WorkingData> workingDatas = deu.GetWorkingDatas();
                foreach (WorkingData meter in workingDatas)
                {
                    switch (meter.Representation.Code)
                    {
                    case "vrDistanceTraveled":
                        distanceMeter = meter;
                        break;
                    }
                }
            }

            // Get the row-level meters for determining status, seeding rates, and product assignment for each row
            IEnumerable <DeviceElementUse> rowDEUs = opData.GetDeviceElementUses(2);
            List <RowConfiguration>        rows    = new List <RowConfiguration>();

            NumericWorkingData exampleRowMeter = null;

            foreach (DeviceElementUse deu in rowDEUs)
            {
                // Link to the catalog.DeviceElementConfigurations in order to determine the width of the row.
                //  Row widths are always in inches
                SectionConfiguration rowConfig = catalog.DeviceElementConfigurations.Find(x => x.Id.ReferenceId == deu.DeviceConfigurationId) as SectionConfiguration;
                RowConfiguration     row       = new RowConfiguration()
                {
                    widthIn = rowConfig.SectionWidth.Value.Value
                };

                IEnumerable <WorkingData> workingDatas = deu.GetWorkingDatas();
                foreach (WorkingData meter in workingDatas)
                {
                    switch (meter.Representation.Code)
                    {
                    case "dtRecordingStatus":
                        row.statusMeter = meter;
                        break;

                    case "vrSeedRateMassActual":
                    case "vrSeedRateSeedsActual":
                        row.appRateMeter = meter;
                        exampleRowMeter  = meter as NumericWorkingData;
                        break;

                    case "vrProductIndex":
                        row.productIndexMeter = meter;
                        break;
                    }
                }

                rows.Add(row);
            }

            string rateUnits = "";

            if (exampleRowMeter != null)
            {
                rateUnits = exampleRowMeter.UnitOfMeasure.Code;
            }

            // Initialize the productSummary dictionary
            //  Each product used in the planting operation is identified in the opData.ProductIds list.
            Dictionary <int, ProductSummary> productSummaryByProductId = new Dictionary <int, ProductSummary>();

            foreach (int productId in opData.ProductIds)
            {
                ProductSummary productSummary = new ProductSummary();
                productSummary.product = catalog.Products.Find(x => x.Id.ReferenceId == productId);

                productSummaryByProductId[productId] = productSummary;
            }

            // Keep track of the default productId.
            //  Single-product applications will only specify one product and will not use vrProductIndex meters
            int defaultProductId = opData.ProductIds[0];

            // Loop through all the spatial records
            IEnumerable <SpatialRecord> spatialRecords = opData.GetSpatialRecords();

            foreach (SpatialRecord spatialRecord in spatialRecords)
            {
                NumericRepresentationValue distance = spatialRecord.GetMeterValue(distanceMeter) as NumericRepresentationValue;
                double distanceFt = distance.Value.Value;

                // Loop through each row - we need to examine the status, product assignment, and rate of each row individually
                foreach (RowConfiguration row in rows)
                {
                    EnumeratedValue rowStatus = spatialRecord.GetMeterValue(row.statusMeter) as EnumeratedValue;
                    if (rowStatus.Value.Value == "Off")
                    {
                        // Skip inactive rows
                        continue;
                    }

                    int productId = defaultProductId;
                    if (row.productIndexMeter != null)
                    {
                        // Check to see which product is currently being planted by the current row unit
                        //  Only used for split planter and multi-hybrid planter
                        NumericRepresentationValue productIndex = spatialRecord.GetMeterValue(row.productIndexMeter) as NumericRepresentationValue;
                        if (productIndex != null)
                        {
                            productId = (int)productIndex.Value.Value;
                        }
                    }

                    // Calculate the number of acres covered by this row unit at this point in time
                    double acres = row.CalculateAcres(distanceFt);
                    productSummaryByProductId[productId].totalAcres += acres;

                    if (row.appRateMeter != null)
                    {
                        NumericRepresentationValue appRate = spatialRecord.GetMeterValue(row.appRateMeter) as NumericRepresentationValue;
                        if (appRate != null)
                        {
                            double rate   = appRate.Value.Value; // seeds/ac or lbs/ac
                            double amount = rate * acres;        // seeds or lbs
                            productSummaryByProductId[productId].totalAmount += amount;
                        }
                    }
                }
            }

            Console.WriteLine("Planting Sumamry by Variety.  Rate Units: " + rateUnits);
            foreach (ProductSummary productSummary in productSummaryByProductId.Values)
            {
                Console.WriteLine(productSummary.ToString());
            }
        }
예제 #9
0
 public static IEnumerable <WorkingData> GetWorkingData(this OperationData operationData)
 {
     return(Enumerable.Range(0, operationData.MaxDepth)
            .SelectMany(i => operationData.GetDeviceElementUses(i))
            .SelectMany(e => e.GetWorkingDatas()));
 }