Beispiel #1
0
        private List <MileageInfo> Sort_SumDuplicate(List <MileageInfo> slopes)
        {
            slopes.Sort(new MileageCompare());
            // 排序后集合中可能会有重复的里程(比如一个里程中,将一种边坡防护分两级坡分开算)

            // 现在将排序后相同里程的数据进行相加
            var         distinctSlopes = new List <MileageInfo>();
            MileageInfo lastSlope      = slopes[0];
            double      lastMile       = lastSlope.Mileage;

            distinctSlopes.Add(lastSlope);
            for (int i = 1; i < slopes.Count; i++)
            {
                var sp = slopes[i];
                if (sp.Mileage == lastMile)
                {
                    lastSlope.SpLength += sp.SpLength;
                }
                else
                {
                    lastSlope = sp;
                    lastMile  = sp.Mileage;
                    distinctSlopes.Add(lastSlope);
                }
            }

            return(distinctSlopes);
        }
Beispiel #2
0
 /// <summary> 用新的数据替换对象中的原数据 </summary>
 public void Override(MileageInfo newSection)
 {
     Mileage  = newSection.Mileage;
     Type     = newSection.Type;
     SpLength = newSection.SpLength;
 }
Beispiel #3
0
        public void Execute(bool containsHeader)
        {
            Range topLeftCell = null;
            var   slopes      = GetSlopes(true, ref topLeftCell);

            if (slopes != null && slopes.Count > 0)
            {
                // 1、对横断面数据进行排序,排序后集合中不会有重复的里程
                slopes = Sort_SumDuplicate(slopes);

                // 2、 去掉有测量值的定位断面
                var    sortedSections   = new Stack <MileageInfo>();
                double duplicateMileage = double.Epsilon;
                for (int i = slopes.Count - 1; i >= 0; i--)
                {
                    var slp = slopes[i];
                    if (slp.Mileage == duplicateMileage)
                    {
                        // 说明出现重复里程,此时从众多重复里程中仅保留有测量值的那个里程断面
                        if (slp.Type == MileageInfoType.Measured)
                        {
                            // 替换掉原集合中的值
                            sortedSections.Peek().Override(slp);
                        }
                    }
                    else
                    {
                        // 说明与上一个桩号不重复
                        sortedSections.Push(slp);
                        duplicateMileage = slp.Mileage;
                    }
                }

                // 3、 进行插值,此时 sortedSlopes 中,较小的里程位于堆的上面,
                // 而且集合中只有“定位”与“测量”两种断面,并没有“插值”断面
                var allSections     = new List <MileageInfo>();
                var count           = sortedSections.Count;
                var smallestSection = sortedSections.Pop();
                allSections.Add(smallestSection);
                //
                var lastSec  = smallestSection;
                var lastType = smallestSection.Type;
                for (int i = 1; i < count; i++)
                {
                    var slp = sortedSections.Pop();

                    if (slp.Type != lastType)
                    {
                        // 说明从定位断面转到了测量断面,或者从测量断面转到了定位断面,此时要进行断面插值
                        var interpMile = (lastSec.Mileage + slp.Mileage) / 2;
                        var interpSec  = new MileageInfo(interpMile, MileageInfoType.Interpolated, 0);
                        allSections.Add(interpSec);
                    }
                    //
                    allSections.Add(slp);

                    lastSec  = slp;
                    lastType = slp.Type;
                }
                // 4、将结果写回 Excel
                var slopesArr = MileageInfo.ConvertToArr(allSections);
                var sht       = _excelApp.ActiveSheet;
                ;
                RangeValueConverter.FillRange(sht, topLeftCell.Row, topLeftCell.Column + 3, slopesArr, false);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 从 Excel 表格中获取横断面数据
        /// </summary>
        /// <returns></returns>
        public List <MileageInfo> GetSlopes(bool containsHeader, ref Range topLeftCell)
        {
            var slopes = new List <MileageInfo>();
            var rg     = _excelApp.Selection as Range;

            if (rg != null)
            {
                // 将选择的范围进行适当的收缩,以匹配有效数据的区域
                Range col  = rg.Columns[1];
                Range cell = col.Ex_ShrinkeVectorAndCheckNull().Ex_CornerCell(CornerIndex.BottomLeft);

                // cell 表示选择区域的有效数据区域的最左下角的单元格
                rg = containsHeader
                    ? rg.Rows[$"{2}:{cell.Row - rg.Row + 1}"] // 将表头剃除
                    : rg.Rows[$"{1}:{cell.Row - rg.Row + 1}"];
                topLeftCell = rg.Cells[1, 1];

                object[,] arr = RangeValueConverter.GetRangeValue <object>(rg.Value);
                int  errorRow  = rg.Row - 1;
                bool keepPromt = true;
                for (int r = 0; r < arr.GetLength(0); r++)
                {
                    errorRow += 1;
                    //
                    float mile = -1;
                    if (!float.TryParse(arr[r, 0].ToString(), out mile))
                    {
                        if (keepPromt)
                        {
                            keepPromt = PrompError($"第{errorRow}行数据有误,无法解析桩号数据。");
                        }
                        continue;
                    }
                    //
                    MileageInfoType tp;
                    var             tpStr = arr[r, 1].ToString();
                    if (MileageInfo.TypeMapping.ContainsKey(tpStr))
                    {
                        tp = MileageInfo.TypeMapping[tpStr];
                    }
                    else
                    {
                        if (keepPromt)
                        {
                            keepPromt = PrompError($"第{errorRow}行数据有误,无法解析横断面类型。");
                        }
                        continue;
                    }
                    //
                    double slopeLength = 0;
                    if (!double.TryParse(arr[r, 2].ToString(), out slopeLength))
                    {
                        if (keepPromt)
                        {
                            keepPromt = PrompError($"第{errorRow}行数据有误,无法解析边坡长度。");
                        }
                        continue;
                    }
                    //
                    var s = new MileageInfo(mileage: mile, type: tp, slopeLength: slopeLength);
                    slopes.Add(s);
                }
            }
            return(slopes);
        }