コード例 #1
0
        /// <summary>
        /// Since the profile line will be drawn between line segment mid points we need to interpolate the cell edge points to lie on these line segments.
        /// </summary>
        /// <param name="profileResult">The profile containing the list of line segment points, both edges and mid points, for each profile type.</param>
        /// <param name="calcType">The type of summary volumes calculation</param>
        public void InterpolateEdges(CompactionProfileResult <CompactionProfileDataResult> profileResult, VolumeCalcType?calcType)
        {
            log.LogDebug("Interpolating edges");
            foreach (var result in profileResult.results)
            {
                log.LogDebug($"Interpolating edges for {result.type}");

                if (result.data.Count >= 3)
                {
                    //First and last points are not gaps or edges. They're always the start and end of the profile line.
                    for (int i = 1; i < result.data.Count - 1; i++)
                    {
                        if (result.data[i].cellType == ProfileCellType.MidPoint)
                        {
                            continue;
                        }

                        //No y to interpolate for summary volumes design-ground
                        if (result.type != CompactionDataPoint.SUMMARY_VOLUMES || calcType != VolumeCalcType.DesignToGround)
                        {
                            InterpolatePoint(i, result.data, result.type, false);
                        }

                        //y2 to interpolate for only summary volumes ground-ground and design-ground
                        if (result.type == CompactionDataPoint.SUMMARY_VOLUMES && calcType != VolumeCalcType.GroundToDesign)
                        {
                            InterpolatePoint(i, result.data, result.type, true);
                        }
                    }
                }
                log.LogDebug($"After interpolation for {result.type}");
            }
        }
コード例 #2
0
 /// <summary>
 /// Adds slicer end points to the profile results if not already present
 /// </summary>
 /// <param name="profile">The profile result to check</param>
 public void AddSlicerEndPoints(CompactionProfileResult <CompactionDesignProfileResult> profile)
 {
     //Raptor returns only the vertices on the design surface.
     //Add slicer end points with NaN elevation if not present for a profile.
     if (profile.gridDistanceBetweenProfilePoints > 0)
     {
         foreach (var result in profile.results)
         {
             if (result.data.Count > 0)
             {
                 if (result.data[0].station > 0)
                 {
                     result.data.Insert(0, new CompactionProfileVertex {
                         cellType = ProfileCellType.Gap, station = 0, elevation = float.NaN
                     });
                 }
                 if (Math.Abs(result.data[result.data.Count - 1].station - profile.gridDistanceBetweenProfilePoints) > ProfilesHelper.ONE_MM)
                 {
                     //The start of the gap between the last point and the slicer end point is the end of the actual data.
                     result.data[result.data.Count - 1].cellType = ProfileCellType.Gap;
                     //Now add the slicer end point.
                     result.data.Add(new CompactionProfileVertex {
                         cellType = ProfileCellType.Gap, station = profile.gridDistanceBetweenProfilePoints, elevation = float.NaN
                     });
                 }
             }
         }
     }
 }
コード例 #3
0
        /// <summary>
        /// Convert from one summary volumes profile representation to another.
        /// </summary>
        /// <param name="slicerProfileResult">The profile result to convert from</param>
        /// <param name="calcType">The type of summary volumes profile</param>
        /// <returns>The new profile result representation</returns>
        public CompactionProfileDataResult RearrangeProfileResult(
            CompactionProfileResult <CompactionSummaryVolumesProfileCell> slicerProfileResult, VolumeCalcType?calcType)
        {
            log.LogDebug("ConvertProfileResult: Summary volumes profile");

            if (slicerProfileResult == null)
            {
                return(null);
            }

            return(new CompactionProfileDataResult
            {
                type = CompactionDataPoint.SUMMARY_VOLUMES,
                data = (from p in slicerProfileResult.results
                        select new CompactionDataPoint
                {
                    type = CompactionDataPoint.SUMMARY_VOLUMES,
                    cellType = p.cellType,
                    x = p.station,
                    //y or y2 will be set later using the summary volumes design
                    y = calcType == VolumeCalcType.DesignToGround ? float.NaN : p.lastPassHeight1,
                    value = -p.cutFill,
                    y2 = calcType == VolumeCalcType.GroundToDesign ? float.NaN : p.lastPassHeight2
                }).ToList()
            });
        }
