Пример #1
0
        protected override void OnClick()
        {
            ICadastralEditor   pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd;

            ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd;

            //bool bStartedWithPacketOpen = pCadPacketMan.PacketOpen;

            if (pParcEditorMan == null)
            {
                return;
            }

            IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor");

            if (pEd.EditState == esriEditState.esriStateNotEditing)
            {
                MessageBox.Show("Please start editing and try again.");
                return;
            }

            IParcelConstruction       pConstr                   = pParcEditorMan.ParcelConstruction;
            IParcelConstruction4      pConstr4                  = pConstr as IParcelConstruction4;
            ICadastralPoints          pCadastralPts             = pConstr4 as ICadastralPoints;
            ICadastralEditorSettings2 pCadastralEditorSettings2 = pCadEd as ICadastralEditorSettings2;

            ICadastralFixedPoints pFixedPoints = pCadastralPts as ICadastralFixedPoints;
            IPointCalculation     pPointCalc   = new PointCalculationClass();

            if (pConstr == null)
            {
                return;
            }

            IGSLine pParcelLine = null;
            IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd;
            IGSPoint             pStartPoint     = null;
            List <int>           lstPointIds     = new List <int>();

            List <IVector3D> Traverse = new List <IVector3D>();

            //get rotation here
            IParcelConstructionData    pConstrData = pConstr4.ConstructionData;
            IConstructionParentParcels pConstructionParentParcels = pConstrData as IConstructionParentParcels;

            ICadastralUndoRedo pCadUndoRedo = pConstr as ICadastralUndoRedo;

            try
            {
                int iParcelID = -1;
                if (pConstructionParentParcels.ParentParcelCount > 0)
                {
                    pConstructionParentParcels.GetParentParcel(0, ref iParcelID);
                }

                ICadastralParcel pCadaParcel = pCadPacketMan.JobPacket as ICadastralParcel;

                IGSParcel pGSParcel = null;

                if (pCadaParcel != null)
                {
                    pGSParcel = pCadaParcel.GetParcel(iParcelID);
                }
                //if in measurement view then rotation is 0
                double TheRotation = 0;

                if (pGSParcel == null)
                {
                    pGSParcel = pConstr.Parcel;
                }

                if (!pCadastralEditorSettings2.MeasurementView)
                {
                    TheRotation = pGSParcel.Rotation;//radians
                }
                if (TheRotation == 123456789)
                {
                    TheRotation = 0;
                }

                pPointCalc.Rotation = TheRotation;
                IGSPoint pClosingPoint = null;

                #region simple method as fall-back
                bool bUseSimpleStackSelection = false;
                if (bUseSimpleStackSelection)
                {
                    //bool bLineSelectionSequence = false;
                    //IGSLine pLastSelectedGSLineInGrid = null;
                    //for (int i = 0; i < pConstr.LineCount; i++)
                    //{
                    //  if (pConstr.GetLineSelection(i))
                    //  {
                    //    if (pConstr.GetLine(i, ref pParcelLine))
                    //    {
                    //      if (!bLineSelectionSequence) //first line
                    //      {
                    //        pStartPoint = pCadastralPts.GetPoint(pParcelLine.FromPoint);
                    //        pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint);
                    //      }

                    //      pPointCalc.AddLine(pParcelLine);

                    //      pLastSelectedGSLineInGrid = pParcelLine;
                    //      pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint);
                    //      lstPointIds.Add(pToPoint.Id);

                    //    }
                    //    bLineSelectionSequence = true;

                    //    double dBear = pParcelLine.Bearing; //Azimuth of IVector3D is north azimuth radians zero degrees north
                    //    double dDist = pParcelLine.Distance;
                    //    IVector3D vec = new Vector3DClass();
                    //    vec.PolarSet(dBear, 0, dDist); ////Azimuth of IVector3D is north azimuth radians zero degrees north
                    //    Traverse.Add(vec);
                    //  }
                    //  else
                    //  {
                    //    if (bLineSelectionSequence && pConstr.GetLine(i, ref pParcelLine) && HasLineSelectionAfter(pConstr, i))
                    //    //if there was a prior selection and this line is a complete line, and there is no later selection
                    //    {
                    //      MessageBox.Show("Please select a continuous set of lines for closure.");
                    //      return;
                    //    }
                    //  }
                    //}
                    //pClosingPoint = pCadastralPts.GetPoint(pLastSelectedGSLineInGrid.ToPoint);
                }
                else
                #endregion

                {//build a forward star for the selected lines
                    IEnumCELines pCELines     = new EnumCELinesClass();
                    IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines;
                    ILongArray   pLongArray   = new LongArrayClass();
                    int          iFirstToNode = -1;
                    for (int i = 0; i < pConstr.LineCount; i++)
                    {
                        if (pConstr.GetLineSelection(i))
                        {
                            if (pConstr.GetLine(i, ref pParcelLine))
                            {
                                if (iFirstToNode < 0)
                                {
                                    iFirstToNode = pParcelLine.ToPoint;
                                }
                                pLongArray.Add(i);
                                pCELines.Add(pParcelLine);
                            }
                        }
                    }

                    if (pCELines.Count == 0)
                    {
                        MessageBox.Show("No lines selected. Please select a continuous set of lines for closure." + Environment.NewLine +
                                        "Line selection should not have branches.", "Traverse");
                        return;
                    }

                    IParcelLineFunctions3 ParcelLineFx = new ParcelFunctionsClass();
                    IGSForwardStar        pFwdStar     = ParcelLineFx.CreateForwardStar(pEnumGSLines);
                    //forward star object is now created for all the selected lines,
                    //need to first re-sequence the lines, and test for branching and discontinuity

                    int           iBranches = 0; int iTracedLines = 0;
                    int           iLoops = 0; int iTerminals = 0;
                    List <int>    LineIDList = new List <int>();
                    List <int>    FromList   = new List <int>();
                    List <int>    ToList     = new List <int>();
                    List <string> FromToLine = new List <string>();

                    bool bTraceSucceeded = TraceLines(ref pFwdStar, iFirstToNode, ref iBranches, ref iTracedLines,
                                                      ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0);

                    if (iBranches > 0)
                    {
                        MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine +
                                        "Line selection should not have branches.", "Traverse");
                        return;
                    }

                    if (iTracedLines < pLongArray.Count)
                    {
                        MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine +
                                        "Selected Lines should be connected in a single sequence without branches.", "Traverse");
                        return;
                    }

                    //if it's a single loop check to see if the sequence needs to be reversed
                    //CW or CCW based on bearings
                    if (iLoops == 1)
                    {
                        bool bIsReversed = false;
                        foreach (int i in FromList)
                        {
                            if (i < 0)
                            {
                                bIsReversed = true;
                            }
                            else
                            {
                                bIsReversed = false;
                                break;
                            }
                        }
                        if (bIsReversed)
                        {//all courses are running reversed, so reverse the whole sequence
                            FromToLine.Clear();
                            FromList.Reverse();
                            ToList.Reverse();
                            int    iNewFrom   = -ToList[ToList.Count - 1];
                            int    iNewTo     = -FromList[ToList.Count - 1];
                            string sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString();
                            FromToLine.Add(sNewFromTo);
                            for (int i = 1; i < ToList.Count; i++)
                            {
                                iNewFrom   = -ToList[i - 1];
                                iNewTo     = -FromList[i - 1];
                                sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString();
                                FromToLine.Add(sNewFromTo);
                            }
                        }
                    }

                    LineIDList.Clear();
                    FromList.Clear();
                    ToList.Clear();
                    pLongArray.RemoveAll();

                    pCadUndoRedo.StartUndoRedoSession("Adjust Traverse");

                    if (iLoops == 0)
                    {
                        //re-sequence using TraceLines function based on either end point, because the order of
                        //selected construction lines in grid don't control start or end point
                        FromToLine.Clear();
                        int iTerminus = -1;
                        iTracedLines = 0;
                        iBranches    = 0;
                        iLoops       = 0; iTerminals = 0;
                        FindTerminusForSequence(ref pFwdStar, iFirstToNode, ref iTerminus, 0);
                        if (iTerminus == -1)
                        {
                            pCadUndoRedo.WriteUndoRedoSession(false);
                            return;
                        }
                        TraceLines(ref pFwdStar, iTerminus, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals,
                                   ref FromToLine, ref FromList, ref ToList, 0);
                    }

                    List <IVector3D> SequencedTraverse = new List <IVector3D>();
                    IGSLine          pGSLineInPath     = null;
                    foreach (string s in FromToLine)
                    {
                        string[] sFromTo = s.Split(',');
                        int      iFrom   = Convert.ToInt32(sFromTo[0]);
                        int      iTo     = Convert.ToInt32(sFromTo[1]);

                        bool bReversed = pFwdStar.GetLine(iFrom, iTo, ref pGSLineInPath);
                        if (bReversed)
                        {
                            IGSLine pGSLine180 = new GSLineClass();
                            pGSLine180.FromPoint = pGSLineInPath.ToPoint;
                            pGSLine180.ToPoint   = pGSLineInPath.FromPoint;
                            pGSLine180.Bearing   = pGSLineInPath.Bearing + Math.PI;
                            pGSLine180.Distance  = pGSLineInPath.Distance;

                            IVector3D vec180 = new Vector3DClass();
                            vec180.PolarSet(pGSLine180.Bearing, 0, pGSLine180.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north
                            Traverse.Add(vec180);
                            lstPointIds.Add(pGSLine180.ToPoint);
                            pPointCalc.AddLine(pGSLine180);
                        }
                        else
                        {
                            double    dBear = pGSLineInPath.Bearing;
                            double    dDist = pGSLineInPath.Distance;
                            IVector3D vec   = new Vector3DClass();
                            vec.PolarSet(dBear, 0, dDist); //Azimuth of IVector3D is north azimuth radians zero degrees north
                            Traverse.Add(vec);
                            lstPointIds.Add(pGSLineInPath.ToPoint);
                            pPointCalc.AddLine(pGSLineInPath);
                        }

                        if (pStartPoint == null)
                        {
                            if (bReversed)
                            {
                                pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint);
                            }
                            else
                            {
                                pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint);
                            }
                        }

                        if (bReversed)
                        {
                            pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint);
                        }
                        else
                        {
                            pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint);
                        }
                    }
                }

                if (pStartPoint == null)
                {
                    pCadUndoRedo.WriteUndoRedoSession(false);
                    return;
                }
                IPoint pStart = new PointClass();
                pStart.X = pStartPoint.X;
                pStart.Y = pStartPoint.Y;

                string sAdjustMethod = "Compass";
                esriParcelAdjustmentType eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass;

                if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentNone ||
                    pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCompass)
                {
                    eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass;
                }
                else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCrandall)
                {
                    sAdjustMethod = "Crandall";
                    eAdjMethod    = pCadastralEditorSettings2.ParcelAdjustment;
                }
                else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentTransit)
                {
                    sAdjustMethod = "Transit";
                    eAdjMethod    = pCadastralEditorSettings2.ParcelAdjustment;
                }

                pPointCalc.CalculatePoints(eAdjMethod, pStartPoint.Id, pStartPoint, pClosingPoint.Id, pClosingPoint, true);
                ITraverseClosure pClose = pPointCalc.Closure;
                List <string>    lstCoursesFromTo = new List <string>();
                List <IVector3D> AdjustedTraverse = new List <IVector3D>();
                double           dAdjustedPointX = 0; double dAdjustedPointY = 0;
                double           dPreviousPointX = 0; double dPreviousPointY = 0;

                for (int i = 0; i < pClose.CourseCount; i++)
                {
                    IGSPoint pPt = pCadastralPts.GetPoint(lstPointIds[i]);
                    dAdjustedPointY = pPointCalc.GetCalculatedPoint(lstPointIds[i], ref dAdjustedPointX);
                    string    sFromTo       = "";
                    IVector3D pAdjustedLine = new Vector3DClass();
                    if (i == 0)
                    {
                        sFromTo = pStartPoint.Id.ToString() + "-" + lstPointIds[i].ToString();
                        pAdjustedLine.SetComponents(dAdjustedPointX - pStartPoint.X, dAdjustedPointY - pStartPoint.Y, 0);
                    }
                    else
                    {
                        sFromTo = lstPointIds[i - 1].ToString() + "-" + lstPointIds[i].ToString();
                        pAdjustedLine.SetComponents(dAdjustedPointX - dPreviousPointX, dAdjustedPointY - dPreviousPointY, 0);
                    }
                    lstCoursesFromTo.Add(sFromTo);

                    IVector3D Z_Axis = new Vector3DClass();
                    Z_Axis.SetComponents(0, 0, 100);

                    pAdjustedLine.Rotate(TheRotation, Z_Axis);
                    AdjustedTraverse.Add(pAdjustedLine);

                    dPreviousPointX = dAdjustedPointX;
                    dPreviousPointY = dAdjustedPointY;

                    pPt.X = dAdjustedPointX;
                    pPt.Y = dAdjustedPointY;

                    if (!pCadastralEditorSettings2.MeasurementView)
                    {
                        pFixedPoints.SetFixedPoint(lstPointIds[i], true);
                    }
                }

                double  dMisclosureDistance = pClose.MisclosureDistance; double dMisclosureBearing = pClose.MisclosureDirection;
                IVector MiscloseVector = new Vector3DClass();

                IEditProperties2 pEdProps = pEd as IEditProperties2;

                IAngularConverter pAngConv = new AngularConverterClass();
                pAngConv.SetAngle(dMisclosureBearing, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians);
                //int iPrec = 7;
                //if (pConstr.Parcel.Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds)
                //  iPrec = 0;

                string sMiscloseBearing = pAngConv.GetString(pEdProps.DirectionType, pEdProps.DirectionUnits, pEdProps.AngularUnitPrecision);

                Utilities UTIL   = new Utilities();
                string    sRatio = "High Accuracy";

                if (pClose.RelativeErrorRatio < 10000)
                {
                    sRatio = "1:" + pClose.RelativeErrorRatio.ToString("0");
                }

                if (dMisclosureDistance >= 0.001)
                {
                    sMiscloseBearing = UTIL.FormatDirectionDashesToDegMinSecSymbols(sMiscloseBearing);
                }
                else
                {
                    sMiscloseBearing = "----";
                }

                ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass();
                double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, pConstr.Parcel.Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter);

                string sReport = "Closure:" + Environment.NewLine +
                                 "        error:  " + sRatio + Environment.NewLine +
                                 "        distance:  " + (dMisclosureDistance / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
                                 "        bearing:  " + sMiscloseBearing + Environment.NewLine +
                                 "        xdist:  " + (pClose.MisclosureX / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
                                 "        ydist:  " + (pClose.MisclosureY / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
                                 "        courses: " + (pClose.CourseCount) + Environment.NewLine +
                                 Environment.NewLine + "Adjustment:" + Environment.NewLine +
                                 "        method: " + sAdjustMethod;

                dlgTraverseResults dlgTraverseResults = new dlgTraverseResults();
                AddTraverseInfoToGrid(pConstr.Parcel.Plan, dlgTraverseResults.dataGridView1, Traverse, AdjustedTraverse, lstCoursesFromTo);
                dlgTraverseResults.txtMiscloseReport.Text = sReport;
                DialogResult dRes = dlgTraverseResults.ShowDialog();
                if (dRes == DialogResult.Cancel)
                {
                    //since we cancelled, set the points back
                    foreach (int i in lstPointIds)
                    {
                        pFixedPoints.SetFixedPoint(i, false);
                    }
                    pCadUndoRedo.WriteUndoRedoSession(false);
                }
                else
                {
                    pCadUndoRedo.WriteUndoRedoSession(true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + "Line number:" + ex.LineNumber().ToString()
                                + " in " + ex.TargetSite.Name, "Traverse");
                pCadUndoRedo.WriteUndoRedoSession(false);
            }
        }
        private IGSLine CreateGSLine(IMetricUnitConverter MetricConversion, ICadastralPoints CadastralPoints,
                                     ref IPoint FromPointInToPointOut, int FromPointID, double Direction, double Distance,
                                     double Radius, int Accuracy, int UserLineType, int Category, bool ComputeToPoint, out int ToPointID)
        {
            //In this function, Radius == 0 means a straight line
            //If the radius is >0 or <0 then the line is a circular curve with Distance as the chord length
            //for curves Bearing means chord bearing
            //negative radius means a curve to the left, positive radius curve to the right
            //for no Accuracy, no Type, or no Category pass in -1
            //Bearing is in north azimuth radians

            IGSLine pLine = new GSLineClass();

            pLine.Bearing = Direction; //direction is in radians north azimuth
            double dConvertedDistance = 0;

            MetricConversion.ConvertDistance(esriCadastralUnitConversionType.esriCUCToMetric, Distance, ref dConvertedDistance);
            pLine.Distance = dConvertedDistance; //needs to be in meters;

            if (Math.Abs(Radius) > 0)
            {
                MetricConversion.ConvertDistance(esriCadastralUnitConversionType.esriCUCToMetric, Radius, ref dConvertedDistance);
                pLine.Radius = dConvertedDistance; //needs to be in meters;
            }

            pLine.FromPoint = FromPointID;
            pLine.ToPoint   = -1;

            if (Accuracy > -1)
            {
                pLine.Accuracy = Accuracy;
            }
            if (UserLineType > -1)
            {
                pLine.LineType = UserLineType;
            }
            if (Category > -1)
            {
                pLine.Category = (esriCadastralLineCategory)Category;
            }

            //Make sure that any extended attributes on the line have their default values set
            IGSAttributes pGSAttributes = (IGSAttributes)pLine;

            if (pGSAttributes != null)
            {
                ICadastralObjectSetup pCadaObjSetup = (ICadastralObjectSetup)MetricConversion; //QI
                pCadaObjSetup.AddExtendedAttributes(pGSAttributes);
                pCadaObjSetup.SetDefaultValues(pGSAttributes);
            }

            //Compute the new end point for the line.
            //FromPointInToPointOut is in units of the map projection.
            ICurve pCurv = MetricConversion.GetSurveyedLine(pLine, CadastralPoints, false, FromPointInToPointOut);

            //pCurv is also in the units of the map projection. Convert the end point to metric units.

            FromPointInToPointOut   = pCurv.ToPoint;//pass the new To point back out
            FromPointInToPointOut.Z = 0;
            IGSPoint pGSPointTo = MetricConversion.SetGSPoint(FromPointInToPointOut);

            if (ComputeToPoint)
            {
                CadastralPoints.AddPoint(pGSPointTo);
                pLine.ToPoint = pGSPointTo.Id;
                ToPointID     = pLine.ToPoint;
            }
            else
            {
                ToPointID = -1;
            }

            if (pCurv is ICircularArc)
            {
                ICircularArc pCircArc = (ICircularArc)pCurv;
                IPoint       pCtrPt   = pCircArc.CenterPoint;
                IZAware      pZAw     = (IZAware)pCtrPt;
                pZAw.ZAware = true;
                pCtrPt.Z    = 0;
                IGSPoint pGSCtrPt = MetricConversion.SetGSPoint(pCtrPt);
                CadastralPoints.AddPoint(pGSCtrPt);
                pLine.CenterPoint = pGSCtrPt.Id;
            }

            return(pLine);
        }
        private IGSLine CreateGSLineFromCommaSeparatedString(String inCourse, esriDirectionUnits inDirectionUnits,
                                                             esriDirectionType inDirectionType)
        {
            string[] sCourse   = inCourse.Split(',');
            int      iUpperBnd = sCourse.GetUpperBound(0);
            double   dToMeterUnitConversion = m_dScaleFactor;

            if (m_dScaleFactor == -1)
            {//if the scale factor wasn't found in the file for some reason
                Utilities UTILS = new Utilities();
                dToMeterUnitConversion = UTILS.ToMeterUnitConversion();
            }
            if (iUpperBnd <= 4)
            {
                return(null);
            }
            IGSLine pLine         = new GSLineClass();
            string  sLineCat      = "";
            string  sLineUserType = "";
            string  sAccCat       = "";
            string  sFromPt       = (string)sCourse.GetValue(0); //from point
            //string sTemplate = (string)sCourse.GetValue(1);//line template
            string sDirection = (string)sCourse.GetValue(1);     //direction
            string sDistance  = (string)sCourse.GetValue(2);     //distance
            string sRadius    = (string)sCourse.GetValue(3);     //radius
            string sChord     = (string)sCourse.GetValue(4);     //chord
            string sToPt      = (string)sCourse.GetValue(5);     //to point

            if (iUpperBnd >= 6)
            {
                sLineCat = (string)sCourse.GetValue(6); //line category
            }
            if (iUpperBnd >= 7)
            {
                sLineUserType = (string)sCourse.GetValue(7); //line user type
            }
            if (iUpperBnd >= 8)
            {
                sAccCat = (string)sCourse.GetValue(8); //accuracy category
            }
            int    iFromPt       = -1;                 //from point
            int    iToPt         = -1;                 //to point
            int    iLineCat      = -1;                 //line category
            int    iLineUserType = -1;                 //line user type
            int    iAccCat       = -1;                 //accuracy
            double dDistance     = -123456789;         //distance
            double dChord        = -123456789;         //chord
            double dRadius       = -123456789;         //radius

            try
            {
                iFromPt = Convert.ToInt32(sFromPt); //from point
                iToPt   = Convert.ToInt32(sToPt);   //to point
                if (sLineCat.Trim().Length > 0)
                {
                    iLineCat = Convert.ToInt32(sLineCat); //line category
                }
                if (sLineUserType.Trim().Length > 0)
                {
                    iLineUserType = Convert.ToInt32(sLineUserType); //line user type
                }
                if (sAccCat.Trim().Length > 0)
                {
                    iAccCat = Convert.ToInt32(sAccCat); //accuracy
                }
                if (sDistance.Trim().Length > 0)
                {
                    dDistance = Convert.ToDouble(sDistance); //distance
                }
                if (sChord.Trim().Length > 0)
                {
                    dChord = Convert.ToDouble(sChord); //chord
                }
                if (sRadius.Trim().Length > 0)
                {
                    dRadius = Convert.ToDouble(sRadius); //radius
                }
            }
            catch
            {
                return(null);
            }
            double dBear = DirectionString_2_NorthAzimuth(sDirection, inDirectionType, inDirectionUnits);

            pLine.Bearing = dBear;
            if (dDistance != -123456789)
            {
                pLine.Distance = dDistance * dToMeterUnitConversion;
            }
            if (dChord != -123456789)
            {
                pLine.Distance = dChord * dToMeterUnitConversion;
            }
            if (dRadius != -123456789)
            {
                pLine.Radius = dRadius * dToMeterUnitConversion;
            }
            pLine.FromPoint = iFromPt;
            pLine.ToPoint   = iToPt;
            if (iAccCat > -1)
            {
                pLine.Accuracy = iAccCat;
            }
            if (iLineUserType > -1)
            {
                pLine.LineType = iLineUserType;
            }
            if (iLineCat > -1)
            {
                pLine.Category = (esriCadastralLineCategory)iLineCat;
            }
            return(pLine);
        }
        private IGSLine CreateGSLine(String inCourse, esriDirectionUnits inDirectionUnits,
                                     esriDirectionType inDirectionType, ISegment EntryTangent,
                                     out ISegment ExitTangent, out ICircularArc outCircularArc)
        {//
            string[]  sCourse = inCourse.Split(' ');
            Utilities UTILS   = new Utilities();
            double    dToMeterUnitConversion = UTILS.ToMeterUnitConversion();
            // ISegment ExitTangent = null;
            string item = (string)sCourse.GetValue(0);

            if (item.ToLower() == "dd")
            {//Direction distance -- straight line course
                IGSLine pLine = new GSLineClass();
                double  dBear = DirectionString_2_NorthAzimuth((string)sCourse.GetValue(1), inDirectionType, inDirectionUnits);
                pLine.Bearing   = dBear;
                pLine.Distance  = Convert.ToDouble(sCourse.GetValue(2)) * dToMeterUnitConversion;
                pLine.FromPoint = m_count;
                m_count        += 1;
                pLine.ToPoint   = m_count;
                //Now define the tangent exit segment
                //in case it's needed for the next course (TC tangent curve, or Angle deflection)
                double dPolar = DirectionString_2_PolarRadians((string)sCourse.GetValue(1),
                                                               inDirectionType, inDirectionUnits);
                IPoint pFromPt = new PointClass();
                pFromPt.PutCoords(1000, 1000);
                IConstructPoint2 pToPt = new PointClass();
                pToPt.ConstructAngleDistance(pFromPt, dPolar, 100);
                ILine ExitTangentLine = new LineClass();
                ExitTangentLine.PutCoords(pFromPt, (IPoint)pToPt);
                ExitTangent    = (ISegment)ExitTangentLine;
                outCircularArc = null;
                Marshal.ReleaseComObject(pFromPt);
                Marshal.ReleaseComObject(pToPt);
                return(pLine);
            }
            if (item.ToLower() == "ad")
            {//Angle deflection distance
                IGSLine pLine      = new GSLineClass();
                double  dDeflAngle = Angle_2_Radians((string)sCourse.GetValue(1), inDirectionUnits);
                //now need to take the previous tangent segment, reverse its orientation and
                //add +ve clockwise to get the bearing
                ILine  calcLine = (ILine)EntryTangent;
                double dBear    = PolarRAD_2_SouthAzimuthRAD(calcLine.Angle) + dDeflAngle;
                pLine.Bearing   = dBear;
                pLine.Distance  = Convert.ToDouble(sCourse.GetValue(2)) * dToMeterUnitConversion;
                pLine.FromPoint = m_count;
                m_count        += 1;
                pLine.ToPoint   = m_count;
                //Now define the tangent exit segment
                //in case it's needed for the next course (TC tangent curve, or Angle deflection)
                IPoint pFromPt = new PointClass();
                pFromPt.PutCoords(1000, 1000);
                IConstructPoint2 pToPt  = new PointClass();
                double           dPolar = NorthAzimuthRAD_2_PolarRAD(dBear);
                pToPt.ConstructAngleDistance(pFromPt, dPolar, 100);
                ILine ExitTangentLine = new LineClass();
                ExitTangentLine.PutCoords(pFromPt, (IPoint)pToPt);
                ExitTangent    = (ISegment)ExitTangentLine;
                outCircularArc = null;
                Marshal.ReleaseComObject(pFromPt);
                Marshal.ReleaseComObject(pToPt);

                return(pLine);
            }
            else if ((item.ToLower() == "nc") || (item.ToLower() == "tc"))
            {
                double       dChordlength;
                double       dChordBearing;
                ICircularArc pArc = ConstructCurveFromString(inCourse, EntryTangent,
                                                             inDirectionType, inDirectionUnits, out dChordlength, out dChordBearing);
                try
                {
                    IGSLine pLine = new GSLineClass();
                    pLine.Bearing = PolarRAD_2_NorthAzimuthRAD(dChordBearing);
                    pLine.Radius  = pArc.Radius * dToMeterUnitConversion;//convert to meters
                    if (pArc.IsCounterClockwise)
                    {
                        pLine.Radius = pLine.Radius * -1;
                    }
                    pLine.Distance  = dChordlength * dToMeterUnitConversion; //convert to meters
                    pLine.FromPoint = m_count;
                    m_count        += 1;
                    pLine.ToPoint   = m_count;
                    ILine pTangentLine = new LineClass();
                    pArc.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 1, true, 100, pTangentLine);
                    //pass the exit tangent back out for use as next entry tangent
                    ExitTangent    = (ISegment)pTangentLine;
                    outCircularArc = pArc;
                    return(pLine);
                }
                catch { }
            }
            outCircularArc = null;
            ExitTangent    = null;
            return(null);
        }
        protected override void OnClick()
        {
            ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
              IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd;

              ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd;
              //bool bStartedWithPacketOpen = pCadPacketMan.PacketOpen;

              if (pParcEditorMan == null)
            return;

              IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor");
              if (pEd.EditState == esriEditState.esriStateNotEditing)
              {
            MessageBox.Show("Please start editing and try again.");
            return;
              }

              IParcelConstruction pConstr = pParcEditorMan.ParcelConstruction;
              IParcelConstruction4 pConstr4 = pConstr as IParcelConstruction4;
              ICadastralPoints pCadastralPts = pConstr4 as ICadastralPoints;
              ICadastralEditorSettings2 pCadastralEditorSettings2 = pCadEd as ICadastralEditorSettings2;

              ICadastralFixedPoints pFixedPoints = pCadastralPts as ICadastralFixedPoints;
              IPointCalculation pPointCalc = new PointCalculationClass();

              if (pConstr == null)
            return;

              IGSLine pParcelLine = null;
              IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd;
              IGSPoint pStartPoint = null;
              List<int> lstPointIds = new List<int>();

              List<IVector3D> Traverse = new List<IVector3D>();

              //get rotation here
              IParcelConstructionData pConstrData = pConstr4.ConstructionData;
              IConstructionParentParcels pConstructionParentParcels = pConstrData as IConstructionParentParcels;

              ICadastralUndoRedo pCadUndoRedo = pConstr as ICadastralUndoRedo;
              try
              {
            int iParcelID = -1;
            if (pConstructionParentParcels.ParentParcelCount>0)
              pConstructionParentParcels.GetParentParcel(0, ref iParcelID);

            ICadastralParcel pCadaParcel = pCadPacketMan.JobPacket as ICadastralParcel;

            IGSParcel pGSParcel = null;

            if (pCadaParcel != null)
              pGSParcel = pCadaParcel.GetParcel(iParcelID);
            //if in measurement view then rotation is 0
            double TheRotation = 0;

            if (pGSParcel == null)
              pGSParcel = pConstr.Parcel;

            if (!pCadastralEditorSettings2.MeasurementView)
              TheRotation = pGSParcel.Rotation;//radians

            if (TheRotation == 123456789)
              TheRotation = 0;

            pPointCalc.Rotation = TheRotation;
            IGSPoint pClosingPoint = null;

            #region simple method as fall-back
            bool bUseSimpleStackSelection = false;
            if (bUseSimpleStackSelection)
            {
              //bool bLineSelectionSequence = false;
              //IGSLine pLastSelectedGSLineInGrid = null;
              //for (int i = 0; i < pConstr.LineCount; i++)
              //{
              //  if (pConstr.GetLineSelection(i))
              //  {
              //    if (pConstr.GetLine(i, ref pParcelLine))
              //    {
              //      if (!bLineSelectionSequence) //first line
              //      {
              //        pStartPoint = pCadastralPts.GetPoint(pParcelLine.FromPoint);
              //        pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint);
              //      }

              //      pPointCalc.AddLine(pParcelLine);

              //      pLastSelectedGSLineInGrid = pParcelLine;
              //      pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint);
              //      lstPointIds.Add(pToPoint.Id);

              //    }
              //    bLineSelectionSequence = true;

              //    double dBear = pParcelLine.Bearing; //Azimuth of IVector3D is north azimuth radians zero degrees north
              //    double dDist = pParcelLine.Distance;
              //    IVector3D vec = new Vector3DClass();
              //    vec.PolarSet(dBear, 0, dDist); ////Azimuth of IVector3D is north azimuth radians zero degrees north
              //    Traverse.Add(vec);
              //  }
              //  else
              //  {
              //    if (bLineSelectionSequence && pConstr.GetLine(i, ref pParcelLine) && HasLineSelectionAfter(pConstr, i))
              //    //if there was a prior selection and this line is a complete line, and there is no later selection
              //    {
              //      MessageBox.Show("Please select a continuous set of lines for closure.");
              //      return;
              //    }
              //  }
              //}
              //pClosingPoint = pCadastralPts.GetPoint(pLastSelectedGSLineInGrid.ToPoint);
            }
            else
            #endregion

            {//build a forward star for the selected lines
              IEnumCELines pCELines = new EnumCELinesClass();
              IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines;
              ILongArray pLongArray = new LongArrayClass();
              int iFirstToNode = -1;
              for (int i = 0; i < pConstr.LineCount; i++)
              {
            if (pConstr.GetLineSelection(i))
            {
              if (pConstr.GetLine(i, ref pParcelLine))
              {
                if (iFirstToNode < 0)
                  iFirstToNode = pParcelLine.ToPoint;
                pLongArray.Add(i);
                pCELines.Add(pParcelLine);
              }
            }
              }

              if (pCELines.Count==0)
              {
            MessageBox.Show("No lines selected. Please select a continuous set of lines for closure." + Environment.NewLine +
              "Line selection should not have branches.", "Traverse");
            return;
              }

              IParcelLineFunctions3 ParcelLineFx = new ParcelFunctionsClass();
              IGSForwardStar pFwdStar = ParcelLineFx.CreateForwardStar(pEnumGSLines);
              //forward star object is now created for all the selected lines,
              //need to first re-sequence the lines, and test for branching and discontinuity

              int iBranches = 0; int iTracedLines = 0;
              int iLoops = 0; int iTerminals = 0;
              List<int> LineIDList = new List<int>();
              List<int> FromList = new List<int>();
              List<int> ToList = new List<int>();
              List<string> FromToLine = new List<string>();

              bool bTraceSucceeded = TraceLines(ref pFwdStar, iFirstToNode, ref iBranches, ref iTracedLines,
            ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0);

              if (iBranches > 0)
              {
            MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine +
              "Line selection should not have branches.", "Traverse");
            return;
              }

              if (iTracedLines < pLongArray.Count)
              {
            MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine +
              "Selected Lines should be connected in a single sequence without branches.", "Traverse");
            return;
              }

              //if it's a single loop check to see if the sequence needs to be reversed
              //CW or CCW based on bearings
              if (iLoops == 1)
              {
            bool bIsReversed = false;
            foreach (int i in FromList)
            {
              if (i < 0)
                bIsReversed = true;
              else
              {
                bIsReversed = false;
                break;
              }
            }
            if (bIsReversed)
            {//all courses are running reversed, so reverse the whole sequence
              FromToLine.Clear();
              FromList.Reverse();
              ToList.Reverse();
              int iNewFrom = -ToList[ToList.Count-1];
              int iNewTo = -FromList[ToList.Count-1];
              string sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString();
              FromToLine.Add(sNewFromTo);
              for (int i =1; i < ToList.Count ;i++)
              {
                iNewFrom = -ToList[i-1];
                iNewTo = -FromList[i-1];
                sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString();
                FromToLine.Add(sNewFromTo);
              }
            }
              }

              LineIDList.Clear();
              FromList.Clear();
              ToList.Clear();
              pLongArray.RemoveAll();

              pCadUndoRedo.StartUndoRedoSession("Adjust Traverse");

              if (iLoops == 0)
              {
            //re-sequence using TraceLines function based on either end point, because the order of
            //selected construction lines in grid don't control start or end point
            FromToLine.Clear();
            int iTerminus = -1;
            iTracedLines = 0;
            iBranches = 0;
            iLoops = 0; iTerminals = 0;
            FindTerminusForSequence(ref pFwdStar, iFirstToNode, ref iTerminus, 0);
            if (iTerminus == -1)
            {
              pCadUndoRedo.WriteUndoRedoSession(false);
              return;
            }
            TraceLines(ref pFwdStar, iTerminus, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals,
              ref FromToLine, ref FromList, ref ToList, 0);
              }

              List<IVector3D> SequencedTraverse = new List<IVector3D>();
              IGSLine pGSLineInPath = null;
              foreach (string s in FromToLine)
              {
            string[] sFromTo = s.Split(',');
            int iFrom = Convert.ToInt32(sFromTo[0]);
            int iTo = Convert.ToInt32(sFromTo[1]);

            bool bReversed = pFwdStar.GetLine(iFrom, iTo, ref pGSLineInPath);
            if (bReversed)
            {
              IGSLine pGSLine180 = new GSLineClass();
              pGSLine180.FromPoint = pGSLineInPath.ToPoint;
              pGSLine180.ToPoint = pGSLineInPath.FromPoint;
              pGSLine180.Bearing = pGSLineInPath.Bearing + Math.PI;
              pGSLine180.Distance = pGSLineInPath.Distance;

              IVector3D vec180 = new Vector3DClass();
              vec180.PolarSet(pGSLine180.Bearing, 0, pGSLine180.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north
              Traverse.Add(vec180);
              lstPointIds.Add(pGSLine180.ToPoint);
              pPointCalc.AddLine(pGSLine180);
            }
            else
            {
              double dBear = pGSLineInPath.Bearing;
              double dDist = pGSLineInPath.Distance;
              IVector3D vec = new Vector3DClass();
              vec.PolarSet(dBear, 0, dDist); //Azimuth of IVector3D is north azimuth radians zero degrees north
              Traverse.Add(vec);
              lstPointIds.Add(pGSLineInPath.ToPoint);
              pPointCalc.AddLine(pGSLineInPath);
            }

            if (pStartPoint == null)
            {
              if (bReversed)
                pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint);
              else
                pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint);
            }

            if (bReversed)
              pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint);
            else
              pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint);
              }
            }

            if (pStartPoint == null)
            {
              pCadUndoRedo.WriteUndoRedoSession(false);
              return;
            }
            IPoint pStart = new PointClass();
            pStart.X = pStartPoint.X;
            pStart.Y = pStartPoint.Y;

            string sAdjustMethod = "Compass";
            esriParcelAdjustmentType eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass;

            if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentNone ||
              pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCompass)
              eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass;
            else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCrandall)
            {
              sAdjustMethod = "Crandall";
              eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment;
            }
            else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentTransit)
            {
              sAdjustMethod = "Transit";
              eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment;
            }

            pPointCalc.CalculatePoints(eAdjMethod, pStartPoint.Id, pStartPoint, pClosingPoint.Id, pClosingPoint, true);
            ITraverseClosure pClose = pPointCalc.Closure;
            List<string> lstCoursesFromTo = new List<string>();
            List<IVector3D> AdjustedTraverse = new List<IVector3D>();
            double dAdjustedPointX = 0; double dAdjustedPointY = 0;
            double dPreviousPointX = 0; double dPreviousPointY = 0;

            for (int i = 0; i < pClose.CourseCount; i++)
            {
              IGSPoint pPt = pCadastralPts.GetPoint(lstPointIds[i]);
              dAdjustedPointY = pPointCalc.GetCalculatedPoint(lstPointIds[i], ref dAdjustedPointX);
              string sFromTo = "";
              IVector3D pAdjustedLine = new Vector3DClass();
              if (i == 0)
              {
            sFromTo = pStartPoint.Id.ToString() + "-" + lstPointIds[i].ToString();
            pAdjustedLine.SetComponents(dAdjustedPointX - pStartPoint.X, dAdjustedPointY - pStartPoint.Y, 0);
              }
              else
              {
            sFromTo = lstPointIds[i - 1].ToString() + "-" + lstPointIds[i].ToString();
            pAdjustedLine.SetComponents(dAdjustedPointX - dPreviousPointX, dAdjustedPointY - dPreviousPointY, 0);
              }
              lstCoursesFromTo.Add(sFromTo);

              IVector3D Z_Axis = new Vector3DClass();
              Z_Axis.SetComponents(0, 0, 100);

              pAdjustedLine.Rotate(TheRotation, Z_Axis);
              AdjustedTraverse.Add(pAdjustedLine);

              dPreviousPointX = dAdjustedPointX;
              dPreviousPointY = dAdjustedPointY;

              pPt.X = dAdjustedPointX;
              pPt.Y = dAdjustedPointY;

              if (!pCadastralEditorSettings2.MeasurementView)
            pFixedPoints.SetFixedPoint(lstPointIds[i], true);
            }

            double dMisclosureDistance = pClose.MisclosureDistance; double dMisclosureBearing = pClose.MisclosureDirection;
            IVector MiscloseVector = new Vector3DClass();

            IEditProperties2 pEdProps = pEd as IEditProperties2;

            IAngularConverter pAngConv = new AngularConverterClass();
            pAngConv.SetAngle(dMisclosureBearing, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians);
            //int iPrec = 7;
            //if (pConstr.Parcel.Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds)
            //  iPrec = 0;

            string sMiscloseBearing = pAngConv.GetString(pEdProps.DirectionType, pEdProps.DirectionUnits, pEdProps.AngularUnitPrecision);

            Utilities UTIL = new Utilities();
            string sRatio = "High Accuracy";

            if (pClose.RelativeErrorRatio < 10000)
              sRatio = "1:" + pClose.RelativeErrorRatio.ToString("0");

            if (dMisclosureDistance >= 0.001)
              sMiscloseBearing = UTIL.FormatDirectionDashesToDegMinSecSymbols(sMiscloseBearing);
            else
              sMiscloseBearing = "----";

            ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass();
            double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, pConstr.Parcel.Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter);

            string sReport = "Closure:" + Environment.NewLine +
              "        error:  " + sRatio + Environment.NewLine +
              "        distance:  " + (dMisclosureDistance / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
              "        bearing:  " + sMiscloseBearing + Environment.NewLine +
              "        xdist:  " + (pClose.MisclosureX / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
              "        ydist:  " + (pClose.MisclosureY / dMetersPerUnit).ToString("0.000") + Environment.NewLine +
              "        courses: " + (pClose.CourseCount) + Environment.NewLine +
              Environment.NewLine + "Adjustment:" + Environment.NewLine +
              "        method: " + sAdjustMethod;

            dlgTraverseResults dlgTraverseResults = new dlgTraverseResults();
            AddTraverseInfoToGrid(pConstr.Parcel.Plan, dlgTraverseResults.dataGridView1, Traverse, AdjustedTraverse, lstCoursesFromTo);
            dlgTraverseResults.txtMiscloseReport.Text = sReport;
            DialogResult dRes = dlgTraverseResults.ShowDialog();
            if (dRes == DialogResult.Cancel)
            {
              //since we cancelled, set the points back
              foreach (int i in lstPointIds)
            pFixedPoints.SetFixedPoint(i, false);
              pCadUndoRedo.WriteUndoRedoSession(false);
            }
            else
              pCadUndoRedo.WriteUndoRedoSession(true);
              }
              catch (Exception ex)
              {
            MessageBox.Show(ex.Message + Environment.NewLine + "Line number:" + ex.LineNumber().ToString()
              + " in " + ex.TargetSite.Name, "Traverse");
            pCadUndoRedo.WriteUndoRedoSession(false);
              }
        }
        private IGSLine CreateGSLineFromCommaSeparatedString(String inCourse, esriDirectionUnits inDirectionUnits,
            esriDirectionType inDirectionType)
        {
            string[] sCourse = inCourse.Split(',');
              int iUpperBnd = sCourse.GetUpperBound(0);
              double dToMeterUnitConversion = m_dScaleFactor;
              if (m_dScaleFactor == -1)
              {//if the scale factor wasn't found in the file for some reason
            Utilities UTILS = new Utilities();
            dToMeterUnitConversion = UTILS.ToMeterUnitConversion();
              }
              if (iUpperBnd <= 4) { return null; }
              IGSLine pLine = new GSLineClass();
              string sLineCat = "";
              string sLineUserType = "";
              string sAccCat = "";
              string sFromPt = (string)sCourse.GetValue(0);//from point
              //string sTemplate = (string)sCourse.GetValue(1);//line template
              string sDirection = (string)sCourse.GetValue(1);//direction
              string sDistance = (string)sCourse.GetValue(2);//distance
              string sRadius = (string)sCourse.GetValue(3);//radius
              string sChord = (string)sCourse.GetValue(4);//chord
              string sToPt = (string)sCourse.GetValue(5);//to point
              if (iUpperBnd >= 6)
            sLineCat = (string)sCourse.GetValue(6); //line category
              if (iUpperBnd >= 7)
            sLineUserType = (string)sCourse.GetValue(7); //line user type
              if (iUpperBnd >= 8)
            sAccCat = (string)sCourse.GetValue(8); //accuracy category

              int iFromPt = -1; //from point
              int iToPt = -1; //to point
              int iLineCat = -1;//line category
              int iLineUserType = -1;//line user type
              int iAccCat = -1;//accuracy
              double dDistance = -123456789;//distance
              double dChord = -123456789;//chord
              double dRadius = -123456789;//radius

              try
              {
            iFromPt = Convert.ToInt32(sFromPt); //from point
            iToPt = Convert.ToInt32(sToPt); //to point
            if (sLineCat.Trim().Length > 0)
              iLineCat = Convert.ToInt32(sLineCat); //line category
            if (sLineUserType.Trim().Length > 0)
              iLineUserType = Convert.ToInt32(sLineUserType); //line user type
            if (sAccCat.Trim().Length > 0)
              iAccCat = Convert.ToInt32(sAccCat); //accuracy
            if (sDistance.Trim().Length > 0)
              dDistance = Convert.ToDouble(sDistance); //distance
            if (sChord.Trim().Length > 0)
              dChord = Convert.ToDouble(sChord); //chord
            if (sRadius.Trim().Length > 0)
              dRadius = Convert.ToDouble(sRadius); //radius
              }
              catch
              {
            return null;
              }
              double dBear = DirectionString_2_NorthAzimuth(sDirection, inDirectionType, inDirectionUnits);
              pLine.Bearing = dBear;
              if (dDistance != -123456789)
            pLine.Distance = dDistance * dToMeterUnitConversion;
              if (dChord != -123456789)
            pLine.Distance = dChord * dToMeterUnitConversion;
              if (dRadius != -123456789)
            pLine.Radius = dRadius * dToMeterUnitConversion;
              pLine.FromPoint = iFromPt;
              pLine.ToPoint = iToPt;
              if (iAccCat > -1)
            pLine.Accuracy = iAccCat;
              if (iLineUserType > -1)
            pLine.LineType = iLineUserType;
              if (iLineCat > -1)
            pLine.Category = (esriCadastralLineCategory)iLineCat;
              return pLine;
        }
        private IGSLine CreateGSLine(String inCourse, esriDirectionUnits inDirectionUnits,
            esriDirectionType inDirectionType, ISegment EntryTangent,
            out ISegment ExitTangent, out ICircularArc outCircularArc)
        {
            //
              string[] sCourse = inCourse.Split(' ');
              Utilities UTILS = new Utilities();
              double dToMeterUnitConversion = UTILS.ToMeterUnitConversion();
              // ISegment ExitTangent = null;
              string item = (string)sCourse.GetValue(0);
              if (item.ToLower() == "dd")
              {//Direction distance -- straight line course
            IGSLine pLine = new GSLineClass();
            double dBear = DirectionString_2_NorthAzimuth((string)sCourse.GetValue(1), inDirectionType, inDirectionUnits);
            pLine.Bearing = dBear;
            pLine.Distance = Convert.ToDouble(sCourse.GetValue(2)) * dToMeterUnitConversion;
            pLine.FromPoint = m_count;
            m_count += 1;
            pLine.ToPoint = m_count;
            //Now define the tangent exit segment
            //in case it's needed for the next course (TC tangent curve, or Angle deflection)
            double dPolar = DirectionString_2_PolarRadians((string)sCourse.GetValue(1),
                inDirectionType, inDirectionUnits);
            IPoint pFromPt = new PointClass();
            pFromPt.PutCoords(1000, 1000);
            IConstructPoint2 pToPt = new PointClass();
            pToPt.ConstructAngleDistance(pFromPt, dPolar, 100);
            ILine ExitTangentLine = new LineClass();
            ExitTangentLine.PutCoords(pFromPt, (IPoint)pToPt);
            ExitTangent = (ISegment)ExitTangentLine;
            outCircularArc = null;
            Marshal.ReleaseComObject(pFromPt);
            Marshal.ReleaseComObject(pToPt);
            return pLine;
              }
              if (item.ToLower() == "ad")
              {//Angle deflection distance
            IGSLine pLine = new GSLineClass();
            double dDeflAngle = Angle_2_Radians((string)sCourse.GetValue(1), inDirectionUnits);
            //now need to take the previous tangent segment, reverse its orientation and
            //add +ve clockwise to get the bearing
            ILine calcLine = (ILine)EntryTangent;
            double dBear = PolarRAD_2_SouthAzimuthRAD(calcLine.Angle) + dDeflAngle;
            pLine.Bearing = dBear;
            pLine.Distance = Convert.ToDouble(sCourse.GetValue(2)) * dToMeterUnitConversion;
            pLine.FromPoint = m_count;
            m_count += 1;
            pLine.ToPoint = m_count;
            //Now define the tangent exit segment
            //in case it's needed for the next course (TC tangent curve, or Angle deflection)
            IPoint pFromPt = new PointClass();
            pFromPt.PutCoords(1000, 1000);
            IConstructPoint2 pToPt = new PointClass();
            double dPolar = NorthAzimuthRAD_2_PolarRAD(dBear);
            pToPt.ConstructAngleDistance(pFromPt, dPolar, 100);
            ILine ExitTangentLine = new LineClass();
            ExitTangentLine.PutCoords(pFromPt, (IPoint)pToPt);
            ExitTangent = (ISegment)ExitTangentLine;
            outCircularArc = null;
            Marshal.ReleaseComObject(pFromPt);
            Marshal.ReleaseComObject(pToPt);

            return pLine;
              }
              else if ((item.ToLower() == "nc") || (item.ToLower() == "tc"))
              {
            double dChordlength;
            double dChordBearing;
            ICircularArc pArc = ConstructCurveFromString(inCourse, EntryTangent,
                inDirectionType, inDirectionUnits, out dChordlength, out dChordBearing);
            try
            {
              IGSLine pLine = new GSLineClass();
              pLine.Bearing = PolarRAD_2_NorthAzimuthRAD(dChordBearing);
              pLine.Radius = pArc.Radius * dToMeterUnitConversion;//convert to meters
              if (pArc.IsCounterClockwise) { pLine.Radius = pLine.Radius * -1; }
              pLine.Distance = dChordlength * dToMeterUnitConversion; //convert to meters
              pLine.FromPoint = m_count;
              m_count += 1;
              pLine.ToPoint = m_count;
              ILine pTangentLine = new LineClass();
              pArc.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 1, true, 100, pTangentLine);
              //pass the exit tangent back out for use as next entry tangent
              ExitTangent = (ISegment)pTangentLine;
              outCircularArc = pArc;
              return pLine;
            }
            catch { }
              }
              outCircularArc = null;
              ExitTangent = null;
              return null;
        }