Пример #1
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_ClearBit()
        {
            // Test setting a bit on and off, at two corners to test boundary conditions
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            bits.SetBit(0, 0);

            Assert.NotEqual(0U, bits.Bits[0]);
            Assert.Equal(1, bits.CountBits());

            bits.ClearBit(0, 0);

            Assert.Equal(0U, bits.Bits[0]);
            Assert.Equal(0, bits.CountBits());

            bits.SetBit(31, 31);

            Assert.NotEqual(0U, bits.Bits[31]);
            Assert.Equal(1, bits.CountBits());

            bits.ClearBit(31, 31);

            Assert.Equal(0U, bits.Bits[31]);
            Assert.Equal(0, bits.CountBits());
        }
Пример #2
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_Serialisation_Arbitrary()
        {
            // Test serialisation with arbitrary bits set
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            bits.SetBit(0, 0);
            bits.SetBit(10, 10);
            bits.SetBit(20, 20);
            bits.SetBit(31, 31);

            MemoryStream ms = new MemoryStream(Consts.TREX_DEFAULT_MEMORY_STREAM_CAPACITY_ON_CREATION);
            BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8, true);

            bits.Write(bw);
            BinaryReader br = new BinaryReader(ms, Encoding.UTF8, true);

            ms.Position = 0;

            SubGridTreeBitmapSubGridBits bits2 = SubGridTreeBitmapSubGridBits.FullMask;

            bits2.Read(br);

            Assert.True(bits.Equals(bits2), "Bits not equal after serialisation with arbitrary mask");
            Assert.Equal(4, bits.CountBits());
        }
Пример #3
0
        private static void PerformScan(double siteModelCellSize, FilteredValueAssignmentContext assignmentContext,
                                        SubGridTreeBitmapSubGridBits sieveBitmask,
                                        int numRowsToScan, int numColsToScan,
                                        double stepNorthX, double stepNorthY, double stepEastX, double stepEastY,
                                        double subGridMinX, double subGridMinY,
                                        double firstScanPointEast, double firstScanPointNorth)
        {
            // Skip-Iterate through the cells marking those cells that require values
            // calculated for them in the bitmask. Also record the actual probe locations
            // that determined the cells to be processed.

            for (var I = 0; I < numRowsToScan; I++)
            {
                var currentNorth = firstScanPointNorth + I * stepNorthY;
                var currentEast  = firstScanPointEast + I * stepNorthX;

                for (var J = 0; J < numColsToScan; J++)
                {
                    var eastCol  = (int)Math.Floor((currentEast - subGridMinX) / siteModelCellSize);
                    var northRow = (int)Math.Floor((currentNorth - subGridMinY) / siteModelCellSize);

                    if (Range.InRange(eastCol, 0, SubGridTreeConsts.SubGridTreeDimensionMinus1) &&
                        Range.InRange(northRow, 0, SubGridTreeConsts.SubGridTreeDimensionMinus1))
                    {
                        sieveBitmask.SetBit(eastCol, northRow);
                        assignmentContext.ProbePositions[eastCol, northRow]
                        .SetOffsets((float)(currentEast - subGridMinX), (float)(currentNorth - subGridMinY));
                    }

                    currentEast  += stepEastX;
                    currentNorth += stepEastY;
                }
            }
        }
Пример #4
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_ForEach_Action()
        {
            // Test iteration action for empty, full and arbitrary masks
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);

            int sum;

            sum = 0;
            bits.ForEach((x, y) => { if (bits.BitSet(x, y))
                                     {
                                         sum++;
                                     }
                         });
            Assert.True(sum == bits.CountBits() && sum == SubGridTreeConsts.CellsPerSubGrid, "Summation via ForEach on full mask did not give expected result");

            sum = 0;
            bits.Clear();
            bits.ForEach((x, y) => { if (bits.BitSet(x, y))
                                     {
                                         sum++;
                                     }
                         });
            Assert.True(sum == bits.CountBits() && sum == 0, "Summation via ForEach on empty mask did not give expected result");

            sum = 0;
            bits.SetBit(1, 1);
            bits.ForEach((x, y) => { if (bits.BitSet(x, y))
                                     {
                                         sum++;
                                     }
                         });
            Assert.True(sum == bits.CountBits() && sum == 1, "Summation via ForEach on mask with single bit set at (1, 1) did not give expected result");
        }
Пример #5
0
        /// <summary>
        /// Constructs a mask using polygonal and positional spatial filtering aspects of a filter.
        /// </summary>
        private static void ConstructSubGridSpatialAndPositionalMask(SubGridCellAddress currentSubGridOrigin,
                                                                     InterceptList intercepts,
                                                                     int fromProfileCellIndex,
                                                                     SubGridTreeBitmapSubGridBits mask,
                                                                     ICellSpatialFilter cellFilter,
                                                                     ISubGridTree subGridTree)
        {
            var cellFilterHasSpatialOrPositionalFilters = cellFilter.HasSpatialOrPositionalFilters;
            var interceptsCount = intercepts.Count;

            mask.Clear();

            for (var interceptIdx = fromProfileCellIndex; interceptIdx < interceptsCount; interceptIdx++)
            {
                // Determine the on-the-ground cell underneath the midpoint of each cell on the intercept line
                subGridTree.CalculateIndexOfCellContainingPosition(intercepts.Items[interceptIdx].MidPointX,
                                                                   intercepts.Items[interceptIdx].MidPointY, out var otgCellX, out var otgCellY);

                var thisSubGridOrigin = new SubGridCellAddress(otgCellX & ~SubGridTreeConsts.SubGridLocalKeyMask, otgCellY & ~SubGridTreeConsts.SubGridLocalKeyMask);

                if (!currentSubGridOrigin.Equals(thisSubGridOrigin))
                {
                    break;
                }

                var cellX = otgCellX & SubGridTreeConsts.SubGridLocalKeyMask;
                var cellY = otgCellY & SubGridTreeConsts.SubGridLocalKeyMask;

                if (cellFilterHasSpatialOrPositionalFilters)
                {
                    subGridTree.GetCellCenterPosition(otgCellX, otgCellY, out var cellCenterX, out var cellCenterY);

                    if (cellFilter.IsCellInSelection(cellCenterX, cellCenterY))
                    {
                        mask.SetBit(cellX, cellY);
                    }
                }
                else
                {
                    mask.SetBit(cellX, cellY);
                }
            }
        }
