Esempio n. 1
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_ForEach_Function()
        {
            // Test iteration function for empty, full and arbitrary masks
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            bits.ForEach((x, y) => { return(true); });
            Assert.Equal(bits.CountBits(), SubGridTreeConsts.CellsPerSubGrid);

            bits.Clear();
            bits.ForEach((x, y) => { return(x < 16); });
            Assert.Equal(bits.CountBits(), SubGridTreeConsts.CellsPerSubGrid / 2);

            bits.Clear();
            bits.ForEach((x, y) => { return((x == 1) && (y == 1)); });
            Assert.Equal(1, bits.CountBits());
        }
Esempio n. 2
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");
        }
Esempio n. 3
0
        public void Test_SubGridTreeBitmapSubGridBitsTests_Clear()
        {
            SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Filled);

            Assert.True(bits.IsFull(), "Bits not full");

            bits.Clear();
            Assert.True(bits.IsEmpty(), "Bits not empty after performing a Clear()");
        }
Esempio n. 4
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());
        }
Esempio n. 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);
                }
            }
        }
Esempio n. 6
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)");
        }
Esempio n. 7
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);
        }
Esempio n. 8
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);
                }
            }
        }
Esempio n. 9
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
                }
            }
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        /// <summary>
        /// Computes a filter patch for a sub grid with respect to the alignment and a station/offset range over the alignment.
        /// Note: This is a CPU intensive operation. TRex currently uses an approach of polygonal spatial filtering with a boundary
        /// computed from the alignment geometry and station/offset bounds.
        /// </summary>
        public override bool ComputeFilterPatch(double startStn, double endStn, double leftOffset, double rightOffset,
                                                SubGridTreeBitmapSubGridBits mask, SubGridTreeBitmapSubGridBits patch,
                                                double originX, double originY, double cellSize, double offset)
        {
            var leftOffsetValue  = -leftOffset;
            var rightOffsetValue = rightOffset;

            if (leftOffsetValue > rightOffsetValue)
            {
                MinMax.Swap(ref leftOffsetValue, ref rightOffsetValue);
            }

            //   SIGLogMessage.PublishNoODS(Self, Format('Constructing filter patch for Stn:%.3f-%.3f, Ofs:%.3f-%.3f, originX:%.3f, originY:%.3f',
            //   [startStn, endStn, LeftOffsetValue, RightOffsetValue, originX, originY]));

            if (_data == null)
            {
                _log.LogError("No data element provided to SVL filter patch calculation");
                return(false);
            }

            patch.Clear();

            // Check the corners of the sub grid. If all are out of the offset range then assume
            // none of the cells are applicable. All four corners need to be on the same side of the
            // alignment in terms of offset to fail the sub grid.
            var cornersOutOfOffsetRange     = 0;
            var cornersOutOfOffsetRangeSign = 0;

            var originXPlusHalfCellSize = originX + cellSize / 2;
            var originYPlusHalfCellSize = originY + cellSize / 2;

            for (var i = 0; i < _corners.Length; i++)
            {
                _data.ComputeStnOfs(originXPlusHalfCellSize + _corners[i].X * cellSize, originYPlusHalfCellSize + _corners[i].Y * cellSize, out var stn, out var ofs);

                if (!(stn != Consts.NullDouble && ofs != Consts.NullDouble && Range.InRange(stn, startStn, endStn)) &&
                    !Range.InRange(ofs, leftOffsetValue, rightOffsetValue))
                {
                    if (i == 0)
                    {
                        cornersOutOfOffsetRangeSign = Math.Sign(ofs);
                    }

                    if (cornersOutOfOffsetRangeSign == Math.Sign(ofs))
                    {
                        cornersOutOfOffsetRange++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (cornersOutOfOffsetRange == _corners.Length)
            {
                // Return success with the empty patch
                //SIGLogMessage.PublishNoODS(Self, 'All corners of patch exceed stn:ofs boundary');
                return(true);
            }

            // Iterate across the cells in the mask computing and checking the stn:ofs of
            // each point using the previously successful element as a hint for the next
            // computation
            for (var i = 0; i < SubGridTreeConsts.SubGridTreeDimension; i++)
            {
                for (var j = 0; j < SubGridTreeConsts.SubGridTreeDimension; j++)
                {
                    if (!mask.BitSet(i, j))
                    {
                        continue;
                    }

                    // Force element to be nil for all calculation until we resolve the issue
                    // of an in appropriate element 'capturing' the focus and then being used to
                    // calculate inappropriate offsets due to it's station range covering the
                    // points being computed.

                    NFFStationedLineworkEntity element = null;

                    _data.ComputeStnOfs(originXPlusHalfCellSize + i * cellSize, originYPlusHalfCellSize + j * cellSize,
                                        out var stn, out var ofs, ref element);

                    if (stn != Consts.NullDouble && ofs != Consts.NullDouble)
                    {
                        patch.SetBitValue(i, j, Range.InRange(stn, startStn, endStn) && Range.InRange(ofs, leftOffsetValue, rightOffsetValue));
                    }
                }
            }

            //  SIGLogMessage.PublishNoODS(Self, Format('Filter patch construction successful with %d bits', [patch.CountBits]));

            return(true);
        }
Esempio n. 12
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);
        }
Esempio n. 13
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);
        }