Esempio n. 1
0
        public void Test_SubgridCellAddress_Equality()
        {
            SubGridCellAddress ca  = new SubGridCellAddress(1, 1);
            SubGridCellAddress ca2 = new SubGridCellAddress(1, 1);
            SubGridCellAddress ca3 = new SubGridCellAddress(3, 3);

            Assert.True(ca.Equals(ca2), "Equality check between identical addresses failed");
            Assert.False(ca.Equals(ca3), "Inequality between different addresses failed");
        }
Esempio n. 2
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. 3
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. 4
0
        /// <summary>
        /// Constructs a vector of cells in profileCells along the path of the profile geometry containing in nEECoords
        /// </summary>
        public bool Build(XYZ[] nEECoords, List <T> profileCells)
        {
            NEECoords    = nEECoords;
            ProfileCells = profileCells;

            CellSize = SiteModel.CellSize;

            CurrStationPos = 0;

            CurrentSubgridOrigin  = new SubGridCellAddress(int.MaxValue, int.MaxValue);
            ReturnDesignElevation = CutFillDesignWrapper?.Design != null;
            DesignElevations      = null;

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

            for (int loopBound = NEECoords.Length - 1, I = 0; I < loopBound; I++)
            {
                StartX       = NEECoords[I].X;
                StartY       = NEECoords[I].Y;
                StartStation = NEECoords[I].Z;

                EndX       = NEECoords[I + 1].X;
                EndY       = NEECoords[I + 1].Y;
                EndStation = NEECoords[I + 1].Z;

                if (I == 0)                                               // Add start point of profile line to intercept list
                {
                    CurrStationPos = SlicerToolUsed ? 0 : NEECoords[I].Z; // alignment profiles pass in station for more accuracy
                    VtHzIntercepts.AddPoint(StartX, StartY, CurrStationPos);
                }

                Distance = SlicerToolUsed
          ? MathUtilities.Hypot(EndX - StartX, EndY - StartY) // station is not passed so compute
          : EndStation - StartStation;                        // use precise station passed

                if (Distance == 0)                            // if we have two points the same
                {
                    continue;
                }

                // Get all intercepts between profile line and cell boundaries for this segment
                CalculateHorizontalIntercepts(CurrStationPos); // pass the distance down alignment this segment starts
                CalculateVerticalIntercepts(CurrStationPos);

                CurrStationPos += Distance; // add distance to current station
            }

            // Merge vertical and horizontal cell boundary/profile line intercepts
            VtHzIntercepts.MergeInterceptLists(VtIntercepts, HzIntercepts);

            // Add end point of profile line to intercept list
            VtHzIntercepts.AddPoint(EndX, EndY, CurrStationPos);

            // Update each intercept with it's midpoint and intercept length
            // i.e. the midpoint on the line between one intercept and the next one
            // and the length between those intercepts
            VtHzIntercepts.UpdateMergedListInterceptMidPoints();

            if (VtHzIntercepts.Count > ProfileCells.Capacity)
            {
                ProfileCells.Capacity = VtHzIntercepts.Count;
            }

            // Iterate over all intercepts calculating the results for each cell that lies in
            // a subgrid handled by this node
            for (int i = 0; i < VtHzIntercepts.Count; i++)
            {
                if (Aborted)
                {
                    return(false);
                }

                // Determine the on-the-ground cell underneath the midpoint of each intercept line
                SiteModel.Grid.CalculateIndexOfCellContainingPosition(VtHzIntercepts.Items[i].MidPointX,
                                                                      VtHzIntercepts.Items[i].MidPointY, out OTGCellX, out OTGCellY);

                ThisSubgridOrigin = new SubGridCellAddress(OTGCellX & ~SubGridTreeConsts.SubGridLocalKeyMask, OTGCellY & ~SubGridTreeConsts.SubGridLocalKeyMask);

                if (!CurrentSubgridOrigin.Equals(ThisSubgridOrigin))
                {
                    if (!primaryPartitionMap[ThisSubgridOrigin.ToSpatialPartitionDescriptor()])
                    {
                        continue;
                    }

                    CurrentSubgridOrigin = ThisSubgridOrigin;

                    if (!ProfileFilterMask.ConstructSubGridCellFilterMask(SiteModel, CurrentSubgridOrigin, VtHzIntercepts, i, FilterMask, CellFilter,
                                                                          SurfaceDesignMaskDesign))
                    {
                        continue;
                    }

                    if (ReturnDesignElevation && CutFillDesignWrapper?.Design != null) // cut fill profile request then get elevation at same spot along design
                    {
                        var getDesignHeightsResult = CutFillDesignWrapper.Design.GetDesignHeightsViaLocalCompute(SiteModel, CutFillDesignWrapper.Offset, new SubGridCellAddress(OTGCellX, OTGCellY), CellSize);

                        DesignElevations = getDesignHeightsResult.designHeights;
                        DesignResult     = getDesignHeightsResult.errorCode;

                        if (DesignResult != DesignProfilerRequestResult.OK &&
                            DesignResult != DesignProfilerRequestResult.NoElevationsInRequestedPatch)
                        {
                            continue;
                        }

                        if (DesignResult == DesignProfilerRequestResult.NoElevationsInRequestedPatch)
                        {
                            DesignElevations = null; // force a null height to be written
                        }
                    }
                }

                if (FilterMask.BitSet(OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask, OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask))
                {
                    AddCellPassesDataToList(OTGCellX, OTGCellY, VtHzIntercepts.Items[i].ProfileItemIndex, VtHzIntercepts.Items[i].InterceptLength);
                }
            }

            Log.LogInformation($"CellProfileBuilder constructed a vector of {VtHzIntercepts.Count} vertices");

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