Пример #6
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_CountBits()
        {
            SubGridTreeBitmapSubGridBits bits = SubGridTreeBitmapSubGridBits.FullMask;

            Assert.Equal(bits.CountBits(), SubGridTreeConsts.CellsPerSubGrid);

            bits.Clear();
            Assert.Equal(0, bits.CountBits());

            bits.SetBit(1, 1);
            Assert.Equal(1, bits.CountBits());
        }
Пример #7
0
        private static void ConstructSubGridSpatialAndPositionalMask(ISubGridTree tree,
                                                                     SubGridCellAddress currentSubGridOrigin,
                                                                     List <T> profileCells,
                                                                     SubGridTreeBitmapSubGridBits mask,
                                                                     int fromProfileCellIndex,
                                                                     ICellSpatialFilter cellFilter)
        {
            mask.Clear();

            // From current position to end...
            for (var cellIdx = fromProfileCellIndex; cellIdx < profileCells.Count; cellIdx++)
            {
                var profileCell       = profileCells[cellIdx];
                var thisSubGridOrigin = new SubGridCellAddress(
                    profileCell.OTGCellX & ~SubGridTreeConsts.SubGridLocalKeyMask,
                    profileCell.OTGCellY & ~SubGridTreeConsts.SubGridLocalKeyMask);

                if (!currentSubGridOrigin.Equals(thisSubGridOrigin))
                {
                    break;
                }

                var cellX = (byte)(profileCell.OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask);
                var cellY = (byte)(profileCell.OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask);

                if (cellFilter.HasSpatialOrPositionalFilters)
                {
                    tree.GetCellCenterPosition(profileCell.OTGCellX, profileCell.OTGCellY,
                                               out var cellCenterX, out var cellCenterY);
                    if (cellFilter.IsCellInSelection(cellCenterX, cellCenterY))
                    {
                        mask.SetBit(cellX, cellY);
                    }
                }
                else
                {
                    mask.SetBit(cellX, cellY);
                }
            }
        }
Пример #8
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_Operators_OR()
        {
            SubGridTreeBitmapSubGridBits bits1 = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);
            SubGridTreeBitmapSubGridBits bits2 = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            Assert.Equal((bits1 | bits2), bits1);

            bits1.ClearBit(1, 1);
            Assert.Equal((bits1 | bits2), bits1);

            bits2.SetBit(1, 1);
            Assert.True((bits1 | bits2).IsFull(), "ORing after clearing/setting bits did not return full mask");
        }
Пример #9
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_Operators_XOR()
        {
            SubGridTreeBitmapSubGridBits bits1 = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);
            SubGridTreeBitmapSubGridBits bits2 = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            Assert.True((bits1 ^ bits1).IsEmpty(), "XORing bits with self did not result in empty mask");
            Assert.Equal(bits1, (bits1 ^ bits2));
            Assert.True((bits1 ^ bits2).IsFull(), "XORing an empty mask with a full mask did not produce a full mask");

            bits2.SetBit(1, 1);
            Assert.True((bits1 ^ bits1).IsEmpty(), "XORing single bit with itself did not clear bit");
            Assert.False((bits1 ^ bits1).BitSet(1, 1), "XORing single bit with itself did not clear bit");
        }
Пример #10
0
        /// <summary>
        /// Gets the production data values for the requested cell
        /// </summary>
        private async Task GetProductionData(ISiteModel siteModel, IDesignWrapper cutFillDesign, CellDatumResponse_ClusterCompute result, CellDatumRequestArgument_ClusterCompute arg)
        {
            var existenceMap = siteModel.ExistenceMap;

            var utilities  = DIContext.Obtain <IRequestorUtilities>();
            var requestors = utilities.ConstructRequestors(null, siteModel, arg.Overrides, arg.LiftParams,
                                                           utilities.ConstructRequestorIntermediaries(siteModel, arg.Filters, true, GridDataType.CellProfile),
                                                           AreaControlSet.CreateAreaControlSet(), existenceMap);

            // Get the sub grid relative cell location
            int cellX = arg.OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask;
            int cellY = arg.OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask;

            // Reach into the sub-grid request layer and retrieve an appropriate sub-grid
            var cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            cellOverrideMask.SetBit(cellX, cellY);
            requestors[0].CellOverrideMask = cellOverrideMask;

            // using the cell address get the index of cell in clientGrid
            var thisSubGridOrigin            = new SubGridCellAddress(arg.OTGCellX, arg.OTGCellY);
            var requestSubGridInternalResult = requestors[0].RequestSubGridInternal(thisSubGridOrigin, true, true);

            if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError)
            {
                if (requestSubGridInternalResult.requestResult == ServerRequestResult.SubGridNotFound)
                {
                    result.ReturnCode = CellDatumReturnCode.NoValueFound;
                }
                else
                {
                    Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed with code {requestSubGridInternalResult.requestResult}");
                }
                return;
            }

            var cell = ((ClientCellProfileLeafSubgrid)requestSubGridInternalResult.clientGrid).Cells[cellX, cellY];

            if (cell.PassCount > 0) // Cell is not in our areaControlSet...
            {
                await ExtractRequiredValue(cutFillDesign, cell, result, arg);

                result.TimeStampUTC = cell.LastPassTime;
            }
        }
