Пример #1
0
        private void FindTerminusForSequence(ref IGSForwardStar FwdStar, int StartNodeId,
                                             ref int TerminusPoint, int iInfinityChecker)
        {
            if (TerminusPoint > -1)
            {
                return;
            }

            //iInfinityChecker++;
            if (iInfinityChecker++ > 5000)
            {
                return;
            }

            ILongArray iLngArr = FwdStar.get_ToNodes(StartNodeId);
            int        iCnt2   = 0;

            iCnt2 = iLngArr.Count;
            IGSLine pGSLine = null;

            for (int i = 0; i < iCnt2; i++)
            {
                int  i2          = iLngArr.get_Element(i);
                bool bIsReversed = FwdStar.GetLine(StartNodeId, i2, ref pGSLine);

                if (iCnt2 == 1) //this is a terminus/end-line
                {
                    TerminusPoint = StartNodeId;
                }

                FindTerminusForSequence(ref FwdStar, i2, ref TerminusPoint, iInfinityChecker);
            }
        }
        void OnBeforeStopParcelEditing()
        {
            if (m_ParcelEditHelperExt.RecordToField)
            {
                return;
            }

            IParcelConstruction4 pTrav    = (IParcelConstruction4)m_pParcEditorMan.ParcelConstruction;
            IEnumGSLines         pGSLines = pTrav.GetLines(false, false);

            pGSLines.Reset();
            IGSLine   pGSLine   = null;
            IGSParcel pGSParcel = null;

            pGSLines.Next(ref pGSParcel, ref pGSLine);
            while (pGSLine != null)
            {
                IGSAttributes pLineAtts = (IGSAttributes)pGSLine;
                double        brgRecord = Convert.ToDouble(pGSLine.Bearing);
                brgRecord = brgRecord * 180 / Math.PI;
                pLineAtts.SetProperty(m_ParcelEditHelperExt.FieldName, brgRecord);
                //pGSParcel.Modified();
                pGSLines.Next(ref pGSParcel, ref pGSLine);
            }

            pTrav.UpdateGridFromGSLines(true, false);
        }
        object OnGridCellEdit(ref int row, ref int col, ref object inValue)
        {
            string m_sFieldName       = m_ParcelEditHelperExt.FieldName;
            bool   m_bRecordFieldName = m_ParcelEditHelperExt.RecordToField;
            object OutValue           = inValue;

            if (col == 2 && m_bRecordFieldName)//this is the bearing field
            {
                IParcelConstruction pTrav   = (IParcelConstruction)m_pParcEditorMan.ParcelConstruction;
                IGSLine             pGSLine = null;
                bool IsCompleteLine         = (pTrav.GetLine(row, ref pGSLine));
                //true means it's a complete line
                //false means it's a partial line
                //note that the type of the inValue must be honoured when returning the value from this function, in this case we are rebuilding the string for the same value, unaltered.
                //however the other relevant work done is to set the record field to the same value to capture what was entered prior to resequencing and potential bearing changes.
                //this happens either for a complete line or a partial one
                //The logic could be changed to be more conservative and only capture the record for a partial line (IsCompleteLine==false), since that would only record the first time it's cogo'd,
                //compared to this code that records edits of completed lines *as well as* partial lines
                IAngularConverter pAngConv = new AngularConverterClass();
                string            sBear    = Convert.ToString(inValue);
                sBear = sBear.Replace("°", "-");
                sBear = sBear.Replace("'", "-");
                sBear = sBear.Replace("\"", "");

                if (!pAngConv.SetString(sBear, esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds)) //TODO: base this on Plan properties
                {
                    return(OutValue);
                }
                double brgRecord = pAngConv.GetAngle(esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDUDecimalDegrees);

                sBear = pAngConv.GetString(esriDirectionType.esriDTQuadrantBearing, esriDirectionUnits.esriDUDegreesMinutesSeconds, 0);

                IParcelConstruction4 pTrav4 = pTrav as IParcelConstruction4;
                pTrav4.UpdateGridFromGSLines(true, false);
                sBear = sBear.Replace(" ", "");
                sBear = sBear.Insert(sBear.Length - 1, "\"");
                int i = sBear.LastIndexOf('-');
                sBear = sBear.Insert(i, "'");
                i     = sBear.IndexOf('-');
                sBear = sBear.Insert(i, "°");
                sBear = sBear.Replace("-", "");

                IGSAttributes pLineAtts = (IGSAttributes)pGSLine;
                pLineAtts.SetProperty(m_sFieldName, sBear);
                return(sBear);
                //note that the type of the inValue must be honoured when returning the value from this function.
            }
            return(OutValue);
        }
