示例#1
0
        /// <summary>
        /// Unpacks elements of the request argument that are represented as byte arrays in the Ignite request
        /// </summary>
        protected void PrepareArgument()
        {
            var originatingIgniteNodeId = Ignite.GetCluster().GetLocalNode().Id;

            Log.LogInformation($"Preparing argument with OriginatingIgniteNodeId = {originatingIgniteNodeId}, TRexNodeId = {TRexNodeId}");

            arg = new TSubGridsRequestArgument
            {
                ProjectID    = SiteModelID,
                RequestID    = RequestID,
                GridDataType = RequestedGridDataType,
                IncludeSurveyedSurfaceInformation = IncludeSurveyedSurfaceInformation,
                ProdDataMaskBytes            = ProdDataMask.ToBytes(),
                SurveyedSurfaceOnlyMaskBytes = SurveyedSurfaceOnlyMask.ToBytes(),
                Filters = Filters,
                OriginatingIgniteNodeId = originatingIgniteNodeId,
                TRexNodeID                  = TRexNodeId,
                ReferenceDesign             = ReferenceDesign,
                AreaControlSet              = AreaControlSet,
                SubGridsRequestComputeStyle = SubGridsRequestComputeStyle
            };

            CustomArgumentInitializer?.Invoke(arg);
        }
示例#2
0
        private void PrepareForExecution()
        {
            CheckArguments();

            // Construct the argument to be supplied to the compute cluster
            PrepareArgument();

            Log.LogInformation($"Prepared argument has TRexNodeId = {arg.TRexNodeID}");
            Log.LogInformation($"Production Data mask in argument to renderer contains {ProdDataMask.CountBits()} sub grids");
            Log.LogInformation($"Surveyed Surface mask in argument to renderer contains {SurveyedSurfaceOnlyMask.CountBits()} sub grids");

            CreateSubGridListener();
        }
示例#3
0
        /// <summary>
        /// Overrides the base Execute() semantics to add a listener available for aggregated processing of sub grids in the request engine.
        /// </summary>
        public override TSubGridRequestsResponse Execute()
        {
            CheckArguments();

            // Construct the argument to be supplied to the compute cluster
            PrepareArgument();

            Log.LogInformation($"Prepared argument has TRexNodeId = {arg.TRexNodeID}");
            Log.LogInformation($"Production Data mask in argument to renderer contains {ProdDataMask.CountBits()} sub grids");
            Log.LogInformation($"Surveyed Surface mask in argument to renderer contains {SurveyedSurfaceOnlyMask.CountBits()} sub grids");

            TSubGridRequestsResponse taskResult = null;

            var sw = Stopwatch.StartNew();

            try
            {
                // Construct the function to be used
                var func = new SubGridsRequestComputeFuncAggregative <TSubGridsRequestArgument, TSubGridRequestsResponse>(TRexTask);

                // Invoke it.
                // Note that this is NOT asking the grid to perform a remote invocation of the request as this aggregative
                // processing is already executing on the cluster node containing sub grids.
                taskResult = func.Invoke(arg);
            }
            finally
            {
                Log.LogInformation($"TaskResult {(taskResult == null ? "<NullResult>" : taskResult.ResponseCode.ToString())}: SubGridRequests.Execute() for DM:{TRexTask.PipeLine.DataModelID} from node {TRexTask.TRexNodeID} for data type {TRexTask.GridDataType} took {sw.ElapsedMilliseconds}ms");
            }

            // Advise the pipeline of all the sub grids that were examined in the aggregated processing
            TRexTask.PipeLine.SubGridsProcessed(taskResult?.NumSubgridsExamined ?? 0);

            // Notify the pipeline that all processing has been completed for it
            TRexTask.PipeLine.PipelineCompleted = true;

            // Send the appropriate response to the caller
            return(taskResult);
        }