Пример #11
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_ComputeCellsExtents()
        {
            // Test extents for empty, full and arbitrary masks
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);

            BoundingIntegerExtent2D boundsFull = bits.ComputeCellsExtents();

            Assert.True(boundsFull.Equals(new BoundingIntegerExtent2D(0, 0, SubGridTreeConsts.SubGridTreeDimensionMinus1, SubGridTreeConsts.SubGridTreeDimensionMinus1)),
                        "ComputeCellsExtents is incorrect for full grid");

            bits.Clear();
            BoundingIntegerExtent2D boundsClear = bits.ComputeCellsExtents();

            Assert.False(boundsClear.IsValidExtent, "ComputeCellsExtents is incorrect for clear grid");

            bits.SetBit(1, 1);
            BoundingIntegerExtent2D bounds11 = bits.ComputeCellsExtents();

            Assert.True(bounds11.Equals(new BoundingIntegerExtent2D(1, 1, 1, 1)), "ComputeCellsExtents is incorrect for grid with bit set at (1, 1)");
        }
Пример #12
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_ForEachClearBit()
        {
            // Test iteration action for empty, full and arbitrary masks
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);

            int sum;

            sum = 0;
            bits.ForEachClearBit((x, y) => { sum++; });
            Assert.Equal(0, sum);

            sum = 0;
            bits.Clear();
            bits.ForEachClearBit((x, y) => { sum++; });
            Assert.Equal(sum, SubGridTreeConsts.CellsPerSubGrid);

            sum = 0;
            bits.SetBit(1, 1);
            bits.ForEachClearBit((x, y) => { sum++; });
            Assert.Equal(sum, SubGridTreeConsts.CellsPerSubGrid - 1);
        }
Пример #13
0
        public static void ConstructSubgridSpatialAndPositionalMask(ILeafSubGrid SubGridAsLeaf,
                                                                    ISiteModel SiteModel,
                                                                    ICombinedFilter Filter,
                                                                    bool AHasOverrideSpatialCellRestriction,
                                                                    BoundingIntegerExtent2D AOverrideSpatialCellRestriction,
                                                                    SubGridTreeBitmapSubGridBits PDMask,
                                                                    SubGridTreeBitmapSubGridBits FilterMask)
        {
            if (Filter == null || !Filter.SpatialFilter.HasSpatialOrPositionalFilters)
            {
                PDMask.Fill();
                FilterMask.Fill();
                return;
            }

            var originX = SubGridAsLeaf.OriginX;
            var originY = SubGridAsLeaf.OriginY;

            var cellSize = SiteModel.CellSize;

            // Get the world location of the origin position
            SiteModel.Grid.GetCellCenterPosition(originX, originY, out var OX, out var OY);

            var SpatialFilter = Filter.SpatialFilter;

            // Attempt to satisfy the calculation below on the basis of the sub grid wholly residing in the override and filter spatial restrictions
            if (SpatialFilter.Fence.IncludesExtent(new BoundingWorldExtent3D(OX, OY,
                                                                             OX + cellSize * SubGridTreeConsts.SubGridTreeDimension,
                                                                             OY + cellSize * SubGridTreeConsts.SubGridTreeDimension)))
            {
                // The extent of the sub grid is wholly contained in the filter, therefore there is no need to iterate though all the cells
                // individually...

                FilterMask.Fill();

                // ... unless there is an override spatial cell restriction that does not enclose the extent of the sub grid
                if (AHasOverrideSpatialCellRestriction &&
                    !AOverrideSpatialCellRestriction.Encloses(new BoundingIntegerExtent2D((int)originX, (int)originY,
                                                                                          (int)originX + SubGridTreeConsts.SubGridTreeDimension,
                                                                                          (int)originY + SubGridTreeConsts.SubGridTreeDimension)))
                {
                    for (byte I = 0; I < SubGridTreeConsts.SubGridTreeDimension; I++)
                    {
                        for (byte J = 0; J < SubGridTreeConsts.SubGridTreeDimension; J++)
                        {
                            if (!AOverrideSpatialCellRestriction.Includes(originX + I, originY + J))
                            {
                                FilterMask.ClearBit(I, J);
                            }
                        }
                    }
                }
            }
            else
            {
                // Perform the calculation the long hand way
                // ... Idea: Invert row and column order of calculation below to get and set bits based on an entire column of bits

                FilterMask.Clear();

                // Construct the filter mask based on the spatial and location (square/circle/polygonal) filtering
                double CX = OX;

                for (byte I = 0; I < SubGridTreeConsts.SubGridTreeDimension; I++)
                {
                    int    OriginXPlusI = originX + I;
                    double CY           = OY; // Set to the first row in the column about to be processed

                    for (byte J = 0; J < SubGridTreeConsts.SubGridTreeDimension; J++)
                    {
                        if (AHasOverrideSpatialCellRestriction && !AOverrideSpatialCellRestriction.Includes((int)OriginXPlusI, (int)(originY + J)))
                        {
                            // Do nothing
                        }
                        else
                        {
                            // SiteModel.Grid.GetCellCenterPosition(OriginXPlusI, originY + J, out CX, out CY);
                            if (SpatialFilter.IsCellInSelection(CX, CY))
                            {
                                FilterMask.SetBit(I, J);
                            }
                        }

                        CY += cellSize; // Move to next row
                    }

                    CX += cellSize; // Move to next column
                }
            }
        }
