예제 #1
0
        public override void InternalFromBinary(IBinaryRawReader reader)
        {
            var version = VersionSerializationHelper.CheckVersionByte(reader, VERSION_NUMBER);

            if (version == 1)
            {
                CalcResult = (DesignProfilerRequestResult)reader.ReadByte();

                if (reader.ReadBoolean())
                {
                    Heights = new ClientHeightLeafSubGrid();
                    Heights.FromBytes(reader.ReadByteArray());
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Calculates a cut/fill sub grid from two elevation sub grids, replacing the elevations
 /// in the first sub grid with the resulting cut fill values
 /// </summary>
 public static void ComputeCutFillSubGrid(IClientHeightLeafSubGrid subGrid1, IClientHeightLeafSubGrid subGrid2)
 {
     SubGridUtilities.SubGridDimensionalIterator((I, J) =>
     {
         if (subGrid1.Cells[I, J] != Consts.NullHeight)
         {
             if (subGrid2.Cells[I, J] != Consts.NullHeight)
             {
                 subGrid1.Cells[I, J] -= subGrid2.Cells[I, J];
             }
             else
             {
                 subGrid1.Cells[I, J] = Consts.NullHeight;
             }
         }
     });
 }
예제 #3
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);
        }
예제 #4
0
        /// <summary>
        /// Processes each sub grid in turn into the resulting profile.
        /// </summary>
        public void ProcessSubGroup(SubGridCellAddress address, bool prodDataAtAddress, SubGridTreeBitmapSubGridBits cellOverrideMask)
        {
            var okToProceed = false;

            // Execute a client grid request for each requester and create an array of the results
            var clientGrids = Requestors.Select(x =>
            {
                x.CellOverrideMask = cellOverrideMask;

                // Reach into the sub grid request layer and retrieve an appropriate sub grid
                var requestSubGridInternalResult = x.RequestSubGridInternal(address, prodDataAtAddress, true);
                if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError)
                {
                    Log.LogError($"Request for sub grid {address} request failed with code {requestSubGridInternalResult.requestResult}");
                }

                return(requestSubGridInternalResult.clientGrid);
            }).ToArray();

            // If an intermediary result was requested then merge the 'from' and intermediary sub grids now
            if (IntermediaryFilterRequired)
            {
                MergeIntermediaryResults(clientGrids[0] as ClientHeightAndTimeLeafSubGrid, clientGrids[1] as ClientHeightAndTimeLeafSubGrid);
                //... and chop out the intermediary grid
                clientGrids = new[] { clientGrids[0], clientGrids[2] };
            }

            // Assign the results of the sub grid requests according to the ordering of the filter in the overall
            // volume type context of the request
            ClientHeightAndTimeLeafSubGrid heightsGrid1 = null;

            if (VolumeType == VolumeComputationType.BetweenFilterAndDesign || VolumeType == VolumeComputationType.Between2Filters)
            {
                heightsGrid1 = clientGrids[0] as ClientHeightAndTimeLeafSubGrid;
            }

            ClientHeightAndTimeLeafSubGrid heightsGrid2 = null;

            if (VolumeType == VolumeComputationType.BetweenDesignAndFilter)
            {
                heightsGrid2 = clientGrids[0] as ClientHeightAndTimeLeafSubGrid;
            }
            else if (VolumeType == VolumeComputationType.Between2Filters)
            {
                heightsGrid2 = clientGrids[1] as ClientHeightAndTimeLeafSubGrid;
            }

            IClientHeightLeafSubGrid designHeights = null;

            if (VolumeType == VolumeComputationType.BetweenFilterAndDesign || VolumeType == VolumeComputationType.BetweenDesignAndFilter)
            {
                if (svDesignWrapper?.Design != null)
                {
                    var getDesignHeightsResult = svDesignWrapper.Design.GetDesignHeightsViaLocalCompute(SiteModel, svDesignWrapper.Offset, address, SiteModel.CellSize);

                    if (getDesignHeightsResult.errorCode != DesignProfilerRequestResult.OK || getDesignHeightsResult.designHeights == null)
                    {
                        if (getDesignHeightsResult.errorCode == DesignProfilerRequestResult.NoElevationsInRequestedPatch)
                        {
                            Log.LogInformation("Call to RequestDesignElevationPatch failed due to no elevations in requested patch.");
                        }
                        else
                        {
                            Log.LogError($"Call to RequestDesignElevationPatch failed due to no TDesignProfilerRequestResult return code {getDesignHeightsResult.errorCode}.");
                        }
                    }
                    else
                    {
                        designHeights = getDesignHeightsResult.designHeights;
                        okToProceed   = true;
                    }
                }
                else
                {
                    Log.LogError("Missing design reference. Call to request Summary Volumes Profile using design failed due to no reference design");
                }
            }
            else
            {
                okToProceed = true;
            }

            if (okToProceed)
            {
                for (int I = 0; I < cellCounter; I++)
                {
                    int cellX = profileCellList[I].OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask;
                    int cellY = profileCellList[I].OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask;
                    if (heightsGrid1 != null)
                    {
                        profileCellList[I].LastCellPassElevation1 = heightsGrid1.Cells[cellX, cellY];
                    }
                    if (heightsGrid2 != null)
                    {
                        profileCellList[I].LastCellPassElevation2 = heightsGrid2.Cells[cellX, cellY];
                    }
                    profileCellList[I].DesignElev = designHeights?.Cells[cellX, cellY] ?? CellPassConsts.NullHeight;
                }
            }
        }