public void AggregateWith_FailWithUnequalDates() { // Allow this to be null, it will receive all the aggregations var response1 = new ProgressiveVolumesResponse { ResultStatus = RequestErrorStatus.OK, Volumes = new[] { new ProgressiveVolumeResponseItem { Date = DateTime.UtcNow, Volume = new SimpleVolumesResponse() } } }; var response2 = new ProgressiveVolumesResponse { ResultStatus = RequestErrorStatus.OK, Volumes = new[] { new ProgressiveVolumeResponseItem { Date = DateTime.UtcNow.AddMinutes(1), Volume = new SimpleVolumesResponse() } } }; Action act = () => response1.AggregateWith(response2); act.Should().Throw <ArgumentException>().WithMessage("Dates of aggregating progressive volume pair are not the same*"); }
/// <summary> /// Converts ProgressiveVolumesResponse data into SummaryVolumesResult data. /// </summary> private ProgressiveSummaryVolumesResult ConvertResult(ProgressiveVolumesResponse result) { return(ProgressiveSummaryVolumesResult.Create( result.Volumes.Select(x => ProgressiveSummaryVolumesResultItem.Create(x.Date, SummaryVolumesResult.Create(BoundingBox3DGridHelper.ConvertExtents(x.Volume.BoundingExtentGrid), x.Volume.Cut ?? 0.0, x.Volume.Fill ?? 0.0, x.Volume.TotalCoverageArea ?? 0.0, x.Volume.CutArea ?? 0.0, x.Volume.FillArea ?? 0.0))).ToArray())); }
private void CheckResponseContainsNullValues(ProgressiveVolumesResponse response) { response.Should().NotBeNull(); if (response.Volumes == null) { return; } foreach (var volume in response.Volumes) { volume.Volume.BoundingExtentGrid.Should().BeEquivalentTo(BoundingWorldExtent3D.Null()); volume.Volume.BoundingExtentLLH.Should().BeEquivalentTo(BoundingWorldExtent3D.Null()); } }
public void AggregateWith_FailWithUnequalListSizes() { // Allow this to be null, it will receive all the aggregations var response1 = new ProgressiveVolumesResponse(); var response2 = new ProgressiveVolumesResponse { ResultStatus = RequestErrorStatus.OK, Volumes = new[] { new ProgressiveVolumeResponseItem() } }; Action act = () => response1.AggregateWith(response2); act.Should().Throw <ArgumentException>().WithMessage("Progressive volumes series should have same length*"); }
private void CheckDefaultSingleCellAtOriginResponse(ProgressiveVolumesResponse response) { // const double EPSILON = 0.000001; response.Should().NotBeNull(); response.ResultStatus.Should().Be(RequestErrorStatus.OK); // todo: Complete this /* * response.BoundingExtentGrid.MinX.Should().BeApproximately(0, EPSILON); * response.BoundingExtentGrid.MinY.Should().BeApproximately(0, EPSILON); * response.BoundingExtentGrid.MaxX.Should().BeApproximately(SubGridTreeConsts.DefaultCellSize, EPSILON); * response.BoundingExtentGrid.MaxY.Should().BeApproximately(SubGridTreeConsts.DefaultCellSize, EPSILON); * response.BoundingExtentGrid.MinZ.Should().Be(Consts.NullDouble); * response.BoundingExtentGrid.MaxZ.Should().Be(Consts.NullDouble); */ }
private void CheckDefaultFilterToFilterSingleTAGFileResponse(ProgressiveVolumesResponse response) { //Was, response = {Cut:1.00113831634521, Fill:2.48526947021484, Cut Area:117.5652, FillArea: 202.9936, Total Area:353.0424, BoundingGrid:MinX: 537669.2, MaxX:537676.34, MinY:5427391.44, MaxY:5427514.52, MinZ: 1E+308, MaxZ:1E+308, BoundingLLH:MinX: 1E+308, MaxX:1E+308, MinY:1... // const double EPSILON = 0.000001; response.Should().NotBeNull(); response.ResultStatus.Should().Be(RequestErrorStatus.OK); response.Volumes.Should().NotBeNull(); // todo: Complete this /* response.BoundingExtentGrid.MinX.Should().BeApproximately(537669.2, EPSILON); * response.BoundingExtentGrid.MinY.Should().BeApproximately(5427391.44, EPSILON); * response.BoundingExtentGrid.MaxX.Should().BeApproximately(537676.34, EPSILON); * response.BoundingExtentGrid.MaxY.Should().BeApproximately(5427514.52, EPSILON); * response.BoundingExtentGrid.MinZ.Should().Be(Consts.NullDouble); * response.BoundingExtentGrid.MaxZ.Should().Be(Consts.NullDouble);*/ }
public void AggregateWith() { var date = DateTime.UtcNow; var response1 = new ProgressiveVolumesResponse { ResultStatus = RequestErrorStatus.OK, Volumes = new[] { new ProgressiveVolumeResponseItem { Date = date, Volume = new SimpleVolumesResponse() } } }; var response2 = new ProgressiveVolumesResponse { ResultStatus = RequestErrorStatus.OK, Volumes = new[] { new ProgressiveVolumeResponseItem { Date = date, Volume = new SimpleVolumesResponse { Cut = 10.0, Fill = 20.0, BoundingExtentGrid = new TRex.Geometry.BoundingWorldExtent3D(1.0, 2.0, 3.0, 4.0, 5.0, 6.0), CutArea = 30.0, FillArea = 40.0, TotalCoverageArea = 100.0 } } } }; response1.AggregateWith(response2); response2.Should().BeEquivalentTo(response1); }
/// <summary> /// Executes the progressive volumes computation returning a ProgressiveVolumesResponse with the results /// </summary> public async Task <ProgressiveVolumesResponse> ExecuteAsync() { var volumesResult = new ProgressiveVolumesResponse(); var resultBoundingExtents = BoundingWorldExtent3D.Null(); var requestDescriptor = Guid.NewGuid(); // TODO ASNodeImplInstance.NextDescriptor; _log.LogInformation($"#In# Performing {nameof(ComputeProgressiveVolumes_Coordinator)}.Execute for DataModel:{SiteModelID}"); try { try { ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequests.Increment(); // Prepare filter for use in the request var resultStatus = FilterUtilities.PrepareFiltersForUse(new[] { Filter, AdditionalSpatialFilter }, SiteModelID); if (resultStatus != RequestErrorStatus.OK) { return(volumesResult); } // Obtain the site model context for the request _siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(SiteModelID); if (_siteModel == null) { return(volumesResult); } // Determine the number of progressions that are required and establish the required aggregation states in the aggregator var numProgressions = (int)((EndDate.Ticks - StartDate.Ticks) / Interval.Ticks); if ((EndDate.Ticks - StartDate.Ticks) % Interval.Ticks == 0) { numProgressions++; } if (VolumeType == VolumeComputationType.Between2Filters) { // One fewer progressions will be calculated as each volume in the progression is computed across the interval of two // surfaces derived from production data. numProgressions--; } if (numProgressions > ClientProgressiveHeightsLeafSubGrid.MaxNumberOfHeightLayers) { throw new ArgumentException($"No more than {ClientProgressiveHeightsLeafSubGrid.MaxNumberOfHeightLayers} height layers may be requested at one time"); } // Create and configure the aggregator that contains the business logic for the underlying volume calculation Aggregator = new ProgressiveVolumesCalculationsAggregator { SiteModel = _siteModel, LiftParams = _liftParams, CellSize = _siteModel.CellSize, VolumeType = VolumeType, CutTolerance = CutTolerance, FillTolerance = FillTolerance, AggregationStates = Enumerable .Range(VolumeType == VolumeComputationType.Between2Filters ? 1 : 0, numProgressions) .Select(x => StartDate + x * Interval) .Select(d => new ProgressiveVolumeAggregationState(_siteModel.CellSize) { Date = d, CutTolerance = CutTolerance, FillTolerance = FillTolerance }).ToArray() }; // Create and configure the volumes calculation engine var computeVolumes = new ProgressiveVolumesCalculator { RequestDescriptor = requestDescriptor, SiteModel = _siteModel, Aggregator = Aggregator, Filter = Filter, VolumeType = VolumeType, LiftParams = _liftParams, StartDate = StartDate, EndDate = EndDate, Interval = Interval }; InitialiseVolumesCalculator(computeVolumes); // Perform the volume computation if (computeVolumes.ComputeVolumeInformation()) { resultStatus = RequestErrorStatus.OK; } else { resultStatus = computeVolumes.AbortedDueToTimeout ? RequestErrorStatus.AbortedDueToPipelineTimeout : RequestErrorStatus.Unknown; } if (resultStatus != RequestErrorStatus.OK) { _log.LogInformation($"Progressive volume result: Failure, error = {resultStatus}"); // Send the (empty) results back to the caller return(volumesResult); } // Instruct the Aggregator to perform any finalization logic before reading out the results Aggregator.Finalise(); var noProductionDataCount = 0; var invalidPlanExtentsCount = 0; foreach (var state in Aggregator.AggregationStates) { _log.LogInformation($"#Result# Progressive volume result: Cut={state.CutFillVolume.CutVolume:F3}, Fill={state.CutFillVolume.FillVolume:F3}, Area={state.CoverageArea:F3}"); if (!state.BoundingExtents.IsValidPlanExtent) { if (state.CoverageArea == 0 && state.CutFillVolume.CutVolume == 0 && state.CutFillVolume.FillVolume == 0) { noProductionDataCount++; } else { invalidPlanExtentsCount++; } } } if (noProductionDataCount == Aggregator.AggregationStates.Length) { resultStatus = RequestErrorStatus.NoProductionDataFound; } else if (invalidPlanExtentsCount == Aggregator.AggregationStates.Length) { resultStatus = RequestErrorStatus.InvalidPlanExtents; } if (resultStatus == RequestErrorStatus.NoProductionDataFound || resultStatus == RequestErrorStatus.InvalidPlanExtents) { _log.LogInformation($"Progressive volume invalid plan extents or no data found: {resultStatus}"); } volumesResult.ResultStatus = resultStatus; if (resultStatus == RequestErrorStatus.OK) { volumesResult.Volumes = Aggregator.AggregationStates.Select(aggregator => new ProgressiveVolumeResponseItem { Date = aggregator.Date, Volume = new SimpleVolumesResponse { Cut = aggregator.CutFillVolume.CutVolume, Fill = aggregator.CutFillVolume.FillVolume, TotalCoverageArea = aggregator.CoverageArea, CutArea = aggregator.CutArea, FillArea = aggregator.FillArea, BoundingExtentGrid = aggregator.BoundingExtents, BoundingExtentLLH = resultBoundingExtents } }).ToArray(); } } finally { ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequestsCompleted.Increment(); if (volumesResult.ResultStatus != RequestErrorStatus.OK) { ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequestsFailed.Increment(); } } } catch (Exception e) { _log.LogError(e, $"Failed to compute the progressive volumes. Site Model ID: {SiteModelID}"); } return(volumesResult); }
private static ProgressiveVolumesResponse ConvertBoundaryFromGridToWGS84(Guid projectUid, ProgressiveVolumesResponse response) { try { var convertCoordinates = DIContext.ObtainRequired <ICoreXWrapper>(); if (response.Volumes != null) { foreach (var aggregator in response.Volumes) { if (!aggregator.Volume.BoundingExtentGrid.IsValidPlanExtent) // No conversion possible { continue; } var neeCoords = new[] { new XYZ( aggregator.Volume.BoundingExtentGrid.MinX, aggregator.Volume.BoundingExtentGrid.MinY, // ReSharper disable once CompareOfFloatsByEqualityOperator aggregator.Volume.BoundingExtentGrid.MinZ == Consts.NullDouble ? 0.0 : aggregator.Volume.BoundingExtentGrid.MinZ), new XYZ( aggregator.Volume.BoundingExtentGrid.MaxX, aggregator.Volume.BoundingExtentGrid.MaxY, // ReSharper disable once CompareOfFloatsByEqualityOperator aggregator.Volume.BoundingExtentGrid.MaxZ == Consts.NullDouble ? 0.0 : aggregator.Volume.BoundingExtentGrid.MaxZ) }; var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(projectUid); var llhCoords = convertCoordinates.NEEToLLH(siteModel.CSIB(), neeCoords.ToCoreX_XYZ()).ToTRex_XYZ(); aggregator.Volume.BoundingExtentLLH = new BoundingWorldExtent3D { MinX = MathUtilities.RadiansToDegrees(llhCoords[0].X), MinY = MathUtilities.RadiansToDegrees(llhCoords[0].Y), MaxX = MathUtilities.RadiansToDegrees(llhCoords[1].X), MaxY = MathUtilities.RadiansToDegrees(llhCoords[1].Y) }; } } } catch (Exception e) { // Don't rethrow here, doing so will terminate the otherwise valid request (with valid response). Leave the grid boundary extents in place with null LLH extents _log.LogError(e, "Exception converting coordinates for progressive volumes. Response will contain grid coordinate extents."); } return(response); }
public void Creation() { var response = new ProgressiveVolumesResponse(); Assert.NotNull(response); }