Пример #14
0
        /// <summary>
        /// For each point in the list, get the sub grid and extract productionData at the station/offset i.e pointOfInterest
        ///    This could be optimized to get any poi from each sub grid before disposal
        /// </summary>
        private StationOffsetReportRequestResponse_ClusterCompute GetProductionData()
        {
            var result = new StationOffsetReportRequestResponse_ClusterCompute {
                ResultStatus = RequestErrorStatus.Unknown
            };

            IDesignWrapper cutFillDesignWrapper = null;

            if (requestArgument.ReferenceDesign != null && requestArgument.ReferenceDesign.DesignID != Guid.Empty)
            {
                var cutFillDesign = siteModel.Designs.Locate(requestArgument.ReferenceDesign.DesignID);
                if (cutFillDesign == null)
                {
                    throw new ArgumentException($"Design {requestArgument.ReferenceDesign.DesignID} not a recognized design in project {requestArgument.ProjectID}");
                }
                cutFillDesignWrapper = new DesignWrapper(requestArgument.ReferenceDesign, cutFillDesign);
            }

            var existenceMap = siteModel.ExistenceMap;
            var utilities    = DIContext.Obtain <IRequestorUtilities>();
            var requestors   = utilities.ConstructRequestors(null, siteModel, requestArgument.Overrides, requestArgument.LiftParams,
                                                             utilities.ConstructRequestorIntermediaries(siteModel, requestArgument.Filters, true, GridDataType.CellProfile),
                                                             AreaControlSet.CreateAreaControlSet(), existenceMap);

            // Obtain the primary partition map to allow this request to determine the elements it needs to process
            bool[] primaryPartitionMap = ImmutableSpatialAffinityPartitionMap.Instance().PrimaryPartitions();
            SubGridTreeBitmapSubGridBits cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            foreach (var point in requestArgument.Points)
            {
                // Determine the on-the-ground cell
                siteModel.Grid.CalculateIndexOfCellContainingPosition(point.Easting, point.Northing, out int OTGCellX, out int OTGCellY);

                var thisSubGridOrigin = new SubGridCellAddress(OTGCellX, OTGCellY);

                if (!primaryPartitionMap[thisSubGridOrigin.ToSpatialPartitionDescriptor()])
                {
                    continue;
                }

                // Get the sub grid relative cell location
                int cellX = OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask;
                int cellY = OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask;

                // Reach into the sub-grid request layer and retrieve an appropriate sub-grid
                cellOverrideMask.Clear();
                cellOverrideMask.SetBit(cellX, cellY);
                requestors[0].CellOverrideMask = cellOverrideMask;

                // using the cell address get the index of cell in clientGrid
                var requestSubGridInternalResult = requestors[0].RequestSubGridInternal(
                    thisSubGridOrigin, true, true);

                if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError)
                {
                    Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed with code {result}");
                    result.StationOffsetRows.Add(new StationOffsetRow(point.Station, point.Offset, point.Northing, point.Easting));
                    continue;
                }

                var hydratedPoint = ExtractRequiredValues(cutFillDesignWrapper, point, requestSubGridInternalResult.clientGrid as ClientCellProfileLeafSubgrid, cellX, cellY);
                result.StationOffsetRows.Add(hydratedPoint);
            }

            result.ResultStatus = RequestErrorStatus.OK;
            return(result);
        }
Пример #15
0
        /// <summary>
        /// Executor that implements requesting and rendering sub grid information to create the cell datum
        /// </summary>
        public async Task <CellPassesResponse> ExecuteAsync(CellPassesRequestArgument_ClusterCompute arg, SubGridSpatialAffinityKey key)
        {
            Log.LogInformation($"Performing Execute for DataModel:{arg.ProjectID}");

            var result = new CellPassesResponse {
                ReturnCode = CellPassesReturnCode.Error
            };

            var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(arg.ProjectID);

            if (siteModel == null)
            {
                Log.LogError($"Failed to locate site model {arg.ProjectID}");
                return(result);
            }

            var existenceMap = siteModel.ExistenceMap;
            var utilities    = DIContext.Obtain <IRequestorUtilities>();
            var requestors   = utilities.ConstructRequestors(null, siteModel, arg.Overrides, arg.LiftParams,
                                                             utilities.ConstructRequestorIntermediaries(siteModel, arg.Filters, true, GridDataType.CellPasses),
                                                             AreaControlSet.CreateAreaControlSet(),
                                                             existenceMap);

            // Get the sub grid relative cell location
            var cellX = arg.OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask;
            var cellY = arg.OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask;

            // Reach into the sub-grid request layer and retrieve an appropriate sub-grid
            var cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            cellOverrideMask.SetBit(cellX, cellY);
            requestors[0].CellOverrideMask = cellOverrideMask;

            var thisSubGridOrigin            = new SubGridCellAddress(arg.OTGCellX, arg.OTGCellY);
            var requestSubGridInternalResult = requestors[0].RequestSubGridInternal(thisSubGridOrigin, true, true);

            if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError)
            {
                if (requestSubGridInternalResult.requestResult == ServerRequestResult.SubGridNotFound)
                {
                    result.ReturnCode = CellPassesReturnCode.NoDataFound;
                }
                else
                {
                    Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed with code {requestSubGridInternalResult.requestResult}");
                }
                return(result);
            }

            if (!(requestSubGridInternalResult.clientGrid is ClientCellProfileAllPassesLeafSubgrid grid))
            {
                Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed due the grid return type being incorrect. Expected {typeof(ClientCellProfileAllPassesLeafSubgrid).Name}, but got {requestSubGridInternalResult.clientGrid.GetType().Name}");
                return(result);
            }

            var cell = grid.Cells[cellX, cellY];

            if (cell.TotalPasses > 0)
            {
                result.ReturnCode = CellPassesReturnCode.DataFound;
                for (var idx = 0; idx < cell.TotalPasses; idx++)
                {
                    var cellPass = cell.CellPasses[idx];
                    result.CellPasses.Add(cellPass);
                }
            }
            else
            {
                result.ReturnCode = CellPassesReturnCode.NoDataFound;
            }

            return(result);
        }