コード例 #4
0
        /// <summary>
        /// Convert from one design profile representation to another
        /// </summary>
        /// <param name="slicerProfileResults">The profile result to convert from</param>
        /// <returns>The new profile result representation</returns>
        public CompactionProfileResult <CompactionDesignProfileResult> ConvertProfileResult(
            Dictionary <Guid, CompactionProfileResult <CompactionProfileVertex> > slicerProfileResults)
        {
            log.LogDebug("ConvertProfileResult: Design profiles");

            //shouldn't ever happen but for safety check arg
            if (slicerProfileResults == null || slicerProfileResults.Count == 0)
            {
                throw new ServiceException(HttpStatusCode.InternalServerError,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError,
                                                                       "Unexpected missing design profile results"));
            }

            //all gridDistanceBetweenProfilePoints are the same if the profile slices the design surface
            var profileWithDistance = slicerProfileResults.Values.Where(v => v.gridDistanceBetweenProfilePoints > 0)
                                      .FirstOrDefault();
            var distance = profileWithDistance?.gridDistanceBetweenProfilePoints ?? 0;

            var profile = new CompactionProfileResult <CompactionDesignProfileResult>
            {
                gridDistanceBetweenProfilePoints = distance,
                results = (from spr in slicerProfileResults
                           select new CompactionDesignProfileResult
                {
                    designFileUid = spr.Key,
                    data = spr.Value.results
                }).ToList()
            };

            return(profile);
        }
コード例 #5
0
        /// <summary>
        /// Process the profile request to get production data profiles
        /// </summary>
        /// <param name="request">Profile request</param>
        /// <returns>Profile for each production data type except summary volumes</returns>
        private async Task <CompactionProfileResult <CompactionProfileDataResult> > ProcessProductionData(CompactionProfileProductionDataRequest request)
        {
            CompactionProfileResult <CompactionProfileDataResult> totalResult;

            var productionDataProfileResult =
#if RAPTOR
                UseTRexGateway("ENABLE_TREX_GATEWAY_PROFILING") ?
#endif
                await ProcessProductionDataWithTRexGateway(request)
#if RAPTOR
            : ProcessProductionDataWithRaptor(request)
#endif
            ;

            if (productionDataProfileResult != null)
            {
                totalResult = profileResultHelper.RearrangeProfileResult(productionDataProfileResult);
            }
            else
            {
                //For convenience return empty list rather than null for easier manipulation
                totalResult = new CompactionProfileResult <CompactionProfileDataResult>
                {
                    results = new List <CompactionProfileDataResult>()
                };
            }
            return(totalResult);
        }
コード例 #6
0
        /// <summary>
        /// Add mid points between the cell edge intersections. This is because the profile line is plotted using these points.
        /// The cell edges are retained as this is where the color changes on the graph or chart.
        /// </summary>
        /// <param name="profileResult">The profile results from Raptor, one list of cell points for each profile type</param>
        /// <returns>The complete list of interspersed edges and  mid points for each profile type.</returns>
        public void AddMidPoints(CompactionProfileResult <CompactionProfileDataResult> profileResult)
        {
            log.LogDebug("Adding midpoints");
            foreach (var result in profileResult.results)
            {
                log.LogDebug($"Adding midpoints for {result.type}");

                if (result.data.Count >= 4)
                {
                    //No mid point for first and last segments since only partial across the cell.
                    //We have already added them as mid points.
                    var points = new List <CompactionDataPoint> {
                        result.data[0]
                    };

                    for (int i = 1; i < result.data.Count - 2; i++)
                    {
                        points.Add(result.data[i]);
                        if (result.data[i].cellType != ProfileCellType.Gap)
                        {
                            var midPoint = new CompactionDataPoint(result.data[i])
                            {
                                cellType = ProfileCellType.MidPoint,
                                x        = result.data[i].x +
                                           (result.data[i + 1].x - result.data[i].x) / 2
                            };
                            points.Add(midPoint);
                        }
                    }
                    points.Add(result.data[result.data.Count - 2]);
                    points.Add(result.data[result.data.Count - 1]);
                    result.data = points;
                }

                StringBuilder sb = new StringBuilder();
                sb.Append($"After adding midpoints for {result.type}: {result.data.Count}");
                foreach (var point in result.data)
                {
                    sb.Append($",{point.cellType}");
                }
                log.LogDebug(sb.ToString());
            }
        }
コード例 #7
0
        private CompactionProfileResult <CompactionProfileVertex> PerformProductionDataProfilePost(CompactionProfileDesignRequest request)
        {
            CompactionProfileResult <CompactionProfileVertex> result;

            try
            {
                ProfilesHelper.ConvertProfileEndPositions(request.GridPoints, request.WGS84Points, out TWGS84Point startPt, out TWGS84Point endPt, out bool positionsAreGrid);

                var designProfile = DesignProfiler.ComputeProfile.RPC.__Global.Construct_CalculateDesignProfile_Args(
                    request.ProjectId ?? VelociraptorConstants.NO_PROJECT_ID,
                    false,
                    startPt,
                    endPt,
                    ValidationConstants3D.MIN_STATION,
                    ValidationConstants3D.MAX_STATION,
                    RaptorConverters.DesignDescriptor(request.DesignDescriptor),
                    RaptorConverters.EmptyDesignDescriptor,
                    RaptorConverters.ConvertFilter(request.Filter, request.ProjectId, raptorClient),
                    positionsAreGrid);

                var memoryStream = raptorClient.GetDesignProfile(designProfile);

                if (memoryStream != null)
                {
                    result = ConvertProfileResult(memoryStream);
                    memoryStream.Close();
                }
                else
                {
                    //For convenience return empty list rather than null for easier manipulation
                    result = new CompactionProfileResult <CompactionProfileVertex> {
                        results = new List <CompactionProfileVertex>()
                    };
                }
            }
            finally
            {
                ContractExecutionStates.ClearDynamic();
            }

            return(result);
        }