示例#4
0
        /// <summary>
        /// Performs scanning operations across sub grids, determining if they should be included in the request
        /// </summary>
        protected bool SubGridEvent(ISubGrid SubGrid)
        {
            // The given sub grid is a leaf sub grid containing a bit mask recording sub grid inclusion in the overall sub grid map
            // being iterated over. This map includes, production data only sub grids, surveyed surface data only sub grids and
            // sub grids that will have both types of data retrieved for them. The analyzer needs to separate out the two in terms
            // of the masks of sub grids that needs to be queried, one for production data (and optionally surveyed surface data) and
            // one for surveyed surface data only.
            // Get the matching sub grid from the production data only bit mask sub grid tree and use this sub grid to be able to separate
            // the two sets of sub grids

            var ProdDataSubGrid = Pipeline.ProdDataExistenceMap.LocateSubGridContaining(SubGrid.OriginX, SubGrid.OriginY) as SubGridTreeLeafBitmapSubGrid;

            byte ScanMinXb, ScanMinYb, ScanMaxXb, ScanMaxYb;
            var  OTGCellSize = SubGrid.Owner.CellSize / SubGridTreeConsts.SubGridTreeDimension;
            var  CastSubGrid = (SubGridTreeLeafBitmapSubGrid)SubGrid;

            if (ScanningFullWorldExtent)
            {
                ScanMinXb = 0;
                ScanMinYb = 0;
                ScanMaxXb = SubGridTreeConsts.SubGridTreeDimensionMinus1;
                ScanMaxYb = SubGridTreeConsts.SubGridTreeDimensionMinus1;
            }
            else
            {
                // Calculate the range of cells in this sub grid we need to scan and request. The steps below
                // calculate the on-the-ground cell indices of the world coordinate bounding extents, then
                // determine the sub grid indices of the cell within this sub grid that contains those
                // cells, then determines the sub grid extents in this sub grid to scan over
                // Remember, each on-the-ground element (bit) in the existence map represents an
                // entire on-the-ground sub grid (32x32 OTG cells) in the matching sub grid tree.

                // Expand the number of cells scanned to create the rendered tile by a single cell width
                // on all sides to ensure the boundaries of tiles are rendered right to the edge of the tile.

                SubGrid.Owner.CalculateIndexOfCellContainingPosition(WorldExtents.MinX - OTGCellSize,
                                                                     WorldExtents.MinY - OTGCellSize,
                                                                     out var ScanMinX, out var ScanMinY);
                SubGrid.Owner.CalculateIndexOfCellContainingPosition(WorldExtents.MaxX + OTGCellSize,
                                                                     WorldExtents.MaxY + OTGCellSize,
                                                                     out var ScanMaxX, out var ScanMaxY);

                ScanMinX = Math.Max(CastSubGrid.OriginX, ScanMinX);
                ScanMinY = Math.Max(CastSubGrid.OriginY, ScanMinY);
                ScanMaxX = Math.Min(ScanMaxX, CastSubGrid.OriginX + SubGridTreeConsts.SubGridTreeDimensionMinus1);
                ScanMaxY = Math.Min(ScanMaxY, CastSubGrid.OriginY + SubGridTreeConsts.SubGridTreeDimensionMinus1);

                SubGrid.GetSubGridCellIndex(ScanMinX, ScanMinY, out ScanMinXb, out ScanMinYb);
                SubGrid.GetSubGridCellIndex(ScanMaxX, ScanMaxY, out ScanMaxXb, out ScanMaxYb);
            }

            // Iterate over the sub range of cells (bits) in this sub grid and request the matching sub grids

            for (byte I = ScanMinXb; I <= ScanMaxXb; I++)
            {
                for (byte J = ScanMinYb; J <= ScanMaxYb; J++)
                {
                    if (CastSubGrid.Bits.BitSet(I, J))
                    {
                        TotalNumberOfCandidateSubGrids++;

                        // If there is a design sub grid overlay map supplied to the renderer then
                        // check to see if this sub grid is in the map, and if so then continue. If it is
                        // not in the map then it does not need to be considered. Design sub grid overlay
                        // indices contain a single bit for each on the ground sub grid (32x32 cells),
                        // which means they are only 5 levels deep. This means the (OriginX + I, OriginY + J)
                        // origin coordinates correctly identify the single bits that denote the sub grids.

                        if (Pipeline.DesignSubGridOverlayMap != null)
                        {
                            if (!Pipeline.DesignSubGridOverlayMap.GetCell(SubGrid.OriginX + I, SubGrid.OriginY + J))
                            {
                                continue;
                            }
                        }

                        // If there is a spatial filter in play then determine if the sub grid about to be requested intersects the spatial filter extent

                        var SubGridSatisfiesFilter = true;
                        foreach (var filter in Pipeline.FilterSet.Filters)
                        {
                            if (filter != null)
                            {
                                var spatialFilter = filter.SpatialFilter;

                                if (spatialFilter.IsSpatial && spatialFilter.Fence != null && spatialFilter.Fence.NumVertices > 0)
                                {
                                    SubGridSatisfiesFilter =
                                        spatialFilter.Fence.IntersectsExtent(
                                            CastSubGrid.Owner.GetCellExtents(CastSubGrid.OriginX + I, CastSubGrid.OriginY + J));
                                }
                                else
                                {
                                    if (spatialFilter.IsPositional)
                                    {
                                        CastSubGrid.Owner.GetCellCenterPosition(CastSubGrid.OriginX + I, CastSubGrid.OriginY + J,
                                                                                out var centerX, out var centerY);

                                        SubGridSatisfiesFilter = MathUtilities.Hypot(spatialFilter.PositionX - centerX, spatialFilter.PositionY - centerY) <
                                                                 spatialFilter.PositionRadius + (Math.Sqrt(2) * CastSubGrid.Owner.CellSize) / 2;
                                    }
                                }

                                if (!SubGridSatisfiesFilter)
                                {
                                    break;
                                }
                            }
                        }

                        if (SubGridSatisfiesFilter)
                        {
                            TotalNumberOfSubGridsAnalysed++;

                            if (SubmitSinglePageOfRequests)
                            {
                                if ((TotalNumberOfSubGridsAnalysed - 1) / SinglePageRequestSize < SinglePageRequestNumber)
                                {
                                    continue;
                                }

                                if ((TotalNumberOfSubGridsAnalysed - 1) / SinglePageRequestSize > SinglePageRequestNumber)
                                {
                                    return(false); // Returning false halts scanning of sub grids
                                }
                            }

                            // Add the leaf sub grid identified by the address below, along with the production data and surveyed surface
                            // flags to the sub grid tree being used to aggregate all the sub grids that need to be queried for the request

                            TotalNumberOfSubGridsToRequest++;

                            // If a single page of sub grids is being requested determine if the sub grid in question is a
                            // part of the page, and if the page has been filled yet.
                            if (CountingRequestsOnly)
                            {
                                continue;
                            }

                            // Set the ProdDataMask for the production data
                            if (ProdDataSubGrid?.Bits.BitSet(I, J) == true)
                            {
                                ProdDataMask.SetCell(CastSubGrid.OriginX + I, CastSubGrid.OriginY + J, true);
                            }
                            else
                            {
                                // Note: This is ONLY recording the sub grids that have surveyed surface data required, but not production data
                                // as a delta to the production data requests
                                SurveyedSurfaceOnlyMask.SetCell(CastSubGrid.OriginX + I, CastSubGrid.OriginY + J, true);
                            }
                        }
                    }
                }
            }

            return(true);
        }