Пример #16
0
        /// <summary>
        /// Computes a bitmask used to sieve out only the cells that will be used in the query context.
        /// The sieved cells are the only cells processed and returned. All other cells will be null values,
        /// even if data is present for them that matches filtering and other conditions
        /// </summary>
        /// <param name="subGridMoniker"></param>
        /// <param name="areaControlSet"></param>
        /// <param name="siteModelCellSize"></param>
        /// <param name="sieveBitmask"></param>
        /// <param name="subGridWorldOriginX"></param>
        /// <param name="subGridWorldOriginY"></param>
        /// <returns></returns>
        public static bool ComputeSieveBitmaskInteger(double subGridWorldOriginX, double subGridWorldOriginY, string subGridMoniker,
                                                      AreaControlSet areaControlSet, double siteModelCellSize, out SubGridTreeBitmapSubGridBits sieveBitmask)
        {
            const int kMaxStepSize = 10000;

            sieveBitmask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            /* TODO - add configuration item for VLPDPSNode_UseSkipStepComputationForWMSSubGridRequests
             * if (!VLPDSvcLocations.VLPDPSNode_UseSkipStepComputationForWMSSubGridRequests)
             *  return false;
             */

            if (areaControlSet.PixelXWorldSize < siteModelCellSize && areaControlSet.PixelYWorldSize < siteModelCellSize)
            {
                return(false);
            }

            // Progress through the cells in the grid, starting from the southern most
            // row in the grid and progressing from the western end to the eastern end
            // (ie: bottom to top, left to right)

            ///////////////// CalculateParameters;  START

            double stepsPerPixelX = areaControlSet.PixelXWorldSize / siteModelCellSize;
            double stepsPerPixelY = areaControlSet.PixelYWorldSize / siteModelCellSize;

            // Note: integers
            int stepX = Math.Min(kMaxStepSize, Math.Max(1, (int)Math.Truncate(stepsPerPixelX)));
            int stepY = Math.Min(kMaxStepSize, Math.Max(1, (int)Math.Truncate(stepsPerPixelY)));

            double stepXIncrement = stepX * siteModelCellSize;
            double stepYIncrement = stepY * siteModelCellSize;

            double stepXIncrementOverTwo = stepXIncrement / 2;
            double stepYIncrementOverTwo = stepYIncrement / 2;

            ///////////////// CalculateParameters;  END

            if (stepX < 2 && stepY < 2)
            {
                return(false);
            }

            if (stepX >= SubGridTreeConsts.SubGridTreeDimension && stepY >= SubGridTreeConsts.SubGridTreeDimension)
            {
                Log.LogDebug($"Skip value of {stepX}/{stepY} chosen for {subGridMoniker}");
            }

            sieveBitmask.Clear();

            // Calculate the world coordinate location of the origin (bottom left corner) of this sub grid
            //subGrid.CalculateWorldOrigin(out double subGridWorldOriginX, out double subGridWorldOriginY);

            // Skip-Iterate through the cells marking those cells that require values
            // calculate for them in the bitmask

            double temp         = subGridWorldOriginY / stepYIncrement;
            double currentNorth = (Math.Truncate(temp) * stepYIncrement) - stepYIncrementOverTwo;
            int    northRow     = (int)Math.Floor((currentNorth - subGridWorldOriginY) / siteModelCellSize);

            while (northRow < 0)
            {
                northRow += stepY;
            }

            while (northRow < SubGridTreeConsts.SubGridTreeDimension)
            {
                temp = subGridWorldOriginX / stepXIncrement;

                double currentEast = (Math.Truncate(temp) * stepXIncrement) - stepXIncrementOverTwo;
                int    eastCol     = (int)Math.Floor((currentEast - subGridWorldOriginX) / siteModelCellSize);

                while (eastCol < 0)
                {
                    eastCol += stepX;
                }

                while (eastCol < SubGridTreeConsts.SubGridTreeDimension)
                {
                    sieveBitmask.SetBit(eastCol, northRow);
                    eastCol += stepX;
                }

                northRow += stepY;
            }

            return(true);
        }
