public async Task <JsonResult> ComputeCompositeElevationProfile(string siteModelID, [FromQuery] double startX, [FromQuery] double startY, [FromQuery] double endX, [FromQuery] double endY) { var siteModelUid = Guid.Parse(siteModelID); var arg = new ProfileRequestArgument_ApplicationService { ProjectID = siteModelUid, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.CellPasses, PositionsAreGrid = true, Filters = new FilterSet(new[] { new CombinedFilter() }), ReferenceDesign = new DesignOffset(), StartPoint = new WGS84Point(lon: startX, lat: startY), EndPoint = new WGS84Point(lon: endX, lat: endY), ReturnAllPassesAndLayers = false, }; // Compute a profile from the bottom left of the screen extents to the top right var request = new ProfileRequest_ApplicationService_ProfileCell(); var response = await request.ExecuteAsync(arg); if (response == null) { return(new JsonResult(@"Profile response is null")); } if (response.ProfileCells == null) { return(new JsonResult(@"Profile response contains no profile cells")); } //var nonNulls = Response.ProfileCells.Where(x => !x.IsNull()).ToArray(); return(new JsonResult(response.ProfileCells.Select(x => new { station = x.Station + x.InterceptLength / 2.0,// Shift the station position to the center of the intercept line across the cell. cellLowestElev = x.CellLowestElev, cellHighestElev = x.CellHighestElev, cellLastElev = x.CellLastElev, cellFirstElev = x.CellFirstElev, cellLowestCompositeElev = x.CellLowestCompositeElev, cellHighestCompositeElev = x.CellHighestCompositeElev, cellLastCompositeElev = x.CellLastCompositeElev, cellFirstCompositeElev = x.CellFirstCompositeElev }))); }
public async Task <JsonResult> ComputeSummaryVolumesProfile(string siteModelID, [FromQuery] double startX, [FromQuery] double startY, [FromQuery] double endX, [FromQuery] double endY) { //TODO: can add design to ground and ground to design by passing the cutFillDesignUid var siteModelUid = Guid.Parse(siteModelID); var arg = new ProfileRequestArgument_ApplicationService { ProjectID = siteModelUid, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.SummaryVolume, PositionsAreGrid = true, Filters = new FilterSet(new CombinedFilter(), new CombinedFilter()), StartPoint = new WGS84Point(lon: startX, lat: startY), EndPoint = new WGS84Point(lon: endX, lat: endY), ReturnAllPassesAndLayers = false, VolumeType = VolumeComputationType.Between2Filters }; // This is a simple earliest filter to latest filter test arg.Filters.Filters[0].AttributeFilter.ReturnEarliestFilteredCellPass = true; arg.Filters.Filters[1].AttributeFilter.ReturnEarliestFilteredCellPass = false; // Compute a profile from the bottom left of the screen extents to the top right var request = new ProfileRequest_ApplicationService_SummaryVolumeProfileCell(); var response = await request.ExecuteAsync(arg); if (response == null) { return(new JsonResult(@"Profile response is null")); } if (response.ProfileCells == null) { return(new JsonResult(@"Profile response contains no profile cells")); } return(new JsonResult(response.ProfileCells.Select(x => new XYZS(0, 0, x.LastCellPassElevation2 - x.LastCellPassElevation1, x.Station, -1)))); }
protected override async Task <ContractExecutionResult> ProcessAsyncEx <T>(T item) { var request = item as SummaryVolumesProfileDataRequest; if (request == null) { ThrowRequestTypeCastException <SummaryVolumesProfileDataRequest>(); } var siteModel = GetSiteModel(request.ProjectUid); var baseFilter = ConvertFilter(request.Filter, siteModel); var topFilter = ConvertFilter(request.TopFilter, siteModel); var referenceDesign = new DesignOffset(request.ReferenceDesignUid ?? Guid.Empty, request.ReferenceDesignOffset ?? 0); var arg = new ProfileRequestArgument_ApplicationService { ProjectID = request.ProjectUid, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.SummaryVolume, PositionsAreGrid = request.PositionsAreGrid, Filters = new FilterSet(baseFilter, topFilter), ReferenceDesign = referenceDesign, StartPoint = new WGS84Point(lon: request.StartX, lat: request.StartY, request.PositionsAreGrid ? Consts.NullDouble : 0),//coord conversion requires elevation set EndPoint = new WGS84Point(lon: request.EndX, lat: request.EndY, request.PositionsAreGrid ? Consts.NullDouble : 0), ReturnAllPassesAndLayers = false, VolumeType = ConvertVolumesHelper.ConvertVolumesType(request.VolumeCalcType), Overrides = AutoMapperUtility.Automapper.Map <OverrideParameters>(request.Overrides), LiftParams = ConvertLift(request.LiftSettings, request.Filter?.LayerType) }; // Compute a profile from the bottom left of the screen extents to the top right var svRequest = new ProfileRequest_ApplicationService_SummaryVolumeProfileCell(); var response = await svRequest.ExecuteAsync(arg); if (response != null) { return(ConvertResult(response)); } throw new ServiceException(HttpStatusCode.BadRequest, new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults, "Failed to get requested Summary Volumes Profile data")); }
public async Task SummaryVolumeProfileCell_SingleCell_FlatDesignAtOrigin_FilterToDesignOrDesignToFilter(VolumeComputationType volumeComputationType, float designElevation, float lastPassElevation1, float lastPassElevation2, int checkCellIndex) { AddRoutings(); var sm = BuildModelForSingleCell(); var design = DITAGFileAndSubGridRequestsWithIgniteFixture.ConstructSingleFlatTriangleDesignAboutOrigin(ref sm, designElevation); var arg = new ProfileRequestArgument_ApplicationService { ProjectID = sm.ID, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.SummaryVolume, PositionsAreGrid = true, Filters = new FilterSet( new CombinedFilter { AttributeFilter = new CellPassAttributeFilter { ReturnEarliestFilteredCellPass = true } }, new CombinedFilter()), ReferenceDesign = new DesignOffset(design, 0), StartPoint = new WGS84Point(-1.0, sm.Grid.CellSize / 2), EndPoint = new WGS84Point(1.0, sm.Grid.CellSize / 2), ReturnAllPassesAndLayers = false, VolumeType = volumeComputationType }; // Compute a profile from the bottom left of the screen extents to the top right var svRequest = new ProfileRequest_ApplicationService_SummaryVolumeProfileCell(); var response = await svRequest.ExecuteAsync(arg); response.Should().NotBeNull(); response.ResultStatus.Should().Be(RequestErrorStatus.OK); response.ProfileCells.Count.Should().Be(6); response.ProfileCells[checkCellIndex].DesignElev.Should().Be(designElevation); response.ProfileCells[checkCellIndex].LastCellPassElevation1.Should().Be(lastPassElevation1); response.ProfileCells[checkCellIndex].LastCellPassElevation2.Should().Be(lastPassElevation2); response.ProfileCells[checkCellIndex].InterceptLength.Should().BeApproximately(sm.Grid.CellSize, 0.001); response.ProfileCells[checkCellIndex].OTGCellX.Should().Be(SubGridTreeConsts.DefaultIndexOriginOffset); response.ProfileCells[checkCellIndex].OTGCellY.Should().Be(SubGridTreeConsts.DefaultIndexOriginOffset); }
public void Test_ProfileRequestArgument_ApplicationService() { var argument = new ProfileRequestArgument_ApplicationService() { ProjectID = Guid.NewGuid(), Filters = new FilterSet(new CombinedFilter()), ReferenceDesign = new DesignOffset(Guid.NewGuid(), 1.5), ProfileTypeRequired = GridDataType.Height, PositionsAreGrid = true, StartPoint = new WGS84Point(MIN_X, MIN_Y, MIN_Z), EndPoint = new WGS84Point(MAX_X, MAX_Y, MAX_Z), ReturnAllPassesAndLayers = false, Overrides = new OverrideParameters { OverrideTemperatureWarningLevels = true, OverridingTemperatureWarningLevels = new TemperatureWarningLevelsRecord(123, 456) } }; SimpleBinarizableInstanceTester.TestClass(argument, "Custom ProfileRequestArgument_ApplicationService not same after round trip serialisation"); }
/// <summary> /// Delegates processing of the profile like to the cluster compute layer, then aggregates together the fractional responses /// received from each participating node in the query /// </summary> public ProfileRequestResponse <T> Invoke(ProfileRequestArgument_ApplicationService arg) { _log.LogInformation("In Invoke()"); try { var executor = new ComputeProfileExecutor_ApplicationService <T>(); return(executor.ExecuteAsync(arg).WaitAndUnwrapException()); } catch (Exception e) { _log.LogError(e, "Exception requesting profile at application layer"); return(new ProfileRequestResponse <T> { ResultStatus = Types.RequestErrorStatus.Exception }); } finally { _log.LogInformation("Out Invoke()"); } }
/// <summary> /// Executes the profiler /// </summary> public async Task <ProfileRequestResponse <T> > ExecuteAsync(ProfileRequestArgument_ApplicationService arg) { _log.LogInformation("Start execution"); try { if (arg.Filters?.Filters != null && arg.Filters.Filters.Length > 0) { // Prepare the filters for use in profiling operations. Failure to prepare any filter results in this request terminating if (!arg.Filters.Filters.Select(x => FilterUtilities.PrepareFilterForUse(x, arg.ProjectID)).All(x => x == RequestErrorStatus.OK)) { return(new ProfileRequestResponse <T> { ResultStatus = RequestErrorStatus.FailedToPrepareFilter }); } } var arg2 = new ProfileRequestArgument_ClusterCompute { ProfileTypeRequired = arg.ProfileTypeRequired, ProfileStyle = arg.ProfileStyle, ProjectID = arg.ProjectID, Filters = arg.Filters, ReferenceDesign = arg.ReferenceDesign, ReturnAllPassesAndLayers = arg.ReturnAllPassesAndLayers, TRexNodeID = arg.TRexNodeID, VolumeType = arg.VolumeType, Overrides = arg.Overrides, LiftParams = arg.LiftParams }; // Perform coordinate conversion on the argument before broadcasting it: if (arg.PositionsAreGrid) { arg2.NEECoords = new[] { arg.StartPoint, arg.EndPoint }.Select(x => new XYZ(x.Lon, x.Lat)).ToArray(); } else { var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(arg.ProjectID); if (siteModel != null) { arg2.NEECoords = DIContext.Obtain <ICoreXWrapper>().WGS84ToCalibration( siteModel.CSIB(), new[] { arg.StartPoint, arg.EndPoint } .ToCoreX_WGS84Point(), CoreX.Types.InputAs.Radians) .ToTRex_XYZ(); } } var request = new ProfileRequest_ClusterCompute <T>(); var profileResponse = await request.ExecuteAsync(arg2); profileResponse.GridDistanceBetweenProfilePoints = MathUtilities.Hypot(arg2.NEECoords[1].X - arg2.NEECoords[0].X, arg2.NEECoords[1].Y - arg2.NEECoords[0].Y); //... and then sort them to get the final result, as well as removing initial and duplicate null values // Remove null cells in the profiles list. Null cells are defined by cells with null CellLastHeight. // All duplicate null cells will be replaced by a by single null cell entry int firstNonNullIndex = 0; var _profileCells = profileResponse?.ProfileCells?.OrderBy(x => x.Station).ToList(); if (_profileCells != null) { profileResponse.ProfileCells = _profileCells.Where((x, i) => { // Remove all leading nulls if (_profileCells[i].IsNull() && i == firstNonNullIndex) { firstNonNullIndex++; return(false); } // Collapse all interior nulls to single nulls, unless the null is at the end. Leave any single terminating null return(i == 0 || !_profileCells[i].IsNull() || (_profileCells[i].IsNull() && !_profileCells[i - 1].IsNull())); }).ToList(); } // Return the care package to the caller return(profileResponse); } finally { _log.LogInformation("End execution"); } }
public async Task <JsonResult> ComputeProductionDataProfile(string siteModelID, [FromQuery] double startX, [FromQuery] double startY, [FromQuery] double endX, [FromQuery] double endY, [FromQuery] int displayMode, [FromQuery] Guid?cutFillDesignUid, [FromQuery] double?offset, [FromBody] OverrideParameters overrides) { var siteModelUid = Guid.Parse(siteModelID); /* * //Use default values for now * var overrides = new OverrideParameters * { * CMVRange = new CMVRangePercentageRecord(80, 130), * MDPRange = new MDPRangePercentageRecord(80, 130), * TargetMachineSpeed = new MachineSpeedExtendedRecord((ushort) (5 * KM_HR_TO_CM_SEC), (ushort) (10 * KM_HR_TO_CM_SEC)) * }; */ var arg = new ProfileRequestArgument_ApplicationService { ProjectID = siteModelUid, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.CellPasses, PositionsAreGrid = true, Filters = new FilterSet(new[] { new CombinedFilter() }), ReferenceDesign = new DesignOffset(cutFillDesignUid ?? Guid.Empty, offset ?? 0.0), StartPoint = new WGS84Point(lon: startX, lat: startY), EndPoint = new WGS84Point(lon: endX, lat: endY), ReturnAllPassesAndLayers = false, Overrides = overrides }; // Compute a profile from the bottom left of the screen extents to the top right var request = new ProfileRequest_ApplicationService_ProfileCell(); var response = await request.ExecuteAsync(arg); if (response == null) { return(new JsonResult(@"Profile response is null")); } if (response.ProfileCells == null) { return(new JsonResult(@"Profile response contains no profile cells")); } var results = (from x in response.ProfileCells let v = ProfileValue(displayMode, x, overrides) select new { station = x.Station, elevation = ProfileElevation(displayMode, x), index = v.index, value = v.value, value2 = v.value2 }); return(new JsonResult(results)); }
public async Task ProfileCell_SingleCell_NoDesign(bool withOverrides) { AddRoutings(); var sm = BuildModelForSingleCell(); var overrides = withOverrides ? new OverrideParameters { OverrideMachineCCV = true, OverridingMachineCCV = 987, OverrideMachineMDP = true, OverridingMachineMDP = 789, OverrideTargetPassCount = true, OverridingTargetPassCountRange = new PassCountRangeRecord(5, 6), OverrideTemperatureWarningLevels = true, OverridingTemperatureWarningLevels = new TemperatureWarningLevelsRecord(400, 1200), TargetMachineSpeed = new MachineSpeedExtendedRecord(777, 888) } : new OverrideParameters(); var arg = new ProfileRequestArgument_ApplicationService { ProjectID = sm.ID, ProfileTypeRequired = GridDataType.Height, ProfileStyle = ProfileStyle.CellPasses, PositionsAreGrid = true, Filters = new FilterSet(new CombinedFilter()), ReferenceDesign = null, StartPoint = new WGS84Point(-1.0, sm.Grid.CellSize / 2), EndPoint = new WGS84Point(1.0, sm.Grid.CellSize / 2), ReturnAllPassesAndLayers = false, Overrides = overrides }; var svRequest = new ProfileRequest_ApplicationService_ProfileCell(); var response = await svRequest.ExecuteAsync(arg); response.Should().NotBeNull(); response.ResultStatus.Should().Be(RequestErrorStatus.OK); response.GridDistanceBetweenProfilePoints.Should().Be(2.0); response.ProfileCells.Count.Should().Be(2); var expectedTargetCCV = (short)(withOverrides ? 987 : 123); var expectedPrevTargetCCV = (short)(withOverrides ? 987 : CellPassConsts.NullCCV); var expectedTargetMDP = (short)(withOverrides ? 789 : 321); var expectedMinTemp = (ushort)(withOverrides ? 400 : 652); var expectedMaxTemp = (ushort)(withOverrides ? 1200 : 655); var expectedMinPassCount = (ushort)(withOverrides ? 5 : 4); var expectedMaxPassCount = (ushort)(withOverrides ? 6 : 4); response.ProfileCells[0].CellFirstElev.Should().Be(0); response.ProfileCells[0].CellLastElev.Should().Be(9); response.ProfileCells[0].CellLowestElev.Should().Be(0); response.ProfileCells[0].CellHighestElev.Should().Be(9); response.ProfileCells[0].CellCCV.Should().Be(132);//123+9 response.ProfileCells[0].CellCCVElev.Should().Be(9); response.ProfileCells[0].CellTargetCCV.Should().Be(expectedTargetCCV); response.ProfileCells[0].CellPreviousMeasuredCCV.Should().Be(131); response.ProfileCells[0].CellPreviousMeasuredTargetCCV.Should().Be(expectedPrevTargetCCV); response.ProfileCells[0].CellMDP.Should().Be(330);//321+9 response.ProfileCells[0].CellMDPElev.Should().Be(9); response.ProfileCells[0].CellTargetMDP.Should().Be(expectedTargetMDP); response.ProfileCells[0].TopLayerPassCountTargetRangeMin.Should().Be(expectedMinPassCount); response.ProfileCells[0].TopLayerPassCountTargetRangeMax.Should().Be(expectedMaxPassCount); response.ProfileCells[0].TopLayerPassCount.Should().Be(10); response.ProfileCells[0].CellMinSpeed.Should().Be(456); response.ProfileCells[0].CellMaxSpeed.Should().Be(465);//456+9 response.ProfileCells[0].CellMaterialTemperatureWarnMin.Should().Be(expectedMinTemp); response.ProfileCells[0].CellMaterialTemperatureWarnMax.Should().Be(expectedMaxTemp); response.ProfileCells[0].CellMaterialTemperature.Should().Be(661);//652+9 response.ProfileCells[0].CellMaterialTemperatureElev.Should().Be(9); response.ProfileCells[1].CellFirstElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellLastElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellLowestElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellHighestElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellCCV.Should().Be(CellPassConsts.NullCCV); response.ProfileCells[1].CellCCVElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellTargetCCV.Should().Be(CellPassConsts.NullCCV); response.ProfileCells[1].CellPreviousMeasuredCCV.Should().Be(CellPassConsts.NullCCV); response.ProfileCells[1].CellPreviousMeasuredTargetCCV.Should().Be(CellPassConsts.NullCCV); response.ProfileCells[1].CellMDP.Should().Be(CellPassConsts.NullMDP); response.ProfileCells[1].CellMDPElev.Should().Be(CellPassConsts.NullHeight); response.ProfileCells[1].CellTargetMDP.Should().Be(CellPassConsts.NullMDP); response.ProfileCells[1].TopLayerPassCountTargetRangeMin.Should().Be(CellPassConsts.NullPassCountValue); response.ProfileCells[1].TopLayerPassCountTargetRangeMax.Should().Be(CellPassConsts.NullPassCountValue); response.ProfileCells[1].TopLayerPassCount.Should().Be(CellPassConsts.NullPassCountValue); //Note: MinSpeed of Null and MaxSpeed of 0 are the defaults meaning no speed values response.ProfileCells[1].CellMinSpeed.Should().Be(CellPassConsts.NullMachineSpeed); response.ProfileCells[1].CellMaxSpeed.Should().Be(0); response.ProfileCells[1].CellMaterialTemperatureWarnMin.Should().Be(CellPassConsts.NullMaterialTemperatureValue); response.ProfileCells[1].CellMaterialTemperatureWarnMax.Should().Be(CellPassConsts.NullMaterialTemperatureValue); response.ProfileCells[1].CellMaterialTemperature.Should().Be(CellPassConsts.NullMaterialTemperatureValue); response.ProfileCells[1].CellMaterialTemperatureElev.Should().Be(CellPassConsts.NullHeight); }