コード例 #8
0
        private CompactionProfileResult <CompactionProfileVertex> ConvertTRexProfileResult(DesignProfileResult profile)
        {
            log.LogDebug("Converting TRex profile result");

            var profileResult = new CompactionProfileResult <CompactionProfileVertex>();

            profileResult.results = profile.HasData() ? profile.ProfileLine.ConvertAll(dpv => new CompactionProfileVertex
            {
                cellType  = dpv.Z >= VelociraptorConstants.NO_HEIGHT ? ProfileCellType.Gap : ProfileCellType.Edge,
                elevation = dpv.Z >= VelociraptorConstants.NO_HEIGHT ? float.NaN : (float)dpv.Z,
                station   = dpv.Station
            }) : new List <CompactionProfileVertex>();

            profileResult.gridDistanceBetweenProfilePoints =
                profile.ProfileLine.Count > 1 ? profile.ProfileLine[profile.ProfileLine.Count - 1].Station - profile.ProfileLine[0].Station : 0;

            FixGaps(profileResult.results);

            return(profileResult);
        }
コード例 #9
0
        private CompactionProfileResult <CompactionProfileVertex> ConvertProfileResult(MemoryStream ms)
        {
            log.LogDebug("Converting profile result");

            var profileResult = new CompactionProfileResult <CompactionProfileVertex>();
            var pdsiProfile   = new DesignProfile();

            pdsiProfile.ReadFromStream(ms);

            profileResult.results = pdsiProfile.vertices.ConvertAll(dpv => new CompactionProfileVertex
            {
                cellType  = dpv.elevation >= VelociraptorConstants.NO_HEIGHT ? ProfileCellType.Gap : ProfileCellType.Edge,
                elevation = dpv.elevation >= VelociraptorConstants.NO_HEIGHT ? float.NaN : dpv.elevation,
                station   = dpv.station
            });

            profileResult.gridDistanceBetweenProfilePoints = pdsiProfile.GridDistanceBetweenProfilePoints;

            FixGaps(profileResult.results);

            return(profileResult);
        }
コード例 #10
0
        /// <summary>
        /// Process profile request to get summary volumes profile
        /// </summary>
        /// <param name="request">Profile request</param>
        /// <param name="totalResult">Results for other production data profile types</param>
        /// <returns>Summary volumes profile</returns>
        private async Task <CompactionProfileDataResult> ProcessSummaryVolumes(CompactionProfileProductionDataRequest request, CompactionProfileResult <CompactionProfileDataResult> totalResult)
        {
            var volumesResult =
#if RAPTOR
                UseTRexGateway("ENABLE_TREX_GATEWAY_PROFILING") ?
#endif
                await ProcessSummaryVolumesWithTRexGateway(request)
#if RAPTOR
          : ProcessSummaryVolumesWithRaptor(request)
#endif
            ;

            //If we have no other profile results apart from summary volumes, set the total grid distance
            if (totalResult.results.Count == 0 && volumesResult != null)
            {
                totalResult.gridDistanceBetweenProfilePoints = volumesResult.gridDistanceBetweenProfilePoints;
            }

            //If we have other profile types but no summary volumes, add summary volumes with just slicer end points
            if (volumesResult == null && totalResult.results.Count > 0)
            {
                var startSlicer = new CompactionSummaryVolumesProfileCell(SumVolGapCell);
                var endSlicer   = new CompactionSummaryVolumesProfileCell(SumVolGapCell);
                endSlicer.station = totalResult.gridDistanceBetweenProfilePoints;
                volumesResult     =
                    new CompactionProfileResult <CompactionSummaryVolumesProfileCell>
                {
                    gridDistanceBetweenProfilePoints = totalResult.gridDistanceBetweenProfilePoints,
                    results = new List <CompactionSummaryVolumesProfileCell>
                    {
                        startSlicer,
                        endSlicer
                    }
                };
            }
            return(profileResultHelper.RearrangeProfileResult(volumesResult, request.VolumeCalcType));
        }