Пример #17
0
        public void ProcessElevationInformationForSubGrid(int cellOriginX, int cellOriginY, float[,] baseSubGrid, float[,] topSubGrid)
        {
            // FCellArea is a handy place to store the cell area, rather than calculate it all the time (value wont change);
            var cellArea = CellSize * CellSize;

            var bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            CellsScanned += SubGridTreeConsts.SubGridTreeCellsPerSubGrid;

            for (var i = 0; i < SubGridTreeConsts.SubGridTreeDimension; i++)
            {
                for (var j = 0; j < SubGridTreeConsts.SubGridTreeDimension; j++)
                {
                    var topZ  = topSubGrid[i, j];
                    var baseZ = baseSubGrid[i, j];

                    if (baseZ != Consts.NullHeight && topZ != Consts.NullHeight)
                    {
                        CellsUsed++;

                        //  Note the fact we have processed this cell in the coverage map
                        bits.SetBit(i, j);

                        var cellUsedInVolumeCalc = (topZ - baseZ >= FillTolerance) || (baseZ - topZ >= CutTolerance);

                        // Accumulate volumes
                        if (cellUsedInVolumeCalc)
                        {
                            var volumeDifference = cellArea * (topZ - baseZ);

                            // Accumulate the 'surplus' volume. Ie: the simple summation of
                            // all cuts and fills.
                            Volume += volumeDifference;

                            // Accumulate the cuts and fills into discrete cut and fill quantities
                            if (topZ < baseZ)
                            {
                                CellsUsedCut++;
                                CutFillVolume.AddCutVolume(Math.Abs(volumeDifference));
                            }
                            else
                            {
                                CellsUsedFill++;
                                CutFillVolume.AddFillVolume(Math.Abs(volumeDifference));
                            }
                        }
                        else
                        {
                            // Note the fact there was no volume change in this cell
                            // NoChangeMap.Cells[BaseScanSubGrid.OriginX + I, BaseScanSubGrid.OriginY + J] := True;
                        }
                    }
                    else
                    {
                        CellsDiscarded++;
                    }
                }
            }

            // Record the bits for this sub grid in the coverage map by requesting the whole sub grid
            // of bits from the leaf level and setting it in one operation under an exclusive lock
            if (!bits.IsEmpty())
            {
                var coverageMapSubGrid = CoverageMap.ConstructPathToCell(cellOriginX, cellOriginY, SubGridPathConstructionType.CreateLeaf);
                ((SubGridTreeLeafBitmapSubGrid)coverageMapSubGrid).Bits = bits;
            }
        }
