Пример #1
0
        public override void InternalFromBinary(IBinaryRawReader reader)
        {
            base.InternalFromBinary(reader);

            var version = VersionSerializationHelper.CheckVersionByte(reader, VERSION_NUMBER);

            if (version == 1)
            {
                ProjectID = reader.ReadGuid() ?? Guid.Empty;

                if (reader.ReadBoolean())
                {
                    (DesignDescriptor = new DesignDescriptor()).FromBinary(reader);
                }

                AsAtDate = DateTime.SpecifyKind(new DateTime(reader.ReadLong()), DateTimeKind.Utc);

                if (reader.ReadBoolean())
                {
                    (Extents = new BoundingWorldExtent3D()).FromBinary(reader);
                }

                if (reader.ReadBoolean())
                {
                    (ExistenceMap = new SubGridTreeSubGridExistenceBitMask()).FromBytes(reader.ReadByteArray());
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Constructor
 /// </summary>
 public SubGridRequestsBase(ITRexTask tRexTask,
                            Guid siteModelID,
                            Guid requestID,
                            Guid trexNodeId,
                            GridDataType requestedGridDataType,
                            bool includeSurveyedSurfaceInformation,
                            ISubGridTreeBitMask prodDataMask,
                            ISubGridTreeBitMask surveyedSurfaceOnlyMask,
                            IFilterSet filters,
                            DesignOffset referenceDesign,
                            AreaControlSet areaControlSet,
                            Action <TSubGridsRequestArgument> customArgumentInitializer,
                            SubGridsRequestComputeStyle subGridsRequestComputeStyle) : this()
 {
     TRexTask                          = tRexTask;
     SiteModelID                       = siteModelID;
     RequestID                         = requestID;
     TRexNodeId                        = trexNodeId;
     RequestedGridDataType             = requestedGridDataType;
     IncludeSurveyedSurfaceInformation = includeSurveyedSurfaceInformation;
     ProdDataMask                      = prodDataMask;
     SurveyedSurfaceOnlyMask           = surveyedSurfaceOnlyMask;
     Filters                     = filters;
     ReferenceDesign             = referenceDesign;
     AreaControlSet              = areaControlSet;
     CustomArgumentInitializer   = customArgumentInitializer;
     SubGridsRequestComputeStyle = SubGridsRequestComputeStyle;
 }
Пример #3
0
        /// <summary>
        /// Integrates the cell passes processed from TAG files into sub grids within the live site model
        /// </summary>
        /// <param name="siteModelFromDatamodel">The site model to perform the change notifications for</param>
        /// <param name="task">The 'seed' task used as a hold all for aggregated machines</param>
        /// <param name="subGridIntegrator">The integrator to use to insert the new cell passes into the live site model</param>
        /// <param name="groupedAggregatedCellPasses">The set of all cell passes from all TAG files, grouped in to a single intermediary site model</param>
        /// <param name="numTagFilesRepresented">The number of TAG files represented in the data set being integrated</param>
        /// <param name="totalPassCountInAggregation">The sum total number of cell passes integrated in the live site model</param>
        private bool IntegrateCellPassesIntoLiveSiteModel(ISiteModel siteModelFromDatamodel,
                                                          AggregatedDataIntegratorTask task,
                                                          SubGridIntegrator subGridIntegrator,
                                                          ISubGridTree groupedAggregatedCellPasses,
                                                          int numTagFilesRepresented,
                                                          out long totalPassCountInAggregation)
        {
            _log.LogInformation($"Aggregation Task Process --> Labeling aggregated cell pass with correct machine ID for {siteModelFromDatamodel.ID}");

            totalPassCountInAggregation = 0;

            // This is a dirty map for the leaf sub grids and is stored as a bitmap grid
            // with one level fewer that the sub grid tree it is representing, and
            // with cells the size of the leaf sub grids themselves. As the cell coordinates
            // we have been given are with respect to the sub grid, we must transform them
            // into coordinates relevant to the dirty bitmap sub grid tree.

            _workingModelUpdateMap = new SubGridTreeSubGridExistenceBitMask
            {
                CellSize = SubGridTreeConsts.SubGridTreeDimension * siteModelFromDatamodel.CellSize,
                ID       = siteModelFromDatamodel.ID
            };

            // Integrate the cell pass data into the main site model and commit each sub grid as it is updated
            // ... first relabel the passes with the machine IDs from the persistent datamodel

            // Compute the vector of internal site model machine indexes between the intermediary site model constructed from the TAG files,
            // and the persistent site model the data us being processed into
            (short taskInternalMachineIndex, short datamodelInternalMachineIndex)[] internalMachineIndexMap = task.IntermediaryTargetMachines
Пример #4
0
        /// <summary>
        /// Constructs a cell profile analyzer that analyzes cells in a cell profile vector
        /// </summary>
        /// <param name="siteModel"></param>
        /// <param name="pDExistenceMap"></param>
        /// <param name="filterSet"></param>
        /// <param name="cellLiftBuilder"></param>
        /// <param name="overrides"></param>
        public CellProfileAnalyzer(ISiteModel siteModel,
                                   ISubGridTreeBitMask pDExistenceMap,
                                   IFilterSet filterSet,
                                   ICellLiftBuilder cellLiftBuilder,
                                   IOverrideParameters overrides,
                                   ILiftParameters liftParams)
            : base(siteModel, pDExistenceMap, filterSet, overrides, liftParams)
        {
            CellLiftBuilder = cellLiftBuilder;

            PassFilter = filterSet.Filters[0].AttributeFilter;
            if (PassFilter.HasElevationRangeFilter && PassFilter.ElevationRangeDesign.DesignID != Guid.Empty)
            {
                var design = siteModel.Designs.Locate(PassFilter.ElevationRangeDesign.DesignID);
                if (design == null)
                {
                    Log.LogError($"ElevationRangeDesign {PassFilter.ElevationRangeDesign.DesignID} is unknown in project {siteModel.ID}");
                }
                else
                {
                    PassFilterElevationRangeDesign = new DesignWrapper(PassFilter.ElevationRangeDesign, design);
                }
            }
            PassFilterAnnex = new CellPassAttributeFilterProcessingAnnex();
            CellFilter      = filterSet.Filters[0].SpatialFilter;
        }
Пример #5
0
        /// <summary>
        /// Constructor for the sub grid retriever helper
        /// </summary>
        /// <param name="siteModel">The project this sub gris is being retrieved from</param>
        /// <param name="gridDataType">The type of client grid data sub grids to be returned by this retriever</param>
        /// <param name="storageProxy">The Ignite storage proxy to be used when requesting data from the persistent store</param>
        /// <param name="filter">The TRex spatial and attribute filtering description for the request</param>
        /// <param name="filterAnnex">An annex of data related to cell by cell filtering where the attributes related to that cell may change from cell to cell</param>
        /// <param name="hasOverrideSpatialCellRestriction">The spatially selected cells are masked by a rectangular restriction boundary</param>
        /// <param name="overrideSpatialCellRestriction"></param>
        /// <param name="prepareGridForCacheStorageIfNoSieving">The cell coordinate bounding box restricting cells involved in the request</param>
        /// <param name="maxNumberOfPassesToReturn">The maximum number of passes in a cell in a sub grid that will be considered when processing the request</param>
        /// <param name="areaControlSet">The skip/step area control set for selection of cells with sub grids for processing. Cells not identified by the control set will return null values.</param>
        /// <param name="populationControl">The delegate responsible for populating events depended on for processing the request.</param>
        /// <param name="pDExistenceMap">The production data existence map for the project the request relates to</param>
        /// <param name="overrides">The set of overriding machine event values to use</param>
        /// <param name="liftParams">The set of layer/lift analysis parameters to use</param>
        public ProgressiveVolumesSubGridRetriever(ISiteModel siteModel,
                                                  GridDataType gridDataType,
                                                  IStorageProxy storageProxy,
                                                  ICombinedFilter filter,
                                                  ICellPassAttributeFilterProcessingAnnex filterAnnex,
                                                  bool hasOverrideSpatialCellRestriction,
                                                  BoundingIntegerExtent2D overrideSpatialCellRestriction,
                                                  bool prepareGridForCacheStorageIfNoSieving,
                                                  int maxNumberOfPassesToReturn,
                                                  AreaControlSet areaControlSet,
                                                  IFilteredValuePopulationControl populationControl,
                                                  ISubGridTreeBitMask pDExistenceMap,
                                                  IOverrideParameters overrides,
                                                  ILiftParameters liftParams)
            : base(siteModel, gridDataType, filter, filterAnnex,
                   hasOverrideSpatialCellRestriction, overrideSpatialCellRestriction, prepareGridForCacheStorageIfNoSieving, maxNumberOfPassesToReturn,
                   storageProxy, areaControlSet, populationControl, pDExistenceMap, overrides, liftParams)
        {
            // Clear any time element from the supplied filter. Time constraints ar derived from the startDate and endDate parameters
            filter.AttributeFilter.HasTimeFilter = false;

            // Clear any instruction in the filter to extract the earliest value - this has no meaning in progressive calculations
            filter.AttributeFilter.ReturnEarliestFilteredCellPass = false;

            // Remove any first/last/highest/lowest aspect from the filter - this has no meaning in progressive calculations
            filter.AttributeFilter.HasElevationTypeFilter = false;

            // Remove any machine filtering - the intent here is to examine volume progression over time, machine breakdowns don't make sense at this point
            filter.AttributeFilter.HasMachineFilter = false;
        }
Пример #6
0
        /// <summary>
        /// Given a design used as an elevation range filter aspect, retrieve the existence map for the design and
        /// includes it in the supplied overall existence map for the query
        /// </summary>
        public static bool ProcessDesignElevationsForFilter(ISiteModel siteModel, //Guid siteModelID,
                                                            ICombinedFilter filter,
                                                            ISubGridTreeBitMask overallExistenceMap)
        {
            if (filter == null)
            {
                return(true);
            }

            if (overallExistenceMap == null)
            {
                return(false);
            }

            if (filter.AttributeFilter.HasElevationRangeFilter && filter.AttributeFilter.ElevationRangeDesign.DesignID != Guid.Empty)
            {
                var designExistenceMap = DIContext.Obtain <IExistenceMaps>().GetSingleExistenceMap
                                             (siteModel.ID, Consts.EXISTENCE_MAP_DESIGN_DESCRIPTOR, filter.AttributeFilter.ElevationRangeDesign.DesignID);

                if (designExistenceMap != null)
                {
                    // Not sure this is really needed...
                    designExistenceMap.CellSize = SubGridTreeConsts.SubGridTreeDimension * siteModel.CellSize;
                    overallExistenceMap.SetOp_OR(designExistenceMap);
                }
            }

            return(true);
        }
Пример #7
0
        /// <summary>
        /// Note: This method destructive modifies bitmask 'one'
        /// </summary>
        /// <param name="one"></param>
        /// <param name="two"></param>
        private void TestBitMasksAreTheSame(ISubGridTreeBitMask one, ISubGridTreeBitMask two)
        {
            // Ensure bit counts are the same
            one.CountBits().Should().Be(two.CountBits());

            // XOR the two bit masks together. This should clear all set bits resulting in a BitCount of zero
            one.SetOp_XOR(two);
            one.CountBits().Should().Be(0);
        }
Пример #8
0
        /// <summary>
        /// Notify all interested nodes in the immutable grid a site model has changed attributes
        /// </summary>
        public void ModelAttributesChanged(SiteModelNotificationEventGridMutability targetGrids,
                                           Guid siteModelID,
                                           bool existenceMapChanged = false,
                                           ISubGridTreeBitMask existenceMapChangeMask = null,
                                           bool designsChanged             = false,
                                           bool surveyedSurfacesChanged    = false,
                                           bool csibChanged                = false,
                                           bool machinesChanged            = false,
                                           bool machineTargetValuesChanged = false,
                                           bool machineDesignsModified     = false,
                                           bool proofingRunsModified       = false,
                                           bool alignmentsChanged          = false,
                                           bool siteModelMarkedForDeletion = false)
        {
            var gridFactory = DIContext.Obtain <ITRexGridFactory>();

            var evt = new SiteModelAttributesChangedEvent
            {
                SiteModelID                 = siteModelID,
                ExistenceMapModified        = existenceMapChanged,
                ExistenceMapChangeMask      = existenceMapChangeMask?.ToBytes(),
                CsibModified                = csibChanged,
                DesignsModified             = designsChanged,
                SurveyedSurfacesModified    = surveyedSurfacesChanged,
                MachinesModified            = machinesChanged,
                MachineTargetValuesModified = machineTargetValuesChanged,
                MachineDesignsModified      = machineDesignsModified,
                ProofingRunsModified        = proofingRunsModified,
                AlignmentsModified          = alignmentsChanged,
                SiteModelMarkedForDeletion  = siteModelMarkedForDeletion,
                ChangeEventUid              = Guid.NewGuid(),
                TimeSentUtc                 = DateTime.UtcNow
            };

            /*
             * if ((targetGrids & SiteModelNotificationEventGridMutability.NotifyImmutable) != 0)
             * gridFactory.Grid(StorageMutability.Immutable).GetMessaging().SendOrdered(evt, MESSAGE_TOPIC_NAME, _messageSendTimeout);
             *
             * if ((targetGrids & SiteModelNotificationEventGridMutability.NotifyMutable) != 0)
             * gridFactory.Grid(StorageMutability.Mutable).GetMessaging().SendOrdered(evt, MESSAGE_TOPIC_NAME, _messageSendTimeout);
             */

            if ((targetGrids & SiteModelNotificationEventGridMutability.NotifyImmutable) != 0)
            {
                evt.SourceNodeUid = gridFactory.Grid(StorageMutability.Immutable).GetCluster().GetLocalNode().Id;
                SendInvokeStyleMessage("Immutable", evt);
            }

            if ((targetGrids & SiteModelNotificationEventGridMutability.NotifyMutable) != 0)
            {
                evt.SourceNodeUid = gridFactory.Grid(StorageMutability.Mutable).GetCluster().GetLocalNode().Id;
                SendInvokeStyleMessage("Mutable", evt);
            }
        }
Пример #9
0
 /// <summary>
 /// Constructs a profile lift builder that analyzes cells in a cell profile vector
 /// </summary>
 public SummaryVolumesCellProfileAnalyzer(ISiteModel siteModel,
                                          ISubGridTreeBitMask pDExistenceMap,
                                          IFilterSet filterSet,
                                          IDesignWrapper referenceDesignWrapper,
                                          ICellLiftBuilder cellLiftBuilder,
                                          VolumeComputationType volumeType,
                                          IOverrideParameters overrides,
                                          ILiftParameters liftParams)
     : base(siteModel, pDExistenceMap, filterSet, overrides, liftParams)
 {
     svDesignWrapper = referenceDesignWrapper;
     VolumeType      = volumeType;
 }
Пример #10
0
        /// <summary>
        /// Constructs a profile lift builder that analyzes cells in a cell profile vector
        /// </summary>
        public CellProfileAnalyzerBase(ISiteModel siteModel,
                                       ISubGridTreeBitMask pDExistenceMap,
                                       IFilterSet filterSet,
                                       IOverrideParameters overrides,
                                       ILiftParameters liftParams)
        {
            SiteModel      = siteModel;
            PDExistenceMap = pDExistenceMap;
            FilterSet      = filterSet;
            Overrides      = overrides;
            LiftParams     = liftParams;

            Initialise();
        }
Пример #11
0
        /// <summary>
        /// Constructor for a TTMDesign that takes the underlying cell size for the site model that will be used when interpolating heights from the design surface
        /// </summary>
        public TTMDesign(double ACellSize)
        {
            Data          = new TrimbleTINModel();
            triangleItems = Data.Triangles.Items;
            vertexItems   = Data.Vertices.Items;

            cellSize = ACellSize;

            // Create a sub grid tree bit mask index that holds one bit per on-the-ground
            // sub grid that intersects at least one triangle in the TTM.
            subGridIndex = new SubGridTreeSubGridExistenceBitMask {
                CellSize = SubGridTreeConsts.SubGridTreeDimension * ACellSize
            };

            // Create the optimized sub grid tree spatial index that minimizes the number of allocations in the final result.
            SpatialIndexOptimised = new OptimisedSpatialIndexSubGridTree(SubGridTreeConsts.SubGridTreeLevels - 1, SubGridTreeConsts.SubGridTreeDimension * ACellSize);
        }
Пример #12
0
        protected SubGridRetrieverBase(ISiteModel siteModel,
                                       GridDataType gridDataType,
                                       ICombinedFilter filter,
                                       ICellPassAttributeFilterProcessingAnnex filterAnnex,
                                       bool hasOverrideSpatialCellRestriction,
                                       BoundingIntegerExtent2D overrideSpatialCellRestriction,
                                       bool prepareGridForCacheStorageIfNoSieving,
                                       int maxNumberOfPassesToReturn,
                                       IStorageProxy storageProxy,
                                       AreaControlSet areaControlSet,
                                       IFilteredValuePopulationControl populationControl,
                                       ISubGridTreeBitMask pDExistenceMap,
                                       IOverrideParameters overrides,
                                       ILiftParameters liftParams)
        {
            _segmentIterator  = null;
            _cellPassIterator = null;

            _siteModel    = siteModel;
            _gridDataType = gridDataType;
            _filter       = filter;
            _filterAnnex  = filterAnnex;
            _hasOverrideSpatialCellRestriction     = hasOverrideSpatialCellRestriction;
            _overrideSpatialCellRestriction        = overrideSpatialCellRestriction;
            _prepareGridForCacheStorageIfNoSieving = prepareGridForCacheStorageIfNoSieving;
            _maxNumberOfPassesToReturn             = maxNumberOfPassesToReturn;
            _storageProxy      = storageProxy;
            _populationControl = populationControl;
            _areaControlSet    = areaControlSet;
            _pdExistenceMap    = pDExistenceMap;
            _overrides         = overrides;
            _liftParams        = liftParams;

            // Create and configure the assignment context which is used to contain a filtered pass and
            // its attendant machine events and target values prior to assignment to the client sub grid.
            _assignmentContext = new FilteredValueAssignmentContext {
                Overrides = overrides, LiftParams = liftParams
            };

            _filter.AttributeFilter.SiteModel = siteModel;

            _canUseGlobalLatestCells = _filter.AttributeFilter.LastRecordedCellPassSatisfiesFilter;
        }
Пример #13
0
 /// <summary>
 /// Constructor for the sub grid retriever helper
 /// </summary>
 /// <param name="siteModel">The project this sub gris is being retrieved from</param>
 /// <param name="gridDataType">The type of client grid data sub grids to be returned by this retriever</param>
 /// <param name="storageProxy">The Ignite storage proxy to be used when requesting data from the persistent store</param>
 /// <param name="filter">The TRex spatial and attribute filtering description for the request</param>
 /// <param name="filterAnnex">An annex of data related to cell by cell filtering where the attributes related to that cell may change from cell to cell</param>
 /// <param name="hasOverrideSpatialCellRestriction">The spatially selected cells are masked by a rectangular restriction boundary</param>
 /// <param name="overrideSpatialCellRestriction"></param>
 /// <param name="prepareGridForCacheStorageIfNoSieving">The cell coordinate bounding box restricting cells involved in the request</param>
 /// <param name="maxNumberOfPassesToReturn">The maximum number of passes in a cell in a sub grid that will be considered when processing the request</param>
 /// <param name="areaControlSet">The skip/step area control set for selection of cells with sub grids for processing. Cells not identified by the control set will return null values.</param>
 /// <param name="populationControl">The delegate responsible for populating events depended on for processing the request.</param>
 /// <param name="pDExistenceMap">The production data existence map for the project the request relates to</param>
 /// <param name="overrides">The set of overriding machine event values to use</param>
 /// <param name="liftParams">The set of layer/lift analysis parameters to use</param>
 public SubGridRetriever(ISiteModel siteModel,
                         GridDataType gridDataType,
                         IStorageProxy storageProxy,
                         ICombinedFilter filter,
                         ICellPassAttributeFilterProcessingAnnex filterAnnex,
                         bool hasOverrideSpatialCellRestriction,
                         BoundingIntegerExtent2D overrideSpatialCellRestriction,
                         bool prepareGridForCacheStorageIfNoSieving,
                         int maxNumberOfPassesToReturn,
                         AreaControlSet areaControlSet,
                         IFilteredValuePopulationControl populationControl,
                         ISubGridTreeBitMask pDExistenceMap,
                         IOverrideParameters overrides,
                         ILiftParameters liftParams)
     : base(siteModel, gridDataType, filter, filterAnnex,
            hasOverrideSpatialCellRestriction, overrideSpatialCellRestriction, prepareGridForCacheStorageIfNoSieving, maxNumberOfPassesToReturn,
            storageProxy, areaControlSet, populationControl, pDExistenceMap, overrides, liftParams)
 {
 }
Пример #14
0
        /* TODO ColorPaletteClassType()
         * private TICDisplayPaletteBaseClass ColorPaletteClassType()
         *  {
         *  case FMode of
         *    ...Height                  : Result  = TICDisplayPalette_Height;
         *    ...CCV                     : Result  = TICDisplayPalette_CCV;
         *    ...CCVPercent              : Result  = TICDisplayPalette_CCVPercent;
         *    ...Latency                 : Result  = TICDisplayPalette_RadioLatency;
         *    ...PassCount               : Result  = TICDisplayPalette_PassCount;
         *    ...PassCountSummary        : Result  = TICDisplayPalette_PassCountSummary;  // Palettes are fixed three color palettes - display will use direct transitions
         *    ...RMV                     : Result  = TICDisplayPalette_RMV;
         *    ...Frequency               : Result  = TICDisplayPalette_Frequency;
         *    ...Amplitude               : Result  = TICDisplayPalette_Amplitude;
         *    ...CutFill                 : Result  = TICDisplayPalette_CutFill;
         *    ...Moisture                : Result  = TICDisplayPalette_Moisture;
         *    ...TemperatureSummary      : Result  = TICDisplayPaletteBase; //TICDisplayPalette_Temperature;
         *    ...GPSMode                 : Result  = TICDisplayPaletteBase; //TICDisplayPalette_GPSMode;
         *    ...CCVSummary              : Result  = TICDisplayPaletteBase; //TICDisplayPalette_CCVSummary;
         *    ...CCVPercentSummary       : Result  = TICDisplayPalette_CCVPercent;
         *    ...CompactionCoverage      : Result  = TICDisplayPalette_CoverageOverlay;
         *    ...VolumeCoverage          : Result  = TICDisplayPalette_VolumeOverlay;
         *    ...MDP                     : Result  = TICDisplayPalette_MDP; // ajr15167
         *    ...MDPSummary              : Result  = TICDisplayPaletteBase;
         *    ...MDPPercent              : Result  = TICDisplayPalette_MDPPercent;
         *    ...MDPPercentSummary       : Result  = TICDisplayPalette_MDPPercent;
         *    ...MachineSpeed            : Result  = TICDisplayPalette_MachineSpeed;
         *    ...CCVPercentChange        : Result  = TICDisplayPalette_CCVPercent;
         *    ...TargetThicknessSummary  : Result  = TICDisplayPalette_VolumeOverlay;
         *    ...TargetSpeedSummary      : Result  = TICDisplayPalette_SpeedSummary;
         *    ...CCVChange               : Result  = TICDisplayPalette_CCVChange;
         *    ...CCA                     : Result  = TICDisplayPalette_CCA;
         *    ...CCASummary              : Result  = TICDisplayPalette_CCASummary;
         *
         *  else
         *    SIGLogMessage.PublishNoODS(Self, Format('ColorPaletteClassType: Unknown display type: %d', [Ord(FMode)]), ...Assert);
         *    Result  = TICDisplayPaletteBase;
         *  end;
         * end;
         */

        /* TODO: ComputeCCAPalette
         * function ComputeCCAPalette :Boolean;
         * var
         *  I, J, K               :Integer;
         *  ResponseVerb        :...VerbBase;
         *  ServerResult        :TICServerRequestResult;
         *  ResponseDataStream  :TStream;
         *  CCAMinimumPasses    :...CCAMinPassesValue;
         *  CCAColorScale       :...CCAColorScale;
         *  CCAPalette          :TColorPalettes;
         *
         * begin
         *  Result  = False;
         *
         *  ResponseVerb  = nil;
         *  try
         *    if Length(FFilter1.Machines) > 0 then
         *      FMachineID  = FFilter1.Machines[0].ID // Must be set by caller
         *    else
         *      FMachineID  = -1; // will fail call
         *    if not Assigned(ASNodeImplInstance) or ASNodeImplInstance.ServiceStopped then
         *      begin
         *        SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Aborting request as service has been stopped', [Self.ClassName]), ...Warning);
         *        Exit;
         *      end;
         *
         *    ASNodeImplInstance.PSLoadBalancer.LoadBalancedPSService.GetMachineCCAMinimumPassesValue(FDataModelID, FMachineID, FFilter1.StartTime, FFilter1.EndTime, FFilter1.LayerID, ResponseVerb);
         *    if Assigned(ResponseVerb) then
         *      with ResponseVerb as ...Verb_SendResponse do
         *        begin
         *          ServerResult  = TICServerRequestResult(ResponseCode);
         *      ResponseDataStream  = ResponseData;
         *          if (ServerResult = ...NoError) and assigned(ResponseData) then
         *            begin
         *              CCAMinimumPasses  = ReadSmallIntFromStream(ResponseDataStream);
         *
         *      Result  = CCAMinimumPasses > 0;
         *
         *              if not Result then
         *                Exit;
         *
         *      CCAColorScale  = ...CCAColorScaleManager.CreateCoverageScale(CCAMinimumPasses);
         *              try
         *                SetLength(CCAPalette.Transitions, CCAColorScale.TotalColors);
         *
         *      J  = Low(CCAPalette.Transitions);
         *      k  = High(CCAPalette.Transitions);
         *                for I  = J to K do
         *                  begin
         *                    CCAPalette.Transitions[I].Color  = CCAColorScale.ColorSegments[K - I].Color;
         *      CCAPalette.Transitions[I].Value   = I+1;
         *                  end;
         *                CCAPalette.ConvertRGBToBGR; // gets done again but needed to match Anatoli palette test :)
         *                WorkingColorPalette.PopulateFromPaletteColors(CCAPalette);
         *                WorkingColorPalette.TransitionColors.ValuesCount  = Length(CCAPalette.Transitions);
         *              finally
         *                if Assigned(CCAColorScale) then
         *                  FreeAndNil(CCAColorScale);
         *      end;
         *            end
         *          else
         *            SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: GetMachineCCAMinimumPassesValue Failed for InternalSiteModelMachineIndex: %d. ReturnCode:%d', [Self.ClassName, FMachineID, Ord(ServerResult)]), ...Warning);
         *        end;
         *  finally
         *    if Assigned(ResponseVerb) then
         *      FreeAndNil(ResponseVerb);
         *      end;
         * end;
         */

        /* TODO: CreateAndInitialiseWorkingColorPalette
         * function CreateAndInitialiseWorkingColorPalette :Boolean;
         * begin
         * Result  = True;
         *
         * // Create a scaled palette to use when rendering the data
         * try
         *   if ColorPaletteClassType<> Nil then
         *    begin
         *
         *       WorkingColorPalette  = ColorPaletteClassType.Create;
         *       WorkingColorPalette.SmoothPalette  = FMode = ...CutFill;
         *
         *       // CCASummary is done per machine id
         *       if FMode in [...CCA, ...CCASummary]
         *     then
         *         Result  = ComputeCCAPalette
         *       else
         *         begin
         *           if Length(FColorPalettes.Transitions) = 0 then
         *             WorkingColorPalette.SetToDefaults
         *           else
         *             WorkingColorPalette.PopulateFromPaletteColors(FColorPalettes);
         *     end;
         *
         *       if Result then
         *         WorkingColorPalette.ComputePalette;
         *     end
         *   else
         *     WorkingColorPalette  = Nil;
         *
         * Except
         *   On e:Exception do
         *     SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Error: %s ', [Self.ClassName, e.Message]), ...Exception);
         * end;
         * end;
         */

        /// <summary>
        /// Renders all sub grids in a representational style that indicates where there is data, but nothing else. This is used for large scale displays
        /// (zoomed out a lot) where meaningful detail cannot be drawn on the tile
        /// </summary>
        private SKBitmap RenderTileAsRepresentationalDueToScale(ISubGridTreeBitMask overallExistenceMap)
        {
            using (var RepresentationalDisplay = PVMDisplayerFactory.GetDisplayer(Mode /*, FICOptions*/))
            {
                using (var mapView = new MapSurface {
                    SquareAspect = false
                })
                {
                    mapView.SetRotation(TileRotation);

                    RepresentationalDisplay.MapView = mapView;

                    RepresentationalDisplay.MapView.SetBounds(NPixelsX, NPixelsY);
                    RepresentationalDisplay.MapView.SetWorldBounds(NEECoords[0].X, NEECoords[0].Y,
                                                                   NEECoords[0].X + WorldTileWidth, NEECoords[0].Y + WorldTileHeight, 0);

                    // Iterate over all the bits in the sub grids drawing a rectangle for each one on the tile being rendered
                    if (overallExistenceMap.ScanSubGrids(RotatedTileBoundingExtents,
                                                         leaf =>
                    {
                        leaf.CalculateWorldOrigin(out var WorldOriginX, out var WorldOriginY);

                        (leaf as SubGridTreeLeafBitmapSubGrid)?.Bits.ForEachSetBit((x, y) =>
                        {
                            RepresentationalDisplay.MapView.DrawRect(WorldOriginX + (x * overallExistenceMap.CellSize),
                                                                     WorldOriginY + (y * overallExistenceMap.CellSize),
                                                                     overallExistenceMap.CellSize, overallExistenceMap.CellSize, true, RepresentColor);
                        });

                        return(true);
                    }))
                    {
                        // Remove the canvas from the map view to prevent it's disposal (it's being returned to the caller)
                        var canvas = RepresentationalDisplay.MapView.BitmapCanvas;
                        RepresentationalDisplay.MapView.BitmapCanvas = null;
                        return(canvas);
                    }
                }
            }

            return(null); // It did not work out...
        }
Пример #15
0
        /// <summary>
        /// Creates a change map buffer queue item and places it in to the cache for the service processor to collect
        /// </summary>
        public void Notify(Guid projectUid, DateTime insertUtc, ISubGridTreeBitMask changeMap, SiteModelChangeMapOrigin origin, SiteModelChangeMapOperation operation)
        {
            try
            {
                _log.LogInformation($"Adding site model change map notification for project {projectUid}");

                _queueCache.Put(new SiteModelChangeBufferQueueKey(projectUid, insertUtc),
                                new SiteModelChangeBufferQueueItem
                {
                    ProjectUID = projectUid,
                    InsertUTC  = insertUtc,
                    Operation  = operation,
                    Origin     = origin,
                    Content    = changeMap?.ToBytes()
                });
            }
            catch (Exception e)
            {
                _log.LogError(e, "Exception notifying site model change map");
            }
        }
Пример #16
0
        /// <summary>
        /// Configures a new profile builder that provides the three core builders used in profiling: construction of cell vector from profile line,
        /// profile analysis orchestration and per cell layer/statistics calculation
        /// </summary>
        public void Configure(ProfileStyle profileStyle,
                              ISiteModel siteModel,
                              ISubGridTreeBitMask productionDataExistenceMap,
                              GridDataType gridDataType,
                              IFilterSet filterSet,
                              IDesignWrapper referenceDesignWrapper,
                              IFilteredValuePopulationControl PopulationControl,
                              ICellPassFastEventLookerUpper CellPassFastEventLookerUpper,
                              VolumeComputationType volumeType,
                              IOverrideParameters overrides,
                              ILiftParameters liftParams,
                              bool slicerToolUsed = true)
        {
            CellLiftBuilder = factory.NewCellLiftBuilder(siteModel, gridDataType, PopulationControl, filterSet, CellPassFastEventLookerUpper);

            CellProfileBuilder = factory.NewCellProfileBuilder(siteModel, filterSet, referenceDesignWrapper, slicerToolUsed);

            CellProfileAnalyzer = factory.NewCellProfileAnalyzer(
                profileStyle, siteModel, productionDataExistenceMap, filterSet,
                referenceDesignWrapper, CellLiftBuilder, volumeType, overrides, liftParams);
        }
Пример #17
0
        /// <summary>
        /// Perform the request extracting all required existence maps and combine them together
        /// </summary>
        public ISubGridTreeBitMask Execute(INonSpatialAffinityKey[] keys)
        {
            ISubGridTreeBitMask combinedMask = null;

            foreach (var key in keys)
            {
                var Mask = _singleRequest.Execute(key);

                if (Mask != null)
                {
                    if (combinedMask == null)
                    {
                        combinedMask = Mask;
                    }
                    else
                    {
                        combinedMask.SetOp_OR(Mask);
                    }
                }
            }

            return(combinedMask);
        }
Пример #18
0
        private void TestSiteModelAndChangeMap_Ingest(ISiteModel siteModel, ISubGridTreeBitMask changeMap, int finalBitCount)
        {
            var insertUtc = DateTime.UtcNow;
            var key       = new SiteModelChangeBufferQueueKey(siteModel.ID, insertUtc);
            var value     = new SiteModelChangeBufferQueueItem
            {
                ProjectUID = siteModel.ID,
                MachineUid = siteModel.Machines.First().ID,
                InsertUTC  = insertUtc,
                Operation  = SiteModelChangeMapOperation.AddSpatialChanges,
                Origin     = SiteModelChangeMapOrigin.Ingest,
                Content    = changeMap.ToBytes()
            };

            PerformProcessEvent(key, value);

            // Check there is now a change map item for the site model with the given content
            var changeMapProxy  = new SiteModelChangeMapProxy();
            var resultChangeMap = changeMapProxy.Get(key.ProjectUID, value.MachineUid);

            resultChangeMap.Should().NotBeNull();
            resultChangeMap.CountBits().Should().Be(finalBitCount);
        }
Пример #19
0
        /// <summary>
        /// Add a new surveyed surface to a site model
        /// </summary>
        public ISurveyedSurface Add(Guid siteModelUid, DesignDescriptor designDescriptor, DateTime asAtDate, BoundingWorldExtent3D extents,
                                    ISubGridTreeBitMask existenceMap)
        {
            if (asAtDate.Kind != DateTimeKind.Utc)
            {
                throw new ArgumentException("AsAtDate must be a UTC date time");
            }

            if (extents == null)
            {
                throw new ArgumentNullException(nameof(extents));
            }

            if (existenceMap == null)
            {
                throw new ArgumentNullException(nameof(existenceMap));
            }

            var ss = Load(siteModelUid);
            var newSurveyedSurface = ss.AddSurveyedSurfaceDetails(designDescriptor.DesignID, designDescriptor, asAtDate, extents);

            // Store the existence map into the cache
            using var stream = existenceMap.ToStream();
            var fileName = BaseExistenceMapRequest.CacheKeyString(ExistenceMaps.Interfaces.Consts.EXISTENCE_SURVEYED_SURFACE_DESCRIPTOR, designDescriptor.DesignID);

            if (_writeStorageProxy.WriteStreamToPersistentStore(siteModelUid, fileName,
                                                                FileSystemStreamType.DesignTopologyExistenceMap, stream, existenceMap) != FileSystemErrorStatus.OK)
            {
                _log.LogError("Failed to write existence map to persistent store for key {fileName}");
                return(null);
            }

            // Store performs Commit() operation
            Store(siteModelUid, ss);

            return(newSurveyedSurface);
        }
Пример #20
0
        /// <summary>
        /// Given a filter compute which of the surfaces in the list match any given time aspect
        /// of the filter, and the overall existence map of the surveyed surfaces that match the filter.
        /// ComparisonList denotes a possibly pre-filtered set of surfaces for another filter; if this is the same as the
        /// filtered set of surfaces then the overall existence map for those surfaces will not be computed as it is
        /// assumed to be the same.
        /// </summary>
        public bool ProcessSurveyedSurfacesForFilter(Guid siteModelId,
                                                     ICombinedFilter filter,
                                                     ISurveyedSurfaces comparisonList,
                                                     ISurveyedSurfaces filteredSurveyedSurfaces,
                                                     ISubGridTreeBitMask overallExistenceMap)
        {
            // Filter out any surveyed surfaces which don't match current filter (if any) - realistically, this is time filters we're thinking of here
            FilterSurveyedSurfaceDetails(filter.AttributeFilter.HasTimeFilter,
                                         filter.AttributeFilter.StartTime, filter.AttributeFilter.EndTime,
                                         filter.AttributeFilter.ExcludeSurveyedSurfaces(),
                                         filteredSurveyedSurfaces,
                                         filter.AttributeFilter.SurveyedSurfaceExclusionList);

            if (filteredSurveyedSurfaces != null)
            {
                if (filteredSurveyedSurfaces.IsSameAs(comparisonList))
                {
                    return(true);
                }

                if (filteredSurveyedSurfaces.Count > 0)
                {
                    var surveyedSurfaceExistenceMap = GetExistenceMaps().GetCombinedExistenceMap(siteModelId,
                                                                                                 filteredSurveyedSurfaces.Select(x => new Tuple <long, Guid>(Consts.EXISTENCE_SURVEYED_SURFACE_DESCRIPTOR, x.ID)).ToArray());

                    if (overallExistenceMap == null)
                    {
                        return(false);
                    }

                    overallExistenceMap.SetOp_OR(surveyedSurfaceExistenceMap);
                }
            }

            return(true);
        }
Пример #21
0
        /// <summary>
        /// Creates a new builder responsible for analyzing profile information for a cell or cells identified along a profile line
        /// </summary>
        public ICellProfileAnalyzer <T> NewCellProfileAnalyzer(ProfileStyle profileStyle,
                                                               ISiteModel siteModel,
                                                               ISubGridTreeBitMask pDExistenceMap,
                                                               IFilterSet filterSet,
                                                               IDesignWrapper referenceDesignWrapper,
                                                               ICellLiftBuilder cellLiftBuilder,
                                                               VolumeComputationType volumeComputationType,
                                                               IOverrideParameters overrides,
                                                               ILiftParameters liftParams)
        {
            switch (profileStyle)
            {
            case ProfileStyle.CellPasses:
                return(DIContext.Obtain <Func <ISiteModel, ISubGridTreeBitMask, IFilterSet, ICellLiftBuilder, IOverrideParameters, ILiftParameters, ICellProfileAnalyzer <T> > >()
                           (siteModel, pDExistenceMap, filterSet, cellLiftBuilder, overrides, liftParams));

            case ProfileStyle.SummaryVolume:
                return(DIContext.Obtain <Func <ISiteModel, ISubGridTreeBitMask, IFilterSet, IDesignWrapper, ICellLiftBuilder, VolumeComputationType, IOverrideParameters, ILiftParameters, ICellProfileAnalyzer <T> > >()
                           (siteModel, pDExistenceMap, filterSet, referenceDesignWrapper, cellLiftBuilder, volumeComputationType, overrides, liftParams));

            default:
                throw new ArgumentOutOfRangeException(nameof(profileStyle), profileStyle, null);
            }
        }
Пример #22
0
        /// <summary>
        /// Performs execution business logic for this executor
        /// </summary>
        public ISurveyedSurface Execute(Guid projectUid, DesignDescriptor designDescriptor, DateTime asAtDate, BoundingWorldExtent3D extents, ISubGridTreeBitMask existenceMap)
        {
            try
            {
                var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(projectUid, false);

                if (siteModel == null)
                {
                    _log.LogError($"Site model {projectUid} not found");
                    return(null);
                }

                var surveyedSurface = DIContext.Obtain <ISurveyedSurfaceManager>().Add(projectUid, designDescriptor, asAtDate, extents, existenceMap);

                if (surveyedSurface == null)
                {
                    _log.LogError($"Failed to add surveyed surface file {designDescriptor}, asAtDate {asAtDate} to project {projectUid}");
                }

                return(surveyedSurface);
            }
            catch (Exception e)
            {
                _log.LogError(e, "Execute: Exception: ");
                return(null);
            }
        }
Пример #23
0
        /// <summary>
        /// Add a new design to a site model
        /// </summary>
        public IDesign Add(Guid siteModelId, DesignDescriptor designDescriptor, BoundingWorldExtent3D extents, ISubGridTreeBitMask existenceMap)
        {
            if (extents == null)
            {
                throw new ArgumentNullException(nameof(extents));
            }

            if (existenceMap == null)
            {
                throw new ArgumentNullException(nameof(existenceMap));
            }

            // Add the design to the designs list
            var designs = Load(siteModelId);
            var result  = designs.AddDesignDetails(designDescriptor.DesignID, designDescriptor, extents);

            // Store the existence map into the cache
            using var stream = existenceMap.ToStream();
            var fileName = BaseExistenceMapRequest.CacheKeyString(ExistenceMaps.Interfaces.Consts.EXISTENCE_MAP_DESIGN_DESCRIPTOR, designDescriptor.DesignID);

            if (_writeStorageProxy.WriteStreamToPersistentStore(siteModelId, fileName,
                                                                FileSystemStreamType.DesignTopologyExistenceMap, stream, existenceMap) != FileSystemErrorStatus.OK)
            {
                _log.LogError("Failed to write existence map to persistent store for key {fileName}");
                return(null);
            }

            // Store performs Commit() operation
            Store(siteModelId, designs);

            return(result);
        }
Пример #24
0
        /// <summary>
        /// Performs execution business logic for this executor
        /// </summary>
        public IDesign Execute(Guid projectUid, DesignDescriptor designDescriptor, BoundingWorldExtent3D extents, ISubGridTreeBitMask existenceMap)
        {
            try
            {
                var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(projectUid, false);

                if (siteModel == null)
                {
                    _log.LogError($"Site model {projectUid} not found");
                    return(null);
                }

                var design = DIContext.Obtain <IDesignManager>().Add(projectUid, designDescriptor, extents, existenceMap);

                if (design == null)
                {
                    _log.LogError($"Failed to add design file {designDescriptor} to project {projectUid}");
                }

                return(design);
            }
            catch (Exception e)
            {
                _log.LogError(e, "Execute: Exception: ");
                return(null);
            }
        }
Пример #25
0
        public RequestErrorStatus ExecutePipeline()
        {
            SubGridPipelineAggregative <SubGridsRequestArgument, SimpleVolumesResponse> PipeLine;

            var Result = RequestErrorStatus.Unknown;

            var PipelineAborted = false;

            // bool ShouldAbortDueToCompletedEventSet  = false;

            try
            {
                ProdDataExistenceMap = SiteModel.ExistenceMap;

                try
                {
                    if (ActiveDesign != null && (VolumeType == VolumeComputationType.BetweenFilterAndDesign || VolumeType == VolumeComputationType.BetweenDesignAndFilter))
                    {
                        if (ActiveDesign == null || ActiveDesign.Design.DesignDescriptor.IsNull)
                        {
                            Log.LogError($"No design provided to prod data/design volumes calc for datamodel {SiteModel.ID}");
                            return(RequestErrorStatus.NoDesignProvided);
                        }

                        DesignSubgridOverlayMap = GetExistenceMaps().GetSingleExistenceMap(SiteModel.ID, ExistenceMaps.Interfaces.Consts.EXISTENCE_MAP_DESIGN_DESCRIPTOR, ActiveDesign.Design.ID);

                        if (DesignSubgridOverlayMap == null)
                        {
                            return(RequestErrorStatus.NoDesignProvided);
                        }
                    }

                    OverallExistenceMap = new SubGridTreeSubGridExistenceBitMask();

                    // Work out the surveyed surfaces and coverage areas that need to be taken into account

                    var SurveyedSurfaces = SiteModel.SurveyedSurfaces;

                    if (SurveyedSurfaces != null)
                    {
                        // See if we need to handle surveyed surface data for 'base'
                        // Filter out any surveyed surfaces which don't match current filter (if any) - realistically, this is time filters we're thinking of here
                        if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenFilterAndDesign)
                        {
                            if (!SurveyedSurfaces.ProcessSurveyedSurfacesForFilter(SiteModel.ID, BaseFilter, FilteredTopSurveyedSurfaces, FilteredBaseSurveyedSurfaces, OverallExistenceMap))
                            {
                                return(RequestErrorStatus.Unknown);
                            }
                        }

                        // See if we need to handle surveyed surface data for 'top'
                        // Filter out any surveyed surfaces which don't match current filter (if any) - realistically, this is time filters we're thinking of here
                        if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenDesignAndFilter)
                        {
                            if (!SurveyedSurfaces.ProcessSurveyedSurfacesForFilter(SiteModel.ID, TopFilter, FilteredBaseSurveyedSurfaces, FilteredTopSurveyedSurfaces, OverallExistenceMap))
                            {
                                return(RequestErrorStatus.Unknown);
                            }
                        }
                    }

                    // Add in the production data existence map to the computed surveyed surfaces existence maps
                    OverallExistenceMap.SetOp_OR(ProdDataExistenceMap);

                    // If necessary, impose spatial constraints from filter design(s)
                    if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenFilterAndDesign)
                    {
                        if (!DesignFilterUtilities.ProcessDesignElevationsForFilter(SiteModel, BaseFilter, OverallExistenceMap))
                        {
                            return(RequestErrorStatus.Unknown);
                        }
                    }

                    if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenDesignAndFilter)
                    {
                        if (!DesignFilterUtilities.ProcessDesignElevationsForFilter(SiteModel, TopFilter, OverallExistenceMap))
                        {
                            return(RequestErrorStatus.Unknown);
                        }
                    }

                    var PipelinedTask = new VolumesComputationTask
                    {
                        Aggregator = Aggregator
                    };

                    try
                    {
                        PipeLine = new SubGridPipelineAggregative <SubGridsRequestArgument, SimpleVolumesResponse>(/*0, */ PipelinedTask);
                        PipelinedTask.PipeLine = PipeLine;

                        ConfigurePipeline(PipeLine);

                        if (PipeLine.Initiate())
                        {
                            var completionResult = PipeLine.WaitForCompletion();
                            Log.LogInformation(completionResult ? "WaitForCompletion successful" : $"WaitForCompletion timed out with {PipeLine.SubGridsRemainingToProcess} sub grids remaining to be processed");

                            if (PipeLine.SubGridsRemainingToProcess > 0)
                            {
                                Log.LogInformation($"Pipeline completed with {PipeLine.SubGridsRemainingToProcess} sub grids remaining to be processed");
                            }
                        }

                        /*
                         * while not FPipeLine.AllFinished and not FPipeLine.PipelineAborted do
                         * begin
                         *  WaitResult := FPipeLine.CompleteEvent.WaitFor(5000);
                         *
                         *  if VLPDSvcLocations.Debug_EmitSubgridPipelineProgressLogging then
                         *    begin
                         *      if ((FEpochCount > 0) or (FPipeLine.SubmissionNode.TotalNumberOfSubgridsScanned > 0)) and
                         *         ((FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0)) then
                         *        SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d): #Progress# - Scanned = %d, Submitted = %d, Processed = %d (with %d pending and %d results outstanding)',
                         *                                                [Self.ClassName,
                         *                                                 FRequestDescriptor, FPipeline.ProjectUid,
                         *                                                 FPipeLine.SubmissionNode.TotalNumberOfSubgridsScanned,
                         *                                                 FPipeLine.SubmissionNode.TotalSumbittedSubgridRequests,
                         *                                                 FPipeLine.OperationNode.TotalOperatedOnSubgrids,
                         *                                                 FPipeLine.OperationNode.NumPendingResultsReceived,
                         *                                                 FPipeLine.OperationNode.OustandingSubgridsToOperateOn]), slmcDebug);
                         *    end;
                         *
                         *  if (WaitResult = wrSignaled) and not FPipeLine.AllFinished and not FPipeLine.PipelineAborted and not FPipeLine.Terminated then
                         *    begin
                         *      if ShouldAbortDueToCompletedEventSet then
                         *        begin
                         *          if (FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0) then
                         *            SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d) being aborted as it''s completed event has remained set but still has work to do (%d outstanding subgrids, %d pending results to process) over a sleep epoch',
                         *                                                  [Self.ClassName,
                         *                                                   FRequestDescriptor, FPipeline.ProjectUid,
                         *                                                   FPipeLine.OperationNode.OustandingSubgridsToOperateOn,
                         *                                                   FPipeLine.OperationNode.NumPendingResultsReceived]), slmcError);
                         *          FPipeLine.Abort;
                         *          ASNodeImplInstance.AsyncResponder.ASNodeResponseProcessor.PerformTaskCancellation(FPipelinedTask);
                         *          Exit;
                         *        end
                         *      else
                         *        begin
                         *          if (FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0) then
                         *            SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d) has it''s completed event set but still has work to do (%d outstanding subgrids, %d pending results to process)',
                         *                                                  [Self.ClassName,
                         *                                                   FRequestDescriptor, FPipeline.ProjectUid,
                         *                                                   FPipeLine.OperationNode.OustandingSubgridsToOperateOn,
                         *                                                   FPipeLine.OperationNode.NumPendingResultsReceived]), slmcDebug);
                         *          Sleep(500);
                         *          ShouldAbortDueToCompletedEventSet := True;
                         *        end;
                         *    end;
                         *
                         *  if FPipeLine.TimeToLiveExpired then
                         *    begin
                         *      FAbortedDueToTimeout := True;
                         *      FPipeLine.Abort;
                         *      ASNodeImplInstance.AsyncResponder.ASNodeResponseProcessor.PerformTaskCancellation(FPipelinedTask);
                         *
                         *      // The pipeline has exceed its allotted time to complete. It will now
                         *      // be aborted and this request will be failed.
                         *      SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d) aborted due to time to live expiration (%d seconds)',
                         *                                              [Self.ClassName, FRequestDescriptor, FPipeLine.TimeToLiveSeconds]), slmcError);
                         *      Exit;
                         *    end;
                         */

                        PipelineAborted = PipeLine.Aborted;

                        if (!PipeLine.Terminated && !PipeLine.Aborted)
                        {
                            Result = RequestErrorStatus.OK;
                        }
                    }
                    finally
                    {
                        if (AbortedDueToTimeout)
                        {
                            Result = RequestErrorStatus.AbortedDueToPipelineTimeout;
                        }
                        else
                        if (PipelinedTask.IsCancelled || PipelineAborted)
                        {
                            Result = RequestErrorStatus.RequestHasBeenCancelled;
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.LogError(e, "ExecutePipeline raised exception");
                }

                return(Result);
            }
            catch (Exception e)
            {
                Log.LogError(e, "Exception");
            }

            return(RequestErrorStatus.Unknown);
        }
Пример #26
0
        /// <summary>
        /// Invalidates sub grids held within all cache contexts for a project that are sensitive to
        /// ingest of production data (eg: from TAG files)
        /// </summary>
        public void InvalidateDueToProductionDataIngest(Guid projectUid, Guid changeEventUid, ISubGridTreeBitMask mask)
        {
            var numInvalidatedSubGrids = 0;
            var numScannedSubGrids     = 0;
            var startTime    = DateTime.UtcNow;
            var contextCount = 0;

            lock (_contexts)
            {
                if (_projectContexts.TryGetValue(projectUid, out var projectContexts))
                {
                    if (projectContexts == null || projectContexts.Count == 0)
                    {
                        return;
                    }

                    contextCount = projectContexts.Count;

                    // Walk through the cloned list of contexts evicting all relevant element per the supplied mask
                    // Only hold a Contexts lock for the duration of a single context. 'Eviction' is really marking the
                    // element as dirty to amortize the effort in executing the invalidation across cache accessor contexts.
                    foreach (var context in projectContexts)
                    {
                        // Empty contexts are ignored
                        if (context.TokenCount == 0)
                        {
                            return;
                        }

                        // If the context in question is not sensitive to production data ingest then ignore it
                        if (!context.Sensitivity.HasFlag(TRexSpatialMemoryCacheInvalidationSensitivity.ProductionDataIngest))
                        {
                            return;
                        }

                        // Iterate across all elements in the mask:
                        // 1. Locate the cache entry
                        // 2. Mark it as dirty
                        mask.ScanAllSetBitsAsSubGridAddresses(origin =>
                        {
                            context.InvalidateSubGrid(origin.X, origin.Y, out var subGridPresentForInvalidation);

                            numScannedSubGrids++;
                            if (subGridPresentForInvalidation)
                            {
                                numInvalidatedSubGrids++;
                            }
                        });
                    }
                }
            }

            _log.LogInformation($"Invalidated {numInvalidatedSubGrids} out of {numScannedSubGrids} scanned sub grid from {contextCount} contexts in {DateTime.UtcNow - startTime} [project {projectUid}, change event ID {changeEventUid}]");
        }
Пример #27
0
        public ISubGridRetriever Instance(ISubGridsRequestArgument subGridsRequestArgument,
                                          ISiteModel siteModel,
                                          GridDataType gridDataType,
                                          IStorageProxy storageProxy,
                                          ICombinedFilter filter,
                                          ICellPassAttributeFilterProcessingAnnex filterAnnex,
                                          bool hasOverrideSpatialCellRestriction,
                                          BoundingIntegerExtent2D overrideSpatialCellRestriction,
                                          int maxNumberOfPassesToReturn,
                                          AreaControlSet areaControlSet,
                                          IFilteredValuePopulationControl populationControl,
                                          ISubGridTreeBitMask pdExistenceMap,
                                          ITRexSpatialMemoryCacheContext[] subGridCacheContexts,
                                          IOverrideParameters overrides,
                                          ILiftParameters liftParams)
        {
            if (gridDataType == GridDataType.ProgressiveVolumes)
            {
                var retriever = new ProgressiveVolumesSubGridRetriever(siteModel,
                                                                       gridDataType,
                                                                       storageProxy,
                                                                       filter,
                                                                       filterAnnex,
                                                                       hasOverrideSpatialCellRestriction,
                                                                       overrideSpatialCellRestriction,
                                                                       subGridCacheContexts != null,
                                                                       maxNumberOfPassesToReturn,
                                                                       areaControlSet,
                                                                       populationControl,
                                                                       pdExistenceMap,
                                                                       overrides,
                                                                       liftParams);

                if (subGridsRequestArgument is IProgressiveVolumesSubGridsRequestArgument argument)
                {
                    retriever.StartDate = argument.StartDate;
                    retriever.EndDate   = argument.EndDate;
                    retriever.Interval  = argument.Interval;
                }
                else
                {
                    throw new ArgumentException($"Argument passed to sub grid retriever factory for progressive volumes retriever construction is not an expected type: {subGridsRequestArgument.GetType()}");
                }

                return(retriever);
            }
            else
            {
                var retriever = new SubGridRetriever(siteModel,
                                                     gridDataType,
                                                     storageProxy,
                                                     filter,
                                                     filterAnnex,
                                                     hasOverrideSpatialCellRestriction,
                                                     overrideSpatialCellRestriction,
                                                     subGridCacheContexts != null,
                                                     maxNumberOfPassesToReturn,
                                                     areaControlSet,
                                                     populationControl,
                                                     pdExistenceMap,
                                                     overrides,
                                                     liftParams);

                return(retriever);
            }
        }
Пример #28
0
        /// <summary>
        /// Constructor that accepts the common parameters around a set of sub grids the requester will be asked to process
        /// and initializes the requester state ready to start processing individual sub grid requests.
        /// </summary>
        public void Initialize(ISubGridsRequestArgument subGridsRequestArgument,
                               ISiteModel siteModel,
                               GridDataType gridDataType,
                               IStorageProxy storageProxy,
                               ICombinedFilter filter,
                               bool hasOverrideSpatialCellRestriction,
                               BoundingIntegerExtent2D overrideSpatialCellRestriction,
                               int maxNumberOfPassesToReturn,
                               AreaControlSet areaControlSet,
                               IFilteredValuePopulationControl populationControl,
                               ISubGridTreeBitMask pdExistenceMap,
                               ITRexSpatialMemoryCache subGridCache,
                               ITRexSpatialMemoryCacheContext[] subGridCacheContexts,
                               ISurveyedSurfaces filteredSurveyedSurfaces,
                               ISurfaceElevationPatchRequest surfaceElevationPatchRequest,
                               IOverrideParameters overrides,
                               ILiftParameters liftParams)
        {
            _siteModel    = siteModel;
            _gridDataType = gridDataType;
            _filter       = filter;

            _hasOverrideSpatialCellRestriction = hasOverrideSpatialCellRestriction;
            _overrideSpatialCellRestriction    = overrideSpatialCellRestriction;

            _retriever = DIContext.Obtain <ISubGridRetrieverFactory>().Instance(subGridsRequestArgument,
                                                                                siteModel,
                                                                                gridDataType,
                                                                                storageProxy,
                                                                                filter,
                                                                                _filterAnnex,
                                                                                hasOverrideSpatialCellRestriction,
                                                                                overrideSpatialCellRestriction,
                                                                                maxNumberOfPassesToReturn,
                                                                                areaControlSet,
                                                                                populationControl,
                                                                                pdExistenceMap,
                                                                                subGridCacheContexts,
                                                                                overrides,
                                                                                liftParams);

            _returnEarliestFilteredCellPass = _filter.AttributeFilter.ReturnEarliestFilteredCellPass;
            _processingMap = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled);

            _surfaceElevationPatchRequest = surfaceElevationPatchRequest;

            _subGridCache         = subGridCache;
            _subGridCacheContexts = subGridCacheContexts;

            _surveyedSurfacePatchType = _filter.AttributeFilter.ReturnEarliestFilteredCellPass ? SurveyedSurfacePatchType.EarliestSingleElevation : SurveyedSurfacePatchType.LatestSingleElevation;

            _filteredSurveyedSurfaces = filteredSurveyedSurfaces;
            _filteredSurveyedSurfaces?.SortChronologically(_surveyedSurfacePatchType == SurveyedSurfacePatchType.LatestSingleElevation);
            _filteredSurveyedSurfacesAsGuidArray = _filteredSurveyedSurfaces?.Select(x => x.ID).ToArray() ?? new Guid[0];

            var elevRangeDesignFilter = _filter.AttributeFilter.ElevationRangeDesign;

            if (elevRangeDesignFilter.DesignID != Guid.Empty)
            {
                var design = _siteModel.Designs.Locate(elevRangeDesignFilter.DesignID);
                if (design == null)
                {
                    _log.LogError($"ElevationRangeDesign {elevRangeDesignFilter.DesignID} is unknown in project {siteModel.ID}");
                }
                else
                {
                    _elevationRangeDesign = new DesignWrapper(elevRangeDesignFilter, design);
                }
            }

            if (_filter.SpatialFilter.IsDesignMask)
            {
                _surfaceDesignMaskDesign = _siteModel.Designs.Locate(_filter.SpatialFilter.SurfaceDesignMaskDesignUid);
            }

            _filter.AttributeFilter.SiteModel = _siteModel;
        }