Пример #1
0
        /// <summary> 交界点是从填进行挖,还是从挖进入填 </summary>
        /// <returns></returns>
        public bool FilltoCut(PointOnCurve2d ptRoad, PointOnCurve2d ptGround)
        {
            var ratioRoad   = ptRoad.GetDerivative(1);
            var ratioGround = ptGround.GetDerivative(1);

            if (Math.Tan(ratioGround.Angle) > Math.Tan(ratioRoad.Angle))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
            //private bool joinedEdge = false;//test

            public void CalcPipePosition(Transaction tr, ObjectId tinSurfId, double defaultDepth, bool sameDepthEveryPt, BlockTableRecord ms)
            {
                //Нужно учитывать размеры колодцев при расчете положения ребра!
                //Колодцы бывают просто цилиндрические и просто коробчатые
                //Учитывать Rotation, BoundingShape, InnerDiameterOrWidth, InnerLength
                //Уточнить кривую в плане по которой идет труба с учетом размеров колодца

                //TODO: Как учесть, что блок прямоугольного колодца может не соответствовать колодцу по направлениям длины и ширины????

                PointOnCurve2d startSplitPt = null;
                PointOnCurve2d endSplitPt   = null;

                CivilDB.Structure strStart = null;
                CivilDB.Structure strEnd   = null;
                if (!StartNode.StructId.IsNull)
                {
                    strStart = (CivilDB.Structure)tr.GetObject(StartNode.StructId, OpenMode.ForRead);
                    //уточнить положение начала кривой в начале с учетом размеров колодца!
                    startSplitPt = GetSplitPt(strStart, true);
                }
                if (!EndNode.StructId.IsNull)
                {
                    strEnd = (CivilDB.Structure)tr.GetObject(EndNode.StructId, OpenMode.ForRead);
                    //уточнить положение конца кривой в начале с учетом размеров колодца!
                    endSplitPt = GetSplitPt(strEnd, false);
                }

                if (startSplitPt != null && endSplitPt != null && startSplitPt.Parameter >= endSplitPt.Parameter)
                {
                    //колодцы стоят вплотную друг к другу или залезают друг на друга. Места для трубы на остается
                    return;
                }

                //проход по составляющим кривой с отбрасыванием частей, отсекаемых колодцами
                //Curve2d.GetSplitCurves работает неправильно
                //Curve2d.Explode тоже не помогает
                if (startSplitPt == null)
                {
                    AddPtToPipePositionList(new XYZ(PositionCurve.StartPoint));
                }
                Curve2d[] segments  = PositionCurve.GetCurves();
                double    currParam = 0;

                foreach (Curve2d seg in segments)
                {
                    Interval interval = seg.GetInterval();
                    double   len      = seg.GetLength(interval.LowerBound, interval.UpperBound);

                    currParam += len;

                    //Если есть точка разбиения в начале и она еще не достигнута
                    if (startSplitPt != null)
                    {
                        if (startSplitPt.Parameter < currParam)
                        {
                            //точка разбиения находится на этой кривой. Ее нужно добавить в список
                            AddPtToPipePositionList(new XYZ(startSplitPt.Point));
                            startSplitPt = null;
                        }
                        else
                        {
                            //точка отсечения начала еще не достигнута, переход к следующей кривой
                            continue;
                        }
                    }


                    if (endSplitPt != null && endSplitPt.Parameter < currParam)
                    {
                        //точка разбиения находится на этой кривой. Ее нужно добавить в список
                        AddPtToPipePositionList(new XYZ(endSplitPt.Point));
                        endSplitPt = null;
                        break;//обход точек заканчивается
                    }

                    AddPtToPipePositionList(new XYZ(seg.EndPoint));
                }


                //Задание глубин заложения ребер по концам
                //- если не задана глубина заложения на одном из концов, сделать их равными
                //- если не задана глубина на обоих концах задать обоим концам глубину по умолчанию согласно вводу в окне
                CivilDB.TinSurface tinSurf         = (CivilDB.TinSurface)tr.GetObject(tinSurfId, OpenMode.ForRead);
                double             startElevByData = double.NegativeInfinity;
                double             endElevByData   = double.NegativeInfinity;

                if (StartPipeJunctionData != null && StartPipeJunctionData.JunctionLevel != double.NegativeInfinity)
                {
                    startElevByData = StartPipeJunctionData.JunctionLevel;
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = startElevByData;
                }
                if (EndPipeJunctionData != null && EndPipeJunctionData.JunctionLevel != double.NegativeInfinity)
                {
                    endElevByData = EndPipeJunctionData.JunctionLevel;
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = endElevByData;
                }



                if (startElevByData != double.NegativeInfinity && endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = startElevByData;
                }
                else if (startElevByData == double.NegativeInfinity && endElevByData != double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = endElevByData;
                }
                else if (startElevByData == double.NegativeInfinity && endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz1 = PipePositionList.First();
                    SetElevBySurf(defaultDepth, tinSurf, xyz1);

                    XYZ xyz2 = PipePositionList.Last();
                    SetElevBySurf(defaultDepth, tinSurf, xyz2);
                }


                //- но не допускать, чтобы труба опускалась ниже дна колодца
                double sartElevByStr = double.NegativeInfinity;
                double endElevByStr  = double.NegativeInfinity;

                if (strStart != null && strStart.SumpElevation > PipePositionList.First().Z)
                {
                    sartElevByStr = strStart.SumpElevation;
                    PipePositionList.First().Z = sartElevByStr;
                }

                if (strEnd != null && strEnd.SumpElevation > PipePositionList.Last().Z)
                {
                    endElevByStr = strEnd.SumpElevation;
                    PipePositionList.Last().Z = endElevByStr;
                }
                //после корректировки уточнить отметку соседней точки если по ней нет данных
                if (sartElevByStr != double.NegativeInfinity &&
                    endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = sartElevByStr;
                }
                else if (startElevByData == double.NegativeInfinity &&
                         endElevByStr != double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = endElevByStr;
                }


                //Убедиться, что если в одном узле без колодца стыкуются несколько ребер,
                //то в месте стыковки обязательно у всех ребер должна быть одинаковая отметка
                double neighborJunctElev = GetNeigborJuncElev(StartNode);
                XYZ    startPos          = PipePositionList.First();

                if (neighborJunctElev != double.NegativeInfinity && startPos.Z != neighborJunctElev)
                {
                    startPos.Z = neighborJunctElev;
                }

                neighborJunctElev = GetNeigborJuncElev(EndNode);
                XYZ endPos = PipePositionList.Last();

                if (neighborJunctElev != double.NegativeInfinity && endPos.Z != neighborJunctElev)
                {
                    endPos.Z = neighborJunctElev;
                }


                //Задание отметок промежуточных точек на ребрах сети (интерполяция либо относительно поверхности)
                if (PipePositionList.Count > 2)
                {
                    if (sameDepthEveryPt)
                    {
                        //одинаковая глубина относительно поверхности земли
                        //метод TinSurface.SampleElevations работает не так как надо! Он не дает подробного учета рельефа!
                        //точки полилинии
                        for (int i = 1; i < PipePositionList.Count - 1; i++)
                        {
                            XYZ xyz = PipePositionList[i];
                            SetElevBySurf(defaultDepth, tinSurf, xyz);
                        }


                        //Помимо углов поворотов нужно добавить промежуточные точки через 1 м для учета рельефа!


                        List <XYZ> positionListExtended = new List <XYZ>();
                        positionListExtended.Add(PipePositionList.First());
                        for (int i = 1; i < PipePositionList.Count; i++)
                        {
                            XYZ      xyz0    = PipePositionList[i - 1];
                            XYZ      xyz1    = PipePositionList[i];
                            double   len     = xyz1.Position2d.GetDistanceTo(xyz0.Position2d);
                            Vector2d vector  = (xyz1.Position2d - xyz0.Position2d).GetNormal();
                            double   currLen = 1;
                            while (currLen < len)
                            {
                                //добавление промежуточных точек
                                Point2d pt = xyz0.Position2d + vector * currLen;
                                XYZ     intermediateXYZ = new XYZ(pt);
                                SetElevBySurf(defaultDepth, tinSurf, intermediateXYZ);
                                positionListExtended.Add(intermediateXYZ);

                                currLen += 1;
                            }
                            positionListExtended.Add(xyz1);
                        }
                        PipePositionList = positionListExtended;
                    }
                    else
                    {
                        //интерполяция между началом и концом
                        double startElev  = startPos.Z;
                        double endElev    = endPos.Z;
                        double elevDiff   = endElev - startElev;
                        double currLength = 0;
                        for (int i = 1; i < PipePositionList.Count - 1; i++)
                        {
                            XYZ xyz = PipePositionList[i];

                            Point2d prevPt = PipePositionList[i - 1].Position2d;
                            currLength += prevPt.GetDistanceTo(xyz.Position2d);


                            xyz.Z = startElev + (elevDiff * currLength / pipeHorizontalLength);
                        }
                    }
                }
            }