Пример #18
0
        protected void ProcessVolumeInformationForSubGrid(ClientHeightLeafSubGrid baseScanSubGrid,
                                                          ClientHeightLeafSubGrid topScanSubGrid)
        {
            _log.LogDebug("In ProcessVolumeInformationForSubGrid");

            try
            {
                // DesignHeights represents all the valid spot elevations for the cells in the
                // sub grid being processed
                (IClientHeightLeafSubGrid designHeights, DesignProfilerRequestResult profilerRequestResult)getDesignHeightsResult = (null, DesignProfilerRequestResult.UnknownError);

                // FCellArea is a handy place to store the cell area, rather than calculate it all the time (value wont change);
                var cellArea = CellSize * CellSize;

                // Query the patch of elevations from the surface model for this sub grid
                if (ActiveDesign?.Design != null)
                {
                    _log.LogDebug("About to call ActiveDesign.Design.GetDesignHeightsViaLocalCompute()");

                    getDesignHeightsResult = ActiveDesign.Design.GetDesignHeightsViaLocalCompute(SiteModel, ActiveDesign.Offset, baseScanSubGrid.OriginAsCellAddress(), CellSize);

                    if (getDesignHeightsResult.profilerRequestResult != DesignProfilerRequestResult.OK &&
                        getDesignHeightsResult.profilerRequestResult != DesignProfilerRequestResult.NoElevationsInRequestedPatch)
                    {
                        _log.LogError($"Design profiler sub grid elevation request for {baseScanSubGrid.OriginAsCellAddress()} failed with error {getDesignHeightsResult.profilerRequestResult}");
                        return;
                    }
                }

                var bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

                // ReSharper disable once CompareOfFloatsByEqualityOperator
                var standardVolumeProcessing = LiftParams.TargetLiftThickness == Consts.NullHeight || LiftParams.TargetLiftThickness <= 0;

                var localCellsScanned   = 0;
                var localCellsUsed      = 0;
                var localCellsDiscarded = 0;
                var localCellsUsedCut   = 0;
                var localCellsUsedFill  = 0;
                var localVolume         = 0.0d;
                var localCutFillVolume  = new CutFillVolume(0, 0);

                // If we are interested in standard volume processing use this cycle
                if (standardVolumeProcessing)
                {
                    localCellsScanned += SubGridTreeConsts.SubGridTreeCellsPerSubGrid;

                    for (var i = 0; i < SubGridTreeConsts.SubGridTreeDimension; i++)
                    {
                        for (var j = 0; j < SubGridTreeConsts.SubGridTreeDimension; j++)
                        {
                            float topZ;
                            var   baseZ = baseScanSubGrid.Cells[i, j];

                            // If the user has configured a first pass thickness, then we need to subtract this height
                            // difference from the BaseZ retrieved from the current cell if this measured height was
                            // the first pass made in the cell.
                            if (LiftParams.FirstPassThickness > 0)
                            {
                                baseZ -= LiftParams.FirstPassThickness;
                            }

                            if (VolumeType == VolumeComputationType.BetweenFilterAndDesign ||
                                VolumeType == VolumeComputationType.BetweenDesignAndFilter)
                            {
                                topZ = getDesignHeightsResult.designHeights?.Cells[i, j] ?? Consts.NullHeight;

                                if (VolumeType == VolumeComputationType.BetweenDesignAndFilter)
                                {
                                    MinMax.Swap(ref baseZ, ref topZ);
                                }
                            }
                            else
                            {
                                topZ = topScanSubGrid.Cells[i, j];
                            }

                            switch (VolumeType)
                            {
                            case VolumeComputationType.None:
                                break;

                            case VolumeComputationType.AboveLevel:
                            {
                                // ReSharper disable once CompareOfFloatsByEqualityOperator
                                if (baseZ != Consts.NullHeight)
                                {
                                    localCellsUsed++;
                                    if (baseZ > BaseLevel)
                                    {
                                        localVolume += cellArea * (baseZ - BaseLevel);
                                    }
                                }
                                else
                                {
                                    localCellsDiscarded++;
                                }

                                break;
                            }

                            case VolumeComputationType.Between2Levels:
                            {
                                // ReSharper disable once CompareOfFloatsByEqualityOperator
                                if (baseZ != Consts.NullHeight)
                                {
                                    localCellsUsed++;

                                    if (baseZ > BaseLevel)
                                    {
                                        localVolume += cellArea * (baseZ < TopLevel ? (baseZ - BaseLevel) : (TopLevel - BaseLevel));
                                    }
                                }
                                else
                                {
                                    localCellsDiscarded++;
                                }

                                break;
                            }

                            case VolumeComputationType.AboveFilter:
                            case VolumeComputationType.Between2Filters:
                            case VolumeComputationType.BetweenFilterAndDesign:
                            case VolumeComputationType.BetweenDesignAndFilter:
                            {
                                // ReSharper disable once CompareOfFloatsByEqualityOperator
                                if (baseZ != Consts.NullHeight &&
                                    // ReSharper disable once CompareOfFloatsByEqualityOperator
                                    topZ != Consts.NullHeight)
                                {
                                    localCellsUsed++;

                                    //  Note the fact we have processed this cell in the coverage map
                                    bits.SetBit(i, j);

                                    var cellUsedInVolumeCalc = (topZ - baseZ >= FillTolerance) || (baseZ - topZ >= CutTolerance);

                                    // Accumulate volumes
                                    if (cellUsedInVolumeCalc)
                                    {
                                        var volumeDifference = cellArea * (topZ - baseZ);

                                        // Accumulate the 'surplus' volume. Ie: the simple summation of
                                        // all cuts and fills.
                                        localVolume += volumeDifference;

                                        // Accumulate the cuts and fills into discrete cut and fill quantities
                                        if (topZ < baseZ)
                                        {
                                            localCellsUsedCut++;
                                            localCutFillVolume.AddCutVolume(Math.Abs(volumeDifference));
                                        }
                                        else
                                        {
                                            localCellsUsedFill++;
                                            localCutFillVolume.AddFillVolume(Math.Abs(volumeDifference));
                                        }
                                    }
                                    else
                                    {
                                        // Note the fact there was no volume change in this cell
                                        // NoChangeMap.Cells[BaseScanSubGrid.OriginX + I, BaseScanSubGrid.OriginY + J] := True;
                                    }
                                }
                                else
                                {
                                    localCellsDiscarded++;
                                }
                            }
                            break;

                            default:
                                _log.LogError($"Unknown volume type {VolumeType} in ProcessVolumeInformationForSubGrid()");
                                break;
                            }
                        }
                    }
                }

                // ReSharper disable once CompareOfFloatsByEqualityOperator
                var targetLiftThicknessCalculationsRequired = LiftParams.TargetLiftThickness != Consts.NullHeight && LiftParams.TargetLiftThickness > 0;

                //If we are interested in thickness calculations do them
                if (targetLiftThicknessCalculationsRequired)
                {
                    var belowToleranceToCheck = LiftParams.TargetLiftThickness - LiftParams.BelowToleranceLiftThickness;
                    var aboveToleranceToCheck = LiftParams.TargetLiftThickness + LiftParams.AboveToleranceLiftThickness;

                    SubGridUtilities.SubGridDimensionalIterator((i, j) =>
                    {
                        var baseZ = baseScanSubGrid.Cells[i, j];
                        var topZ  = topScanSubGrid.Cells[i, j];

                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        if (baseZ != Consts.NullHeight ||
                            // ReSharper disable once CompareOfFloatsByEqualityOperator
                            topZ != Consts.NullHeight)
                        {
                            localCellsScanned++;
                        }

                        //Test if we don't have NULL values and carry on
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        if (baseZ != Consts.NullHeight &&
                            // ReSharper disable once CompareOfFloatsByEqualityOperator
                            topZ != Consts.NullHeight)
                        {
                            bits.SetBit(i, j);
                            double elevationDiff = topZ - baseZ;

                            if (elevationDiff <= aboveToleranceToCheck && elevationDiff >= belowToleranceToCheck)
                            {
                                localCellsUsed++;
                            }
                            else if (elevationDiff > aboveToleranceToCheck)
                            {
                                localCellsUsedFill++;
                            }
                            else if (elevationDiff < belowToleranceToCheck)
                            {
                                localCellsUsedCut++;
                            }
                        }
                        else
                        {
                            localCellsDiscarded++;
                        }
                    });
                }

                // Update the quantities in the aggregator proper
                // Note: the lock is not asynchronous as this will be highly non-contended
                _lock.Wait();
                try
                {
                    CellsScanned   += localCellsScanned;
                    CellsUsed      += localCellsUsed;
                    CellsDiscarded += localCellsDiscarded;
                    CellsUsedCut   += localCellsUsedCut;
                    CellsUsedFill  += localCellsUsedFill;
                    Volume         += localVolume;
                    CutFillVolume.AddCutFillVolume(localCutFillVolume.CutVolume, localCutFillVolume.FillVolume);

                    // Record the bits for this sub grid in the coverage map by requesting the whole sub grid
                    // of bits from the leaf level and setting it in one operation under an exclusive lock
                    if (!bits.IsEmpty())
                    {
                        var coverageMapSubGrid = CoverageMap.ConstructPathToCell(baseScanSubGrid.OriginX, baseScanSubGrid.OriginY, SubGridPathConstructionType.CreateLeaf);
                        ((SubGridTreeLeafBitmapSubGrid)coverageMapSubGrid).Bits = bits;
                    }
                }
                finally
                {
                    _lock.Release();
                }
            }
            catch (Exception e)
            {
                _log.LogError(e, "Exception thrown by ProcessVolumeInformationForSubGrid - rethrowing");
                throw;
            }
            finally
            {
                _log.LogDebug("Out ProcessVolumeInformationForSubGrid");
            }
        }
