コード例 #1
0
        private bool UpdateCircularArcValues(IFeatureClass LineTable, IQueryFilter QueryFilter, bool Unversioned, IDictionary<int, InferredCurve> CurveLookup, myProgessor progressor, Dictionary<int, int> MaxSequenceCache)
        {
            IFeature pLineFeat = null;
            IFeatureBuffer buffer = null;
            IFeatureCursor pLineCurs = null;
            IFeatureCursor pRadialCur = null;
            IFeatureCursor maxCursor = null;
            IDataStatistics dataStatistics = null;

            IGeometryFactory3 geometryFactory = new GeometryEnvironmentClass();
            IGeometry geometry = new PolylineClass();
            geometryFactory.CreateEmptyGeometryByType(LineTable.ShapeType, out geometry);

            IGeometryDef geometryDef = LineTable.Fields.get_Field(LineTable.FindField(LineTable.ShapeFieldName)).GeometryDef;

            if (geometryDef.HasZ)
            {
                IZAware zAware = (IZAware)(geometry);
                zAware.ZAware = true;
            }
            if (geometryDef.HasM)
            {
                IMAware mAware = (IMAware)(geometry);
                mAware.MAware = true;
            }


            try
            {
                CurveByInferenceSettings.FieldPositions positions = new CurveByInferenceSettings.FieldPositions((ITable)LineTable);

                buffer = LineTable.CreateFeatureBuffer();
                pLineCurs = LineTable.Update(QueryFilter, false);
                pRadialCur = LineTable.Insert(false);

                while ((pLineFeat = pLineCurs.NextFeature()) != null)
                {
                    //loop through all of the given lines, and update centerpoint ids, radius, and arc length values
                    if (!progressor.Continue())
                        return false;
                    progressor.Step();

                    InferredCurve curveInfo = CurveLookup[pLineFeat.OID];

                    pLineFeat.set_Value(positions.RadiusFieldIdx, curveInfo.InferredRadius);
                    pLineFeat.set_Value(positions.CenterpointIDFieldIdx, curveInfo.InferredCenterpointID);
                    IFeature feature = pLineFeat as IFeature;
                    double length = 0;
                    if (feature != null)
                    {
                        IPolyline polyline = feature.ShapeCopy as IPolyline;
                        if (polyline != null)
                        {
                            length = ((IProximityOperator)polyline.FromPoint).ReturnDistance(polyline.ToPoint);
                            pLineFeat.set_Value(positions.ArcLengthFieldIdx, length);
                            Marshal.ReleaseComObject(polyline);
                        }
                    }

                    if (Unversioned)
                        pLineCurs.UpdateFeature(pLineFeat);
                    else
                        pLineFeat.Store();

                    //fine the max sequence value 
                    int maxSequence = -1;
                    if (MaxSequenceCache.ContainsKey(curveInfo.Parcel))
                    {
                        maxSequence = MaxSequenceCache[curveInfo.Parcel];
                    }
                    else
                    {
                        maxCursor = LineTable.Search(new QueryFilter() {
                            SubFields = String.Format("{0}, {1}, {2}", LineTable.OIDFieldName, CurveByInferenceSettings.Instance.SequenceFieldName, CurveByInferenceSettings.Instance.ParcelIDFieldName),
                            WhereClause = String.Format("{0} = {1}", CurveByInferenceSettings.Instance.ParcelIDFieldName, curveInfo.Parcel) }, true);

                        int seqenceIdx = maxCursor.Fields.FindField(CurveByInferenceSettings.Instance.SequenceFieldName);

                        IRow maxFeat = null;
                        while ((maxFeat = maxCursor.NextFeature()) != null)
                        {
                            maxSequence = Math.Max((int)maxFeat.get_Value(seqenceIdx), maxSequence);
                            Marshal.ReleaseComObject(maxFeat);
                        }
                        Marshal.ReleaseComObject(maxCursor);

                        MaxSequenceCache.Add(curveInfo.Parcel, maxSequence);
                        dataStatistics = null;
                        maxCursor = null;                        
                    }
                    if (maxSequence <= 0)
                        throw new Exception("Failed to find max sequence value");

                    //the chord bearing
                    double featureBearing = (double)pLineFeat.get_Value(positions.BearingFieldIdx);

                    //half the delta of the proposed curve would be:
                    double halfdelta = toDegrees(Math.Asin(length / 2 / curveInfo.InferredRadius.Value));

                    //perpendicular to the chord
                    double perpendicular = (curveInfo.InferredRadius.Value > 0) ? featureBearing + 90 : featureBearing - 90;
                    if (perpendicular > 360)
                        perpendicular = perpendicular - 360;
                    else if (perpendicular < 0)
                        perpendicular = perpendicular + 360;

                    for (int i = 0; i < 2; i++)
                    {
                        buffer.set_Value(positions.ParcelIDFieldIdx, curveInfo.Parcel);
                        buffer.set_Value(positions.ToPointFieldIdx, curveInfo.InferredCenterpointID);
                        buffer.set_Value(positions.CategoryFieldIdx, 4);
                        buffer.set_Value(positions.SequenceFieldIdx, ++maxSequence);
                        buffer.set_Value(positions.TypeFieldIdx, 0);
                        buffer.set_Value(positions.DistanceFieldIdx, curveInfo.InferredRadius);
                        buffer.set_Value(positions.HistoricalFieldIdx, 0);
                        buffer.set_Value(positions.LineParametersFieldIdx, 0);
                        buffer.set_Value(positions.DensifyTypeIdx, 0);
                        buffer.set_Value(positions.SystemStartDateFieldIdx, pLineFeat.get_Value(positions.SystemStartDateFieldIdx));
                        buffer.Shape = geometry;

                        if (i == 0) // startpoing
                        {
                            buffer.set_Value(positions.FromPointFieldIdx, pLineFeat.get_Value(positions.FromPointFieldIdx));
                            buffer.set_Value(positions.BearingFieldIdx, perpendicular + halfdelta);
                        }
                        else  //endpoint
                        {
                            buffer.set_Value(positions.FromPointFieldIdx, pLineFeat.get_Value(positions.ToPointFieldIdx));
                            buffer.set_Value(positions.BearingFieldIdx, perpendicular - halfdelta);
                        }

                        pRadialCur.InsertFeature(buffer);
                    }

                    MaxSequenceCache[curveInfo.Parcel] = maxSequence; 
                    Marshal.ReleaseComObject(pLineFeat);
                }

                return true;
            }
            catch (COMException ex)
            {
                messageBox.Show(String.Format("Problem updating circular arc: {0} ({1})", ex.Message, ex.ErrorCode));
                return false;
            }
            finally
            {
                if(pLineCurs != null) Marshal.ReleaseComObject(pLineCurs);
                if(buffer != null) Marshal.ReleaseComObject(buffer);
                if(pRadialCur != null) Marshal.ReleaseComObject(pRadialCur);

                if(dataStatistics != null) Marshal.ReleaseComObject(dataStatistics);
                if (maxCursor != null) Marshal.ReleaseComObject(maxCursor);

                if (geometry != null) Marshal.FinalReleaseComObject(geometry);
                if (geometryFactory != null) Marshal.FinalReleaseComObject(geometryFactory);
            }
        }