Пример #4
0
        protected bool HasLineSelectionAfter(IParcelConstruction ConstructionLines, int AfterLineIndex)
        {
            IGSLine pParcelLine = null;

            for (int i = AfterLineIndex + 1; i < ConstructionLines.LineCount; i++)
            {
                if (ConstructionLines.GetLineSelection(i))
                {
                    if (ConstructionLines.GetLine(i, ref pParcelLine))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        object OnGridCellEdit(ref int row, ref int col, ref object inValue)
        {
            object              OutValue = inValue;
            IGSLine             pGSLine  = null;
            IParcelConstruction pCourses = (IParcelConstruction)m_pParcEditorMan.ParcelConstruction;

            if (col == 3) //this is the distance field
            {             //this code uses a value of 0 on the distance field to over-ride
                string sDistance = Convert.ToString(inValue);
                if (sDistance.Trim() == "0")
                {
                    bool IsCompleteLine = (pCourses.GetLine(row, ref pGSLine));
                    //true means it's a complete line, false means it's a partial line
                    if (!IsCompleteLine)
                    {
                        pGSLine.Radius = pGSLine.Distance; //default the radius to be the same as the default distance
                        return(String.Empty);
                    }
                    //note that the type of the inValue must be honoured when returning the value from this function.
                }
            }

            return(OutValue);
        }
        private void CreateParcelFromSegmentCollection(ISegmentCollection Segments, string PlanName)
        {
            int iCnt = Segments.SegmentCount;

            ISegment[] pSegmentArr = new ISegment[iCnt];
            for (int j = 0; j < iCnt; j++)
            {
                pSegmentArr[j] = Segments.get_Segment(j);
            }

            ICadastralEditor   pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd;

            try
            {
                ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd;
                bool bStartedWithPacketOpen           = pCadPacketMan.PacketOpen;
                if (!bStartedWithPacketOpen)
                {
                    m_editor.StartOperation();
                }

                //1. Start map edit session
                ICadastralMapEdit pCadMapEdit = (ICadastralMapEdit)pCadEd;
                pCadMapEdit.StartMapEdit(esriMapEditType.esriMEEmpty, "NewParcel", false);

                //2.	Get job packet
                ICadastralPacket pCadaPacket = pCadPacketMan.JobPacket;

                //3.	Create Plan (new)
                string sPlanName = PlanName;
                //first check to ensure plan is not already in the database.
                IGSPlan pGSPlan = FindFabricPlanByName(sPlanName, pCadEd);

                if (pGSPlan == null)
                {
                    //if plan is null, it was not found and can be created
                    pGSPlan = new GSPlanClass();
                    // 3.a set values
                    pGSPlan.Accuracy = 4;
                    pGSPlan.Name     = sPlanName;
                }

                //3.b Add the plan to the job packet
                ICadastralPlan pCadaPlan = (ICadastralPlan)pCadaPacket;
                pCadaPlan.AddPlan(pGSPlan);

                //4.	Create Parcel
                ICadastralParcel pCadaParcel  = (ICadastralParcel)pCadaPacket;
                IGSParcel        pNewGSParcel = new GSParcelClass();
                //Make sure that any extended attributes on the parcel have their default values set
                IGSAttributes pGSAttributes = (IGSAttributes)pNewGSParcel;
                if (pGSAttributes != null)
                {
                    ICadastralObjectSetup pCadaObjSetup = (ICadastralObjectSetup)pParcEditorMan;
                    pCadaObjSetup.AddExtendedAttributes(pGSAttributes);
                    pCadaObjSetup.SetDefaultValues(pGSAttributes);
                }

                //4a.	Add the parcel to the packet. (do this before addlines)
                // - This will enable us to Acquire the parcel ID,
                // - Having the parcel attached to the packet allows InsertLine to function.
                pCadaParcel.AddParcel(pNewGSParcel);
                pNewGSParcel.Lot  = "NewParcel";
                pNewGSParcel.Type = 7;
                //4b.	Set Plan (created above)
                IGSPlan thePlan = pCadaPlan.GetPlan(sPlanName);
                pNewGSParcel.Plan = thePlan;
                //4c.	Insert GSLines (from new) into GSParcel
                //4d. To bypass join, you can create GSPoints and assign those point IDs to the GSLines.
                ICadastralPoints     pCadaPoints     = (ICadastralPoints)pCadaPacket;
                IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd;

                //Set up the initial start point, POB

                IPoint pPt1 = Segments.get_Segment(0).FromPoint;

                IZAware pZAw = (IZAware)pPt1;
                pZAw.ZAware = true;
                pPt1.Z      = 0; //defaulting to 0

                //Convert the point into metric units, and get a new (in-mem) point id
                IGSPoint pGSPointFrom = pMetricUnitConv.SetGSPoint(pPt1);
                pCadaPoints.AddPoint(pGSPointFrom);
                int iID1      = pGSPointFrom.Id;
                int iID1_Orig = iID1;

                int     index   = 0;
                IGSLine pGSLine = null;
                //++++++++++++ Add Courses ++++++++++++++
                int  iID2    = -1;
                bool bIsLoop = (Math.Abs(pPt1.X - Segments.get_Segment(iCnt - 1).ToPoint.X)) < 0.01 &&
                               (Math.Abs(pPt1.Y - Segments.get_Segment(iCnt - 1).ToPoint.Y)) < 0.01;

                IAngularConverter pAngConv = new AngularConverterClass();

                for (int j = 0; j < iCnt; j++)
                {
                    pSegmentArr[j] = Segments.get_Segment(j);

                    double dDir         = 0; //radians north azimuth
                    ILine  pLineOrChord = new LineClass();
                    pLineOrChord.PutCoords(pSegmentArr[j].FromPoint, pSegmentArr[j].ToPoint);

                    if (pAngConv.SetAngle(pLineOrChord.Angle, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians))
                    {
                        dDir = pAngConv.GetAngle(esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians);
                    }

                    double dDist         = pLineOrChord.Length;
                    double dRadius       = 0;
                    int    iAccuracy     = -1;
                    int    iUserLineType = -1;
                    int    iCategory     = -1;

                    if (pSegmentArr[j] is ICircularArc)
                    {
                        ICircularArc pCircArc = pSegmentArr[j] as ICircularArc;
                        dRadius = pCircArc.Radius;
                        if (pCircArc.IsCounterClockwise)
                        {
                            dRadius = dRadius * -1;
                        }
                    }
                    bool bComputeToPoint = (bIsLoop && (j < iCnt - 1)) || !bIsLoop;
                    //From, Direction (NAz Radians), Distance (map's projection units), Radius
                    pGSLine = CreateGSLine(pMetricUnitConv, pCadaPoints, ref pPt1,
                                           iID1, dDir, dDist, dRadius, iAccuracy, iUserLineType, iCategory, bComputeToPoint, out iID2);

                    if (j < iCnt - 1 || !bIsLoop)
                    {
                        iID1 = iID2;
                    }
                    else if ((j == iCnt - 1) && bIsLoop)
                    {
                        pGSLine.ToPoint = iID1_Orig; //closing the traverse back to the POB
                    }
                    iID2 = -1;

                    //Add the line to the new parcel
                    if (pGSLine != null)
                    {
                        pNewGSParcel.InsertLine(++index, pGSLine);
                    }
                }


                //Add radial lines for circular curves
                pNewGSParcel.AddRadialLines();

                // 4.e then set join=true on the parcel.
                pNewGSParcel.Joined = true;

                //let the packet know that a change has been made
                pCadPacketMan.SetPacketModified(true);

                //save the new parcel
                try
                {
                    pCadMapEdit.StopMapEdit(true);
                }
                catch
                {
                    if (!bStartedWithPacketOpen)
                    {
                        m_editor.AbortOperation();
                    }
                    return;
                }
                if (!bStartedWithPacketOpen)
                {
                    m_editor.StopOperation("New Parcel");
                }
                pCadPacketMan.PartialRefresh();
            }
            catch (Exception ex)
            {
                m_editor.AbortOperation();
                MessageBox.Show(ex.Message);
            }
        }
Пример #7
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);
            }
        }