Пример #19
0
        ///  <summary>
        ///  Builds a fully analyzed vector of profiled cells from the list of cell passed to it
        ///  </summary>
        public override bool Analyze(List <SummaryVolumeProfileCell> profileCells, ISubGridSegmentCellPassIterator cellPassIterator)
        {
            Log.LogDebug($"Analyze Summary Volume ProfileCells. Processing {profileCells.Count}");

            var                CurrentSubgridOrigin = new SubGridCellAddress(int.MaxValue, int.MaxValue);
            ISubGrid           SubGrid        = null;
            IServerLeafSubGrid _SubGridAsLeaf = null;

            profileCell = null;

            // Construct the set of requestors to query elevation sub grids needed for the summary volume calculations.
            var filterSet = FilterUtilities.ConstructFilters(FilterSet, VolumeType);

            IntermediaryFilterRequired = filterSet.Filters.Length == 3;
            var utilities = DIContext.Obtain <IRequestorUtilities>();

            Requestors = utilities.ConstructRequestors(null, SiteModel, Overrides, LiftParams,
                                                       utilities.ConstructRequestorIntermediaries(SiteModel, filterSet, true, GridDataType.HeightAndTime),
                                                       AreaControlSet.CreateAreaControlSet(), PDExistenceMap);

            var cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            for (int I = 0; I < profileCells.Count; I++)
            {
                profileCell = profileCells[I];

                // get sub grid origin for cell address
                var thisSubgridOrigin = new SubGridCellAddress(profileCell.OTGCellX >> SubGridTreeConsts.SubGridIndexBitsPerLevel,
                                                               profileCell.OTGCellY >> SubGridTreeConsts.SubGridIndexBitsPerLevel);

                if (!CurrentSubgridOrigin.Equals(thisSubgridOrigin)) // if we have a new sub grid to fetch
                {
                    // if we have an existing sub grid and a change in sub grid detected process the current sub grid profile cell list
                    if (SubGrid != null)
                    {
                        ProcessSubGroup(new SubGridCellAddress(CurrentSubgridOrigin.X << SubGridTreeConsts.SubGridIndexBitsPerLevel, CurrentSubgridOrigin.Y << SubGridTreeConsts.SubGridIndexBitsPerLevel),
                                        PDExistenceMap[CurrentSubgridOrigin.X, CurrentSubgridOrigin.Y], cellOverrideMask);
                        cellOverrideMask.Clear();
                    }

                    SubGrid     = null;
                    cellCounter = 0;

                    // Does the sub grid tree contain this node in it's existence map? if so get sub grid
                    if (PDExistenceMap[thisSubgridOrigin.X, thisSubgridOrigin.Y])
                    {
                        SubGrid = SubGridTrees.Server.Utilities.SubGridUtilities.LocateSubGridContaining
                                      (SiteModel.PrimaryStorageProxy, SiteModel.Grid, profileCell.OTGCellX, profileCell.OTGCellY, SiteModel.Grid.NumLevels, false, false);
                    }

                    _SubGridAsLeaf = SubGrid as ServerSubGridTreeLeaf;
                    if (_SubGridAsLeaf == null)
                    {
                        continue;
                    }

                    CurrentSubgridOrigin = thisSubgridOrigin; // all good to proceed with this sub grid
                }

                profileCellList[cellCounter++] = profileCell; // add cell to list to process for this sub grid
                cellOverrideMask.SetBit(profileCell.OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask, profileCell.OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask);
            }

            if (cellCounter > 0 && SubGrid != null) // Make sure we process last list
            {
                ProcessSubGroup(new SubGridCellAddress(CurrentSubgridOrigin.X << SubGridTreeConsts.SubGridIndexBitsPerLevel, CurrentSubgridOrigin.Y << SubGridTreeConsts.SubGridIndexBitsPerLevel),
                                PDExistenceMap[CurrentSubgridOrigin.X, CurrentSubgridOrigin.Y], cellOverrideMask);
            }

            return(true);
        }