コード例 #1
0
        /// <summary>
        /// Builds the pipeline configured per the supplied state ready to execute the request
        /// </summary>
        public bool Build()
        {
            // Todo: This method is left as async as a reminder that the GetExistenveMap workflows could either be async (as they
            // potentially read from the persistent store), and/or they couild be cached in the site model designs/surveyed surfaces contexts
            // See Jira CCSSSCON-1481
            try
            {
                var stopWatch = Stopwatch.StartNew();

                // Ensure the task is initialised with the request descriptor
                Task.RequestDescriptor = RequestDescriptor;

                // Ensure the Task grid data type matches the pipeline processor
                Task.GridDataType = GridDataType;

                // Introduce the task and the pipeline to each other
                Pipeline.PipelineTask = Task;
                Task.PipeLine         = Pipeline;

                (Pipeline as ISubGridPipelineBase <TSubGridsRequestArgument>).CustomArgumentInitializer = CustomArgumentInitializer;

                if ((Filters?.Filters?.Length ?? 0) == 0)
                {
                    _log.LogError($"Filters supplied to pipeline processor is null or empty, replacing with single default filter");
                    Filters = new FilterSet(new CombinedFilter());
                }

                // Construct an aggregated set of excluded surveyed surfaces for the filters used in the query
                foreach (var filter in Filters.Filters)
                {
                    if (filter != null && SurveyedSurfaceExclusionList.Length > 0)
                    {
                        SurveyedSurfaceExclusionList = new Guid[filter.AttributeFilter.SurveyedSurfaceExclusionList.Length];
                        Array.Copy(filter.AttributeFilter.SurveyedSurfaceExclusionList, SurveyedSurfaceExclusionList,
                                   SurveyedSurfaceExclusionList.Length);
                    }
                }

                // Get the SiteModel for the request
                SiteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(DataModelID);
                if (SiteModel == null)
                {
                    Response.ResultStatus = RequestErrorStatus.NoSuchDataModel;
                    return(false);
                }

                SpatialExtents = SiteModel.GetAdjustedDataModelSpatialExtents(SurveyedSurfaceExclusionList);

                if (!SpatialExtents.IsValidPlanExtent)
                {
                    Response.ResultStatus = RequestErrorStatus.FailedToRequestDatamodelStatistics; // Or there was no data in the model
                    return(false);
                }

                // Get the current production data existence map from the site model
                ProdDataExistenceMap = SiteModel.ExistenceMap;

                // Obtain the sub grid existence map for the project
                // Retrieve the existence map for the datamodel
                OverallExistenceMap = new SubGridTreeSubGridExistenceBitMask {
                    CellSize = SubGridTreeConsts.SubGridTreeDimension * SiteModel.CellSize
                };

                if (RequireSurveyedSurfaceInformation)
                {
                    // Obtain local reference to surveyed surfaces (lock free access)
                    var localSurveyedSurfaces = SiteModel.SurveyedSurfaces;

                    if (localSurveyedSurfaces != null)
                    {
                        // Construct two filtered surveyed surface lists to act as a rolling pair used as arguments
                        // to the ProcessSurveyedSurfacesForFilter method
                        var filterSurveyedSurfaces   = DIContext.Obtain <ISurveyedSurfaces>();
                        var filteredSurveyedSurfaces = DIContext.Obtain <ISurveyedSurfaces>();

                        SurveyedSurfacesExcludedViaTimeFiltering = Filters.Filters.Length > 0;

                        foreach (var filter in Filters.Filters)
                        {
                            if (!localSurveyedSurfaces.ProcessSurveyedSurfacesForFilter(DataModelID, filter,
                                                                                        filteredSurveyedSurfaces, filterSurveyedSurfaces, OverallExistenceMap))
                            {
                                Response.ResultStatus = RequestErrorStatus.FailedToRequestSubgridExistenceMap;
                                return(false);
                            }

                            SurveyedSurfacesExcludedViaTimeFiltering &= filterSurveyedSurfaces.Count == 0;
                        }
                    }
                }

                OverallExistenceMap.SetOp_OR(ProdDataExistenceMap);

                foreach (var filter in Filters.Filters)
                {
                    if (filter != null)
                    {
                        if (!DesignFilterUtilities.ProcessDesignElevationsForFilter(SiteModel, filter, OverallExistenceMap))
                        {
                            Response.ResultStatus = RequestErrorStatus.NoDesignProvided;
                            return(false);
                        }

                        Response.ResultStatus = FilterUtilities.PrepareFilterForUse(filter, DataModelID);
                        if (Response.ResultStatus != RequestErrorStatus.OK)
                        {
                            _log.LogInformation($"PrepareFilterForUse failed: Datamodel={DataModelID}");
                            return(false);
                        }
                    }
                }

                // Adjust the extents we have been given to encompass the spatial extent of the supplied filters (if any)
                Filters.ApplyFilterAndSubsetBoundariesToExtents(SpatialExtents);

                // If this request involves a relationship with a design then ensure the existence map
                // for the design is loaded in to memory to allow the request pipeline to confine
                // sub grid requests that overlay the actual design
                if (RequestRequiresAccessToDesignFileExistenceMap)
                {
                    if (CutFillDesign == null || CutFillDesign.DesignID == Guid.Empty)
                    {
                        _log.LogError($"No design provided to cut fill, summary volume or thickness overlay render request for datamodel {DataModelID}");
                        Response.ResultStatus = RequestErrorStatus.NoDesignProvided;
                        return(false);
                    }

                    DesignSubGridOverlayMap = GetExistenceMaps().GetSingleExistenceMap(DataModelID, Consts.EXISTENCE_MAP_DESIGN_DESCRIPTOR, CutFillDesign.DesignID);

                    if (DesignSubGridOverlayMap == null)
                    {
                        _log.LogError($"Failed to request sub grid overlay index for design {CutFillDesign.DesignID} in datamodel {DataModelID}");
                        Response.ResultStatus = RequestErrorStatus.NoDesignProvided;
                        return(false);
                    }

                    DesignSubGridOverlayMap.CellSize = SubGridTreeConsts.SubGridTreeDimension * SiteModel.CellSize;
                }

                // Impose the final restriction on the spatial extents from the client context
                SpatialExtents.Intersect(OverrideSpatialExtents);

                // Introduce the Request analyzer to the pipeline and spatial extents it requires
                RequestAnalyser.Pipeline     = Pipeline;
                RequestAnalyser.WorldExtents = SpatialExtents;

                ConfigurePipeline();

                _log.LogInformation($"Pipeline processor build phase completed in {stopWatch.Elapsed}");

                return(true);
            }
            catch (Exception e)
            {
                _log.LogError(e, "Exception occurred in pipeline builder");
                throw;
            }
        }