コード例 #2
0
        public void UpdateCurves(ICadastralFabric pCadFabric, IFeatureClass pFabricLinesFC, IEnumerable<InferredCurve> curvesToUpdate, myProgessor progressor)
        {
            IEnumerable<InferredCurve> updateCurves = (from InferredCurve c in curvesToUpdate where c.Action == UpdateAction.Update select c);

            bool bIsFileBasedGDB = false;
            bool bIsUnVersioned = false;
            bool bUseNonVersionedDelete = false;
            IWorkspace pWS = m_pEd != null ? m_pEd.EditWorkspace : ((IDataset)pFabricLinesFC).Workspace;

            if (!SetupEditEnvironment(pWS, pCadFabric, m_pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersionedDelete))
            {
                messageBox.Show("The editing environment could not be initialized");
                return;
            }

            #region Create Cadastral Job
            string sTime = "";
            if (!bIsUnVersioned && !bIsFileBasedGDB)
            {
                //see if parcel locks can be obtained on the selected parcels. First create a job.
                DateTime localNow = DateTime.Now;
                sTime = Convert.ToString(localNow);
                ICadastralJob pJob = new CadastralJob();
                pJob.Name = sTime;
                pJob.Owner = System.Windows.Forms.SystemInformation.UserName;
                pJob.Description = "Convert lines to curves";
                try
                {
                    Int32 jobId = pCadFabric.CreateJob(pJob);
                }
                catch (COMException ex)
                {
                    if (ex.ErrorCode == (int)fdoError.FDO_E_CADASTRAL_FABRIC_JOB_ALREADY_EXISTS)
                    {
                        messageBox.Show("Job named: '" + pJob.Name + "', already exists");
                    }
                    else
                    {
                        messageBox.Show(ex.Message);
                    }
                    return;
                }
            }
            #endregion

            #region Test for Edit Locks
            ICadastralFabricLocks pFabLocks = (ICadastralFabricLocks)pCadFabric;

            //only need to get locks for parcels that have lines that are to be changed

            ILongArray affectedParcels = new LongArrayClass();
            IFIDSet parcelFIDs = new FIDSet();
            foreach (int i in updateCurves.Select(w => w.Parcel).Distinct())
            {
                parcelFIDs.Add(i);
                affectedParcels.Add(i);
            }

            if (!bIsUnVersioned && !bIsFileBasedGDB)
            {
                pFabLocks.LockingJob = sTime;
                ILongArray pLocksInConflict = null;
                ILongArray pSoftLcksInConflict = null;

                if (!bIsFileBasedGDB)
                    progressor.setStepProgressorProperties(0, "Testing for edit locks on parcels...");

                try
                {
                    pFabLocks.AcquireLocks(affectedParcels, true, ref pLocksInConflict, ref pSoftLcksInConflict);
                }
                catch (COMException pCOMEx)
                {
                    if (pCOMEx.ErrorCode == (int)fdoError.FDO_E_CADASTRAL_FABRIC_JOB_LOCK_ALREADY_EXISTS ||
                        pCOMEx.ErrorCode == (int)fdoError.FDO_E_CADASTRAL_FABRIC_JOB_CURRENTLY_EDITED)
                    {
                        messageBox.Show("Edit Locks could not be acquired on all selected parcels.");
                        // since the operation is being aborted, release any locks that were acquired
                        pFabLocks.UndoLastAcquiredLocks();
                    }
                    else
                        messageBox.Show(pCOMEx.Message + Environment.NewLine + Convert.ToString(pCOMEx.ErrorCode));

                    return;
                }
            }
            #endregion

            if (m_pEd != null && m_pEd.EditState == esriEditState.esriStateEditing)
            {
                try
                {
                    m_pEd.StartOperation();
                }
                catch
                {
                    m_pEd.AbortOperation();//abort any open edit operations and try again
                    m_pEd.StartOperation();
                }
            }
            else
            {
                //this code is extecuted by the tests, only executed against a file gdb
                IWorkspaceEdit wsEdit = (IWorkspaceEdit)pWS;
                wsEdit.StartEditing(false);
                wsEdit.StartEditOperation();
            }

            if (bUseNonVersionedDelete)
            {
                if (!StartEditing(pWS, bIsUnVersioned))
                {
                    messageBox.Show("Couldn't start an edit session");
                    return;
                }
            }

            ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric;
            pSchemaEd.ReleaseReadOnlyFields((ITable)pFabricLinesFC, esriCadastralFabricTable.esriCFTLines); //release for edits

            // m_pEd.StartOperation();

            updateValues(updateCurves, progressor, pFabricLinesFC, bIsUnVersioned);

            ICadastralFabricRegeneration pRegenFabric = new CadastralFabricRegenerator();
            #region regenerator enum
            // enum esriCadastralRegeneratorSetting
            // esriCadastralRegenRegenerateGeometries         =   1
            // esriCadastralRegenRegenerateMissingRadials     =   2,
            // esriCadastralRegenRegenerateMissingPoints      =   4,
            // esriCadastralRegenRemoveOrphanPoints           =   8,
            // esriCadastralRegenRemoveInvalidLinePoints      =   16,
            // esriCadastralRegenSnapLinePoints               =   32,
            // esriCadastralRegenRepairLineSequencing         =   64,
            // esriCadastralRegenRepairPartConnectors         =   128

            // By default, the bitmask member is 0 which will only regenerate geometries.
            // (equivalent to passing in regeneratorBitmask = 1)
            #endregion

            //pRegenFabric.CadastralFabric = pCadFabric;
            //pRegenFabric.RegeneratorBitmask = 7;
            //pRegenFabric.RegenerateParcels(parcelFIDs, false, progressor.cancelTracker);

            if (m_pEd != null)
            {
                m_pEd.StopOperation("Insert missing circular arc information.");
            }
            else
            {
                //this code is extecuted by the tests, only executed against a file gdb
                IWorkspaceEdit wsEdit = (IWorkspaceEdit)pWS;
                wsEdit.StartEditOperation();
                wsEdit.StopEditing(false);
            }
        }