コード例 #11
0
        /// <summary>
        /// Calculate the elevations for cut-fill or summary volumes cells from the design surface.
        /// </summary>
        /// <param name="projectId">Legacy project ID</param>
        /// <param name="ProjectUid">Project's unique identifier</param>
        /// <param name="settings">Project settings</param>
        /// <param name="startLatDegrees">The start latitude of the slicer line in decimal degrees</param>
        /// <param name="startLonDegrees">The start longitude of the slicer line in decimal degrees</param>
        /// <param name="endLatDegrees">The end latitude of the slicer line in decimal degrees</param>
        /// <param name="endLonDegrees">The end longitude of the slicer line in decimal degrees</param>
        /// <param name="design">The design surface descriptor</param>
        /// <param name="profileResultHelper">Utility class to do the work</param>
        /// <param name="slicerProductionDataResult">The slicer profile results containing the production data profiles</param>
        /// <param name="type">The type of profile, either cut-fill or summary volumes</param>
        /// <param name="volumeCalcType">Summary volumes calculation type</param>
        private async Task FindCutFillElevations(
            long projectId,
            Guid ProjectUid,
            CompactionProjectSettings settings,
            double startLatDegrees, double startLonDegrees,
            double endLatDegrees, double endLonDegrees,
            DesignDescriptor design,
            ICompactionProfileResultHelper profileResultHelper,
            CompactionProfileResult <CompactionProfileDataResult> slicerProductionDataResult,
            string type,
            VolumeCalcType volumeCalcType)
        {
            //Get design profile
            var slicerDesignProfileRequest = requestFactory.Create <DesignProfileRequestHelper>(r => r
                                                                                                .ProjectId(projectId)
                                                                                                .ProjectUid(ProjectUid)
                                                                                                .Headers(this.CustomHeaders)
                                                                                                .ProjectSettings(settings)
                                                                                                .DesignDescriptor(design))
                                             .CreateDesignProfileRequest(startLatDegrees, startLonDegrees, endLatDegrees, endLonDegrees);

            slicerDesignProfileRequest.Validate();
            var slicerDesignResult = await WithServiceExceptionTryExecuteAsync(() =>
                                                                               RequestExecutorContainerFactory
                                                                               .Build <CompactionDesignProfileExecutor>(LoggerFactory,
#if RAPTOR
                                                                                                                        RaptorClient,
#endif
                                                                                                                        configStore : ConfigStore, trexCompactionDataProxy : TRexCompactionDataProxy, customHeaders : CustomHeaders,
                                                                                                                        userId : GetUserId(), fileImportProxy : FileImportProxy)
                                                                               .ProcessAsync(slicerDesignProfileRequest)
                                                                               );

            //Find the cut-fill elevations for the cell stations from the design vertex elevations
            profileResultHelper.FindCutFillElevations(slicerProductionDataResult, (CompactionProfileResult <CompactionProfileVertex>)slicerDesignResult, type, volumeCalcType);
        }
