Exemple #1
0
        /// <summary>
        /// Interpolate elevation for the specified point on the line segment from startPoint to endPoint
        /// </summary>
        /// <param name="point">The point to interpolate</param>
        /// <param name="startPoint">The start of the line segment</param>
        /// <param name="endPoint">The end of the line segment</param>
        /// <param name="useY2">True if interpolating the second elevation</param>
        private void InterpolateElevation(CompactionDataPoint point, CompactionDataPoint startPoint, CompactionDataPoint endPoint, bool useY2)
        {
            var proportion = (point.x - startPoint.x) / (endPoint.x - startPoint.x);

            if (useY2)
            {
                point.y2 = InterpolateElevation(proportion, startPoint.y2 ?? float.NaN, endPoint.y2 ?? float.NaN);
            }
            else
            {
                point.y = InterpolateElevation(proportion, startPoint.y, endPoint.y);
            }
            log.LogDebug($"Interpolated station {point.x} of cell type {point.cellType} for type {point.type}");
        }
Exemple #2
0
 /// <summary>
 /// Determine if the current point is a midpoint and has an elevation.
 /// </summary>
 /// <param name="point">The point to check</param>
 /// <param name="useY2">True if checking the second elevation</param>
 /// <returns>True if the cell has a non-NaN elevation value for the specified height type</returns>
 private bool MidPointCellHasHeightValue(CompactionDataPoint point, bool useY2)
 {
     if (point.cellType == ProfileCellType.MidPoint)
     {
         if (useY2)
         {
             if (point.y2.HasValue)
             {
                 return(!float.IsNaN(point.y2.Value));
             }
         }
         else
         {
             return(!float.IsNaN(point.y));
         }
     }
     return(false);
 }
Exemple #3
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());
            }
        }
Exemple #4
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;
                }
            }
        }