コード例 #3
0
        private void updateValues(IEnumerable<InferredCurve> updateCurves, myProgessor progressor, IFeatureClass pFabricLinesFC, bool bIsUnVersioned)
        {
            Dictionary<int, int> MaxSequenceCache = new Dictionary<int, int>();
            IQueryFilter m_pQF = new QueryFilter();

            //Slice the list into sets that will fit into an in list
            int curveCount = updateCurves.Count();
            progressor.setStepProgressorProperties(curveCount, "Updating geometries");
            for (var i = 0; i < curveCount; i += 995)
            {
                Dictionary<int, InferredCurve> curvesSlice = updateCurves.Skip(i).Take(995).ToDictionary(w => w.ObjectID);
                if (!progressor.Continue())
                    return;
                m_pQF.WhereClause = String.Format("{0} IN ({1})", pFabricLinesFC.OIDFieldName, String.Join(",", (from oid in curvesSlice.Keys select oid.ToString()).ToArray()));
                UpdateCircularArcValues(pFabricLinesFC, m_pQF, bIsUnVersioned, curvesSlice, progressor, MaxSequenceCache);
            }
        }
コード例 #4
0
        public void FindCurves(String Name, IFeatureClass pFabricLinesFC, ISelectionSet selSet, string whereClause, myProgessor progressor)
        {
            CurveByInferenceSettings.FieldPositions positions = new CurveByInferenceSettings.FieldPositions((ITable)pFabricLinesFC);
            if (!positions.ValidCheckFields)
            {
                messageBox.Show(string.Format("One or more of the following fields are missing ({0}, {1})", CurveByInferenceSettings.Instance.RadiusFieldName, CurveByInferenceSettings.Instance.CenterpointIDFieldName));
            }


            IQueryFilter qFilter = new QueryFilter();
            if (String.IsNullOrEmpty(whereClause))
            {
                qFilter.WhereClause = "CenterPointID is null and Radius is null";
            }
            else
            {
                qFilter.WhereClause = string.Concat(whereClause, " and CenterPointID is null and Radius is null");
            }

            IFeatureCursor cursor = null;
            if (selSet != null)
            {
                ICursor c;
                ISelectionSet subset = selSet.Select(qFilter, esriSelectionType.esriSelectionTypeIDSet, esriSelectionOption.esriSelectionOptionNormal, null);
                progressor.setStepProgressorProperties(subset.Count, String.Format("Layer {0}: Evaluating Selected Features", Name));

                subset.Search(null, true, out c);
                cursor = (IFeatureCursor)c;
            }
            else
            {
                progressor.setStepProgressorProperties(((ITable)pFabricLinesFC).RowCount(qFilter), String.Format("Layer {0}: Evaluating Features", Name));
                cursor = pFabricLinesFC.Search(qFilter, true);
            }

            //ISelectionSet pSelSet = pFabricLinesFC.Select(qFilter, esriSelectionType.esriSelectionTypeIDSet, esriSelectionOption.esriSelectionOptionNormal, null);
            //progressor.setStepProgressorProperties(pSelSet.Count, String.Format("Layer {0}: Evaluating Features", Name));
            //ICursor cursor = null;
            //pSelSet.Search(null, false, out cursor);


            IFeature pLineFeat = null;
            while ((pLineFeat = (IFeature)cursor.NextFeature() as IFeature) != null)
            {
                if (!progressor.Continue())
                    break;
                progressor.Step();

                if (!Curves.Any(w => w.ObjectID == pLineFeat.OID))
                {
                    IGeometry pGeom = pLineFeat.ShapeCopy;
                    ISegmentCollection pSegColl = pGeom as ISegmentCollection;
                    ISegment pSeg = null;
                    if (pSegColl != null && pSegColl.SegmentCount == 1)
                    {
                        pSeg = pSegColl.get_Segment(0);
                    }
                    else
                    {
                        if (pSegColl == null)
                            messageBox.Show(String.Format("The shape for objectid {0} could not be converted to a segement collection.", pLineFeat.OID));

                        //todo: but for now, only deals with single segment short segments
                        Marshal.ReleaseComObject(pLineFeat);
                        continue;
                    }

                    //if the geometry is a circular arc and the attributes reflect that, move on to the next feature
                    //obsolete, filter is pushed to database
                    //if (pSeg is ICircularArc)
                    //{
                    //    object dVal1 = pLineFeat.get_Value(idxRADIUS);
                    //    object dVal2 = pLineFeat.get_Value(idxCENTERPTID);
                    //    if (!(dVal1 is DBNull) && !(dVal2 is DBNull))
                    //    {
                    //        Marshal.ReleaseComObject(pLineFeat);
                    //        continue;
                    //    }
                    //}

                    //query near lines
                    List<RelatedLine> tangentLines;
                    List<RelatedCurve> sCurveInfoFromNeighbours = GetTangentCurveMatchFeatures(pFabricLinesFC, pLineFeat, (IPolycurve)pGeom, "", positions.RadiusFieldIdx, positions.CenterpointIDFieldIdx, pSeg.Length, out tangentLines);
                                
                    if(sCurveInfoFromNeighbours.Count > 0)
                    //if (HasTangentCurveMatchFeatures(pFabricLinesFC, (IPolycurve)pGeom, "", pSeg.Length, out iFoundTangent, ref sCurveInfoFromNeighbours))
                    {
                        InferredCurve curve = new InferredCurve(pLineFeat.OID, Name, sCurveInfoFromNeighbours);
                        IPolyline polyLine = (IPolyline)pGeom;
                        curve.FromPoint = polyLine.FromPoint;
                        curve.ToPoint = polyLine.ToPoint;
                     
                        //evaluated the position of any tangent lines, and determines if there is a junction situation.  If there is, it will:
                        //  Retrun true with curve.Accepted set
                        //  Return true without curve.Accepted set
                        //  Return false (this indicates that the junction has been used to verify that this segemnt should not have a curve)
                        if (evaluateJunctions(curve, tangentLines))
                        {
                            //junction couldn't eliminate the curve, so return it
                            Curves.Add(curve);
                            curve.PropertyChanged += new PropertyChangedEventHandler(curve_PropertyChanged);
                            curve.Parcel = (int)pLineFeat.get_Value(positions.ParcelIDFieldIdx);

                            if (!curve.HasValue) //if the junction logic didn't set the curve
                            {
                                //check to see if one of the tange curves overlap
                                if (curve.TangentCurves[0].Orientation == RelativeOrientation.Same || curve.TangentCurves[0].Orientation == RelativeOrientation.Reverse)
                                {
                                    curve.InferredRadius = curve.TangentCurves[0].Radius;
                                    curve.InferredCenterpointID = curve.TangentCurves[0].CenterpointID;
                                }
                                else
                                {
                                    //check radial and tangent lines (both need a single centerpoint and radius tangent curve (check done in function)
                                    RefineToBestRadiusAndCenterPoint(curve, pFabricLinesFC, pLineFeat, (IPolycurve)pGeom, tangentLines);
                                }
                            }

                            //if the curve has an accepted curve (ie, it's a candidate to be changed), record the parcel id
                            //if (curve.Accepted != null)
                            //    affectedParcels.Add();

                            //cache the parcel so it can be looked up later
                        }
                    }
                }
                Marshal.ReleaseComObject(pLineFeat);
            }
            Marshal.ReleaseComObject(cursor);

            Total = Curves.Count;
            Inferred = Curves.Count(w => w.Action == UpdateAction.Update);
        }