コード例 #12
0
        /// <summary>
        /// The profiles for various types (CMV, temperature, pass count etc.) may have several points
        /// in sequence which have no data which are effectively a single gap. Remove these repeated
        /// points and just keep the start of the gap and the next data point.
        /// </summary>
        /// <param name="result">The profile result to remove the repeated gaps from</param>
        /// <param name="calcType">The type of summary volumes calculation</param>
        public void RemoveRepeatedNoData(CompactionProfileResult <CompactionProfileDataResult> result, VolumeCalcType?calcType)
        {
            log.LogDebug("RemoveRepeatedNoData: Production data profile");

            bool isDesignToGround = calcType.HasValue && calcType == VolumeCalcType.DesignToGround;

            foreach (var profileResult in result.results)
            {
                if (profileResult.data.Count > 0)
                {
                    //Identify all the gaps. All data with NaN elevation or value is effectively a gap.
                    //The exception is a summary volumes profile that is design to ground where y is NaN as it will be set later using the design. In this case use y2.
                    foreach (var point in profileResult.data)
                    {
                        bool noValue = point.type.StartsWith("passCount") ? point.value == -1 : float.IsNaN(point.value);
                        bool noY     = point.type == CompactionDataPoint.SUMMARY_VOLUMES && isDesignToGround
              ? point.y2.HasValue && float.IsNaN(point.y2.Value)
              : float.IsNaN(point.y);
                        if (noY || noValue)
                        {
                            point.cellType = ProfileCellType.Gap;
                        }
                    }

                    //Now remove repeated gaps.
                    //Always keep first and last points as they are the slicer end points
                    CompactionDataPoint prevData = profileResult.data[0];
                    bool haveGap = prevData.cellType == ProfileCellType.Gap;
                    List <CompactionDataPoint> newList = new List <CompactionDataPoint> {
                        prevData
                    };
                    for (int i = 1; i < profileResult.data.Count - 1; i++)
                    {
                        if (profileResult.data[i].cellType == ProfileCellType.Gap)
                        {
                            if (!haveGap)
                            {
                                //This is the start of a gap - keep it
                                haveGap = true;
                                newList.Add(profileResult.data[i]);
                            }
                            //else ignore it - repeated gap
                        }
                        else
                        {
                            //A data point - keep it
                            haveGap = false;
                            newList.Add(profileResult.data[i]);
                        }
                    }
                    newList.Add(profileResult.data[profileResult.data.Count - 1]);
                    //If the only 2 points are the slicer end points and they have no data then
                    //remove them and return an empty list to indicate no profile data at all.
                    if (newList.Count == 2 && newList[0].cellType == ProfileCellType.Gap &&
                        newList[1].cellType == ProfileCellType.Gap)
                    {
                        newList.RemoveRange(0, 2);
                    }
                    profileResult.data = newList;
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Find the cut-fill elevations for the cells from the cut-fill design elevations
        /// </summary>
        /// <param name="slicerProfileResult">The production data profile result with the cells</param>
        /// <param name="slicerDesignResult">The design profile result with the vertices</param>
        /// <param name="type">The type of profile to do, either cut-fill or summary volumes</param>
        /// <param name="calcType">The type of summary volumes calculation</param>
        public void FindCutFillElevations(CompactionProfileResult <CompactionProfileDataResult> slicerProfileResult,
                                          CompactionProfileResult <CompactionProfileVertex> slicerDesignResult, string type, VolumeCalcType calcType)
        {
            log.LogDebug($"FindCutFillElevations: {type}");

            if (type != CompactionDataPoint.CUT_FILL && type != CompactionDataPoint.SUMMARY_VOLUMES)
            {
                return;
            }

            if (calcType == VolumeCalcType.GroundToGround)
            {
                return;
            }

            var vertices = slicerDesignResult.results;
            var cells    = (from r in slicerProfileResult.results
                            where r.type == type
                            select r).Single().data;

            if (cells != null && cells.Count > 0 && vertices != null && vertices.Count > 0)
            {
                int startIndx = -1;
                foreach (var cell in cells)
                {
                    startIndx = FindVertexIndex(vertices, cell.x, startIndx);
                    if (startIndx != -1)
                    {
                        float newy = float.NaN;
                        //Check for no design elevation
                        if (float.IsNaN(vertices[startIndx].elevation) || float.IsNaN(vertices[startIndx + 1].elevation))
                        {
                            //If the cell station matches (within 3mm) either vertex station
                            //then we can use that vertex elevation directly
                            const double THREE_MM = 0.003;
                            if (Math.Abs(vertices[startIndx].station - cell.x) <= THREE_MM)
                            {
                                newy = vertices[startIndx].elevation;
                            }
                            else if (Math.Abs(vertices[startIndx + 1].station - cell.x) <= THREE_MM)
                            {
                                newy = vertices[startIndx + 1].elevation;
                            }
                        }
                        else
                        {
                            //Calculate elevation by interpolation
                            var proportion = (cell.x - vertices[startIndx].station) /
                                             (vertices[startIndx + 1].station - vertices[startIndx].station);
                            newy = (float)(vertices[startIndx].elevation +
                                           proportion * (vertices[startIndx + 1].elevation - vertices[startIndx].elevation));
                        }
                        if (calcType == VolumeCalcType.DesignToGround)
                        {
                            cell.y = newy;
                        }
                        else
                        {
                            cell.y2 = newy;
                        }
                    }
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Convert from one production data profile representation to another. The source is a list with each item containing the
        /// data for every profile type. The destination is a list of lists, one list for each profile type containing its own data.
        /// </summary>
        /// <param name="slicerProfileResult">The profile result to convert from</param>
        /// <returns>The new profile result representation</returns>
        public CompactionProfileResult <CompactionProfileDataResult> RearrangeProfileResult(
            CompactionProfileResult <CompactionProfileCell> slicerProfileResult)
        {
            log.LogDebug("ConvertProfileResult: Production data profile");

            //shouldn't ever happen but for safety check arg
            if (slicerProfileResult?.results == null)
            {
                throw new ServiceException(HttpStatusCode.InternalServerError,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError,
                                                                       "Unexpected missing profile result"));
            }

            var profile = new CompactionProfileResult <CompactionProfileDataResult>
            {
                gridDistanceBetweenProfilePoints = slicerProfileResult.gridDistanceBetweenProfilePoints,
                results = new List <CompactionProfileDataResult>
                {
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.FIRST_PASS,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.FIRST_PASS,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.firstPassHeight,
                            value = p.firstPassHeight
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.HIGHEST_PASS,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.HIGHEST_PASS,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.highestPassHeight,
                            value = p.highestPassHeight
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.LAST_PASS,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.LAST_PASS,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastPassHeight,
                            value = p.lastPassHeight
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.LOWEST_PASS,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.LOWEST_PASS,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lowestPassHeight,
                            value = p.lowestPassHeight
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.LAST_COMPOSITE,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.LAST_COMPOSITE,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastCompositeHeight,
                            value = p.lastCompositeHeight
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.CMV_SUMMARY,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.CMV_SUMMARY,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.cmvHeight,
                            value = p.cmvPercent,
                            valueType = p.cmvIndex
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.CMV_DETAIL,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.CMV_DETAIL,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.cmvHeight,
                            value = p.cmv
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.CMV_PERCENT_CHANGE,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.CMV_PERCENT_CHANGE,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.cmvHeight,
                            value = p.cmvPercentChange
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.MDP_SUMMARY,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.MDP_SUMMARY,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.mdpHeight,
                            value = p.mdpPercent,
                            valueType = p.mdpIndex
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.TEMPERATURE_SUMMARY,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.TEMPERATURE_SUMMARY,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.temperatureHeight,
                            value = p.temperature,
                            valueType = p.temperatureIndex
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.TEMPERATURE_DETAIL,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.TEMPERATURE_DETAIL,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.temperatureHeight,
                            value = p.temperature
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.SPEED_SUMMARY,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.SPEED_SUMMARY,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastPassHeight,
                            value = p.minSpeed,
                            value2 = p.maxSpeed,
                            valueType = p.speedIndex
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.PASS_COUNT_SUMMARY,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.PASS_COUNT_SUMMARY,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastPassHeight,
                            value = p.topLayerPassCount,
                            valueType = p.passCountIndex
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.PASS_COUNT_DETAIL,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.PASS_COUNT_DETAIL,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastPassHeight,
                            value = p.topLayerPassCount
                        }).ToList()
                    },
                    new CompactionProfileDataResult
                    {
                        type = CompactionDataPoint.CUT_FILL,
                        data = (from p in slicerProfileResult.results
                                select new CompactionDataPoint
                        {
                            type = CompactionDataPoint.CUT_FILL,
                            cellType = p.cellType,
                            x = p.station,
                            y = p.lastCompositeHeight,
                            value = p.cutFill,
                            y2 = float.NaN, //will be set later using the cut-fill design
                        }).ToList()
                    }
                }
            };

            return(profile);
        }
コード例 #15
0
        private CompactionProfileResult <CompactionSummaryVolumesProfileCell> ProcessSummaryVolumesProfileCells(List <SummaryVolumeProfileCell> profileCells, double gridDistanceBetweenProfilePoints, VolumeCalcType calcType)
        {
            var profile = new CompactionProfileResult <CompactionSummaryVolumesProfileCell>();

            profile.results = new List <CompactionSummaryVolumesProfileCell>();
            SummaryVolumeProfileCell prevCell = null;

            foreach (var currCell in profileCells)
            {
                var gapExists = ProfilesHelper.CellGapExists(prevCell, currCell, out var prevStationIntercept);

                if (gapExists)
                {
                    var gapCell = new CompactionSummaryVolumesProfileCell(SumVolGapCell);
                    gapCell.station = prevStationIntercept;
                    profile.results.Add(gapCell);
                }

                var lastPassHeight1 = currCell.LastCellPassElevation1 == VelociraptorConstants.NULL_SINGLE
          ? float.NaN
          : currCell.LastCellPassElevation1;

                var lastPassHeight2 = currCell.LastCellPassElevation2 == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.LastCellPassElevation2;

                var designHeight = currCell.DesignElev == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.DesignElev;

                float cutFill = float.NaN;
                switch (calcType)
                {
                case VolumeCalcType.GroundToGround:
                    cutFill = float.IsNaN(lastPassHeight1) || float.IsNaN(lastPassHeight2)
              ? float.NaN
              : lastPassHeight2 - lastPassHeight1;
                    break;

                case VolumeCalcType.GroundToDesign:
                    cutFill = float.IsNaN(lastPassHeight1) || float.IsNaN(designHeight)
              ? float.NaN
              : designHeight - lastPassHeight1;
                    break;

                case VolumeCalcType.DesignToGround:
                    cutFill = float.IsNaN(designHeight) || float.IsNaN(lastPassHeight2)
              ? float.NaN
              : lastPassHeight2 - designHeight;
                    break;
                }

                profile.results.Add(new CompactionSummaryVolumesProfileCell
                {
                    cellType = prevCell == null ? ProfileCellType.MidPoint : ProfileCellType.Edge,

                    station = currCell.Station,

                    lastPassHeight1 = lastPassHeight1,
                    lastPassHeight2 = lastPassHeight2,
                    designHeight    = designHeight,
                    cutFill         = cutFill
                });

                prevCell = currCell;
            }

            //Add a last point at the intercept length of the last cell so profiles are drawn correctly
            if (prevCell != null && prevCell.InterceptLength > ProfilesHelper.ONE_MM)
            {
                var lastCell = new CompactionSummaryVolumesProfileCell(profile.results[profile.results.Count - 1])
                {
                    station = prevCell.Station + prevCell.InterceptLength
                };

                profile.results.Add(lastCell);
            }

            if (profile.results.Count > 0)
            {
                profile.results[profile.results.Count - 1].cellType = ProfileCellType.MidPoint;
            }

            profile.gridDistanceBetweenProfilePoints = gridDistanceBetweenProfilePoints;

            var sb = new StringBuilder();

            sb.Append($"After summary volumes profile conversion: {profile.results.Count}");
            foreach (var cell in profile.results)
            {
                sb.Append($",{cell.cellType}");
            }

            log.LogDebug(sb.ToString());
            return(profile);
        }
コード例 #16
0
        private CompactionProfileResult <CompactionProfileCell> ProcessProductionDataProfileCells(List <ProfileCellData> profileCells, double gridDistanceBetweenProfilePoints, LiftBuildSettings liftBuildSettings)
        {
            var profile = new CompactionProfileResult <CompactionProfileCell>();

            profile.results = new List <CompactionProfileCell>();
            ProfileCellData prevCell = null;

            foreach (var currCell in profileCells)
            {
                var gapExists = ProfilesHelper.CellGapExists(prevCell, currCell, out double prevStationIntercept);

                if (gapExists)
                {
                    var gapCell = new CompactionProfileCell(GapCell);
                    gapCell.station = prevStationIntercept;
                    profile.results.Add(gapCell);
                }

                var lastPassHeight = currCell.LastPassHeight == VelociraptorConstants.NULL_SINGLE
          ? float.NaN
          : currCell.LastPassHeight;
                var lastCompositeHeight = currCell.CompositeLastPassHeight == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.CompositeLastPassHeight;

                var designHeight = currCell.DesignHeight == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.DesignHeight;
                bool noCCVValue = currCell.TargetCCV == 0 || currCell.TargetCCV == VelociraptorConstants.NO_CCV ||
                                  currCell.CCV == VelociraptorConstants.NO_CCV;
                bool noCCVElevation = currCell.CCVElev == VelociraptorConstants.NULL_SINGLE || noCCVValue;
                bool noMDPValue     = currCell.TargetMDP == 0 || currCell.TargetMDP == VelociraptorConstants.NO_MDP ||
                                      currCell.MDP == VelociraptorConstants.NO_MDP;
                bool noMDPElevation         = currCell.MDPElev == VelociraptorConstants.NULL_SINGLE || noMDPValue;
                bool noTemperatureValue     = currCell.MaterialTemperature == VelociraptorConstants.NO_TEMPERATURE;
                bool noTemperatureElevation = currCell.MaterialTemperatureElev == VelociraptorConstants.NULL_SINGLE ||
                                              noTemperatureValue;
                bool noPassCountValue = currCell.TopLayerPassCount == VelociraptorConstants.NO_PASSCOUNT;

                //Either have none or both speed values
                var noSpeedValue = currCell.CellMaxSpeed == VelociraptorConstants.NO_SPEED;
                var speedMin     = noSpeedValue ? float.NaN : (float)(currCell.CellMinSpeed / ConversionConstants.KM_HR_TO_CM_SEC);
                var speedMax     = noSpeedValue ? float.NaN : (float)(currCell.CellMaxSpeed / ConversionConstants.KM_HR_TO_CM_SEC);

                var cmvPercent = noCCVValue
          ? float.NaN
          : (float)currCell.CCV / (float)currCell.TargetCCV * 100.0F;

                var mdpPercent = noMDPValue
          ? float.NaN
          : (float)currCell.MDP / (float)currCell.TargetMDP * 100.0F;

                var firstPassHeight = currCell.FirstPassHeight == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.FirstPassHeight;

                var highestPassHeight = currCell.HighestPassHeight == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.HighestPassHeight;

                var lowestPassHeight = currCell.LowestPassHeight == VelociraptorConstants.NULL_SINGLE
        ? float.NaN
          : currCell.LowestPassHeight;

                var cutFill = float.IsNaN(lastCompositeHeight) || float.IsNaN(designHeight)
          ? float.NaN
          : lastCompositeHeight - designHeight;

                var cmv         = noCCVValue ? float.NaN : currCell.CCV / 10.0F;
                var cmvHeight   = noCCVElevation ? float.NaN : currCell.CCVElev;
                var mdpHeight   = noMDPElevation ? float.NaN : currCell.MDPElev;
                var temperature =
                    noTemperatureValue
            ? float.NaN
            : currCell.MaterialTemperature / 10.0F; // As temperature is reported in 10th...
                var temperatureHeight = noTemperatureElevation ? float.NaN : currCell.MaterialTemperatureElev;
                var topLayerPassCount = noPassCountValue ? -1 : currCell.TopLayerPassCount;
                var cmvPercentChange  = currCell.CCV == VelociraptorConstants.NO_CCV
          ? float.NaN
          : (currCell.PrevCCV == VelociraptorConstants.NO_CCV
            ? 100.0f
            : (float)(currCell.CCV - currCell.PrevCCV) / (float)currCell.PrevCCV * 100.0f);

                var passCountIndex = noPassCountValue || float.IsNaN(lastPassHeight)
          ? ValueTargetType.NoData
          : (currCell.TopLayerPassCount < currCell.TopLayerPassCountTargetRangeMin
            ? ValueTargetType.BelowTarget
            : (currCell.TopLayerPassCount > currCell.TopLayerPassCountTargetRangeMax
              ? ValueTargetType.AboveTarget
              : ValueTargetType.OnTarget));

                var temperatureIndex = noTemperatureValue || noTemperatureElevation
          ? ValueTargetType.NoData
          : (currCell.MaterialTemperature < currCell.MaterialTemperatureWarnMin
            ? ValueTargetType.BelowTarget
            : (currCell.MaterialTemperature > currCell.MaterialTemperatureWarnMax
              ? ValueTargetType.AboveTarget
              : ValueTargetType.OnTarget));

                var cmvIndex = noCCVValue || noCCVElevation
          ? ValueTargetType.NoData
          : (cmvPercent < liftBuildSettings.CCVRange.Min
            ? ValueTargetType.BelowTarget
            : (cmvPercent > liftBuildSettings.CCVRange.Max ? ValueTargetType.AboveTarget : ValueTargetType.OnTarget));

                var mdpIndex = noMDPValue || noMDPElevation
          ? ValueTargetType.NoData
          : (mdpPercent < liftBuildSettings.MDPRange.Min
            ? ValueTargetType.BelowTarget
            : (mdpPercent > liftBuildSettings.MDPRange.Max ? ValueTargetType.AboveTarget : ValueTargetType.OnTarget));

                var speedIndex = noSpeedValue || float.IsNaN(lastPassHeight)
          ? ValueTargetType.NoData
          : (currCell.CellMaxSpeed > liftBuildSettings.MachineSpeedTarget.MaxTargetMachineSpeed
            ? ValueTargetType.AboveTarget
            : (currCell.CellMinSpeed < liftBuildSettings.MachineSpeedTarget.MinTargetMachineSpeed &&
               currCell.CellMaxSpeed < liftBuildSettings.MachineSpeedTarget.MinTargetMachineSpeed
              ? ValueTargetType.BelowTarget
              : ValueTargetType.OnTarget));

                profile.results.Add(new CompactionProfileCell
                {
                    cellType = prevCell == null ? ProfileCellType.MidPoint : ProfileCellType.Edge,

                    station = currCell.Station,

                    firstPassHeight   = firstPassHeight,
                    highestPassHeight = highestPassHeight,
                    lastPassHeight    = lastPassHeight,
                    lowestPassHeight  = lowestPassHeight,

                    lastCompositeHeight = lastCompositeHeight,
                    designHeight        = designHeight,

                    cutFill = cutFill,

                    cmv        = cmv,
                    cmvPercent = cmvPercent,
                    cmvHeight  = cmvHeight,

                    mdpPercent = mdpPercent,
                    mdpHeight  = mdpHeight,

                    temperature       = temperature,
                    temperatureHeight = temperatureHeight,

                    topLayerPassCount = topLayerPassCount,

                    cmvPercentChange = cmvPercentChange,

                    minSpeed = speedMin,
                    maxSpeed = speedMax,

                    passCountIndex   = passCountIndex,
                    temperatureIndex = temperatureIndex,
                    cmvIndex         = cmvIndex,
                    mdpIndex         = mdpIndex,
                    speedIndex       = speedIndex
                });

                prevCell = currCell;
            }

            //Add a last point at the intercept length of the last cell so profiles are drawn correctly
            if (prevCell != null && prevCell.InterceptLength > ProfilesHelper.ONE_MM)
            {
                var lastCell = new CompactionProfileCell(profile.results[profile.results.Count - 1])
                {
                    station = prevCell.Station + prevCell.InterceptLength
                };

                profile.results.Add(lastCell);
            }

            if (profile.results.Count > 0)
            {
                profile.results[profile.results.Count - 1].cellType = ProfileCellType.MidPoint;
            }

            profile.gridDistanceBetweenProfilePoints = gridDistanceBetweenProfilePoints;

            var sb = new StringBuilder();

            sb.Append($"After profile conversion: {profile.results.Count}");
            foreach (var cell in profile.results)
            {
                sb.Append($",{cell.cellType}");
            }

            log.LogDebug(sb.ToString());
            return(profile);
        }