Пример #8
0
        private bool TraceLines(ref IGSForwardStar FwdStar, int StartNodeId, ref int BranchCount,
                                ref int TracedLinesCount, ref int LoopCount, ref int TerminusCount, ref List <string> FromToLine,
                                ref List <int> FromList, ref List <int> ToList, int iInfinityChecker)
        {
            iInfinityChecker++;
            if (iInfinityChecker > 5000)
            {
                return(false);
            }
            //(This is a self-calling function.) In this context 5000 downstream lines is like infinity,
            //so exit gracefully, and avoid probable endless loop.
            //Possible cause of endless loop? Corrupted data; example, a line with the same from and to point id
            IVector3D vect = new Vector3DClass();

            try
            {
                ILongArray iLngArr = FwdStar.get_ToNodes(StartNodeId);
                //get_ToNodes returns an array of radiated points, not "TO" points in the fabric data model sense
                int iCnt2 = 0;
                iCnt2 = iLngArr.Count;

                if (iCnt2 == 1)
                {
                    TerminusCount++;
                }

                IGSLine pGSLine = null;
                for (int i = 0; i < iCnt2; i++)
                {
                    int i2 = iLngArr.get_Element(i);

                    string sFromTo = StartNodeId.ToString() + "," + i2.ToString();
                    string sToFrom = i2.ToString() + "," + StartNodeId.ToString();

                    if (FromToLine.Contains(sFromTo) || FromToLine.Contains(sToFrom))
                    {
                        if (FromToLine.Contains(sFromTo))
                        {
                            LoopCount++;
                        }
                        continue;
                    }

                    if (iCnt2 > 2)
                    {
                        BranchCount++;
                    }

                    TracedLinesCount++;

                    FromToLine.Add(StartNodeId.ToString() + "," + i2.ToString());

                    bool bIsReversed = FwdStar.GetLine(StartNodeId, i2, ref pGSLine);
                    if (bIsReversed)
                    {
                        FromList.Add(-StartNodeId);
                        ToList.Add(-i2);
                        vect.PolarSet(pGSLine.Bearing + Math.PI, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north
                    }
                    else
                    {
                        FromList.Add(StartNodeId);
                        ToList.Add(i2);
                        vect.PolarSet(pGSLine.Bearing, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north
                    }

                    if (!TraceLines(ref FwdStar, i2, ref BranchCount, ref TracedLinesCount, ref LoopCount, ref TerminusCount,
                                    ref FromToLine, ref FromList, ref ToList, iInfinityChecker))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }
        protected override void OnClick()
        {
            FileType ft = FileType.COGOToolbarTraverse; //start out assuming it is a cogo traverse file

            m_count = 1;
            ICadastralEditor            pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            ICadastralFabric            pCadFabric     = pCadEd.CadastralFabric;
            ICadastralExtensionManager2 pCadExtMan     = (ICadastralExtensionManager2)pCadEd;
            IParcelEditManager          pParcEditorMan = (IParcelEditManager)pCadEd;
            IParcelConstruction         pTrav          = pParcEditorMan.ParcelConstruction;

            if (!(pParcEditorMan.InTraverseEditMode) && !(pParcEditorMan.InConstructionEditMode))
            {//if this is not a construction or a new parcel, then get out.
                MessageBox.Show("Please create a new parcel or new construction first, and then try again.");
                return;
            }

            //Make sure the lines grid is selected
            Utilities UTILS = new Utilities();

            UTILS.SelectCadastralPropertyPage((ICadastralExtensionManager)pCadExtMan, "lines");

            IParcelConstruction3 pTrav3  = (IParcelConstruction3)pTrav;
            IGSParcel            pParcel = null;

            try
            {
                pParcel = pTrav.Parcel;
            }
            catch (COMException error)
            {
                MessageBox.Show(error.Message.ToString());
                return;
            }
            //go get a traverse file
            // Display .Net dialog for File selection.
            OpenFileDialog openFileDialog = new OpenFileDialog();

            // Set File Filter
            openFileDialog.Filter = "Traverse file (*.txt)|*.txt|Comma-delimited(*.csv)|*.csv|All Files|*.*";
            // Disable multi-select
            openFileDialog.Multiselect = false;
            // Don't need to Show Help
            openFileDialog.ShowHelp = false;
            // Set Dialog Title
            openFileDialog.Title       = "Load file";
            openFileDialog.FilterIndex = 2;
            // Display Open File Dialog
            if (openFileDialog.ShowDialog() != DialogResult.OK)
            {
                openFileDialog = null;
                return;
            }

            TextReader tr = null;

            try
            {
                tr = new StreamReader(openFileDialog.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            string sCourse = "";
            int    iCount  = 0;

            string[] sFileLine = new string[0]; //define as dynamic array
            //initialize direction units and format
            esriDirectionType  enumDirectionType  = esriDirectionType.esriDTQuadrantBearing;
            esriDirectionUnits enumDirectionUnits = esriDirectionUnits.esriDUDegreesMinutesSeconds;

            //initialize start and end points
            IPoint StartPoint     = new PointClass();
            IPoint EndPoint       = new PointClass();
            bool   IsLoopTraverse = false;

            //fill the array with the lines from the file
            while (sCourse != null)
            {
                sCourse = tr.ReadLine();
                try
                {
                    if (sCourse.Trim().Length >= 1) //test for empty lines
                    {
                        RedimPreserveString(ref sFileLine, 1);
                        sFileLine[iCount] = sCourse;
                    }
                    iCount++;
                    sCourse = sCourse.ToLower();
                    if (sCourse.Contains("dt"))
                    {
                        if (sCourse.Contains("qb"))
                        {
                            enumDirectionType = esriDirectionType.esriDTQuadrantBearing;
                        }
                        else if (sCourse.Contains("na"))
                        {
                            enumDirectionType = esriDirectionType.esriDTNorthAzimuth;
                        }
                        else if (sCourse.Contains("sa"))
                        {
                            enumDirectionType = esriDirectionType.esriDTSouthAzimuth;
                        }
                        else if (sCourse.Contains("p"))
                        {
                            enumDirectionType = esriDirectionType.esriDTPolar;
                        }
                    }
                    if (sCourse.Contains("du"))
                    {
                        if (sCourse.Contains("dms"))
                        {
                            enumDirectionUnits = esriDirectionUnits.esriDUDegreesMinutesSeconds;
                        }
                        else if (sCourse.Contains("dd"))
                        {
                            enumDirectionUnits = esriDirectionUnits.esriDUDecimalDegrees;
                        }
                        else if (sCourse.Contains("g"))
                        {
                            enumDirectionUnits = esriDirectionUnits.esriDUGons;
                        }
                        else if (sCourse.Contains("r"))
                        {
                            enumDirectionUnits = esriDirectionUnits.esriDURadians;
                        }
                    }
                    if (sCourse.Contains("sp"))
                    {//start point
                        string[] XY = sCourse.Split(' ');
                        double   x  = Convert.ToDouble(XY[1]);
                        double   y  = Convert.ToDouble(XY[2]);
                        StartPoint.PutCoords(x, y);
                    }

                    if (sCourse.Contains("ep"))
                    {//end point
                        string[] XY = sCourse.Split(' ');
                        double   x  = Convert.ToDouble(XY[1]);
                        double   y  = Convert.ToDouble(XY[2]);
                        EndPoint.PutCoords(x, y);
                    }

                    if (sCourse.Contains("tometricfactor"))
                    {//this handles the comma-separated file case
                        string[] sScaleFactor = sCourse.Split(',');
                        m_dScaleFactor = Convert.ToDouble(sScaleFactor[1]);
                    }
                }
                catch { }
            }
            tr.Close(); //close the file and release resources
            string sFileExt = System.IO.Path.GetExtension(openFileDialog.FileName.TrimEnd());

            if ((sFileExt.ToLower() == ".csv") && (sFileLine[0].Contains(",")))
            {//if it's a comma-delimited file
                ft = FileType.CommaDelimited;
            }

            //Test for loop traverse
            if (!(EndPoint.IsEmpty))
            {
                if (EndPoint.Compare(StartPoint) == 0)
                {
                    IsLoopTraverse = true;
                }
                else
                {
                    IsLoopTraverse = false;
                }
            }

            //get highest point id number in grid, and get the to point id on the last line.
            IGSLine pParcelLine     = null;
            int     iFirstToNode    = -1;
            int     iLastToNode     = -1;
            int     iHighestPointID = -1;

            for (int i = 0; i < pTrav.LineCount; i++)
            {
                if (pTrav.GetLine(i, ref pParcelLine))
                {
                    if (iFirstToNode < 0)
                    {
                        iFirstToNode = pParcelLine.ToPoint;
                    }
                    iLastToNode     = pParcelLine.ToPoint;
                    iHighestPointID = iHighestPointID < pParcelLine.ToPoint ? pParcelLine.ToPoint : iHighestPointID;
                    iHighestPointID = iHighestPointID < pParcelLine.FromPoint ? pParcelLine.FromPoint : iHighestPointID;
                }
            }

            ICadastralUndoRedo pCadUndoRedo = pTrav as ICadastralUndoRedo;

            pCadUndoRedo.StartUndoRedoSession("Load Lines From File");
            try
            {
                IGSLine  pLine        = null;
                int      iLinecount   = iCount - 1;
                ISegment pExitTangent = null;
                for (iCount = 0; iCount <= iLinecount; iCount++)
                {
                    if (ft == FileType.COGOToolbarTraverse)
                    {
                        {
                            pLine = null;

                            ICircularArc pCircArc;//need to use this in the test to handle curves greater than 180
                            pLine = CreateGSLine(sFileLine[iCount], enumDirectionUnits, enumDirectionType,
                                                 pExitTangent, out pExitTangent, out pCircArc);
                            //exit tangent from the previous course is the new entry tangent for the next course

                            if (pLine != null)
                            {
                                if (pCircArc == null)
                                {// straight line
                                    //if this is the last course then set the to point to 1
                                    if ((iCount == iLinecount) && IsLoopTraverse)
                                    {
                                        pLine.ToPoint = 1;
                                    }
                                    pTrav.InsertGridRow(-1, pLine);
                                }
                                else
                                {                                                               //some post-processing needed to figure out if a 180 curve needs to be split
                                    if (Math.Abs(pCircArc.CentralAngle) < (Math.PI - 0.000001)) //some tolerance for being close to 180
                                    {                                                           //this curve is OK
                                      //if this is the last course then set the to point to 1
                                        if ((iCount == iLinecount) && IsLoopTraverse)
                                        {
                                            pLine.ToPoint = 1;
                                        }
                                        pTrav.InsertGridRow(-1, pLine);
                                    }
                                    else
                                    {//curve is greater than or equal to 180, special treatment for GSE needed to split curve into 2 parts
                                        //first decrement the count
                                        m_count -= 1;
                                        ISegment pFullSegment = (ISegment)pCircArc; ISegment pFirstHalf; ISegment pSecondHalf;
                                        pFullSegment.SplitAtDistance(0.5, true, out pFirstHalf, out pSecondHalf);
                                        IConstructCircularArc2 pCircArcConstr1 = new CircularArcClass();
                                        ICircularArc           pCircArc1       = (ICircularArc)pCircArcConstr1;
                                        pCircArcConstr1.ConstructEndPointsRadius(pFirstHalf.FromPoint,
                                                                                 pFirstHalf.ToPoint, pCircArc.IsCounterClockwise, pCircArc.Radius, true);
                                        ILine2 pTangentLine = new LineClass();
                                        pCircArc1.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 0, false, 100, pTangentLine);
                                        string sTangentBearing = PolarRadians_2_DirectionString(pTangentLine.Angle,
                                                                                                enumDirectionType, enumDirectionUnits);
                                        sTangentBearing = sTangentBearing.Replace(" ", "");
                                        string sHalfDelta = Radians_2_Angle(Math.Abs(pCircArc1.CentralAngle), enumDirectionUnits);
                                        string sSide      = pCircArc.IsCounterClockwise ? " L " : " R ";

                                        ISegment EntryTangent = (ISegment)pTangentLine;

                                        //construct the string for the first piece
                                        // looks similar to this: NC R 500 D 181-59-59 T N59-59-59W L
                                        string sFirstCurve = "NC R " + Convert.ToString(pCircArc.Radius)
                                                             + " D " + sHalfDelta + " T " + sTangentBearing + sSide;

                                        IGSLine pLineFirstCurve = CreateGSLine(sFirstCurve, enumDirectionUnits, enumDirectionType, pExitTangent,
                                                                               out pExitTangent, out pCircArc);
                                        pTrav.InsertGridRow(-1, pLineFirstCurve);

                                        ICircularArc pCircArc2 = (ICircularArc)pCircArcConstr1;
                                        pCircArcConstr1.ConstructEndPointsRadius(pSecondHalf.FromPoint,
                                                                                 pSecondHalf.ToPoint, pCircArc.IsCounterClockwise, pCircArc.Radius, true);
                                        pCircArc2.QueryTangent(esriSegmentExtension.esriExtendTangentAtTo, 0, false, 100, pTangentLine);
                                        sTangentBearing = PolarRadians_2_DirectionString(pTangentLine.Angle, enumDirectionType, enumDirectionUnits);
                                        sTangentBearing = sTangentBearing.Replace(" ", "");
                                        //construct the string for the second piece
                                        // looks similar to this: NC R 500 D 181-59-59 T N59-59-59W L
                                        string sSecondCurve = "NC R " + Convert.ToString(pCircArc.Radius)
                                                              + " D " + sHalfDelta + " T " + sTangentBearing + sSide;

                                        IGSLine pLineSecondCurve = CreateGSLine(sSecondCurve, enumDirectionUnits, enumDirectionType, pExitTangent,
                                                                                out pExitTangent, out pCircArc);
                                        //if this is the last course then set the to point to 1
                                        if ((iCount == iLinecount) && IsLoopTraverse)
                                        {
                                            pLine.ToPoint = 1;
                                        }
                                        pTrav.InsertGridRow(-1, pLineSecondCurve);
                                    }
                                }
                            }
                        }
                    }
                    else//this is comma-separated version of the grid, so do the following
                    {
                        pLine = null;
                        //apply a point id number offset if there are existing lines in the grid.
                        if (iHighestPointID > -1 && iCount >= 3)
                        {
                            string[] sTraverseCourse = sFileLine[iCount].Split(',');
                            if (iCount == 3)
                            {
                                sTraverseCourse[0] = iLastToNode.ToString();
                                sTraverseCourse[5] = (Convert.ToInt32(sTraverseCourse[5]) + iHighestPointID).ToString();
                            }
                            else if (iCount > 3)
                            {
                                sTraverseCourse[0] = (Convert.ToInt32(sTraverseCourse[0]) + iHighestPointID).ToString();
                                sTraverseCourse[5] = (Convert.ToInt32(sTraverseCourse[5]) + iHighestPointID).ToString();
                            }

                            sFileLine[iCount] = sTraverseCourse[0];
                            int iAttCount = sTraverseCourse.GetLength(0);
                            for (int j = 1; j < iAttCount; j++)
                            {
                                sFileLine[iCount] += "," + sTraverseCourse[j];
                            }
                        }

                        pLine = CreateGSLineFromCommaSeparatedString(sFileLine[iCount], enumDirectionUnits, enumDirectionType);

                        if (pLine != null)
                        {
                            pTrav.InsertGridRow(-1, pLine);
                        }
                    }
                }
                pTrav3.UpdateGridFromGSLines(false);
                IParcelConstruction2 pConstr2 = (IParcelConstruction2)pTrav3; //hidden interface
                pConstr2.RecalculatePoints();                                 //explicit recalculate needed on a construction
                pParcel.Modified();
                pParcEditorMan.Refresh();
                pCadUndoRedo.WriteUndoRedoSession(true);
                sFileLine      = null;
                openFileDialog = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Load Lines From File");
                pCadUndoRedo.WriteUndoRedoSession(false);
            }
        }
        protected override void OnClick()
        {
            ICadastralEditor           pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            IParcelEditManager         pParcEditorMan = (IParcelEditManager)pCadEd;
            ICadastralExtensionManager pCadMan        = pCadEd as ICadastralExtensionManager;
            ICadastralPacketManager    pCadPacketMan  = (ICadastralPacketManager)pCadEd;

            //bool bStartedWithPacketOpen = pCadPacketMan.PacketOpen;

            if (!(pCadMan.ContextItem is IGSLine))
            {
                return;
            }

            IGSLine pGSLine = pCadMan.ContextItem as IGSLine;

            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;
            ICadastralLinePoints2Ex pCadLPsEx = pConstr as ICadastralLinePoints2Ex;

            ILongArray pLngArrBefore = pCadLPsEx.LinePoints;
            List <int> lstLPBefore   = new List <int>();

            for (int i = 0; i < pLngArrBefore.Count; i++)
            {
                lstLPBefore.Add(pLngArrBefore.get_Element(i));
            }

            //first get the current set of breakpoints
            Utilities FabUTILS = new Utilities();

            FabUTILS.ExecuteCommand("{9987F18B-8CC4-4548-8C41-7DB51F289BB3}"); //Run COTS Breakline command

            ILongArray pLngArrAfter = pCadLPsEx.LinePoints;
            List <int> lstLPAfter   = new List <int>();

            for (int i = 0; i < pLngArrAfter.Count; i++)
            {
                lstLPAfter.Add(pLngArrAfter.get_Element(i));
            }

            List <int> lstNewBreakPoints = lstLPAfter.Except(lstLPBefore).ToList();

            if (lstNewBreakPoints.Count == 0)
            {
                return;
            }

            IParcelConstruction4 pConstr4      = pConstr as IParcelConstruction4;
            ICadastralPoints     pCadastralPts = pConstr4 as ICadastralPoints;

            IEnumCELines pCELines     = new EnumCELinesClass();
            IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines;

            pCELines.Add(pGSLine);

            //check if it's a construction line or parent line
            bool         bIsParentLine            = true;
            IEnumGSLines pEnumGSConstructionLines = pConstr4.GetLines(false, false);

            IGSLine   pGSTestLine = null;
            IGSParcel pGSParc     = null;

            pEnumGSConstructionLines.Reset();
            pEnumGSConstructionLines.Next(ref pGSParc, ref pGSTestLine);
            while (pGSTestLine != null)
            {
                if ((pGSLine.FromPoint == pGSTestLine.FromPoint) && (pGSLine.ToPoint == pGSTestLine.ToPoint))
                {
                    bIsParentLine = false;
                    break;
                }
                pEnumGSConstructionLines.Next(ref pGSParc, ref pGSTestLine);
            }

            IParcelLineFunctions3 pParcLineFunctions = new ParcelFunctionsClass();
            IEnumGSLines          pNewLinesEnum      = pParcLineFunctions.BreakLinesAtLinePoints(pEnumGSLines, pCadastralPts, true, false);

            IGSParcel          pGSParcel    = null;
            IGSLine            pGSNewLine   = null;
            ICadastralUndoRedo pCadUndoRedo = pConstr as ICadastralUndoRedo;

            pCadUndoRedo.StartUndoRedoSession("Break-line");

            pNewLinesEnum.Reset();
            pNewLinesEnum.Next(ref pGSParcel, ref pGSNewLine);
            while (pGSNewLine != null)
            {
                pConstr4.InsertGridRow(-1, pGSNewLine, true);
                pNewLinesEnum.Next(ref pGSParcel, ref pGSNewLine);
            }

            ICadastralUnbuildableLines pUnbuildable = pConstr4 as ICadastralUnbuildableLines;

            if (bIsParentLine)
            {
                pUnbuildable.AddLine(pGSLine);
            }
            else
            {
                pConstr4.Planarize(0.001); //delete the original construction line
            }
            pCadUndoRedo.WriteUndoRedoSession(true);
        }
Пример #11
0
        protected override void OnClick()
        {
            ICadastralEditor   pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd;

            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;
            ICadastralPoints    pCadastralPts = pConstr as ICadastralPoints;
            IGSPoint            pFromPoint = null;
            IGSPoint            pToPoint = null;
            IGSLine             pParcelLine = null;
            List <double>       xcoords = new List <double>();
            List <double>       ycoords = new List <double>();
            double dX = 0; double dY = 0;
            bool   bLineSelectionSequence = false;

            #region simple method as fall-back
            for (int i = 0; i < pConstr.LineCount; i++)
            {
                if (pConstr.GetLineSelection(i))
                {
                    if (pConstr.GetLine(i, ref pParcelLine))
                    {
                        pFromPoint = pCadastralPts.GetPoint(pParcelLine.FromPoint);
                        pToPoint   = pCadastralPts.GetPoint(pParcelLine.ToPoint);
                        xcoords.Add((pFromPoint.X + pToPoint.X) / 2);
                        ycoords.Add((pFromPoint.Y + pToPoint.Y) / 2);
                    }
                    bLineSelectionSequence = true;
                }
            }
            if (bLineSelectionSequence)
            {
                dX = xcoords.Average();
                dY = ycoords.Average();
            }
            else
            {
                return;
            }
            IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd;
            double newX = 0;
            double newY = 0;
            pMetricUnitConv.ConvertXY(esriCadastralUnitConversionType.esriCUCFromMetric, dX, dY, ref newX, ref newY);
            // Calculate center point of current map extent
            IPoint centerPoint = new PointClass();
            centerPoint.SpatialReference = ArcMap.Document.ActiveView.FocusMap.SpatialReference;
            centerPoint.PutCoords(newX, newY);

            IEnvelope envelope = ArcMap.Document.ActiveView.Extent;
            envelope.CenterAt(centerPoint);
            //envelope.Expand(zoomRatio, zoomRatio, true);
            ArcMap.Document.ActiveView.Extent = envelope;
            ArcMap.Document.ActiveView.Refresh();

            #endregion
        }
Пример #12
0
        protected override void OnClick()
        {
            // **SAMPLE CODE NOTE**
            // the following code show the mechanics of creating a new parcel using the ICadastralMapEdit interface
            // there is no user interface to enter parcel record data, and the parcel line records are hard -coded
            // for the purposes of this sample code. The center of the map extent is used as the point of beginning
            // for the parcel.
            ICadastralEditor   pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd;

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

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

            try
            {
                ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd;
                bool bStartedWithPacketOpen           = pCadPacketMan.PacketOpen;
                if (!bStartedWithPacketOpen)
                {
                    pEd.StartOperation();
                }

                //1. Start map edit session
                ICadastralMapEdit pCadMapEdit = (ICadastralMapEdit)pCadEd;
                pCadMapEdit.StartMapEdit(esriMapEditType.esriMEEmpty, "NewParcel", false);

                //2.	Get job packet
                ICadastralPacket pCadaPacket = pCadPacketMan.JobPacket;

                //3.	Create Plan (new)
                string sPlanName = "My New Plan";
                //first check to ensure plan is not already in the database.
                IGSPlan pGSPlan = FindFabricPlanByName(sPlanName, pCadEd);

                if (pGSPlan == null)
                {
                    //if plan is null, it was not found and can be created
                    pGSPlan = new GSPlanClass();
                    // 3.a set values
                    pGSPlan.Accuracy = 4;
                    pGSPlan.Name     = sPlanName;
                }

                //3.b Add the plan to the job packet
                ICadastralPlan pCadaPlan = (ICadastralPlan)pCadaPacket;
                pCadaPlan.AddPlan(pGSPlan);

                //4.	Create Parcel
                ICadastralParcel pCadaParcel  = (ICadastralParcel)pCadaPacket;
                IGSParcel        pNewGSParcel = new GSParcelClass();
                //Make sure that any extended attributes on the parcel have their default values set
                IGSAttributes pGSAttributes = (IGSAttributes)pNewGSParcel;
                if (pGSAttributes != null)
                {
                    ICadastralObjectSetup pCadaObjSetup = (ICadastralObjectSetup)pParcEditorMan;
                    pCadaObjSetup.AddExtendedAttributes(pGSAttributes);
                    pCadaObjSetup.SetDefaultValues(pGSAttributes);
                }

                //4a.	Add the parcel to the packet. (do this before addlines)
                // - This will enable us to Acquire the parcel ID,
                // - Having the parcel attached to the packet allows InsertLine to function.
                pCadaParcel.AddParcel(pNewGSParcel);
                pNewGSParcel.Lot  = "NewParcel";
                pNewGSParcel.Type = 7;
                //4b.	Set Plan (created above)
                IGSPlan thePlan = pCadaPlan.GetPlan(sPlanName);
                pNewGSParcel.Plan = thePlan;
                //4c.	Insert GSLines (from new) into GSParcel
                //4d. To bypass join, you can create GSPoints and assign those point IDs to the GSLines.
                ICadastralPoints     pCadaPoints     = (ICadastralPoints)pCadaPacket;
                IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd;

                //Set up the initial start point, POB
                //This sample code starts from the middle of the map, and defines 4 lines of a parcel
                //The first course is a straight line, the other 3 courses are circular arcs
                IArea  pArea = (IArea)ArcMap.Document.ActiveView.Extent;
                IPoint pPt1  = pArea.Centroid;

                IZAware pZAw = (IZAware)pPt1;
                pZAw.ZAware = true;
                pPt1.Z      = 0; //defaulting to 0

                //Convert the point into metric units, and get a new (in-mem) point id
                IGSPoint pGSPointFrom = pMetricUnitConv.SetGSPoint(pPt1);
                pCadaPoints.AddPoint(pGSPointFrom);
                int iID1 = pGSPointFrom.Id;

                int index = 0;
                //++++++++++++ Course 1 ++++++++++++++
                int iID2 = -1;
                //From, Direction (NAz Radians), Distance (map's projection units), Radius
                IGSLine pGSLine = CreateGSLine(pMetricUnitConv, pCadaPoints, ref pPt1,
                                               iID1, 0, 100, 0, -1, -1, -1, true, out iID2);
                //Add the line to the new parcel
                if (pGSLine != null)
                {
                    pNewGSParcel.InsertLine(++index, pGSLine);
                }

                //++++++++++++ Course 2 ++++++++++++++
                int iID3 = -1;
                pGSLine = CreateGSLine(pMetricUnitConv, pCadaPoints, ref pPt1,
                                       iID2, (Math.PI / 2), 100, -80, -1, -1, -1, true, out iID3);
                if (pGSLine != null)
                {
                    pNewGSParcel.InsertLine(++index, pGSLine);
                }

                //++++++++++++ Course 3 ++++++++++++++
                int iID4 = -1;
                pGSLine = CreateGSLine(pMetricUnitConv, pCadaPoints, ref pPt1,
                                       iID3, Math.PI, 100, 80, -1, -1, -1, true, out iID4);
                if (pGSLine != null)
                {
                    pNewGSParcel.InsertLine(++index, pGSLine);
                }

                //++++++++++++ Course 4 ++++++++++++++
                //close back to point of beginning
                int i = -1;
                pGSLine = CreateGSLine(pMetricUnitConv, pCadaPoints, ref pPt1,
                                       iID4, (3 * Math.PI / 2), 100, 200, -1, -1, -1, false, out i);
                pGSLine.ToPoint = iID1; //closing the traverse back to the POB
                if (pGSLine != null)
                {
                    pNewGSParcel.InsertLine(++index, pGSLine);
                }

                //Add radial lines for circular curves
                pNewGSParcel.AddRadialLines();

                // 4.e then set join=true on the parcel.
                pNewGSParcel.Joined = true;

                //let the packet know that a change has been made
                pCadPacketMan.SetPacketModified(true);

                //save the new parcel
                try
                {
                    pCadMapEdit.StopMapEdit(true);
                }
                catch
                {
                    if (!bStartedWithPacketOpen)
                    {
                        pEd.AbortOperation();
                    }
                    return;
                }
                if (!bStartedWithPacketOpen)
                {
                    pEd.StopOperation("New Parcel");
                }
                pCadPacketMan.PartialRefresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        protected override void OnClick()
        {
            ICadastralEditor            pCadEd         = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension");
            ICadastralFabric            pCadFabric     = pCadEd.CadastralFabric;
            ICadastralExtensionManager2 pCadExtMan     = (ICadastralExtensionManager2)pCadEd;
            IParcelEditManager          pParcEditorMan = (IParcelEditManager)pCadEd;
            IParcelConstruction         pTrav          = pParcEditorMan.ParcelConstruction;

            //Test for the visibility of the parcel details window
            IDockableWindowManager pDocWinMgr = (IDockableWindowManager)ArcMap.Application;
            UID pUID = new UIDClass();

            pUID.Value = "{28531B78-7C42-4785-805D-2A7EC8879EA1}";//ArcID.ParcelDetails
            IDockableWindow pParcelDet = pDocWinMgr.GetDockableWindow(pUID);

            if (!pParcelDet.IsVisible())
            {
                MessageBox.Show("The Parcel Details window is not visible. \r\nThere is no data to save.");
                return;
            }

            //Make sure the lines grid is selected
            Utilities UTILS = new Utilities();

            UTILS.SelectCadastralPropertyPage((ICadastralExtensionManager)pCadExtMan, "lines");

            //test to make sure there is data there to be saved
            IParcelConstruction3 pConstr = (IParcelConstruction3)pTrav;
            IGSParcel            pParcel = null;

            //
            try
            {
                pParcel = pTrav.Parcel;
            }
            catch (COMException err)
            {
                MessageBox.Show(err.Message + Environment.NewLine + "ERROR: Select a parcel or add lines to the grid. \r\nThere is no data to save. ");
                return;
            }
            //define the file that needs to be saved
            // Display .Net dialog for File saving.
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            // Set File Filter
            saveFileDialog.Filter           = "Comma-delimited(*.csv)|*.csv|All Files|*.*";
            saveFileDialog.FilterIndex      = 1;
            saveFileDialog.RestoreDirectory = true;
            // Warn on overwrite
            saveFileDialog.OverwritePrompt = true;
            // Don't need to Show Help
            saveFileDialog.ShowHelp = false;
            // Set Dialog Title
            saveFileDialog.Title = "Save file";

            // Display Open File Dialog
            if (saveFileDialog.ShowDialog() != DialogResult.OK)
            {
                saveFileDialog = null;
                return;
            }
            TextWriter tw = null;

            try
            {
                tw = new StreamWriter(saveFileDialog.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            try
            {
                IGSPlan pPlan = pTrav.Parcel.Plan;
                int     iDF   = (int)pPlan.DirectionFormat;
                switch (iDF)
                {
                case (int)esriDirectionType.esriDTNorthAzimuth:
                    tw.WriteLine("DT,NA");
                    break;

                case (int)esriDirectionType.esriDTPolar:
                    tw.WriteLine("DT,P");
                    break;

                case (int)esriDirectionType.esriDTQuadrantBearing:
                    tw.WriteLine("DT,QB");
                    break;

                case (int)esriDirectionType.esriDTSouthAzimuth:
                    tw.WriteLine("DT,SA");
                    break;

                default:
                    tw.WriteLine("DT,NA");
                    break;
                }

                int iAU = (int)pPlan.AngleUnits;
                switch (iAU)
                {
                case (int)esriDirectionUnits.esriDUDecimalDegrees:
                    tw.WriteLine("DU,DD");
                    break;

                case (int)esriDirectionUnits.esriDUDegreesMinutesSeconds:
                    tw.WriteLine("DU,DMS");
                    break;

                case (int)esriDirectionUnits.esriDUGons:
                case (int)esriDirectionUnits.esriDUGradians:
                    tw.WriteLine("DU,G");
                    break;

                case (int)esriDirectionUnits.esriDURadians:
                    tw.WriteLine("DU,R");
                    break;

                default:
                    tw.WriteLine("DU,R");
                    break;
                }

                ICadastralUnitConversion pUnitConv = new CadastralUnitConversionClass();
                double dMetricConversion           = pUnitConv.ConvertDouble(1, pPlan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter);
                string sLU = Convert.ToString(dMetricConversion);

                tw.WriteLine("ToMetricFactor," + sLU);

                IEnumGSLines pGSLines = pTrav.GetLines();
                pGSLines.Reset();
                IGSLine   pGSLine   = null;
                IGSParcel pGSParcel = null;
                pGSLines.Next(ref pGSParcel, ref pGSLine);
                while (pGSLine != null)
                {
                    int iFromPt  = pGSLine.FromPoint;     //from point
                    int iToPt    = pGSLine.ToPoint;       //to point
                    int iLineCat = (int)pGSLine.Category; //line category
                    if (iLineCat == 4)
                    {
                        pGSLines.Next(ref pGSParcel, ref pGSLine);
                        continue;                            //ignore radial lines
                    }
                    int    iLineUserType = pGSLine.LineType; //line user type
                    int    iAccCat       = pGSLine.Accuracy; //accuracy
                    double dDistance     = pGSLine.Distance; //distance
                    double dChord        = pGSLine.Distance; //chord
                    double dRadius       = pGSLine.Radius;   //radius

                    string sLineCat      = Convert.ToString(iLineCat);
                    string sLineUserType = Convert.ToString(iLineUserType);

                    if (iLineUserType > 2140000000)
                    {
                        sLineUserType = "";
                    }

                    string sAccCat = Convert.ToString(iAccCat);
                    string sFromPt = Convert.ToString(iFromPt);//from point

                    //following need conversion
                    string sDirection = NorthAzRadians_2_DirectionString(pGSLine.Bearing, pPlan.DirectionFormat, pPlan.AngleUnits); //direction
                    string sDistance  = Convert.ToString(dDistance / dMetricConversion);                                            //distance
                    string sRadius    = "";
                    string sChord     = "";

                    if (dRadius != 123456789)
                    {                                                                //circular curve
                        sRadius   = Convert.ToString(dRadius / dMetricConversion);   //radius
                        sChord    = Convert.ToString(dDistance / dMetricConversion); //chord
                        sDistance = "";                                              //distance is replaced with the chord distance
                    }

                    string sToPt = Convert.ToString(iToPt);//to point
                    //write the line
                    tw.WriteLine(sFromPt + "," + sDirection + "," + sDistance + "," + sRadius + "," + sChord + "," + sToPt + ","
                                 + sLineCat + "," + sLineUserType + "," + sAccCat);

                    pGSLines.Next(ref pGSParcel, ref pGSLine);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                tw.Close();
                saveFileDialog = null;
            }
        }
        private void CalculateStatedArea(IQueryFilter m_pQF, ITable pParcelsTable, ICadastralEditor pCadEd, ISpatialReference pMapSR,
                                         double SquareMetersPerUnitFactor, string Suffix, int DecimalPlaces, ref Dictionary <int, string> dict_ParcelSelection2CalculatedArea, ITrackCancel pTrackCancel)
        {
            bool bTrackCancel = (pTrackCancel != null);
            //ILine pLine = new LineClass();

            ICursor   pCursor       = pParcelsTable.Search(m_pQF, false);
            IRow      pParcelRecord = pCursor.NextRow();
            Utilities Utils         = new Utilities();

            IArray                     pParcelFeatArr = new ArrayClass();
            IGeoDataset                pGeoDS         = (IGeoDataset)((IFeatureClass)pParcelsTable).FeatureDataset;
            ISpatialReference          pFabricSR      = pGeoDS.SpatialReference;
            IProjectedCoordinateSystem pPCS           = null;
            double                     dMetersPerUnit = 1;
            bool bFabricIsInGCS = !(pFabricSR is IProjectedCoordinateSystem);

            if (!bFabricIsInGCS)
            {
                pPCS           = (IProjectedCoordinateSystem)pFabricSR;
                dMetersPerUnit = pPCS.CoordinateUnit.MetersPerUnit;
            }
            else
            {
                pPCS           = (IProjectedCoordinateSystem)pMapSR;
                dMetersPerUnit = pPCS.CoordinateUnit.MetersPerUnit;
            }

            //for each parcel record
            while (pParcelRecord != null)
            {
                IFeature pFeat = (IFeature)pParcelRecord;
                //IGeometry pGeom = pFeat.Shape;
                pParcelFeatArr.Add(pFeat);

                Marshal.ReleaseComObject(pParcelRecord);
                if (bTrackCancel)
                {
                    if (!pTrackCancel.Continue())
                    {
                        break;
                    }
                }

                pParcelRecord = pCursor.NextRow();
            }
            Marshal.ReleaseComObject(pCursor);

            ICadastralFeatureGenerator pFeatureGenerator = new CadastralFeatureGeneratorClass();
            IEnumGSParcels             pEnumGSParcels    = pFeatureGenerator.CreateParcelsFromFeatures(pCadEd, pParcelFeatArr, true);

            pEnumGSParcels.Reset();
            Dictionary <int, int>    dict_ParcelAndStartPt = new Dictionary <int, int>();
            Dictionary <int, IPoint> dict_PointID2Point    = new Dictionary <int, IPoint>();

            //dict_PointID2Point -->> this lookup makes an assumption that the fabric TO point geometry is at the same location as the line *geometry* endpoint
            IParcelLineFunctions3 ParcelLineFx = new ParcelFunctionsClass();

            IGSParcel pGSParcel      = pEnumGSParcels.Next();
            int       iFromPtIDX     = -1;
            int       iToPtIDX       = -1;
            int       iParcelIDX     = -1;
            int       iIsMajorFldIdx = -1;

            while (pGSParcel != null)
            {
                IEnumCELines pCELines     = new EnumCELinesClass();
                IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines;

                IEnumGSLines pGSLinesInner = pGSParcel.GetParcelLines(null, false);
                pGSLinesInner.Reset();
                IGSParcel         pTemp   = null;
                IGSLine           pGSLine = null;
                ICadastralFeature pCF     = (ICadastralFeature)pGSParcel;
                int iParcID = pCF.Row.OID;
                pGSLinesInner.Next(ref pTemp, ref pGSLine);
                bool bStartPointAdded = false;
                int  iFromPtID        = -1;
                while (pGSLine != null)
                {
                    if (pGSLine.Category == esriCadastralLineCategory.esriCadastralLineBoundary ||
                        pGSLine.Category == esriCadastralLineCategory.esriCadastralLineRoad ||
                        pGSLine.Category == esriCadastralLineCategory.esriCadastralLinePartConnection)
                    {
                        pCELines.Add(pGSLine);
                        ICadastralFeature pCadastralLineFeature = (ICadastralFeature)pGSLine;
                        IFeature          pLineFeat             = (IFeature)pCadastralLineFeature.Row;
                        if (iFromPtIDX == -1)
                        {
                            iFromPtIDX = pLineFeat.Fields.FindField("FROMPOINTID");
                        }
                        if (iToPtIDX == -1)
                        {
                            iToPtIDX = pLineFeat.Fields.FindField("TOPOINTID");
                        }
                        if (iParcelIDX == -1)
                        {
                            iParcelIDX = pLineFeat.Fields.FindField("PARCELID");
                        }
                        if (iIsMajorFldIdx == -1)
                        {
                            iIsMajorFldIdx = pLineFeat.Fields.FindField("ISMAJOR");
                        }

                        if (!bStartPointAdded)
                        {
                            iFromPtID        = (int)pLineFeat.get_Value(iFromPtIDX);
                            bStartPointAdded = true;
                        }
                        IPolyline pPolyline = (IPolyline)pLineFeat.ShapeCopy;
                        //if (bFabricIsInGCS)
                        pPolyline.Project(pPCS);
                        //dict_PointID2Point -->> this lookup makes an assumption that the fabric TO point geometry is at the same location as the line *geometry* endpoint
                        int iToPtID = (int)pLineFeat.get_Value(iToPtIDX);
                        //first make sure the point is not already added
                        if (!dict_PointID2Point.ContainsKey(iToPtID))
                        {
                            dict_PointID2Point.Add(iToPtID, pPolyline.ToPoint);
                        }
                    }
                    pGSLinesInner.Next(ref pTemp, ref pGSLine);
                }

                if (pGSParcel.Unclosed)
                {//skip unclosed parcels
                    pGSParcel = pEnumGSParcels.Next();
                    continue;
                }

                ICadastralFeature pCadastralPolygonFeature = (ICadastralFeature)pGSParcel;
                IFeature          pPolygonFeat             = (IFeature)pCadastralPolygonFeature.Row;
                IPolygon          pParcelPolygon           = (IPolygon)pPolygonFeat.ShapeCopy;

                IGSForwardStar pFwdStar = ParcelLineFx.CreateForwardStar(pEnumGSLines);
                //forward star is created for this parcel, now ready to find misclose for the parcel
                List <int>       LineIdsList               = new List <int>();
                List <IVector3D> TraverseCourses           = new List <IVector3D>();
                List <int>       FabricPointIDList         = new List <int>();
                List <double>    RadiusList                = new List <double>();
                List <bool>      IsMajorList               = new List <bool>();
                List <bool>      IsRunningCounterClockwise = new List <bool>();

                bool bPass = false;
                if (!bFabricIsInGCS)
                {
                    bPass = Utils.GetParcelTraverseEx(ref pFwdStar, iIsMajorFldIdx, iFromPtID, dMetersPerUnit,
                                                      ref LineIdsList, ref TraverseCourses, ref FabricPointIDList, ref RadiusList, ref IsMajorList, ref IsRunningCounterClockwise,
                                                      pParcelPolygon, 0, -1, -1, false);
                }
                else
                {
                    bPass = Utils.GetParcelTraverseEx(ref pFwdStar, iIsMajorFldIdx, iFromPtID, dMetersPerUnit * dMetersPerUnit,
                                                      ref LineIdsList, ref TraverseCourses, ref FabricPointIDList, ref RadiusList, ref IsMajorList, ref IsRunningCounterClockwise,
                                                      pParcelPolygon, 0, -1, -1, false);
                }
                //List<double> SysValList = new List<double>();
                IVector3D MiscloseVector = null;
                IPoint[]  FabricPoints   = new IPoint[FabricPointIDList.Count];//from control

                int f = 0;
                foreach (int j in FabricPointIDList)
                {
                    FabricPoints[f++] = dict_PointID2Point[j];
                }

                double dRatio = 10000;
                double dArea  = 0;
                double dGroundToGridFactor = pGSParcel.Scale;
                bool   bHasCircularArcs    = false;
                f = FabricPointIDList.Count - 1;
                IPoint[] AdjustedTraversePoints = Utils.BowditchAdjustEx(TraverseCourses, FabricPoints[f], FabricPoints[f],
                                                                         RadiusList, IsMajorList, IsRunningCounterClockwise, out MiscloseVector, out dRatio, out dArea,
                                                                         out bHasCircularArcs);

                if (MiscloseVector == null)
                {//skip if vector closure failed
                    pGSParcel = pEnumGSParcels.Next();
                    continue;
                }
                //now compare the Geometry polygon area with the computed area to see if we need to use parametric computed area
                // there needs to be at least one circular arc to warrant using this approach.
                IArea  pGeomArea           = pPolygonFeat.ShapeCopy as IArea;
                double dGroundArea         = pGeomArea.Area / (dGroundToGridFactor * dGroundToGridFactor);
                double dAreaPercentageDiff = Math.Abs(dGroundArea - Math.Abs(dArea)) / dGroundArea;

                if (dAreaPercentageDiff > 0.075 && bHasCircularArcs && dRatio > 250)
                {
                    dArea = dGroundArea;
                }
                else if (bHasCircularArcs && dArea < 0 && dRatio > 7500) //if dArea is negative then lines are running counter-clockwise
                {
                    dArea = Math.Abs(dArea);
                }
                else if (bHasCircularArcs && dArea < 0 && pParcelPolygon.ExteriorRingCount > 1)
                {
                    dArea = pGeomArea.Area;
                }

                dArea *= (dMetersPerUnit * dMetersPerUnit); //convert to square meters first
                dArea /= SquareMetersPerUnitFactor;         //convert to the given unit equivalent

                string sFormattedArea = Math.Round(dArea, DecimalPlaces).ToString() + Suffix;
                dict_ParcelSelection2CalculatedArea.Add(pGSParcel.DatabaseId, sFormattedArea);

                pGSParcel = pEnumGSParcels.Next();

                //if (bShowProgressor)
                //{
                //  if (pStepProgressor.Position < pStepProgressor.MaxRange)
                //    pStepProgressor.Step();
                //}
            }
        }