protected override void OnClick() { bool bShowProgressor = false; IStepProgressor pStepProgressor = null; //Create a CancelTracker. ITrackCancel pTrackCancel = null; IProgressDialogFactory pProgressorDialogFact; IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); //first get the selected parcel features UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); //check if there is a Manual Mode "modify" job active =========== ICadastralPacketManager pCadPacMan = (ICadastralPacketManager)pCadExtMan; if (pCadPacMan.PacketOpen) { MessageBox.Show("The Delete Control command cannot be used when there is an open job.\r\nPlease finish or discard the open job, and try again.", "Delete Selected Control"); return; } IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); IActiveView pActiveView = ArcMap.Document.ActiveView; IMap pMap = pActiveView.FocusMap; ICadastralFabric pCadFabric = null; clsFabricUtils FabricUTILS = new clsFabricUtils(); IProgressDialog2 pProgressorDialog = null; //if we're in an edit session then grab the target fabric if (pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } if (pCadFabric == null) {//find the first fabric in the map if (!FabricUTILS.GetFabricFromMap(pMap, out pCadFabric)) { MessageBox.Show ("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } IArray CFControlLayers = new ArrayClass(); if (!(FabricUTILS.GetControlLayersFromFabric(pMap, pCadFabric, out CFControlLayers))) { return; //no fabric sublayers available for the targeted fabric } bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersionedDelete = false; IWorkspace pWS = null; ITable pPointsTable = null; ITable pControlTable = null; try { if (pEd.EditState == esriEditState.esriStateEditing) { try { pEd.StartOperation(); } catch { pEd.AbortOperation();//abort any open edit operations and try again pEd.StartOperation(); } } IFeatureLayer pFL = (IFeatureLayer)CFControlLayers.get_Element(0); IDataset pDS = (IDataset)pFL.FeatureClass; pWS = pDS.Workspace; if (!FabricUTILS.SetupEditEnvironment(pWS, pCadFabric, pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersionedDelete)) { return; } //loop through each control layer and //Get the selection of control int iCnt = 0; int iTotalSelectionCount = 0; for (; iCnt < CFControlLayers.Count; iCnt++) { pFL = (IFeatureLayer)CFControlLayers.get_Element(iCnt); IFeatureSelection pFeatSel = (IFeatureSelection)pFL; ISelectionSet2 pSelSet = (ISelectionSet2)pFeatSel.SelectionSet; iTotalSelectionCount += pSelSet.Count; } if (iTotalSelectionCount == 0) { MessageBox.Show("Please select some fabric control points and try again.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Information); if (bUseNonVersionedDelete) { pCadEd.CadastralFabricLayer = null; CFControlLayers = null; } return; } bShowProgressor = (iTotalSelectionCount > 10); if (bShowProgressor) { pProgressorDialogFact = new ProgressDialogFactoryClass(); pTrackCancel = new CancelTrackerClass(); pStepProgressor = pProgressorDialogFact.Create(pTrackCancel, ArcMap.Application.hWnd); pProgressorDialog = (IProgressDialog2)pStepProgressor; pStepProgressor.MinRange = 1; pStepProgressor.MaxRange = iTotalSelectionCount * 2; //(runs through selection twice) pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; } //loop through each control layer and //delete from its selection m_pQF = new QueryFilterClass(); iCnt = 0; for (; iCnt < CFControlLayers.Count; iCnt++) { pFL = (IFeatureLayer)CFControlLayers.get_Element(iCnt); IFeatureSelection pFeatSel = (IFeatureSelection)pFL; ISelectionSet2 pSelSet = (ISelectionSet2)pFeatSel.SelectionSet; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; string sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); string sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); if (bShowProgressor) { pProgressorDialog.ShowDialog(); pStepProgressor.Message = "Collecting Control point data..."; } //Add the OIDs of all the selected control points into a new feature IDSet string[] sOIDListPoints = { "(" }; int tokenLimit = 995; //int tokenLimit = 5; //temp for testing bool bCont = true; int j = 0; int iCounter = 0; m_pFIDSetControl = new FIDSetClass(); ICursor pCursor = null; pSelSet.Search(null, false, out pCursor);//code deletes all selected control points IFeatureCursor pControlFeatCurs = (IFeatureCursor)pCursor; IFeature pControlFeat = pControlFeatCurs.NextFeature(); int iPointID = pControlFeatCurs.FindField("POINTID"); while (pControlFeat != null) { //Check if the cancel button was pressed. If so, stop process if (bShowProgressor) { bCont = pTrackCancel.Continue(); if (!bCont) { break; } } bool bExists = false; m_pFIDSetControl.Find(pControlFeat.OID, out bExists); if (!bExists) { m_pFIDSetControl.Add(pControlFeat.OID); object obj = pControlFeat.get_Value(iPointID); if (iCounter <= tokenLimit) { //if the PointID is not null add it to a query string as well if (obj != DBNull.Value) { sOIDListPoints[j] += Convert.ToString(obj) + ","; } iCounter++; } else {//maximum tokens reached //set up the next OIDList sOIDListPoints[j] = sOIDListPoints[j].Trim(); iCounter = 0; j++; FabricUTILS.RedimPreserveString(ref sOIDListPoints, 1); sOIDListPoints[j] = "("; if (obj != DBNull.Value) { sOIDListPoints[j] += Convert.ToString(obj) + ","; } } } Marshal.ReleaseComObject(pControlFeat); //garbage collection pControlFeat = pControlFeatCurs.NextFeature(); if (bShowProgressor) { if (pStepProgressor.Position < pStepProgressor.MaxRange) { pStepProgressor.Step(); } } } Marshal.ReleaseComObject(pCursor); //garbage collection if (!bCont) { AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } if (bUseNonVersionedDelete) { if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) { if (bUseNonVersionedDelete) { pCadEd.CadastralFabricLayer = null; } return; } } //first delete all the control point records if (bShowProgressor) { pStepProgressor.Message = "Deleting control points..."; } bool bSuccess = true; pPointsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); pControlTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTControl); if (!bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsByFIDSet(pControlTable, m_pFIDSetControl, pStepProgressor, pTrackCancel); } if (bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pControlTable, m_pFIDSetControl, pStepProgressor, pTrackCancel); } if (!bSuccess) { AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } //next need to use an in clause to update the points, ... ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; //...for each item in the sOIDListPoints array foreach (string inClause in sOIDListPoints) { string sClause = inClause.Trim().TrimEnd(','); if (sClause.EndsWith("(")) { continue; } if (sClause.Length < 3) { continue; } pSchemaEd.ReleaseReadOnlyFields(pPointsTable, esriCadastralFabricTable.esriCFTPoints); m_pQF.WhereClause = (sPref + pPointsTable.OIDFieldName + sSuff).Trim() + " IN " + sClause + ")"; if (!FabricUTILS.ResetPointAssociations(pPointsTable, m_pQF, bIsUnVersioned)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); return; } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); } } if (bUseNonVersionedDelete) { FabricUTILS.StopEditing(pWS); } if (pEd.EditState == esriEditState.esriStateEditing) { pEd.StopOperation("Delete Control Points"); } } catch (Exception ex) { MessageBox.Show(ex.Message); return; } finally { RefreshMap(pActiveView, CFControlLayers); //update the TOC IMxDocument mxDocument = (ESRI.ArcGIS.ArcMapUI.IMxDocument)(ArcMap.Application.Document); for (int i = 0; i < mxDocument.ContentsViewCount; i++) { IContentsView pCV = (IContentsView)mxDocument.get_ContentsView(i); pCV.Refresh(null); } if (pProgressorDialog != null) { pProgressorDialog.HideDialog(); } if (bUseNonVersionedDelete) { pCadEd.CadastralFabricLayer = null; CFControlLayers = null; } if (pMouseCursor != null) { pMouseCursor.SetCursor(0); } } }
protected override void OnClick() { m_pApp = (IApplication)ArcMap.Application; if (m_pApp == null) { //if the app is null then could be running from ArcCatalog m_pApp = (IApplication)ArcCatalog.Application; } if (m_pApp == null) { MessageBox.Show("Could not access the application.", "No Application found"); return; } IGxApplication pGXApp = (IGxApplication)m_pApp; stdole.IUnknown pUnk = null; try { pUnk = (stdole.IUnknown)pGXApp.SelectedObject.InternalObjectName.Open(); } catch (COMException ex) { if (ex.ErrorCode == (int)fdoError.FDO_E_DATASET_TYPE_NOT_SUPPORTED_IN_RELEASE || ex.ErrorCode == -2147220944) { MessageBox.Show("The dataset is not supported in this release.", "Could not open the dataset"); } else { MessageBox.Show(ex.ErrorCode.ToString(), "Could not open the dataset"); } return; } if (pUnk is ICadastralFabric) { m_pCadaFab = (ICadastralFabric)pUnk; } else { MessageBox.Show("Please select a parcel fabric and try again.", "Not a parcel fabric"); return; } IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); clsFabricUtils FabricUTILS = new clsFabricUtils(); IProgressDialog2 pProgressorDialog = null; ITable pTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); IDataset pDS = (IDataset)pTable; IWorkspace pWS = pDS.Workspace; bool bIsFileBasedGDB = true; bool bIsUnVersioned = true; FabricUTILS.GetFabricPlatform(pWS, m_pCadaFab, out bIsFileBasedGDB, out bIsUnVersioned); if (!bIsFileBasedGDB && !bIsUnVersioned) { MessageBox.Show("Truncate operates on non-versioned fabrics." + Environment.NewLine + "Please unversion the fabric and try again.", "Tables are versioned"); return; } //Do a Start and Stop editing to make sure truncate it not running within an edit session if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) {//if start editing fails then bail Cleanup(pProgressorDialog, pMouseCursor); return; } FabricUTILS.StopEditing(pWS); dlgTruncate pTruncateDialog = new dlgTruncate(); IArray TableArray = new ESRI.ArcGIS.esriSystem.ArrayClass(); pTruncateDialog.TheFabric = m_pCadaFab; pTruncateDialog.TheTableArray = TableArray; //Display the dialog DialogResult pDialogResult = pTruncateDialog.ShowDialog(); if (pDialogResult != DialogResult.OK) { pTruncateDialog = null; if (TableArray != null) { TableArray.RemoveAll(); } return; } m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, m_pApp.hWnd); pProgressorDialog = (IProgressDialog2)m_pStepProgressor; m_pStepProgressor.MinRange = 0; m_pStepProgressor.MaxRange = pTruncateDialog.DropRowCount; m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; bool bSuccess = false; int iControlRowCount = 0; //look in registry to get flag on whether to run truncate on standard tables, or to delete by row. string sDesktopVers = FabricUTILS.GetDesktopVersionFromRegistry(); if (sDesktopVers.Trim() == "") { sDesktopVers = "Desktop10.0"; } else { sDesktopVers = "Desktop" + sDesktopVers; } bool bDeleteTablesByRowInsteadOfTruncate = false; string sValues = FabricUTILS.ReadFromRegistry(RegistryHive.CurrentUser, "Software\\ESRI\\" + sDesktopVers + "\\ArcMap\\Cadastral", "AddIn.DeleteFabricRecords_Truncate"); if (sValues.Trim().ToLower() == "deletebytruncateonstandardtables" || bIsFileBasedGDB) { bDeleteTablesByRowInsteadOfTruncate = false; } if (sValues.Trim().ToLower() == "deletebyrowonstandardtables") { bDeleteTablesByRowInsteadOfTruncate = true; } if (pTruncateDialog.TruncateControl && !pTruncateDialog.TruncateParcelsLinesPoints) { // get the control point count ITable pControlTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTControl); iControlRowCount = pControlTable.RowCount(null); } try { //Work on the table array pTable = null; m_pFIDSet = new FIDSetClass(); for (int i = 0; i <= TableArray.Count - 1; i++) { //if (TableArray.get_Element(i) is ITable) ...redundant { pTable = (ITable)TableArray.get_Element(i); IDataset pDataSet = (IDataset)pTable; //Following code uses the truncate method //*** if (pTable is IFeatureClass || !bDeleteTablesByRowInsteadOfTruncate) { ITableWrite2 pTableWr = (ITableWrite2)pTable; m_pStepProgressor.Message = "Deleting all rows in " + pDataSet.Name; int RowCnt = pTable.RowCount(null); pTableWr.Truncate(); m_pStepProgressor.MaxRange -= RowCnt; //now re-insert the default plan string sName = pDataSet.Name.ToUpper().Trim(); if (sName.EndsWith("_PLANS")) { int idxPlanName = pTable.FindField("Name"); int idxPlanDescription = pTable.FindField("Description"); int idxPlanAngleUnits = pTable.FindField("AngleUnits"); int idxPlanAreaUnits = pTable.FindField("AreaUnits"); int idxPlanDistanceUnits = pTable.FindField("DistanceUnits"); int idxPlanDirectionFormat = pTable.FindField("DirectionFormat"); int idxPlanLineParameters = pTable.FindField("LineParameters"); int idxPlanCombinedGridFactor = pTable.FindField("CombinedGridFactor"); int idxPlanTrueMidBrg = pTable.FindField("TrueMidBrg"); int idxPlanAccuracy = pTable.FindField("Accuracy"); int idxPlanInternalAngles = pTable.FindField("InternalAngles"); ICursor pCur = pTableWr.InsertRows(false); IRowBuffer pRowBuff = pTable.CreateRowBuffer(); double dOneMeterEquals = FabricUTILS.ConvertMetersToFabricUnits(1, m_pCadaFab); bool bIsMetric = (dOneMeterEquals == 1); //write category 1 pRowBuff.set_Value(idxPlanName, "<map>"); pRowBuff.set_Value(idxPlanDescription, "System default plan"); pRowBuff.set_Value(idxPlanAngleUnits, 3); // if (bIsMetric) { pRowBuff.set_Value(idxPlanAreaUnits, 5); pRowBuff.set_Value(idxPlanDistanceUnits, 9001); pRowBuff.set_Value(idxPlanDirectionFormat, 1); } else { pRowBuff.set_Value(idxPlanAreaUnits, 4); pRowBuff.set_Value(idxPlanDistanceUnits, 9003); pRowBuff.set_Value(idxPlanDirectionFormat, 4); } pRowBuff.set_Value(idxPlanLineParameters, 4); pRowBuff.set_Value(idxPlanCombinedGridFactor, 1); //pRowBuff.set_Value(idxPlanTrueMidBrg, 1); pRowBuff.set_Value(idxPlanAccuracy, 4); pRowBuff.set_Value(idxPlanInternalAngles, 0); pCur.InsertRow(pRowBuff); pCur.Flush(); if (pRowBuff != null) { Marshal.ReleaseComObject(pRowBuff); } if (pCur != null) { Marshal.ReleaseComObject(pCur); } } } } } } catch (COMException ex) { MessageBox.Show(ex.Message + ": " + Convert.ToString(ex.ErrorCode)); Cleanup(pProgressorDialog, pMouseCursor); return; } //do the loop again, this time within the edit transaction and using the delete function for the chosen tables try { //Start an Edit Transaction if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) {//if start editing fails then bail Cleanup(pProgressorDialog, pMouseCursor); return; } for (int i = 0; i <= TableArray.Count - 1; i++) { //if (TableArray.get_Element(i) is ITable) { pTable = (ITable)TableArray.get_Element(i); IDataset pDataSet = (IDataset)pTable; if (pTable is IFeatureClass || !bDeleteTablesByRowInsteadOfTruncate) { } else { //The following code is in place to workaround a limitation of truncate for fabric classes //without a shapefield. It uses an alternative method for removing all the rows //with the Delete function. //General note: This method could be used exclusively, without needing the truncate method. //One advantage is that it allows the option to cancel the whole //operation using the cancel tracker. Truncate is faster, but is problematic if //the truncate fails, and leaves a partially deleted fabric. For example, if the //lines table is deleted but the points table truncate fails, the fabric would be in a //corrupt state. //**** m_pFIDSet.SetEmpty(); string sName = pDataSet.Name.ToUpper().Trim(); m_pStepProgressor.Message = "Loading rows from " + pDataSet.Name; if (sName.EndsWith("_PLANS")) {//for Plans table make sure the default plan is not deleted IQueryFilter pQF = new QueryFilterClass(); string sPref; string sSuff; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); string sFieldName = "NAME"; //pQF.WhereClause = sPref + sFieldName + sSuff + " <> '<map>'"; pQF.WhereClause = sFieldName + " <> '<map>'"; if (!BuildFIDSetFromTable(pTable, pQF, ref m_pFIDSet)) { FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); return; } } else { if (!BuildFIDSetFromTable(pTable, null, ref m_pFIDSet)) { FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); return; } } if (m_pFIDSet.Count() == 0) { continue; } m_pStepProgressor.Message = "Deleting all rows in " + pDataSet.Name; bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pTable, m_pFIDSet, m_pStepProgressor, m_pTrackCancel); if (!bSuccess) { FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); return; } } } } //now need to Fix control-to-point associations if one table was truncated //and the other was not if (pTruncateDialog.TruncateControl && !pTruncateDialog.TruncateParcelsLinesPoints) { IQueryFilter pQF = new QueryFilterClass(); string sPref; string sSuff; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); ITable PointTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); m_pStepProgressor.Message = "Resetting control associations on points...please wait."; int idxFld = PointTable.FindField("NAME"); string sFieldName = PointTable.Fields.get_Field(idxFld).Name; //NAME IS NOT NULL AND (NAME <>'' OR NAME <>' ') //pQF.WhereClause = sPref + sFieldName + sSuff + " IS NOT NULL AND (" + // sPref + sFieldName + sSuff + "<>'' OR " + sPref + sFieldName + sSuff + " <>' ')"; //pQF.WhereClause = sFieldName + " IS NOT NULL AND (" + sFieldName + "<>'' OR " + sFieldName + " <>' ')"; pQF.WhereClause = sFieldName + " IS NOT NULL AND " + sFieldName + " > ''"; //changed 1/14/2016 ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)m_pCadaFab; pSchemaEd.ReleaseReadOnlyFields(PointTable, esriCadastralFabricTable.esriCFTPoints); m_pStepProgressor.MinRange = 0; m_pStepProgressor.MaxRange = iControlRowCount; if (!ResetPointAssociations(PointTable, pQF, true, m_pStepProgressor, m_pTrackCancel)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); return; } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); } else if (pTruncateDialog.TruncateParcelsLinesPoints && !pTruncateDialog.TruncateControl) { IQueryFilter pQF = new QueryFilterClass(); string sPref; string sSuff; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); //POINTID >=0 AND POINTID IS NOT NULL m_pStepProgressor.Message = "Resetting associations on control points...please wait."; ITable ControlTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTControl); int idxFld = ControlTable.FindField("POINTID"); string sFieldName = ControlTable.Fields.get_Field(idxFld).Name; //pQF.WhereClause = sPref + sFieldName + sSuff + " IS NOT NULL AND " + // sPref + sFieldName + sSuff + " >=0"; pQF.WhereClause = sFieldName + " IS NOT NULL AND " + sFieldName + " >=0"; ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)m_pCadaFab; pSchemaEd.ReleaseReadOnlyFields(ControlTable, esriCadastralFabricTable.esriCFTControl); if (!FabricUTILS.ResetControlAssociations(ControlTable, null, true)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl); FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); return; } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl); } //now need to re-assign default accuracy table values, if the option was checked if (pTruncateDialog.ResetAccuracyTableDefaults) { double dCat1 = FabricUTILS.ConvertMetersToFabricUnits(0.001, m_pCadaFab); double dCat2 = FabricUTILS.ConvertMetersToFabricUnits(0.01, m_pCadaFab); double dCat3 = FabricUTILS.ConvertMetersToFabricUnits(0.02, m_pCadaFab); double dCat4 = FabricUTILS.ConvertMetersToFabricUnits(0.05, m_pCadaFab); double dCat5 = FabricUTILS.ConvertMetersToFabricUnits(0.2, m_pCadaFab); double dCat6 = FabricUTILS.ConvertMetersToFabricUnits(1, m_pCadaFab); double dCat7 = FabricUTILS.ConvertMetersToFabricUnits(10, m_pCadaFab); ITable pAccTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTAccuracy); int idxBrgSD = pAccTable.FindField("BrgSD"); int idxDistSD = pAccTable.FindField("DistSD"); int idxPPM = pAccTable.FindField("PPM"); int idxCategory = pAccTable.FindField("Category"); int idxDescription = pAccTable.FindField("Description"); ITableWrite2 pTableWr = (ITableWrite2)pAccTable; ICursor pCur = pTableWr.InsertRows(false); IRowBuffer pRowBuff = pAccTable.CreateRowBuffer(); //write category 1 pRowBuff.set_Value(idxCategory, 1); pRowBuff.set_Value(idxBrgSD, 5); pRowBuff.set_Value(idxDistSD, dCat1); pRowBuff.set_Value(idxPPM, 5); pRowBuff.set_Value(idxDescription, "1 - Highest"); pCur.InsertRow(pRowBuff); //write category 2 pRowBuff.set_Value(idxCategory, 2); pRowBuff.set_Value(idxBrgSD, 30); pRowBuff.set_Value(idxDistSD, dCat2); pRowBuff.set_Value(idxPPM, 25); pRowBuff.set_Value(idxDescription, "2 - After 1980"); pCur.InsertRow(pRowBuff); //write category 3 pRowBuff.set_Value(idxCategory, 3); pRowBuff.set_Value(idxBrgSD, 60); pRowBuff.set_Value(idxDistSD, dCat3); pRowBuff.set_Value(idxPPM, 50); pRowBuff.set_Value(idxDescription, "3 - 1908 to 1980"); pCur.InsertRow(pRowBuff); //write category 4 pRowBuff.set_Value(idxCategory, 4); pRowBuff.set_Value(idxBrgSD, 120); pRowBuff.set_Value(idxDistSD, dCat4); pRowBuff.set_Value(idxPPM, 125); pRowBuff.set_Value(idxDescription, "4 - 1881 to 1907"); pCur.InsertRow(pRowBuff); //write category 5 pRowBuff.set_Value(idxCategory, 5); pRowBuff.set_Value(idxBrgSD, 300); pRowBuff.set_Value(idxDistSD, dCat5); pRowBuff.set_Value(idxPPM, 125); pRowBuff.set_Value(idxDescription, "5 - Before 1881"); pCur.InsertRow(pRowBuff); //write category 6 pRowBuff.set_Value(idxCategory, 6); pRowBuff.set_Value(idxBrgSD, 3600); pRowBuff.set_Value(idxDistSD, dCat6); pRowBuff.set_Value(idxPPM, 1000); pRowBuff.set_Value(idxDescription, "6 - 1800"); pCur.InsertRow(pRowBuff); //write category 7 pRowBuff.set_Value(idxCategory, 7); pRowBuff.set_Value(idxBrgSD, 6000); pRowBuff.set_Value(idxDistSD, dCat7); pRowBuff.set_Value(idxPPM, 5000); pRowBuff.set_Value(idxDescription, "7 - Lowest"); pCur.InsertRow(pRowBuff); pCur.Flush(); if (pRowBuff != null) { Marshal.ReleaseComObject(pRowBuff); } if (pCur != null) { Marshal.ReleaseComObject(pCur); } } //now need to cleanup the IDSequence table if ALL the tables were truncated if (pTruncateDialog.TruncateControl && pTruncateDialog.TruncateParcelsLinesPoints && pTruncateDialog.TruncateJobs && pTruncateDialog.TruncateAdjustments) { IWorkspace2 pWS2 = (IWorkspace2)pWS; IDataset TheFabricDS = (IDataset)m_pCadaFab; string sFabricName = TheFabricDS.Name; string sName = sFabricName + "_IDSequencer"; bool bExists = pWS2.get_NameExists(esriDatasetType.esriDTTable, sName); IFeatureWorkspace pFWS = (IFeatureWorkspace)pWS; ITable pSequencerTable; if (bExists) { pSequencerTable = pFWS.OpenTable(sName); IFIDSet pFIDSet = new FIDSetClass(); if (BuildFIDSetFromTable(pSequencerTable, null, ref pFIDSet)) { FabricUTILS.DeleteRowsUnversioned(pWS, pSequencerTable, pFIDSet, null, null); } } } Cleanup(pProgressorDialog, pMouseCursor); if (TableArray != null) { TableArray.RemoveAll(); } FabricUTILS.StopEditing(pWS); } catch (Exception ex) { FabricUTILS.AbortEditing(pWS); Cleanup(pProgressorDialog, pMouseCursor); MessageBox.Show(Convert.ToString(ex.Message)); } }
protected override void OnClick() { //first check that we are currently editing if (ArcMap.Editor.EditState != esriEditState.esriStateEditing) { MessageBox.Show("Please start editing and try again.", "Sample Code"); return; } //get the cadastral editor ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension"); //get the fabric line layers that belong to the target fabric. // **SAMPLE CODE NOTE** //This next function allows for more than 1 fabric lines sublayer in the map document, and uses a line layer array //However, this sample code assumes just one line fabric sub layer, and works with the first found //The function is provided for other expanded uses if needed elsewhere. IArray LineLayerArray; if (!GetFabricSubLayers(ArcMap.Document.ActiveView.FocusMap, esriCadastralFabricTable.esriCFTLines, true, pCadEd.CadastralFabric, out LineLayerArray)) { return; } // get the line selection; this code sample uses first line layer for the target fabric (first element) ISelectionSet2 LineSelection = GetSelectionFromLayer(LineLayerArray.get_Element(0) as ICadastralFabricSubLayer); // check to see if there is only one parcel line selected // **SAMPLE CODE NOTE** //This sample code ensures one line feature, although it can be easily adapted for use on //multiple line selection. if (LineSelection.Count != 1) { MessageBox.Show("Please select only one parcel line from the Target fabric.", "Sample Code"); return; } //Get a search cursor from the line selection to get the parcel id //We need to get an edit lock on the parcel using the parcel id //An edit lock will guarantee the edit will persist in a multi-user environment after a reconcile ILongArray pParcelsToLock = new LongArrayClass(); IFIDSet pFIDSetForParcelRegen = new FIDSet(); ICursor pCur; LineSelection.Search(null, false, out pCur); //this cursor returns the selected lines // **SAMPLE CODE NOTE** //setup for potential use for multiple line selection, even though this sample uses a single line selection //get the field indices for line attributes needed. int idxParcelID = pCur.FindField("parcelid"); int idxToPointID = pCur.FindField("topointid"); int idxFromPointID = pCur.FindField("frompointid"); int idxCenterPtId = pCur.FindField("centerpointid"); int idxDistance = pCur.FindField("distance"); int idxRadius = pCur.FindField("radius"); int idxCategory = pCur.FindField("category"); //also need the fabric point table and fields IFeatureClass pFabricPointsFC = (IFeatureClass)pCadEd.CadastralFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); int idxPointX = pFabricPointsFC.FindField("x"); int idxPointY = pFabricPointsFC.FindField("y"); int idxPointCtrPt = pFabricPointsFC.FindField("centerpoint"); var ListFromToPairsForRadialLines = new List <int[]>(); // **SAMPLE CODE NOTE** //setup for potential use for multiple line selection, even though this sample uses a single line selection //the list declared above is here for potential use in Add-ins that make use of multiple circular arc lines int[] ParcelIdCtrPtIdFromId1FromId2; IRow pRow = pCur.NextRow(); while (pRow != null) { int iParcelID = (int)pRow.get_Value(idxParcelID); pParcelsToLock.Add(iParcelID); //LongArray for the parcel locks pFIDSetForParcelRegen.Add(iParcelID); //FIDSet for the parcel regenerate //now check for a center point id on the line; this is for the case of changing the radius of an existing curve object value = pRow.get_Value(idxCenterPtId); if (value != DBNull.Value) { //collecting information to remove radial lines ParcelIdCtrPtIdFromId1FromId2 = new int[4]; // 4-element array ParcelIdCtrPtIdFromId1FromId2[0] = iParcelID; ParcelIdCtrPtIdFromId1FromId2[1] = (int)value; //center point is always the to point of the radial line ParcelIdCtrPtIdFromId1FromId2[2] = (int)pRow.get_Value(idxFromPointID); ParcelIdCtrPtIdFromId1FromId2[3] = (int)pRow.get_Value(idxToPointID); // **SAMPLE CODE NOTE** //now add the array, to the list to accomodate other add-ins that may use //more than one selected circular arc line ListFromToPairsForRadialLines.Add(ParcelIdCtrPtIdFromId1FromId2); } Marshal.ReleaseComObject(pRow); pRow = pCur.NextRow(); } Marshal.ReleaseComObject(pCur); bool IsFileBasedGDB = (ArcMap.Editor.EditWorkspace.WorkspaceFactory.WorkspaceType != esriWorkspaceType.esriRemoteDatabaseWorkspace); if (!IsFileBasedGDB) { //for file geodatabase creating a job is optional //see if parcel locks can be obtained on the selected parcels. First create a job. string NewJobName = ""; if (!CreateJob(pCadEd.CadastralFabric, "Sample Code change line to curve", out NewJobName)) { return; } if (!TestForEditLocks(pCadEd.CadastralFabric, NewJobName, pParcelsToLock)) { return; } } //if we get this far, an edit lock has been acquired, or this is file geodatabase (no lock required) //prompt the user for a new radius value string sRadius = Interaction.InputBox("Enter a new Radius:", "Radius"); //**SAMPLE CODE NOTE** : // using the Interaction class from the Microsfot Visual Basic library // is a quick and easy way to provide an input dialog in a single line of code for sample purposes, // without neeing to add a windows form, dockable window, or other UI elements into this project. double dRadius = 0; if (!Double.TryParse(sRadius, out dRadius)) { return; } //we have a valid double value, so we can get ready to edit IProgressDialogFactory pProgressorDialogFact = new ProgressDialogFactoryClass(); ITrackCancel pTrackCancel = new CancelTracker(); IStepProgressor pStepProgressor = pProgressorDialogFact.Create(pTrackCancel, ArcMap.Application.hWnd); IProgressDialog2 pProgressorDialog = (IProgressDialog2)pStepProgressor; ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadEd.CadastralFabric; try { //turn off the read-only flag on the lines table and points table pSchemaEd.ReleaseReadOnlyFields(LineSelection.Target, esriCadastralFabricTable.esriCFTLines); //release read-only pSchemaEd.ReleaseReadOnlyFields((ITable)pFabricPointsFC, esriCadastralFabricTable.esriCFTPoints); //release read-only //start an edit operation ArcMap.Editor.StartOperation(); //get an update cursor to make the edit on the line(s) LineSelection.Update(null, false, out pCur); pRow = pCur.NextRow(); int iChangeCount = 0; while (pRow != null) { double dChord = (double)pRow.get_Value(idxDistance); if (Math.Abs(dRadius) <= dChord / 2 && dRadius != 0) //minimum allowable radius is half the chord { Marshal.ReleaseComObject(pRow); pRow = pCur.NextRow(); continue; } //compute a center point location from new radius, unless it's 0 int iNewCtrPtId = 0; if (dRadius != 0) { IFeature pFeat = pRow as IFeature; IPoint pCtrPt = ComputeCenterPointFromRadius(pFeat.Shape as IPolyline, dRadius, true); IFeature pNewPointFeat = pFabricPointsFC.CreateFeature(); //**SAMPLE CODE NOTE** : //if adding a large number of points (more than 20) then createfeature is not the fastest approach, //Instead you would pre-allocate points using an insert cursor... //At this point in the code, the normal geodatabase performance considerations apply iNewCtrPtId = pNewPointFeat.OID; pNewPointFeat.set_Value(idxPointX, pCtrPt.X); pNewPointFeat.set_Value(idxPointY, pCtrPt.Y); pNewPointFeat.set_Value(idxPointCtrPt, 1); //1 = true boolean pNewPointFeat.Shape = pCtrPt; pNewPointFeat.Store(); } //get the initial radius if the line is a curve (radius is being updated) object obj = pRow.get_Value(idxRadius); bool bIsChangingFromCurve = (obj != DBNull.Value); //there is a radius value obj = pRow.get_Value(idxCenterPtId); bIsChangingFromCurve = bIsChangingFromCurve && (obj != DBNull.Value); //radius value and Ctr Pt ID exist int iExistingCtrPtId = 0; if (bIsChangingFromCurve) { iExistingCtrPtId = (int)obj; } if (dRadius == 0) //user entered value is zero meaning convert to straight line { //changing to a straight line so set the center point an radius to null pRow.set_Value(idxRadius, DBNull.Value); pRow.set_Value(idxCenterPtId, DBNull.Value); } else if (!bIsChangingFromCurve) //user entered a new radius, and the existing line is not a curve { //changing to a circular arc so set the radius, and set the center point id to the new point's OID pRow.set_Value(idxRadius, dRadius); pRow.set_Value(idxCenterPtId, iNewCtrPtId); } else if (bIsChangingFromCurve) //user entered a radius, and the existing line is a curve { pCur.UpdateRow(pRow); } iChangeCount++; Marshal.ReleaseComObject(pRow); pRow = pCur.NextRow(); } Marshal.ReleaseComObject(pCur); if (iChangeCount == 0) {//if there are no changes then don't add to the edit operation stack ArcMap.Editor.AbortOperation(); return; } if (ListFromToPairsForRadialLines.Count > 0) { IQueryFilter pQuFilter = new QueryFilter(); string sCat = LineSelection.Target.Fields.get_Field(idxCategory).Name; string sToPt = LineSelection.Target.Fields.get_Field(idxToPointID).Name; string sFromPt = LineSelection.Target.Fields.get_Field(idxFromPointID).Name; string sParcelID = LineSelection.Target.Fields.get_Field(idxParcelID).Name; string sInClauseToPts = "("; string sInClauseFromPts = "("; string sInClauseParcelIds = "("; //**SAMPLE CODE NOTE** : //The following In Clause, when contructed for production environments //should take into account the token limit on Oracle database platforms. (<1000) // the processing of the in clause should be broekn into blocks with the in cluase has no more than 1000 elements foreach (int[] iParcelIdCtrPtIdFromId1FromId2 in ListFromToPairsForRadialLines) { if (sInClauseParcelIds.Length == 1) { sInClauseParcelIds += iParcelIdCtrPtIdFromId1FromId2[0].ToString(); } else { sInClauseParcelIds += "," + iParcelIdCtrPtIdFromId1FromId2[0].ToString(); } if (sInClauseToPts.Length == 1) { sInClauseToPts += iParcelIdCtrPtIdFromId1FromId2[1].ToString(); } else { sInClauseToPts += "," + iParcelIdCtrPtIdFromId1FromId2[1].ToString(); } if (sInClauseFromPts.Length == 1) { sInClauseFromPts += iParcelIdCtrPtIdFromId1FromId2[2].ToString(); sInClauseFromPts += "," + iParcelIdCtrPtIdFromId1FromId2[3].ToString(); } else { sInClauseFromPts += "," + iParcelIdCtrPtIdFromId1FromId2[2].ToString(); sInClauseFromPts += "," + iParcelIdCtrPtIdFromId1FromId2[2].ToString(); } } pQuFilter.WhereClause = sCat + " = 4 AND " + sParcelID + " IN " + sInClauseParcelIds + ") AND " + sFromPt + " IN " + sInClauseFromPts + ") AND " + sToPt + " IN " + sInClauseToPts + ")"; LineSelection.Target.DeleteSearchedRows(pQuFilter); } //with the new information added to the line, the rest of the parcel needs to be updated //regenerate the parcel using the parcel fidset 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 = pCadEd.CadastralFabric; pRegenFabric.RegeneratorBitmask = 7; pRegenFabric.RegenerateParcels(pFIDSetForParcelRegen, false, pTrackCancel); //15 (enum values of 8 means remove orphan points; this only works when doing entire fabric) //TODO: remove orphaned center points programmatically pStepProgressor.MinRange = 0; pStepProgressor.MaxRange = iChangeCount; pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; pRegenFabric.RegenerateParcels(pFIDSetForParcelRegen, false, pTrackCancel); ArcMap.Editor.StopOperation("Change line radius"); } catch (Exception ex) { ArcMap.Editor.AbortOperation(); MessageBox.Show(ex.Message); } finally { if (pSchemaEd != null) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTLines); } pStepProgressor = null; if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pProgressorDialog = null; RefreshMap(LineLayerArray); ICadastralExtensionManager pCExMan = (ICadastralExtensionManager)pCadEd; IParcelPropertiesWindow2 pPropW = (IParcelPropertiesWindow2)pCExMan.ParcelPropertiesWindow; pPropW.RefreshAll(); //update the TOC IMxDocument mxDocument = (ESRI.ArcGIS.ArcMapUI.IMxDocument)(ArcMap.Application.Document); for (int i = 0; i < mxDocument.ContentsViewCount; i++) { IContentsView pCV = (IContentsView)mxDocument.get_ContentsView(i); pCV.Refresh(null); } } }
protected override void OnClick() { #region Prepare for editing IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); //check if there is a Manual Mode "modify" job active =========== ICadastralPacketManager pCadPacMan = (ICadastralPacketManager)pCadExtMan; if (pCadPacMan.PacketOpen) { MessageBox.Show("This command cannot be used when there is an open job.\r\nPlease finish or discard the open job, and try again.", "Delete Selected Parcels"); return; } IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); IActiveView pActiveView = ArcMap.Document.ActiveView; IMap pMap = pActiveView.FocusMap; ICadastralFabric pCadFabric = null; clsFabricUtils FabricUTILS = new clsFabricUtils(); IProgressDialog2 pProgressorDialog = null; //if we're in an edit session then grab the target fabric if (pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } else { MessageBox.Show("Please start editing and try again."); return; } if (pCadFabric == null) {//find the first fabric in the map if (!FabricUTILS.GetFabricFromMap(pMap, out pCadFabric)) { MessageBox.Show ("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } IArray CFParcelLayers = new ArrayClass(); if (!(FabricUTILS.GetFabricSubLayersFromFabric(pMap, pCadFabric, out CFPointLayer, out CFLineLayer, out CFParcelLayers, out CFControlLayer, out CFLinePointLayer))) { return; //no fabric sublayers available for the targeted fabric } //bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersionedDelete = false; //ICadastralFabricLayer pCFLayer = null; IWorkspace pWS = null; ITable pParcelsTable = null; ITable pLinesTable = null; ITable pLinePtsTable = null; ITable pPointsTable = null; pParcelsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); pLinesTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLines); pLinePtsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLinePoints); pPointsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); #endregion dlgChangeParcelHistory pChangeHistoryDialog = new dlgChangeParcelHistory(); // ******** Display the dialog ********* DialogResult pDialogResult = pChangeHistoryDialog.ShowDialog(); if (pDialogResult != DialogResult.OK) { return; } //************************ #region Get Selection //Get the selection of parcels IFeatureLayer pFL = (IFeatureLayer)CFParcelLayers.get_Element(0); IDataset pDS = (IDataset)pFL.FeatureClass; pWS = pDS.Workspace; ICadastralSelection pCadaSel = (ICadastralSelection)pCadEd; IEnumGSParcels pEnumGSParcels = pCadaSel.SelectedParcels;// need to get the parcels before trying to get the parcel count: BUG workaround IFeatureSelection pFeatSel = (IFeatureSelection)pFL; ISelectionSet2 pSelSet = (ISelectionSet2)pFeatSel.SelectionSet; ICadastralFabricSchemaEdit2 pSchemaEd = null; try { int iParcelCount = pCadaSel.SelectedParcelCount; bool m_bShowProgressor = (iParcelCount > 10); if (m_bShowProgressor) { m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, ArcMap.Application.hWnd); pProgressorDialog = (IProgressDialog2)m_pStepProgressor; m_pStepProgressor.MinRange = 1; m_pStepProgressor.MaxRange = iParcelCount * 14; //(estimate 7 lines per parcel, 4 pts per parcel) m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; } if (m_bShowProgressor) { pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Initializing..."; } #endregion #region Get Parcel History Fields //Get the parcel table history fields //SystemStart, SystemEnd, LegalStart, LegalEnd, Historic int iParcSysStartDate = pParcelsTable.FindField("systemstartdate"); int iParcSysEndDate = pParcelsTable.FindField("systemenddate"); int iParcLegalStartDate = pParcelsTable.FindField("legalstartdate"); int iParcLegalEndDate = pParcelsTable.FindField("legalenddate"); int iParcHistorical = pParcelsTable.FindField("historical"); //Add the OIDs of all the selected parcels into a new feature IDSet //Need a Lookup for the History information Dictionary <int, string> ParcelToHistory_DICT = new Dictionary <int, string>(); List <string> sOIDList = new List <string>(); sOIDList.Add(""); int tokenLimit = 995; bool bCont = true; int j = 0; int iCounter = 0; m_pFIDSetParcels = new FIDSetClass(); pEnumGSParcels.Reset(); IGSParcel pGSParcel = pEnumGSParcels.Next(); while (pGSParcel != null) { //Check if the cancel button was pressed. If so, stop process if (m_bShowProgressor) { bCont = m_pTrackCancel.Continue(); if (!bCont) { break; } } m_pFIDSetParcels.Add(pGSParcel.DatabaseId); if (iCounter <= tokenLimit) { if (sOIDList[j].Trim() == "") { sOIDList[j] = Convert.ToString(pGSParcel.DatabaseId); } else { sOIDList[j] = sOIDList[j] + "," + Convert.ToString(pGSParcel.DatabaseId); } iCounter++; } else {//maximum tokens reached iCounter = 0; //set up the next OIDList j++; sOIDList.Add(""); sOIDList[j] = Convert.ToString(pGSParcel.DatabaseId); } //add to the lookup IGSAttributes pGSParcelAttributes = (IGSAttributes)pGSParcel; object pObj = pGSParcelAttributes.GetProperty("systemstartdate"); string sSystemStartParcel = ""; if (pObj != null) { sSystemStartParcel = pObj.ToString(); } pObj = pGSParcelAttributes.GetProperty("systemenddate"); string sSystemEndParcel = ""; if (pObj != null) { sSystemEndParcel = pObj.ToString(); } string sLegalStartParcel = pGSParcel.LegalStartDate.ToString(); string sLegalEndParcel = pGSParcel.LegalEndDate.ToString(); string sHistorical = pGSParcel.Historical.ToString(); ParcelToHistory_DICT.Add(pGSParcel.DatabaseId, sSystemStartParcel + "," + sSystemEndParcel + "," + sLegalStartParcel + "," + sLegalEndParcel + "," + sHistorical); Marshal.ReleaseComObject(pGSParcel); //garbage collection pGSParcel = pEnumGSParcels.Next(); if (m_bShowProgressor) { if (m_pStepProgressor.Position < m_pStepProgressor.MaxRange) { m_pStepProgressor.Step(); } } } Marshal.ReleaseComObject(pEnumGSParcels); //garbage collection #endregion #region Confirm Edit Locks bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersioned = false; if (!FabricUTILS.SetupEditEnvironment(pWS, pCadFabric, pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersioned)) { return; } //if we're in an enterprise then test for edit locks 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 CadastralJobClass(); pJob.Name = sTime; pJob.Owner = System.Windows.Forms.SystemInformation.UserName; pJob.Description = "Delete selected parcels"; 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); } m_pStepProgressor = null; if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pProgressorDialog = null; Marshal.ReleaseComObject(pJob); if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; } return; } Marshal.ReleaseComObject(pJob); } ICadastralFabricLocks pFabLocks = (ICadastralFabricLocks)pCadFabric; if (!bIsUnVersioned && !bIsFileBasedGDB) { pFabLocks.LockingJob = sTime; ILongArray pLocksInConflict = null; ILongArray pSoftLcksInConflict = null; ILongArray pParcelsToLock = new LongArrayClass(); FabricUTILS.FIDsetToLongArray(m_pFIDSetParcels, ref pParcelsToLock, m_pStepProgressor); if (m_bShowProgressor && !bIsFileBasedGDB) { m_pStepProgressor.Message = "Testing for edit locks on parcels..."; } try { pFabLocks.AcquireLocks(pParcelsToLock, 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)); } if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; } return; } Marshal.ReleaseComObject(pSoftLcksInConflict); Marshal.ReleaseComObject(pParcelsToLock); Marshal.ReleaseComObject(pLocksInConflict); } #endregion string sParcelSysEndDate = pParcelsTable.Fields.get_Field(iParcSysEndDate).Name; string sParcelLegalStartDate = pParcelsTable.Fields.get_Field(iParcLegalStartDate).Name; string sParcelLegalEndDate = pParcelsTable.Fields.get_Field(iParcLegalEndDate).Name; string sParcelHistoric = pParcelsTable.Fields.get_Field(iParcHistorical).Name; if (m_bShowProgressor) { pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Updating parcel history..."; } pEd.StartOperation(); #region The Edit //make change to parcels bool bSuccess = false; ICursor pCurs = null; IQueryFilter pQuFilter = new QueryFilterClass(); pQuFilter.SubFields = pParcelsTable.OIDFieldName + "," + sParcelLegalEndDate + "," + sParcelLegalStartDate + "," + sParcelSysEndDate + "," + sParcelHistoric; bool bSystemEndDate_Clear = pChangeHistoryDialog.chkSystemEndDate.Checked && pChangeHistoryDialog.optClearSEDate.Checked; bool bLegalStDate_Clear = pChangeHistoryDialog.chkLegalStartDate.Checked && pChangeHistoryDialog.optClearLSDate.Checked; bool bLegalEndDate_Clear = pChangeHistoryDialog.chkLegalEndDate.Checked && pChangeHistoryDialog.optClearLEDate.Checked; bool bSystemEndDate_Set = pChangeHistoryDialog.chkSystemEndDate.Checked && pChangeHistoryDialog.optChooseSEDate.Checked; bool bLegalStDate_Set = pChangeHistoryDialog.chkLegalStartDate.Checked && pChangeHistoryDialog.optChooseLSDate.Checked; bool bLegalEndDate_Set = pChangeHistoryDialog.chkLegalEndDate.Checked && pChangeHistoryDialog.optChooseLEDate.Checked; List <bool> bHistory = new List <bool>(); bHistory.Add(bSystemEndDate_Clear); bHistory.Add(bLegalStDate_Clear); bHistory.Add(bLegalEndDate_Clear); bHistory.Add(bSystemEndDate_Set); bHistory.Add(bLegalStDate_Set); bHistory.Add(bLegalEndDate_Set); List <string> sDates = new List <string>(); sDates.Add(pChangeHistoryDialog.dtSEDatePicker.Text); sDates.Add(pChangeHistoryDialog.dtLSDatePicker.Text); sDates.Add(pChangeHistoryDialog.dtLEDatePicker.Text); pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; pSchemaEd.ReleaseReadOnlyFields(pLinesTable, esriCadastralFabricTable.esriCFTLines); //release safety-catch pSchemaEd.ReleaseReadOnlyFields(pParcelsTable, esriCadastralFabricTable.esriCFTParcels); //release safety-catch pSchemaEd.ReleaseReadOnlyFields(pPointsTable, esriCadastralFabricTable.esriCFTPoints); //release safety-catch foreach (string sInClause in sOIDList) { if (sInClause.Trim() == "") { continue; } pQuFilter.WhereClause = pParcelsTable.OIDFieldName + " IN (" + sInClause + ")"; pCurs = pParcelsTable.Update(pQuFilter, false); bSuccess = FabricUTILS.ChangeDatesOnTableMulti(pCurs, bHistory, sDates, bUseNonVersioned, ParcelToHistory_DICT, m_pStepProgressor, m_pTrackCancel); if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } if (bUseNonVersioned) { FabricUTILS.AbortEditing(pWS); } else { pEd.AbortOperation(); } //clear selection, to make sure the parcel explorer is updated and refreshed properly return; } } //make change to points and lines if (!FabricUTILS.UpdateHistoryOnLines(pLinesTable, pPointsTable, iParcelCount, pCadFabric, sOIDList, ParcelToHistory_DICT, m_pStepProgressor, m_pTrackCancel)) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } if (bUseNonVersioned) { FabricUTILS.AbortEditing(pWS); } else { pEd.AbortOperation(); } } else { pEd.StopOperation("Change Parcel History"); } #endregion //now refresh the map layers RefreshMap(pActiveView, CFParcelLayers, CFPointLayer, CFLineLayer, CFControlLayer, CFLinePointLayer); } catch (Exception ex) { pEd.AbortOperation(); MessageBox.Show("Error:" + ex.Message); } finally { if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); //set safety back on pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTLines); //set safety back on pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); //set safety back on } }
protected override void OnMouseDown(MouseEventArgs arg) { IFeatureLayer pPointLayer = null; IFeatureLayer pLineLayer = null; IArray pParcelLayers = null; IFeatureLayer pControlLayer = null; IFeatureLayer pLinePointLayer = null; double dXYTol = 0.003; clsFabricUtils FabricUTILS = new clsFabricUtils(); IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); //first get the extension UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); //check if there is a Manual Mode "modify" job active =========== ICadastralPacketManager pCadPacMan = (ICadastralPacketManager)pCadExtMan; if (pCadPacMan.PacketOpen) { FabricUTILS.ExecuteCommand(m_CommUID); MessageBox.Show("This tool cannot be used when there is an open parcel, construction, or job.\r\nPlease complete or discard the open items, and try again."); return; } ICadastralFabric pCadFabric = null; //if we're in an edit session then grab the target fabric if (pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } else { FabricUTILS.ExecuteCommand(m_CommUID); MessageBox.Show("This tool works on a parcel fabric in an edit session.\r\nPlease start editing and try again."); return; } if (pCadFabric == null) {//find the first fabric in the map if (!FabricUTILS.GetFabricFromMap(ArcMap.Document.ActiveView.FocusMap, out pCadFabric)) { FabricUTILS.ExecuteCommand(m_CommUID); MessageBox.Show("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } IGeoDataset pGeoDS = (IGeoDataset)pCadFabric; ISpatialReferenceTolerance pSpatRefTol = (ISpatialReferenceTolerance)pGeoDS.SpatialReference; if (pSpatRefTol.XYToleranceValid == esriSRToleranceEnum.esriSRToleranceOK) { dXYTol = pSpatRefTol.XYTolerance; } IMouseCursor pMouseCursor = null; ISpatialFilter pSpatFilt = null; //spatial filter query hinging off the dragged rectangle selection IQueryFilter pQuFilter = null; //used for the non-spatial query for radial lines, as they have no geometry IRubberBand2 pRubberRect = null; IGeometryBag pGeomBag = null; ITopologicalOperator5 pUnionedPolyine = null; IPolygon pBufferedToolSelectGeometry = null; //geometry used to search for parents IFIDSet pLineFIDs = null; //the FIDSet used to collect the lines that'll be deleted IFIDSet pPointFIDs = null; // the FIDSet used to collect the points that'll be deleted IFIDSet pLinePointFIDs = null; // the FIDSet used to collect the line-points that'll be deleted List <int> pDeletedLinesPoints = new List <int>(); //list used to stage the ids for points that are referenced by lines List <int> pUsedPoints = new List <int>(); //list used to collect pointids that are referenced by existing lines List <int> CtrPointIDList = new List <int>(); //list for collecting the ids of center points List <int> pParcelsList = new List <int>(); //used only to avoid adding duplicates to IN clause string for, based on ties to radial lines List <int> pOrphanPointsList = new List <int>(); //list of orphan points defined from radial ines List <int> pPointsInsideBoxList = new List <int>(); //list of parcels that exist and that intersect the drag-box List <string> sFromToPair = new List <string>(); //list of from/to pairs for manging line points List <int> pLineToParcelIDRef = new List <int>(); //list of parcel id refs stored on lines IInvalidArea3 pInvArea = null; IFeatureClass pLines = null; IFeatureClass pPoints = null; IFeatureClass pParcels = null; IFeatureClass pLinePoints = null; IWorkspace pWS = null; try { #region define the rubber envelope geometry pRubberRect = new RubberEnvelopeClass(); IGeometry ToolSelectEnvelope = pRubberRect.TrackNew(ArcMap.Document.ActiveView.ScreenDisplay, null); if (ToolSelectEnvelope == null) { return; } ISegmentCollection pSegmentColl = new PolygonClass(); pSegmentColl.SetRectangle(ToolSelectEnvelope.Envelope); IPolygon ToolSelectGeometry = (IPolygon)pSegmentColl; if (pCadFabric == null) { return; } pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); #endregion FabricUTILS.GetFabricSubLayersFromFabric(ArcMap.Document.ActiveView.FocusMap, pCadFabric, out pPointLayer, out pLineLayer, out pParcelLayers, out pControlLayer, out pLinePointLayer); #region get tables and field indexes pLines = (IFeatureClass)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLines); pPoints = (IFeatureClass)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); pParcels = (IFeatureClass)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); pLinePoints = (IFeatureClass)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLinePoints); string sPref = ""; string sSuff = ""; int iCtrPtFldIDX = pLines.FindField("CENTERPOINTID"); int iFromPtFldIDX = pLines.FindField("FROMPOINTID"); int iToPtFldIDX = pLines.FindField("TOPOINTID"); int iCatFldIDX = pLines.FindField("CATEGORY"); int iParcelIDX = pLines.FindField("PARCELID"); int iDistanceIDX = pLines.FindField("DISTANCE"); pWS = pLines.FeatureDataset.Workspace; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); pSpatFilt = new SpatialFilterClass(); pSpatFilt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatFilt.Geometry = ToolSelectGeometry; #endregion #region center point //need to make sure that center points are correctly handled for cases where the center point //is inside the select box, but the curve itself is not. The following is used to build an //IN CLAUSE for All the center points that are found within the tool's select geometry. int iIsCtrPtIDX = pPoints.FindField("CENTERPOINT"); int iCount = 0; int iCntCtrPoint = 0; string sCtrPntIDList1 = ""; IFeatureCursor pFeatCursPoints = pPoints.Search(pSpatFilt, false); IFeature pFeat7 = pFeatCursPoints.NextFeature(); while (pFeat7 != null) { iCount++; int iVal = -1; object Attr_val = pFeat7.get_Value(iIsCtrPtIDX); if (Attr_val != DBNull.Value) { iVal = Convert.ToInt32(pFeat7.get_Value(iIsCtrPtIDX)); } if (iVal == 1) { if (sCtrPntIDList1.Trim() == "") { sCtrPntIDList1 += pFeat7.OID.ToString(); } else { sCtrPntIDList1 += "," + pFeat7.OID.ToString(); } iCntCtrPoint++; } pPointsInsideBoxList.Add(pFeat7.OID); //used to check for orphan linepoints pOrphanPointsList.Add(pFeat7.OID); //this gets whittled down till only "pure" orphan points remain Marshal.ReleaseComObject(pFeat7); pFeat7 = pFeatCursPoints.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursPoints); #endregion #region create convex hull of lines //get the lines that intersect the search box and build a //polygon search geometry being the convex hull of those lines. IFeatureCursor pFeatCursLines = pLines.Search(pSpatFilt, false); pGeomBag = new GeometryBagClass(); IGeometryCollection pGeomColl = (IGeometryCollection)pGeomBag; IFeature pFeat1 = pFeatCursLines.NextFeature(); m_sDebug = "Add lines to Geometry Collection."; string sParcelRefOnLines = ""; object missing = Type.Missing; while (pFeat1 != null) { int iVal = (int)pFeat1.get_Value(iFromPtFldIDX); string sFromTo = iVal.ToString() + ":"; if (pOrphanPointsList.Contains(iVal)) //Does this need to be done...will remove fail if it's not there? { pOrphanPointsList.Remove(iVal); //does this need to be in the if block? } iVal = (int)pFeat1.get_Value(iToPtFldIDX); sFromTo += iVal.ToString(); if (pOrphanPointsList.Contains(iVal)) { pOrphanPointsList.Remove(iVal); } sFromToPair.Add(sFromTo); pGeomColl.AddGeometry(pFeat1.ShapeCopy, missing, missing); if (sParcelRefOnLines.Trim() == "") { sParcelRefOnLines = pFeat1.get_Value(iParcelIDX).ToString(); } else { sParcelRefOnLines += "," + pFeat1.get_Value(iParcelIDX).ToString(); } Marshal.ReleaseComObject(pFeat1); pFeat1 = pFeatCursLines.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLines); #endregion #region Add Center Points for curves outside map extent if (iCntCtrPoint > 999) { throw new InvalidOperationException("The Delete Orphans tool works with smaller amounts of data." + Environment.NewLine + "Please try again, by selecting fewer fabric lines and points. (More than 1000 center points returned.)"); } //If there is no line geometry found, and there are also no points found, then nothing to do... if (pGeomColl.GeometryCount == 0 && iCount == 0) { return; } //Radial lines have no geometry so there is a special treatment for those; //that special treatment takes two forms, //1. if a circular arc is selected and it turns out that it is an orphan line, then we //need to take down its radial lines, and its center point as well. //2. if a center point is selected, we need to check if it's an orphan, by searching for its parent. //The parent parcel can easily be well beyond the query rectangle, so the original //search rectangle is buffered by the largest found radius distance, to make sure that all //parent parcels are "find-able." //The radial lines themselves are also needed; Get the radial lines from the Center Points //CtrPt is always TO point, so find lines CATEGORY = 4 AND TOPOINT IN () string sRadialLineListParcelID = ""; string sRadialLinesID = ""; string sRadialLinePoints = ""; double dRadiusBuff = 0; pQuFilter = new QueryFilterClass(); //Find all the radial lines based on the search query if (sCtrPntIDList1.Trim() != "") { pQuFilter.WhereClause = "CATEGORY = 4 AND TOPOINTID IN (" + sCtrPntIDList1 + ")"; //add all the *references* to Parcel ids for the radial lines, //and add the ID's of the lines IFeatureCursor pFeatCursLines8 = pLines.Search(pQuFilter, false); IFeature pFeat8 = pFeatCursLines8.NextFeature(); while (pFeat8 != null) { object Attr_val = pFeat8.get_Value(iDistanceIDX); double dVal = 0; if (Attr_val != DBNull.Value) { dVal = Convert.ToDouble(Attr_val); } dRadiusBuff = dRadiusBuff > dVal ? dRadiusBuff : dVal; int iVal = Convert.ToInt32(pFeat8.get_Value(iParcelIDX)); if (!pParcelsList.Contains(iVal)) { if (sRadialLineListParcelID.Trim() == "") { sRadialLineListParcelID += Convert.ToString(iVal); } else { sRadialLineListParcelID += "," + Convert.ToString(iVal); } } pParcelsList.Add(iVal); //pOrphanPointsList is used for "Pure Orphan point" detection //meaning that these are points that do not have ANY line, not even an orphan line. iVal = (int)pFeat8.get_Value(iFromPtFldIDX); if (pOrphanPointsList.Contains(iVal)) { pOrphanPointsList.Remove(iVal); } iVal = (int)pFeat8.get_Value(iToPtFldIDX); if (pOrphanPointsList.Contains(iVal)) { pOrphanPointsList.Remove(iVal); } if (sRadialLinesID.Trim() == "") { sRadialLinesID += Convert.ToString(iVal); } else { sRadialLinesID += "," + Convert.ToString(iVal); } //Add from point to list if (sRadialLinePoints.Trim() == "") { sRadialLinePoints += Convert.ToString(pFeat8.get_Value(iFromPtFldIDX)); } else { sRadialLinePoints += "," + Convert.ToString(pFeat8.get_Value(iFromPtFldIDX)); } //Add To point to list sRadialLinePoints += "," + Convert.ToString(pFeat8.get_Value(iToPtFldIDX)); Marshal.ReleaseComObject(pFeat8); pFeat8 = pFeatCursLines8.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLines8); //create a polygon goeometry that is a buffer of the selection rectangle expanded //to the greatest radius of all the radial lines found. ITopologicalOperator topologicalOperator = (ITopologicalOperator)ToolSelectGeometry; pBufferedToolSelectGeometry = topologicalOperator.Buffer(dRadiusBuff) as IPolygon; } else { pQuFilter.WhereClause = ""; } #endregion #region OrphanLines if (pGeomColl.GeometryCount != 0) { pUnionedPolyine = new PolylineClass(); pUnionedPolyine.ConstructUnion((IEnumGeometry)pGeomBag); ITopologicalOperator pTopoOp = (ITopologicalOperator)pUnionedPolyine; IGeometry pConvexHull = pTopoOp.ConvexHull(); //With this convex hull, do a small buffer, //theis search geometry is used as a spatial query on the parcel polygons //and also on the parcel lines, to build IN Clauses pTopoOp = (ITopologicalOperator)pConvexHull; IGeometry pBufferedConvexHull = pTopoOp.Buffer(10 * dXYTol); if (pBufferedToolSelectGeometry != null) { pTopoOp = (ITopologicalOperator)pBufferedToolSelectGeometry; IGeometry pUnionPolygon = pTopoOp.Union(pBufferedConvexHull); pSpatFilt.Geometry = pUnionPolygon; } else { pSpatFilt.Geometry = pBufferedConvexHull; } } else { if (pQuFilter.WhereClause.Trim() == "" && pBufferedToolSelectGeometry == null) { pSpatFilt.Geometry = ToolSelectGeometry; } else { pSpatFilt.Geometry = pBufferedToolSelectGeometry; } } IColor pColor = new RgbColorClass(); pColor.RGB = System.Drawing.Color.Blue.ToArgb(); IScreenDisplay pScreenDisplay = ArcMap.Document.ActiveView.ScreenDisplay; FabricUTILS.FlashGeometry(pSpatFilt.Geometry, pScreenDisplay, pColor, 5, 100); pSpatFilt.SearchOrder = esriSearchOrder.esriSearchOrderSpatial; m_sDebug = "Searching Parcels table."; pInvArea = new InvalidAreaClass(); IFeatureCursor pFeatCursParcels = pParcels.Search(pSpatFilt, false); IFeature pFeat2 = pFeatCursParcels.NextFeature(); string sParcelIDList = ""; iCount = 0; //create the "NOT IN" CLAUSE for parcels that exist in the DB and that are within the search area //Will be used as a search on lines to get the Orphan Lines while (pFeat2 != null) { iCount++; if (sParcelIDList.Trim() == "") { sParcelIDList += pFeat2.OID.ToString(); } else { sParcelIDList += "," + pFeat2.OID.ToString(); } Marshal.ReleaseComObject(pFeat2); if (iCount > 999) { break; } pFeat2 = pFeatCursParcels.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursParcels); //if we have more than 999 in clause tokens, there will be problems on Oracle. //Since this is an interactive tool, we expect it not to be used on a large amount of data. //for this reason, the following message is displayed if more than 999 parcels are returned in this query. //TODO: for the future this can be made to work on larger sets of data. if (iCount > 999) { throw new InvalidOperationException("The Delete Orphans tool works with smaller amounts of data." + Environment.NewLine + "Please try again, by selecting fewer fabric lines and points. (More than 1000 parcels returned.)"); } m_sDebug = "Building the used points list."; //This first pass contains all references to points found within the parent parcel search buffer //Later, points are removed from this list IFeatureCursor pFeatCursLargerLineSet = pLines.Search(pSpatFilt, false); IFeature pFeat3 = pFeatCursLargerLineSet.NextFeature(); while (pFeat3 != null) { iCount++; object Attr_val = pFeat3.get_Value(iCtrPtFldIDX); if (Attr_val != DBNull.Value) { pUsedPoints.Add(Convert.ToInt32(Attr_val)); //add center point } int iVal = (int)pFeat3.get_Value(iFromPtFldIDX); pUsedPoints.Add(iVal);//add from point iVal = (int)pFeat3.get_Value(iToPtFldIDX); pUsedPoints.Add(iVal);//add to point Marshal.ReleaseComObject(pFeat3); pFeat3 = pFeatCursLargerLineSet.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLargerLineSet); //pUsedPoints list is at this stage, references to points for all lines found within the search area. //use the IN clause of the parcel ids to search for lines within //the original search box, and that are also orphans that do not have a parent parcel. pSpatFilt.WhereClause = ""; pSpatFilt.Geometry = ToolSelectGeometry; pSpatFilt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatFilt.SearchOrder = esriSearchOrder.esriSearchOrderSpatial; IFeatureCursor pFeatCursor = null; if (pGeomColl.GeometryCount == 0) { if (sParcelIDList.Trim().Length > 0 && sCtrPntIDList1.Trim().Length > 0) { pQuFilter.WhereClause = "(PARCELID NOT IN (" + sParcelIDList + ")) AND (CATEGORY = 4 AND TOPOINTID IN (" + sCtrPntIDList1 + "))"; pFeatCursor = pLines.Search(pQuFilter, false); } else if (sParcelIDList.Trim().Length == 0 && sCtrPntIDList1.Trim().Length > 0) { pQuFilter.WhereClause = "CATEGORY = 4 AND TOPOINTID IN (" + sCtrPntIDList1 + ")"; pFeatCursor = pLines.Search(pQuFilter, false); } } else {//do a spatial query if (sParcelIDList.Trim().Length > 0) { pSpatFilt.WhereClause = "PARCELID NOT IN (" + sParcelIDList + ")"; } else { pSpatFilt.WhereClause = ""; } pFeatCursor = pLines.Search(pSpatFilt, false); } m_sDebug = "Collecting lines to be deleted."; //start collecting the lines that need to be deleted iCount = 0; int iCtrPointCount = 0; string sCtrPointIDList = ""; string sLineParcelIDReference = ""; //Feature cursor is lines that are NOT IN the ParcelIDList if (pFeatCursor != null) { pLineFIDs = new FIDSetClass(); IFeature pFeat4 = pFeatCursor.NextFeature(); while (pFeat4 != null) { iCount++; pLineFIDs.Add(pFeat4.OID); int iParcRef = Convert.ToInt32(pFeat4.get_Value(iParcelIDX)); if (sLineParcelIDReference.Trim() == "") { sLineParcelIDReference = iParcRef.ToString(); } else { if (!pLineToParcelIDRef.Contains(iParcRef)) { sLineParcelIDReference += "," + iParcRef.ToString(); } } pLineToParcelIDRef.Add(iParcRef); pInvArea.Add((IObject)pFeat4); //now for this line, get it's points //first add the center point reference if there is one object Attr_val = pFeat4.get_Value(iCtrPtFldIDX); if (Attr_val != DBNull.Value) { iCtrPointCount++; int iCtrPointID = Convert.ToInt32(Attr_val); pDeletedLinesPoints.Add(iCtrPointID); //add this line's center point pUsedPoints.Remove(iCtrPointID); if (sCtrPointIDList.Trim() == "") { sCtrPointIDList = iCtrPointID.ToString(); } else { if (CtrPointIDList.Contains(iCtrPointID)) { iCtrPointCount--; } else { sCtrPointIDList += "," + iCtrPointID.ToString(); } } CtrPointIDList.Add(iCtrPointID);//to keep track of repeats } //and also add the FROM and TO point references if they exist int iVal = (int)pFeat4.get_Value(iFromPtFldIDX); pDeletedLinesPoints.Add(iVal);//add FROM point if (pGeomColl.GeometryCount > 0) { pUsedPoints.Remove(iVal); } iVal = (int)pFeat4.get_Value(iToPtFldIDX); pDeletedLinesPoints.Add(iVal);//add TO point if (pGeomColl.GeometryCount > 0) { pUsedPoints.Remove(iVal); } Marshal.ReleaseComObject(pFeat4); if (iCtrPointCount > 999) { break; } pFeat4 = pFeatCursor.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursor); } if (iCtrPointCount > 999) { throw new InvalidOperationException("The Delete Orphans tool works with smaller amounts of data." + Environment.NewLine + "Please try again, by selecting fewer fabric lines and points. (More than 1000 center points returned.)"); } m_sDebug = "Adding orphan radial lines to list."; if (sCtrPointIDList.Trim().Length > 0) { //add the Radial lines at each end of the curves using the collected CtrPtIDs //CtrPt is always TO point, so find lines CATEGORY = 4 AND TOPOINT IN () pQuFilter.WhereClause = "CATEGORY = 4 AND TOPOINTID IN (" + sCtrPointIDList + ")"; pFeatCursor = pLines.Search(pQuFilter, false); IFeature pFeat5 = pFeatCursor.NextFeature(); while (pFeat5 != null) { pLineFIDs.Add(pFeat5.OID); int iParcRef = Convert.ToInt32(pFeat5.get_Value(iParcelIDX)); pLineToParcelIDRef.Add(iParcRef); if (sLineParcelIDReference.Trim() == "") { sLineParcelIDReference = iParcRef.ToString(); } else { if (!pLineToParcelIDRef.Contains(iParcRef)) { sLineParcelIDReference += "," + iParcRef.ToString(); } } Marshal.ReleaseComObject(pFeat5); pFeat5 = pFeatCursor.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursor); } else { pQuFilter.WhereClause = ""; } //refine the DeletedLinesPoints list foreach (int i in pUsedPoints) { if (pDeletedLinesPoints.Contains(i)) { do { } while (pDeletedLinesPoints.Remove(i)); } } //add the points to a new FIDSet pPointFIDs = new FIDSetClass(); foreach (int i in pDeletedLinesPoints) { pPointFIDs.Add(i); } #endregion #region OrphanPoints //We already know which points to delete based on taking down the orphan lines. //We need to still add to the points FIDSet those points that are "pure" ophan points //as defined for the pOrphanPointsList variable. //and add the orphan points to the points FIDSet foreach (int i in pOrphanPointsList) { bool bFound = false; pPointFIDs.Find(i, out bFound); if (!bFound) { pPointFIDs.Add(i); } } #endregion #region orphan Line points //next check for orphan line-points //the line-point is deleted if there is no underlying point //or if the from and to point references do not exist. pSpatFilt.WhereClause = ""; pSpatFilt.Geometry = ToolSelectGeometry; IFeatureCursor pFeatCursLinePoints = pLinePoints.Search(pSpatFilt, false); IFeature pLPFeat = pFeatCursLinePoints.NextFeature(); int iLinePtPointIdIdx = pLinePoints.FindField("LINEPOINTID"); int iLinePtFromPtIdIdx = pLinePoints.FindField("FROMPOINTID"); int iLinePtToPtIdIdx = pLinePoints.FindField("TOPOINTID"); pLinePointFIDs = new FIDSetClass(); while (pLPFeat != null) { bool bExistsA = true; bool bExists1 = true; bool bExists2 = true; bool bExists3 = true; int iVal = (int)pLPFeat.get_Value(iLinePtPointIdIdx); pPointFIDs.Find(iVal, out bExists1); if (!pPointsInsideBoxList.Contains(iVal)) { bExistsA = false; } iVal = (int)pLPFeat.get_Value(iLinePtFromPtIdIdx); string sFrom = iVal.ToString(); pPointFIDs.Find(iVal, out bExists2); iVal = (int)pLPFeat.get_Value(iLinePtToPtIdIdx); string sTo = iVal.ToString(); pPointFIDs.Find(iVal, out bExists3); int iOID = pLPFeat.OID; if (bExists1 || bExists2 || bExists3) { pLinePointFIDs.Add(iOID); } if (!sFromToPair.Contains(sFrom + ":" + sTo) && !sFromToPair.Contains(sTo + ":" + sFrom)) { pLinePointFIDs.Find(iOID, out bExists1); if (!bExists1) { pLinePointFIDs.Add(iOID); } } //if (!bExistsA || !bExistsB || !bExistsC) if (!bExistsA) { bool bFound = true; pLinePointFIDs.Find(iOID, out bFound); if (!bFound) { pLinePointFIDs.Add(iOID); } } pPointsInsideBoxList.Contains(iVal); Marshal.ReleaseComObject(pLPFeat); pLPFeat = pFeatCursLinePoints.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLinePoints); #endregion #region Refine the lines that are on the delete list //next step is to refine and double-check to make sure that the lines that are on the delete list //do not have a parcel record somewhere else (not spatially connected to the line) (example unjoined, or bad geom) string sFreshlyFoundParcels = ""; if (sLineParcelIDReference.Trim() != "") { pQuFilter.WhereClause = sPref + pParcels.OIDFieldName + sSuff + " IN (" + sLineParcelIDReference + ")"; pFeatCursor = pParcels.Search(pQuFilter, false); IFeature pFeat6 = pFeatCursor.NextFeature(); while (pFeat6 != null) { int iOID = pFeat6.OID; if (sFreshlyFoundParcels.Trim() == "") { sFreshlyFoundParcels = iOID.ToString(); } else { sFreshlyFoundParcels += "," + iOID.ToString(); } Marshal.ReleaseComObject(pFeat6); pFeat6 = pFeatCursor.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursor); if (sFreshlyFoundParcels.Trim() != "") { pQuFilter.WhereClause = "PARCELID IN (" + sFreshlyFoundParcels + ")"; pFeatCursor = pLines.Search(pQuFilter, false); IFeature pFeat9 = pFeatCursor.NextFeature(); while (pFeat9 != null) { int iOID = pFeat9.OID; bool bIsHere = false; pLineFIDs.Delete(iOID); int iVal = Convert.ToInt32(pFeat9.get_Value(iFromPtFldIDX)); pPointFIDs.Find(iVal, out bIsHere); if (bIsHere) { pPointFIDs.Delete(iVal); } iVal = Convert.ToInt32(pFeat9.get_Value(iToPtFldIDX)); pPointFIDs.Find(iVal, out bIsHere); if (bIsHere) { pPointFIDs.Delete(iVal); } Marshal.ReleaseComObject(pFeat9); pFeat9 = pFeatCursor.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursor); } } #endregion #region Make sure the points on the delete list are not part of a construction //For post 10.0, Make sure the points on the delete list are not part of a construction if they are then null geometry //pQuFilter.WhereClause=pLines.LengthField.Name + " = 0 AND CATEGORY <> 4"; //IFeatureCursor pFeatCursLines101 = pLines.Search(pQuFilter, false); //this would open a new cursor and do a query on the entire #endregion #region report results and do edits dlgReport Report = new dlgReport(); //Display the dialog System.Drawing.Color BackColorNow = Report.textBox1.BackColor; if (iCount == 0 && pPointFIDs.Count() == 0 && pLinePointFIDs.Count() == 0) { Report.textBox1.BackColor = System.Drawing.Color.LightGreen; Report.textBox1.Text = "Selected area has no orphan lines or points."; } else { int iCount1 = 0; int iCount2 = 0; int iCount3 = 0; if (pLineFIDs != null) { iCount1 = pLineFIDs.Count(); } if (pPointFIDs != null) { iCount2 = pPointFIDs.Count(); } if (pLinePointFIDs != null) { iCount3 = pLinePointFIDs.Count(); } iCount = iCount1 + iCount2 + iCount3; if (iCount > 0) { pEd.StartOperation(); FabricUTILS.DeleteRowsByFIDSet((ITable)pLines, pLineFIDs, null, null); FabricUTILS.DeleteRowsByFIDSet((ITable)pPoints, pPointFIDs, null, null); if (pPointFIDs.Count() > 0) { //now need to update the control points associated with any deleted points. ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; ITable pControlTable = pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTControl); int idxNameFldOnControl = pControlTable.FindField("POINTID"); string ControlNameFldName = pControlTable.Fields.get_Field(idxNameFldOnControl).Name; int i; List <int> pPointFIDList = new List <int>(); pPointFIDs.Reset(); pPointFIDs.Next(out i); while (i > -1) { pPointFIDList.Add(i); pPointFIDs.Next(out i); } List <string> InClausePointsNotConnectedToLines = FabricUTILS.InClauseFromOIDsList(pPointFIDList, 995); pQuFilter.WhereClause = ControlNameFldName + " IN (" + InClausePointsNotConnectedToLines[0] + ")"; pSchemaEd.ReleaseReadOnlyFields(pControlTable, esriCadastralFabricTable.esriCFTControl); //release safety-catch if (!FabricUTILS.ResetControlAssociations(pControlTable, pQuFilter, false)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl);//set safety back on pEd.AbortOperation(); return; } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl);//set safety back on } pQuFilter.WhereClause = ""; FabricUTILS.DeleteRowsByFIDSet((ITable)pLinePoints, pLinePointFIDs, null, null); pEd.StopOperation("Delete " + iCount.ToString() + " orphans"); Report.textBox1.Text = "Deleted:"; if (iCount1 > 0) { Report.textBox1.Text += Environment.NewLine + iCount1.ToString() + " orphaned lines"; } if (iCount2 > 0) { Report.textBox1.Text += Environment.NewLine + iCount2.ToString() + " orphaned points"; } if (iCount3 > 0) { Report.textBox1.Text += Environment.NewLine + iCount3.ToString() + " orphaned line points"; } } if (sFreshlyFoundParcels.Trim() != "") { if (Report.textBox1.Text.Trim() != "") { Report.textBox1.Text += Environment.NewLine; } Report.textBox1.Text += "Info: Line(s) that you selected are not directly" + Environment.NewLine + "touching a parent parcel geometry. Check parcels with OIDs:" + sFreshlyFoundParcels; } } IArea pArea = (IArea)ToolSelectGeometry; if (pArea.Area > 0) { SetDialogLocationAtPoint(Report, pArea.Centroid); } DialogResult pDialogResult = Report.ShowDialog(); Report.textBox1.BackColor = BackColorNow; pInvArea.Display = ArcMap.Document.ActiveView.ScreenDisplay; pInvArea.Invalidate((short)esriScreenCache.esriAllScreenCaches); if (pPointLayer != null) { ArcMap.Document.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, pPointLayer, ArcMap.Document.ActiveView.Extent); } #endregion } catch (Exception ex) { if (pEd != null) { pEd.AbortOperation(); } MessageBox.Show(ex.Message + Environment.NewLine + m_sDebug, "Delete Orphans Tool"); this.OnDeactivate(); } #region Final Cleanup finally { pDeletedLinesPoints.Clear(); pDeletedLinesPoints = null; pUsedPoints.Clear(); pUsedPoints = null; CtrPointIDList.Clear(); CtrPointIDList = null; pParcelsList.Clear(); pParcelsList = null; pOrphanPointsList.Clear(); pOrphanPointsList = null; pPointsInsideBoxList.Clear(); pPointsInsideBoxList = null; pLineToParcelIDRef.Clear(); pLineToParcelIDRef = null; sFromToPair.Clear(); sFromToPair = null; FabricUTILS = null; } #endregion }
protected override void OnClick() { IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); //first get the selected parcel features UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); Marshal.ReleaseComObject(pUID); IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); IFeatureLayer CFPointLayer = null; IFeatureLayer CFLineLayer = null; IFeatureLayer CFControlLayer = null; IFeatureLayer CFLinePointLayer = null; IActiveView pActiveView = ArcMap.Document.ActiveView; IMap pMap = pActiveView.FocusMap; ICadastralFabric pCadFabric = null; IProgressDialog2 pProgressorDialog = null; clsFabricUtils UTILS = new clsFabricUtils(); //if we're in an edit session then grab the target fabric if (pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } if (pCadFabric == null) {//find the first fabric in the map if (!UTILS.GetFabricFromMap(pMap, out pCadFabric)) { MessageBox.Show ("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } IArray CFParcelLayers = new ArrayClass(); if (!(UTILS.GetFabricSubLayersFromFabric(pMap, pCadFabric, out CFPointLayer, out CFLineLayer, out CFParcelLayers, out CFControlLayer, out CFLinePointLayer))) { return; //no fabric sublayers available for the targeted fabric } bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersioned = false; IWorkspace pWS = null; try { //Get the selection of parcels IFeatureLayer pFL = (IFeatureLayer)CFParcelLayers.get_Element(0); IDataset pDS = (IDataset)pFL.FeatureClass; pWS = pDS.Workspace; if (!UTILS.SetupEditEnvironment(pWS, pCadFabric, pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersioned)) { return; } if (bUseNonVersioned) { ICadastralFabricLayer pCFLayer = new CadastralFabricLayerClass(); pCFLayer.CadastralFabric = pCadFabric; pCadEd.CadastralFabricLayer = pCFLayer;//NOTE: Need to set this back to NULL when done. } Hashtable FabLyrToFieldMap = new Hashtable(); DateChanger pDateChangerDialog = new DateChanger(); pDateChangerDialog.cboBoxFabricClasses.Items.Clear(); string[] FieldStrArr = new string[CFParcelLayers.Count]; for (int i = 0; i < CFParcelLayers.Count; i++) { FieldStrArr[i] = ""; IFeatureLayer lyr = (IFeatureLayer)CFParcelLayers.get_Element(i); // ICadastralFabricLayer cflyr = CFParcelLayers.get_Element(i); pDateChangerDialog.cboBoxFabricClasses.Items.Add(lyr.Name); IFields pFlds = lyr.FeatureClass.Fields; for (int j = 0; j < lyr.FeatureClass.Fields.FieldCount; j++) { IField pFld = lyr.FeatureClass.Fields.get_Field(j); if (pFld.Type == esriFieldType.esriFieldTypeDate) { if (FieldStrArr[i].Trim() == "") { FieldStrArr[i] = pFld.Name; } else { FieldStrArr[i] += "," + pFld.Name; } } } FabLyrToFieldMap.Add(i, FieldStrArr[i]); } pDateChangerDialog.FieldMap = FabLyrToFieldMap; pDateChangerDialog.cboBoxFabricClasses.SelectedIndex = 0; // ******** Display the dialog ********* DialogResult pDialogResult = pDateChangerDialog.ShowDialog(); if (pDialogResult != DialogResult.OK) { return; } //************************ //*** get the choices from the dialog IFeatureLayer flyr = (IFeatureLayer)CFParcelLayers.get_Element(pDateChangerDialog.cboBoxFabricClasses.SelectedIndex); int iDateFld = flyr.FeatureClass.Fields.FindField(pDateChangerDialog.cboBoxFields.Text); if (pDateChangerDialog.radioButton2.Checked) { IField pFld = flyr.FeatureClass.Fields.get_Field(iDateFld); if (!pFld.IsNullable) { MessageBox.Show("The field you selected does not allow NULL values, and must have a date." + Environment.NewLine + "Please try again using the date option, or using a different date field.", "Field does not Allow Null", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } ICadastralFabricSubLayer pSubLyr = (ICadastralFabricSubLayer)flyr; bool bLines = false; bool bParcels = false; if (pSubLyr.CadastralTableType == esriCadastralFabricTable.esriCFTLines) { bLines = true; } if (pSubLyr.CadastralTableType == esriCadastralFabricTable.esriCFTParcels) { bParcels = true; } //find out if there is a selection for the chosen layer bool ChosenLayerHasSelection = false; IFeatureSelection pFeatSel = null; ISelectionSet2 pSelSet = null; ICadastralSelection pCadaSel = null; IEnumGSParcels pEnumGSParcels = null; int iFeatureCnt = 0; pFeatSel = (IFeatureSelection)flyr; if (pFeatSel != null) { pSelSet = (ISelectionSet2)pFeatSel.SelectionSet; ChosenLayerHasSelection = (pSelSet.Count > 0); iFeatureCnt = pSelSet.Count; } //**** if (iFeatureCnt == 0) { if (MessageBox.Show("There are no features selected in the " + flyr.Name + " layer." + Environment.NewLine + "Click OK to Change dates for ALL features in the layer.", "No Selection", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } } else { pCadaSel = (ICadastralSelection)pCadEd; //** TODO: this enum should be based on the selected points, lines, or line-points pEnumGSParcels = pCadaSel.SelectedParcels;// need to get the parcels before trying to get the parcel count: BUG workaround //*** } if (iFeatureCnt == 0) { m_pCursor = (ICursor)flyr.FeatureClass.Search(null, false); ITable pTable = (ITable)flyr.FeatureClass; iFeatureCnt = pTable.RowCount(null); } m_bShowProgressor = (iFeatureCnt > 10); if (m_bShowProgressor) { m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, ArcMap.Application.hWnd); pProgressorDialog = (IProgressDialog2)m_pStepProgressor; m_pStepProgressor.MinRange = 1; m_pStepProgressor.MaxRange = iFeatureCnt; m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; } m_pQF = new QueryFilterClass(); string sPref; string sSuff; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); //====== need to do this for all the parcel sublayers in the map that are part of the target fabric if (m_bShowProgressor) { pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Collecting data..."; } bool bCont = true; m_pFIDSetParcels = new FIDSetClass(); if (ChosenLayerHasSelection && bParcels && !bIsUnVersioned) { //if there is a selection add the OIDs of all the selected parcels into a new feature IDSet pEnumGSParcels.Reset(); IGSParcel pGSParcel = pEnumGSParcels.Next(); while (pGSParcel != null) { //Check if the cancel button was pressed. If so, stop process if (m_bShowProgressor) { bCont = m_pTrackCancel.Continue(); if (!bCont) { break; } } m_pFIDSetParcels.Add(pGSParcel.DatabaseId); Marshal.ReleaseComObject(pGSParcel); //garbage collection pGSParcel = pEnumGSParcels.Next(); //} if (m_bShowProgressor) { if (m_pStepProgressor.Position < m_pStepProgressor.MaxRange) { m_pStepProgressor.Step(); } } } } if ((!ChosenLayerHasSelection && bParcels && !bIsUnVersioned) || (!ChosenLayerHasSelection && bLines && !bIsUnVersioned)) { IRow pRow = m_pCursor.NextRow(); while (pRow != null) { m_pFIDSetParcels.Add(pRow.OID); Marshal.ReleaseComObject(pRow); pRow = m_pCursor.NextRow(); } Marshal.ReleaseComObject(m_pCursor); } if (bLines && ChosenLayerHasSelection && !bIsUnVersioned) { pSelSet.Search(null, false, out m_pCursor); IRow pRow = m_pCursor.NextRow(); int iFld = m_pCursor.FindField("PARCELID"); while (pRow != null) { m_pFIDSetParcels.Add((int)pRow.get_Value(iFld)); Marshal.ReleaseComObject(pRow); pRow = m_pCursor.NextRow(); } Marshal.ReleaseComObject(m_pCursor); } //========================================================= if (!bCont) { //Since I'm using update cursor need to clear the cadastral selection pCadaSel.SelectedParcels = null; //clear selection, to make sure the parcel explorer is updated and refreshed properly return; } string sTime = ""; if (!bIsUnVersioned) { //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 CadastralJobClass(); pJob.Name = sTime; pJob.Owner = System.Windows.Forms.SystemInformation.UserName; pJob.Description = "Change Date on selected parcels"; 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); } m_pStepProgressor = null; if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pProgressorDialog = null; if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; } return; } } //if we're in an enterprise then test for edit locks ICadastralFabricLocks pFabLocks = (ICadastralFabricLocks)pCadFabric; if (!bIsUnVersioned) { pFabLocks.LockingJob = sTime; ILongArray pLocksInConflict = null; ILongArray pSoftLcksInConflict = null; ILongArray pParcelsToLock = new LongArrayClass(); UTILS.FIDsetToLongArray(m_pFIDSetParcels, ref pParcelsToLock, m_pStepProgressor); if (m_pStepProgressor != null && !bIsFileBasedGDB) { m_pStepProgressor.Message = "Testing for edit locks on parcels..."; } try { pFabLocks.AcquireLocks(pParcelsToLock, true, ref pLocksInConflict, ref pSoftLcksInConflict); } catch (COMException pCOMEx) { if (pCOMEx.ErrorCode == (int)fdoError.FDO_E_CADASTRAL_FABRIC_JOB_LOCK_ALREADY_EXISTS) { 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(); //clear selection, to make sure the parcel explorer is updated and refreshed properly RefreshMap(pActiveView, CFParcelLayers, CFPointLayer, CFLineLayer, CFControlLayer, CFLinePointLayer); } else { MessageBox.Show(Convert.ToString(pCOMEx.ErrorCode)); } if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; } return; } } //Now... start the edit. Start an edit operation. if (pEd.EditState == esriEditState.esriStateEditing) { pEd.StartOperation(); } if (bUseNonVersioned) { if (!UTILS.StartEditing(pWS, bUseNonVersioned)) { if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; } return; } } //Change all the date records if (m_pStepProgressor != null) { m_pStepProgressor.Message = "Changing dates..."; } bool bSuccess = true; ITable Table2Edit = (ITable)flyr.FeatureClass; ITableWrite pTableWr = (ITableWrite)Table2Edit; if (ChosenLayerHasSelection) { //TODO: Selection based update does not work on unversioned tables //need to change this code to create an update cursor from the selection, //including code for tokens > 995 pSelSet.Update(null, false, out m_pCursor); } else { if (bUseNonVersioned) { m_pCursor = pTableWr.UpdateRows(null, false); } else { m_pCursor = Table2Edit.Update(null, false); } } ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; if (bLines) { pSchemaEd.ReleaseReadOnlyFields(Table2Edit, esriCadastralFabricTable.esriCFTLines); //release safety-catch } else if (bParcels) { pSchemaEd.ReleaseReadOnlyFields(Table2Edit, esriCadastralFabricTable.esriCFTParcels); //release safety-catch } else { pSchemaEd.ReleaseReadOnlyFields(Table2Edit, esriCadastralFabricTable.esriCFTPoints); //release safety-catch pSchemaEd.ReleaseReadOnlyFields(Table2Edit, esriCadastralFabricTable.esriCFTControl); //release safety-catch pSchemaEd.ReleaseReadOnlyFields(Table2Edit, esriCadastralFabricTable.esriCFTLinePoints); //release safety-catch } if (pDateChangerDialog.radioButton2.Checked) { bSuccess = UTILS.ChangeDatesOnTable(m_pCursor, pDateChangerDialog.cboBoxFields.Text, "", bUseNonVersioned, m_pStepProgressor, m_pTrackCancel); } else { bSuccess = UTILS.ChangeDatesOnTable(m_pCursor, pDateChangerDialog.cboBoxFields.Text, pDateChangerDialog.dateTimePicker1.Text, bUseNonVersioned, m_pStepProgressor, m_pTrackCancel); } if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } if (bUseNonVersioned) { UTILS.AbortEditing(pWS); } else { pEd.AbortOperation(); } //clear selection, to make sure the parcel explorer is updated and refreshed properly return; } if (pEd.EditState == esriEditState.esriStateEditing) { pEd.StopOperation("Change Date"); } if (bUseNonVersioned) { UTILS.StopEditing(pWS); } if (bParcels) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); } else if (bLines) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTLines); } else { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); //release safety-catch pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl); //release safety-catch pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTLinePoints); //release safety-catch } } catch (Exception ex) { MessageBox.Show("Error:" + ex.Message); if (bUseNonVersioned) { UTILS.AbortEditing(pWS); } else { pEd.AbortOperation(); } } finally { RefreshMap(pActiveView, CFParcelLayers, CFPointLayer, CFLineLayer, CFControlLayer, CFLinePointLayer); if (bUseNonVersioned) { pCadEd.CadastralFabricLayer = null; CFParcelLayers = null; CFPointLayer = null; CFLineLayer = null; CFControlLayer = null; CFLinePointLayer = null; } m_pStepProgressor = null; if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pProgressorDialog = null; } }
protected override void OnClick() { m_bNoUpdates = false; m_sReport = "Direction Inverse Report:"; IEditor m_pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); if (m_pEd.EditState == esriEditState.esriStateNotEditing) { MessageBox.Show("Please start editing first, and try again.", "Start Editing"); return; } UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); //check if there is a Manual Mode "modify" job active =========== ICadastralPacketManager pCadPacMan = (ICadastralPacketManager)pCadExtMan; if (pCadPacMan.PacketOpen) { MessageBox.Show("The Delete Parcels command cannot be used when there is an open job.\r\nPlease finish or discard the open job, and try again.", "Delete Selected Parcels"); return; } try { IEditProperties2 pEditorProps2 = (IEditProperties2)m_pEd; IArray LineLyrArr; IMap pMap = m_pEd.Map; ICadastralFabric pCadFabric = null; //ISpatialReference pSpatRef = m_pEd.Map.SpatialReference; //IProjectedCoordinateSystem2 pPCS = null; IActiveView pActiveView = ArcMap.Document.ActiveView; //double dMetersPerUnit = 1; //if (pSpatRef == null) // ; //else if (pSpatRef is IProjectedCoordinateSystem2) //{ // pPCS = (IProjectedCoordinateSystem2)pSpatRef; // string sUnit = pPCS.CoordinateUnit.Name; // if (sUnit.Contains("Foot") && sUnit.Contains("US")) // sUnit = "U.S. Feet"; // dMetersPerUnit = pPCS.CoordinateUnit.MetersPerUnit; //} IAngularConverter pAngConv = new AngularConverterClass(); Utilities Utils = new Utilities(); if (!Utils.GetFabricSubLayers(pMap, esriCadastralFabricTable.esriCFTLines, out LineLyrArr)) { return; } //if we're in an edit session then grab the target fabric if (m_pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } if (pCadFabric == null) {//find the first fabric in the map if (!Utils.GetFabricFromMap(pMap, out pCadFabric)) { MessageBox.Show ("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } List <int> lstLineIds = new List <int>(); IFeatureClass pFabricLinesFC = (IFeatureClass)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLines); int idxParcelIDFld = pFabricLinesFC.Fields.FindField("ParcelID"); int idxCENTERPTID = pFabricLinesFC.Fields.FindField("CenterPointID"); int idxRADIUS = pFabricLinesFC.Fields.FindField("Radius"); bool bFieldsPresent = true; if (idxParcelIDFld == -1) { bFieldsPresent = false; } if (idxCENTERPTID == -1) { bFieldsPresent = false; } if (idxRADIUS == -1) { bFieldsPresent = false; } if (!bFieldsPresent) { MessageBox.Show("Fields missing."); return; } Dictionary <int, List <string> > dictLineToCurveNeighbourData = new Dictionary <int, List <string> >(); m_pFIDSetParcels = new FIDSet(); for (int i = 0; i < LineLyrArr.Count; i++) { IFeatureSelection pFeatSel = LineLyrArr.Element[i] as IFeatureSelection; ISelectionSet pSelSet = pFeatSel.SelectionSet; ICursor pCursor = null; pSelSet.Search(null, false, out pCursor); IFeature pLineFeat = pCursor.NextRow() as IFeature; while (pLineFeat != null) { if (!lstLineIds.Contains(pLineFeat.OID)) { IGeometry pGeom = pLineFeat.ShapeCopy; ISegmentCollection pSegColl = pGeom as ISegmentCollection; ISegment pSeg = null; if (pSegColl.SegmentCount == 1) { pSeg = pSegColl.get_Segment(0); } else { //todo: but for now, only deals with single segment short segments Marshal.ReleaseComObject(pLineFeat); pLineFeat = pCursor.NextRow() as IFeature; continue; } //check geometry for circular arc if (pSeg is ICircularArc) { object dVal1 = pLineFeat.get_Value(idxRADIUS); object dVal2 = pLineFeat.get_Value(idxCENTERPTID); ICircularArc pCircArc = pSeg as ICircularArc; if (dVal1 != DBNull.Value && dVal2 != DBNull.Value) { Marshal.ReleaseComObject(pLineFeat); pLineFeat = pCursor.NextRow() as IFeature; continue; } } //query near lines int iFoundTangent = 0; List <string> sCurveInfoFromNeighbours = new List <string>(); if (Utils.HasTangentCurveMatchFeatures(pFabricLinesFC, (IPolycurve)pGeom, "", 1.5, 0.033, 1, (pSeg.Length * 1.1), out iFoundTangent, ref sCurveInfoFromNeighbours)) { lstLineIds.Add(pLineFeat.OID); int j = (int)pLineFeat.get_Value(idxParcelIDFld); m_pFIDSetParcels.Add(j); dictLineToCurveNeighbourData.Add(pLineFeat.OID, sCurveInfoFromNeighbours); } if (iFoundTangent == 1) //if there's only one tangent look further afield { int iFoundLinesCount = 0; int iFoundParallel = 0; if (Utils.HasParallelCurveMatchFeatures(pFabricLinesFC, (IPolycurve)pGeom, "", 1.5, 70, out iFoundLinesCount, out iFoundParallel, ref sCurveInfoFromNeighbours)) { if (!dictLineToCurveNeighbourData.ContainsKey(pLineFeat.OID)) { dictLineToCurveNeighbourData.Add(pLineFeat.OID, sCurveInfoFromNeighbours); } } } } Marshal.ReleaseComObject(pLineFeat); pLineFeat = pCursor.NextRow() as IFeature; } Marshal.ReleaseComObject(pCursor); } #region line to curve candidate analysis if (lstLineIds.Count == 0) { return; } RefineToBestRadiusAndCenterPoint(dictLineToCurveNeighbourData); #endregion if (dictLineToCurveNeighbourData.Count == 0) { return; } bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersionedDelete = false; IWorkspace pWS = m_pEd.EditWorkspace; IProgressDialog2 pProgressorDialog = null; IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); if (!Utils.SetupEditEnvironment(pWS, pCadFabric, m_pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersionedDelete)) { 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 CadastralJobClass(); 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 int[] pParcelIds = new int[m_pFIDSetParcels.Count()]; ILongArray pParcelsToLock = new LongArrayClass(); Utils.FIDsetToLongArray(m_pFIDSetParcels, ref pParcelsToLock, ref pParcelIds, m_pStepProgressor); if (!bIsUnVersioned && !bIsFileBasedGDB) { pFabLocks.LockingJob = sTime; ILongArray pLocksInConflict = null; ILongArray pSoftLcksInConflict = null; if (m_bShowProgressor && !bIsFileBasedGDB) { m_pStepProgressor.Message = "Testing for edit locks on parcels..."; } try { pFabLocks.AcquireLocks(pParcelsToLock, 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.EditState == esriEditState.esriStateEditing) { try { m_pEd.StartOperation(); } catch { m_pEd.AbortOperation();//abort any open edit operations and try again m_pEd.StartOperation(); } } if (bUseNonVersionedDelete) { if (!Utils.StartEditing(pWS, bIsUnVersioned)) { return; } } ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; pSchemaEd.ReleaseReadOnlyFields((ITable)pFabricLinesFC, esriCadastralFabricTable.esriCFTLines); //release for edits m_pQF = new QueryFilter(); // m_pEd.StartOperation(); List <string> sInClauseList = Utils.InClauseFromOIDsList(lstLineIds, 995); foreach (string InClause in sInClauseList) { m_pQF.WhereClause = pFabricLinesFC.OIDFieldName + " IN (" + InClause + ")"; if (!UpdateCircularArcValues((ITable)pFabricLinesFC, m_pQF, bIsUnVersioned, dictLineToCurveNeighbourData)) { ; } } m_pEd.StopOperation("Insert missing circular arc information."); } catch (Exception ex) { MessageBox.Show(ex.Message); m_pEd.AbortOperation(); } finally { } }
protected override void OnClick() { IApplication pApp; ICadastralFabric m_pCadaFab; IQueryFilter m_pQF; #region Get Fabric pApp = (IApplication)ArcMap.Application; if (pApp == null) { //if the app is null then could be running from ArcCatalog pApp = (IApplication)ArcCatalog.Application; } if (pApp == null) { MessageBox.Show("Could not access the application.", "No Application found"); return; } IGxApplication pGXApp = (IGxApplication)pApp; stdole.IUnknown pUnk = null; try { pUnk = (stdole.IUnknown)pGXApp.SelectedObject.InternalObjectName.Open(); } catch (COMException ex) { if (ex.ErrorCode == (int)fdoError.FDO_E_DATASET_TYPE_NOT_SUPPORTED_IN_RELEASE || ex.ErrorCode == -2147220944) { MessageBox.Show("The dataset is not supported in this release.", "Could not open the dataset"); } else { MessageBox.Show(ex.ErrorCode.ToString(), "Could not open the dataset"); } return; } if (pUnk is ICadastralFabric) { m_pCadaFab = (ICadastralFabric)pUnk; } else { MessageBox.Show("Please select a parcel fabric and try again.", "Not a parcel fabric"); return; } #endregion IFeatureClass pFabricPointClass = (IFeatureClass)m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); IDataset pDS = (IDataset)pFabricPointClass; IWorkspace pWS = pDS.Workspace; bool bIsFileBasedGDB = true; bool bIsUnVersioned = true; Utilities FabricUTILS = new Utilities(); FabricUTILS.GetFabricPlatform(pWS, m_pCadaFab, out bIsFileBasedGDB, out bIsUnVersioned); if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) { return; } m_pQF = new QueryFilterClass(); m_pQF.WhereClause = ""; int iChangePointCount = 0; try { //next need to use an in clause to update the points, ... ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)m_pCadaFab; pSchemaEd.ReleaseReadOnlyFields((ITable)pFabricPointClass, esriCadastralFabricTable.esriCFTPoints); IGeoDataset pGeoDS = (IGeoDataset)pFabricPointClass; ISpatialReferenceTolerance pSRTol = (ISpatialReferenceTolerance)pGeoDS.SpatialReference; double dTolerance = pSRTol.XYTolerance; if (!UpdatePointXYFromGeometry((ITable)pFabricPointClass, m_pQF, (bIsUnVersioned || bIsFileBasedGDB), dTolerance, out iChangePointCount)) { FabricUTILS.AbortEditing(pWS); return; } FabricUTILS.StopEditing(pWS); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints); MessageBox.Show("Updated " + iChangePointCount.ToString() + " points that had coordinates different" + Environment.NewLine + "from their geometry by more than " + dTolerance.ToString("0.00000000").TrimEnd('0'), "Coordinate Inverse", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message); FabricUTILS.AbortEditing(pWS); } finally { } }
protected override void OnClick() { m_pApp = (IApplication)ArcMap.Application; if (m_pApp == null) { //if the app is null then could be running from ArcCatalog m_pApp = (IApplication)ArcCatalog.Application; } if (m_pApp == null) { MessageBox.Show("Could not access the application.", "No Application found"); return; } IGxApplication pGXApp = (IGxApplication)m_pApp; stdole.IUnknown pUnk = null; try { pUnk = (stdole.IUnknown)pGXApp.SelectedObject.InternalObjectName.Open(); } catch (COMException ex) { if (ex.ErrorCode == (int)fdoError.FDO_E_DATASET_TYPE_NOT_SUPPORTED_IN_RELEASE || ex.ErrorCode == -2147220944) { MessageBox.Show("The dataset is not supported in this release.", "Could not open the dataset"); } else { MessageBox.Show(ex.ErrorCode.ToString(), "Could not open the dataset"); } return; } if (pUnk is ICadastralFabric) { m_pCadaFab = (ICadastralFabric)pUnk; } else { MessageBox.Show("Please select a parcel fabric and try again.", "Not a parcel fabric"); return; } IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); Utils FabricUTILS = new Utils(); ITable pTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); IDataset pDS = (IDataset)pTable; IWorkspace pWS = pDS.Workspace; bool bIsFileBasedGDB = true; bool bIsUnVersioned = true; FabricUTILS.GetFabricPlatform(pWS, m_pCadaFab, out bIsFileBasedGDB, out bIsUnVersioned); //Do a Start and Stop editing to make sure we're not running in an edit session if (!FabricUTILS.StartEditing(pWS, true)) {//if start editing fails then bail if (pUnk != null) { Marshal.ReleaseComObject(pUnk); } Cleanup(pMouseCursor, null, pTable, null, pWS, null); FabricUTILS = null; return; } FabricUTILS.StopEditing(pWS); IFIDSet pPlansToDelete = null; try { string[] SummaryNames = new string[0]; //define as dynamic array string[] RepeatPlans = new string[0]; //define as dynamic array ITable pPlansTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTPlans); //load all the plan names into a string array m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, m_pApp.hWnd); IProgressDialog2 pProgressorDialog = (IProgressDialog2)m_pStepProgressor; int iRowCount = pPlansTable.RowCount(null); m_pStepProgressor.MinRange = 1; m_pStepProgressor.MaxRange = iRowCount * 2; m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Finding same-name plans to merge..."; int iRepeatCnt = 0; if (!FindRepeatPlans(pPlansTable, out RepeatPlans, out SummaryNames, out iRepeatCnt)) { pProgressorDialog.HideDialog(); if (iRepeatCnt == 0) { MessageBox.Show("All plans in the fabric have unique names." + Environment.NewLine + "There are no plans to merge.", "Merge plans by name"); } else { MessageBox.Show("There was a problem searching for repeat plans.", "Merge plans by name"); } SummaryNames = null; RepeatPlans = null; Cleanup(pMouseCursor, null, pTable, pPlansTable, pWS, pProgressorDialog); return; } dlgMergeSameNamePlans TheSummaryDialog = new dlgMergeSameNamePlans(); FillTheSummaryList(TheSummaryDialog, SummaryNames); DialogResult dResult = TheSummaryDialog.ShowDialog(); if (dResult == DialogResult.Cancel) { pProgressorDialog.HideDialog(); SummaryNames = null; RepeatPlans = null; Cleanup(pMouseCursor, null, pTable, pPlansTable, pWS, pProgressorDialog); pPlansTable = null; return; } //get the time now m_pStartTime = new TimeClass(); m_pStartTime.SetFromCurrentLocalTime(); Dictionary <int, int> Lookup = new Dictionary <int, int>(); string[] InClause = new string[0]; //define as dynamic array m_pStepProgressor.Message = "Creating the merge query..."; FabricUTILS.BuildSearchMapAndQuery(RepeatPlans, out Lookup, out InClause, out pPlansToDelete); ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)m_pCadaFab; ITable ParcelTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); pSchemaEd.ReleaseReadOnlyFields(ParcelTable, esriCadastralFabricTable.esriCFTParcels); //release safety-catch if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) { Cleanup(pMouseCursor, pPlansToDelete, pTable, pPlansTable, pWS, pProgressorDialog); InClause = null; Lookup.Clear(); Lookup = null; return; } //setup progressor dialog for merge m_pStepProgressor.Message = "Moving parcels from source to target plans..."; if (!FabricUTILS.MergePlans(ParcelTable, Lookup, InClause, bIsUnVersioned, m_pStepProgressor, m_pTrackCancel)) { FabricUTILS.AbortEditing(pWS); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); Cleanup(pMouseCursor, pPlansToDelete, pTable, pPlansTable, pWS, pProgressorDialog); InClause = null; Lookup.Clear(); Lookup = null; return; } if (TheSummaryDialog.checkBox1.Checked) { //setup progressor dialog for Delete m_pStepProgressor.MaxRange = pPlansToDelete.Count(); m_pStepProgressor.Message = "Deleting source plans..."; if (bIsUnVersioned) { if (!FabricUTILS.DeleteRowsUnversioned(pWS, pPlansTable, pPlansToDelete, m_pStepProgressor, m_pTrackCancel)) { Cleanup(pMouseCursor, pPlansToDelete, pTable, pPlansTable, pWS, pProgressorDialog); } } else { if (!FabricUTILS.DeleteRowsByFIDSet(pPlansTable, pPlansToDelete, m_pStepProgressor, m_pTrackCancel)) { Cleanup(pMouseCursor, pPlansToDelete, pTable, pPlansTable, pWS, pProgressorDialog); } } } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); m_pEndTime = new TimeClass(); m_pEndTime.SetFromCurrentLocalTime(); ITimeDuration HowLong = m_pEndTime.SubtractTime(m_pStartTime); m_pStepProgressor.Message = "[" + HowLong.Hours.ToString("00") + "h " + HowLong.Minutes.ToString("00") + "m " + HowLong.Seconds.ToString("00") + "s]" + " Saving changes...please wait."; FabricUTILS.StopEditing(pWS); Cleanup(pMouseCursor, pPlansToDelete, pTable, pPlansTable, pWS, pProgressorDialog); } catch (COMException ex) { MessageBox.Show(Convert.ToString(ex.ErrorCode)); Cleanup(pMouseCursor, pPlansToDelete, pTable, null, pWS, null); } }
protected override void OnClick() { m_pApp = (IApplication)ArcMap.Application; if (m_pApp == null) { //if the app is null then could be running from ArcCatalog m_pApp = (IApplication)ArcCatalog.Application; } if (m_pApp == null) { MessageBox.Show("Could not access the application.", "No Application found"); return; } IGxApplication pGXApp = (IGxApplication)m_pApp; stdole.IUnknown pUnk = null; try { pUnk = (stdole.IUnknown)pGXApp.SelectedObject.InternalObjectName.Open(); } catch (COMException ex) { if (ex.ErrorCode == (int)fdoError.FDO_E_DATASET_TYPE_NOT_SUPPORTED_IN_RELEASE || ex.ErrorCode == -2147220944) { MessageBox.Show("The dataset is not supported in this release.", "Could not open the dataset"); } else { MessageBox.Show(ex.ErrorCode.ToString(), "Could not open the dataset"); } return; } if (pUnk is ICadastralFabric) { m_pCadaFab = (ICadastralFabric)pUnk; } else { MessageBox.Show("Please select a parcel fabric and try again.", "Not a parcel fabric"); return; } IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); Utils FabricUTILS = new Utils(); ITable pTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); IDataset pDS = (IDataset)pTable; IWorkspace pWS = pDS.Workspace; bool bIsFileBasedGDB = true; bool bIsUnVersioned = true; FabricUTILS.GetFabricPlatform(pWS, m_pCadaFab, out bIsFileBasedGDB, out bIsUnVersioned); //Do a Start and Stop editing to make sure we're not running in an edit session if (!FabricUTILS.StartEditing(pWS, true)) {//if start editing fails then bail if (pUnk != null) { Marshal.ReleaseComObject(pUnk); } Cleanup(pMouseCursor, null, pTable, null, pWS, null, true); FabricUTILS = null; return; } FabricUTILS.StopEditing(pWS); ITable pPlansTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTPlans); ITable pParcelsTable = m_pCadaFab.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, m_pApp.hWnd); IProgressDialog2 pProgressorDialog = (IProgressDialog2)m_pStepProgressor; int iRowCount = pPlansTable.RowCount(null); int iRowCount2 = pParcelsTable.RowCount(null); m_pStepProgressor.MinRange = 1; m_pStepProgressor.MaxRange = iRowCount + iRowCount2; m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Searching " + iRowCount2.ToString() + " parcel records..."; int iFixCnt = 0; //load all the plan names into a string array ArrayList NoPlanParcels = new ArrayList(); ArrayList NoPlanParcelsGrouped = new ArrayList(); ArrayList PlansList = new ArrayList(); Dictionary <int, int> ParcelLookup = new Dictionary <int, int>(); if (!FindNoPlanParcels(pPlansTable, pParcelsTable, ref PlansList, ref NoPlanParcels, ref NoPlanParcelsGrouped, ref ParcelLookup, out iFixCnt)) { pProgressorDialog.HideDialog(); if (iFixCnt > 0) { MessageBox.Show("Canceled searching for parcels with no plan.", "Fix Parcels With No Name"); } NoPlanParcels = null; Cleanup(pMouseCursor, null, pTable, pPlansTable, pWS, pProgressorDialog, true); return; } m_pStepProgressor.Message = "Search complete."; NoPlanParcels.Sort(); dlgFixParcelsWithNoPlan MissingPlansDialog = new dlgFixParcelsWithNoPlan(); FillTheList(MissingPlansDialog.listView1, NoPlanParcels); FillTheList(MissingPlansDialog.listViewByGroup, NoPlanParcelsGrouped); FillTheListBox(MissingPlansDialog.listPlans, PlansList); MissingPlansDialog.ThePlansList = PlansList; MissingPlansDialog.label1.Text = "Found " + iFixCnt.ToString() + " parcels that have a missing plan record."; MissingPlansDialog.lblSelectionCount.Text = "(" + iFixCnt.ToString() + " of " + iFixCnt.ToString() + " selected to fix)"; //cleanup Cleanup(null, null, null, null, null, pProgressorDialog, false); DialogResult dResult = MissingPlansDialog.ShowDialog(); if (dResult == DialogResult.Cancel) { Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); return; } //re-initilize the progressor m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, m_pApp.hWnd); pProgressorDialog = (IProgressDialog2)m_pStepProgressor; m_pStepProgressor.MinRange = 1; m_pStepProgressor.MaxRange = MissingPlansDialog.listView1.CheckedItems.Count; m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Fixing parcels without a plan..."; if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) { pProgressorDialog.HideDialog(); Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); FabricUTILS = null; return; } int iNewPlanID = 0; //Need to collect the choices from the UI and write the results to the DB ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)m_pCadaFab; if (MissingPlansDialog.radioBtnExistingPlan.Checked) {//Get the id of the EXISTING Plan string sPlanString = MissingPlansDialog.listPlans.SelectedItem.ToString(); string[] sPlanOID = Regex.Split(sPlanString, "oid:"); sPlanOID[1].Trim(); iNewPlanID = Convert.ToInt32(sPlanOID[1].Remove(sPlanOID[1].LastIndexOf(")"))); } Dictionary <string, int> PlanLookUp = new Dictionary <string, int>(); ArrayList iUnitsAndFormat = new ArrayList(); iUnitsAndFormat.Add(m_AngleUnits); iUnitsAndFormat.Add(m_AreaUnits); iUnitsAndFormat.Add(m_DistanceUnits); iUnitsAndFormat.Add(m_DirectionFormat); iUnitsAndFormat.Add(m_LineParams); if (MissingPlansDialog.radioBtnUserDef.Checked) { //create a NEW plan named with user's entered text ArrayList sPlanInserts = new ArrayList(); pSchemaEd.ReleaseReadOnlyFields(pPlansTable, esriCadastralFabricTable.esriCFTPlans); //release safety-catch sPlanInserts.Add(MissingPlansDialog.txtPlanName.Text); FabricUTILS.InsertPlanRecords(pPlansTable, sPlanInserts, iUnitsAndFormat, PlansList, bIsUnVersioned, null, null, ref PlanLookUp); if (!PlanLookUp.TryGetValue(MissingPlansDialog.txtPlanName.Text, out iNewPlanID)) { Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); FabricUTILS = null; return; } } if (MissingPlansDialog.radioBtnPlanID.Checked) {//create multiple new plans for each PlanID ArrayList sPlanInserts = new ArrayList(); foreach (ListViewItem listItem in MissingPlansDialog.listViewByGroup.CheckedItems) { sPlanInserts.Add("[" + listItem.SubItems[0].Text + "]"); } pSchemaEd.ReleaseReadOnlyFields(pPlansTable, esriCadastralFabricTable.esriCFTPlans); //release safety-catch FabricUTILS.InsertPlanRecords(pPlansTable, sPlanInserts, iUnitsAndFormat, PlansList, bIsUnVersioned, null, null, ref PlanLookUp); } ArrayList sParcelUpdates = new ArrayList(); sParcelUpdates.Add(""); int i = 0; int iCnt = 0; int iTokenLimit = 995; foreach (ListViewItem listItem in MissingPlansDialog.listView1.CheckedItems) { string s = listItem.SubItems[1].Text; string[] sItems = Regex.Split(s, "id:"); if (iCnt >= iTokenLimit) //time to start a new row { sParcelUpdates.Add(""); //add a new item to the arraylist iCnt = 0; //reset token counter i++; //increment array index } sItems[1] = sItems[1].Remove(sItems[1].LastIndexOf(")")); if (iCnt == 0) { sParcelUpdates[i] += sItems[1]; } else { sParcelUpdates[i] += "," + sItems[1]; } iCnt++; } //============edit block========== try { pSchemaEd.ReleaseReadOnlyFields(pTable, esriCadastralFabricTable.esriCFTParcels); //release safety-catch if (MissingPlansDialog.radioBtnUserDef.Checked || MissingPlansDialog.radioBtnExistingPlan.Checked) { if (!FabricUTILS.UpdateParcelRecords(pTable, sParcelUpdates, iNewPlanID, bIsUnVersioned, m_pStepProgressor, m_pTrackCancel)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPlans); FabricUTILS.AbortEditing(pWS); Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); FabricUTILS = null; return; } } if (MissingPlansDialog.radioBtnPlanID.Checked) { if (!FabricUTILS.UpdateParcelRecordsByPlanGroup(pTable, sParcelUpdates, PlanLookUp, ParcelLookup, bIsUnVersioned, m_pStepProgressor, m_pTrackCancel)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPlans); FabricUTILS.AbortEditing(pWS); Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); FabricUTILS = null; return; } } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTParcels); pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPlans); FabricUTILS.StopEditing(pWS); //Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); //FabricUTILS = null; } catch (COMException Ex) { MessageBox.Show(Ex.ErrorCode.ToString() + ":" + Ex.Message, "Fix Missing Plans"); } finally { Cleanup(null, null, pTable, pPlansTable, pWS, pProgressorDialog, true); FabricUTILS = null; } }
protected override void OnClick() { IMouseCursor pMouseCursor = new MouseCursorClass(); pMouseCursor.SetCursor(2); //first get the selected parcel features UID pUID = new UIDClass(); pUID.Value = "{114D685F-99B7-4B63-B09F-6D1A41A4DDC1}"; ICadastralExtensionManager2 pCadExtMan = (ICadastralExtensionManager2)ArcMap.Application.FindExtensionByCLSID(pUID); ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByCLSID(pUID); //check if there is a Manual Mode "modify" job active =========== ICadastralPacketManager pCadPacMan = (ICadastralPacketManager)pCadExtMan; if (pCadPacMan.PacketOpen) { MessageBox.Show("The Delete Parcels command cannot be used when there is an open job.\r\nPlease finish or discard the open job, and try again.", "Delete Selected Parcels"); return; } IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); IActiveView pActiveView = ArcMap.Document.ActiveView; IMap pMap = pActiveView.FocusMap; ICadastralFabric pCadFabric = null; clsFabricUtils FabricUTILS = new clsFabricUtils(); IProgressDialog2 pProgressorDialog = null; //if we're in an edit session then grab the target fabric if (pEd.EditState == esriEditState.esriStateEditing) { pCadFabric = pCadEd.CadastralFabric; } if (pCadFabric == null) {//find the first fabric in the map if (!FabricUTILS.GetFabricFromMap(pMap, out pCadFabric)) { MessageBox.Show ("No Parcel Fabric found in the map.\r\nPlease add a single fabric to the map, and try again."); return; } } IArray CFParcelLayers = new ArrayClass(); if (!(FabricUTILS.GetFabricSubLayersFromFabric(pMap, pCadFabric, out CFPointLayer, out CFLineLayer, out CFParcelLayers, out CFControlLayer, out CFLinePointLayer))) { return; //no fabric sublayers available for the targeted fabric } bool bIsFileBasedGDB = false; bool bIsUnVersioned = false; bool bUseNonVersionedDelete = false; IWorkspace pWS = null; ICadastralFabricLayer pCFLayer = null; ITable pParcelsTable = null; ITable pLinesTable = null; ITable pLinePtsTable = null; ITable pPointsTable = null; ITable pControlTable = null; try { //Get the selection of parcels IFeatureLayer pFL = (IFeatureLayer)CFParcelLayers.get_Element(0); IDataset pDS = (IDataset)pFL.FeatureClass; pWS = pDS.Workspace; if (!FabricUTILS.SetupEditEnvironment(pWS, pCadFabric, pEd, out bIsFileBasedGDB, out bIsUnVersioned, out bUseNonVersionedDelete)) { return; } if (bUseNonVersionedDelete) { pCFLayer = new CadastralFabricLayerClass(); pCFLayer.CadastralFabric = pCadFabric; pCadEd.CadastralFabricLayer = pCFLayer;//NOTE: Need to set this back to NULL when done. } ICadastralSelection pCadaSel = (ICadastralSelection)pCadEd; IEnumGSParcels pEnumGSParcels = pCadaSel.SelectedParcels;// need to get the parcels before trying to get the parcel count: BUG workaround IFeatureSelection pFeatSel = (IFeatureSelection)pFL; ISelectionSet2 pSelSet = (ISelectionSet2)pFeatSel.SelectionSet; bMoreThan995UnjoinedParcels = (pSelSet.Count > pCadaSel.SelectedParcelCount); //used for bug workaround if (pCadaSel.SelectedParcelCount == 0 && pSelSet.Count == 0) { MessageBox.Show("Please select some fabric parcels and try again.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Information); pMouseCursor.SetCursor(0); if (bUseNonVersionedDelete) { pCadEd.CadastralFabricLayer = null; CFParcelLayers = null; CFPointLayer = null; CFLineLayer = null; CFControlLayer = null; CFLinePointLayer = null; } return; } if (bMoreThan995UnjoinedParcels) { m_bShowProgressor = (pSelSet.Count > 10); } else { m_bShowProgressor = (pCadaSel.SelectedParcelCount > 10); } if (m_bShowProgressor) { m_pProgressorDialogFact = new ProgressDialogFactoryClass(); m_pTrackCancel = new CancelTrackerClass(); m_pStepProgressor = m_pProgressorDialogFact.Create(m_pTrackCancel, ArcMap.Application.hWnd); pProgressorDialog = (IProgressDialog2)m_pStepProgressor; m_pStepProgressor.MinRange = 1; if (bMoreThan995UnjoinedParcels) { m_pStepProgressor.MaxRange = pSelSet.Count * 18; //(estimate 7 lines per parcel, 4 pts per parcel, 3 line points per parcel, and there is a second loop on parcel list) } else { m_pStepProgressor.MaxRange = pCadaSel.SelectedParcelCount * 18; //(estimate 7 lines per parcel, 4 pts per parcel, 3 line points per parcel, and there is a second loop on parcel list) } m_pStepProgressor.StepValue = 1; pProgressorDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressSpiral; } m_pQF = new QueryFilterClass(); string sPref; string sSuff; ISQLSyntax pSQLSyntax = (ISQLSyntax)pWS; sPref = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix); sSuff = pSQLSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix); //====== need to do this for all the parcel sublayers in the map that are part of the target fabric if (m_bShowProgressor) { pProgressorDialog.ShowDialog(); m_pStepProgressor.Message = "Collecting parcel data..."; } //Add the OIDs of all the selected parcels into a new feature IDSet string[] sOIDList = { "(" }; int tokenLimit = 995; bool bCont = true; int j = 0; int iCounter = 0; m_pFIDSetParcels = new FIDSetClass(); //===================== start bug workaraound for 10.0 client =================== if (bMoreThan995UnjoinedParcels) { ICursor pCursor = null; pSelSet.Search(null, false, out pCursor);//code deletes all selected parcels IFeatureCursor pParcelFeatCurs = (IFeatureCursor)pCursor; IFeature pParcFeat = pParcelFeatCurs.NextFeature(); while (pParcFeat != null) { //Check if the cancel button was pressed. If so, stop process if (m_bShowProgressor) { bCont = m_pTrackCancel.Continue(); if (!bCont) { break; } } bool bExists = false; m_pFIDSetParcels.Find(pParcFeat.OID, out bExists); if (!bExists) { m_pFIDSetParcels.Add(pParcFeat.OID); if (iCounter <= tokenLimit) { sOIDList[j] = sOIDList[j] + Convert.ToString(pParcFeat.OID) + ","; iCounter++; } else {//maximum tokens reached sOIDList[j] = sOIDList[j].Trim(); iCounter = 0; //set up the next OIDList j++; FabricUTILS.RedimPreserveString(ref sOIDList, 1); sOIDList[j] = "("; sOIDList[j] = sOIDList[j] + Convert.ToString(pParcFeat.OID) + ","; } } Marshal.ReleaseComObject(pParcFeat); //garbage collection pParcFeat = pParcelFeatCurs.NextFeature(); if (m_bShowProgressor) { if (m_pStepProgressor.Position < m_pStepProgressor.MaxRange) { m_pStepProgressor.Step(); } } } Marshal.ReleaseComObject(pCursor); //garbage collection //===================== end bug workaraound for 10.0 client =================== } else //===the following code path is preferred====== { pEnumGSParcels.Reset(); IGSParcel pGSParcel = pEnumGSParcels.Next(); while (pGSParcel != null) { //Check if the cancel button was pressed. If so, stop process if (m_bShowProgressor) { bCont = m_pTrackCancel.Continue(); if (!bCont) { break; } } m_pFIDSetParcels.Add(pGSParcel.DatabaseId); if (iCounter <= tokenLimit) { sOIDList[j] = sOIDList[j] + Convert.ToString(pGSParcel.DatabaseId) + ","; iCounter++; } else {//maximum tokens reached sOIDList[j] = sOIDList[j].Trim(); iCounter = 0; //set up the next OIDList j++; FabricUTILS.RedimPreserveString(ref sOIDList, 1); sOIDList[j] = "("; sOIDList[j] = sOIDList[j] + Convert.ToString(pGSParcel.DatabaseId) + ","; } Marshal.ReleaseComObject(pGSParcel); //garbage collection pGSParcel = pEnumGSParcels.Next(); if (m_bShowProgressor) { if (m_pStepProgressor.Position < m_pStepProgressor.MaxRange) { m_pStepProgressor.Step(); } } } Marshal.ReleaseComObject(pEnumGSParcels); //garbage collection } if (!bCont) { AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } 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 CadastralJobClass(); pJob.Name = sTime; pJob.Owner = System.Windows.Forms.SystemInformation.UserName; pJob.Description = "Delete selected parcels"; 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; } } //if we're in an enterprise then test for edit locks ICadastralFabricLocks pFabLocks = (ICadastralFabricLocks)pCadFabric; if (!bIsUnVersioned && !bIsFileBasedGDB) { pFabLocks.LockingJob = sTime; ILongArray pLocksInConflict = null; ILongArray pSoftLcksInConflict = null; ILongArray pParcelsToLock = new LongArrayClass(); FabricUTILS.FIDsetToLongArray(m_pFIDSetParcels, ref pParcelsToLock, m_pStepProgressor); if (m_bShowProgressor && !bIsFileBasedGDB) { m_pStepProgressor.Message = "Testing for edit locks on parcels..."; } try { pFabLocks.AcquireLocks(pParcelsToLock, 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; } } //Build an IDSet of lines for the parcel to be deleted, and build an IDSet of the points for those lines m_pFIDSetLines = new FIDSetClass(); m_pFIDSetPoints = new FIDSetClass(); if (pEd.EditState == esriEditState.esriStateEditing) { try { pEd.StartOperation(); } catch { pEd.AbortOperation();//abort any open edit operations and try again pEd.StartOperation(); } } if (bUseNonVersionedDelete) { if (!FabricUTILS.StartEditing(pWS, bIsUnVersioned)) { return; } } //first delete all the parcel records if (m_bShowProgressor) { m_pStepProgressor.Message = "Deleting parcels..."; } bool bSuccess = true; pParcelsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTParcels); pLinesTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLines); pLinePtsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTLinePoints); pPointsTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTPoints); pControlTable = (ITable)pCadFabric.get_CadastralTable(esriCadastralFabricTable.esriCFTControl); if (!bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsByFIDSet(pParcelsTable, m_pFIDSetParcels, m_pStepProgressor, m_pTrackCancel); } if (bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pParcelsTable, m_pFIDSetParcels, m_pStepProgressor, m_pTrackCancel); } if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } AbortEdits(bUseNonVersionedDelete, pEd, pWS); if (!bIsUnVersioned) { //check version and if the Cancel button was not clicked and we're higher than //version 10.0, then re-try the delete with the core delete command string sVersion = Application.ProductVersion; int iErrCode = FabricUTILS.LastErrorCode; if (!sVersion.StartsWith("10.0") && iErrCode == -2147217400) { FabricUTILS.ExecuteCommand("{B0A62C1C-7FAE-457A-AB25-A966B7254EF6}"); } } return; } //next need to use an in clause for lines, so ... string[] sPointOIDList = { "" }; int iCnt = 0; int iTokenCnt = 0; int iStepCnt = 1; //...for each item in the sOIDList array foreach (string inClause in sOIDList) { ICursor pLineCurs = FabricUTILS.GetCursorFromCommaSeparatedOIDList(pLinesTable, inClause, "PARCELID"); IRow pRow = pLineCurs.NextRow(); Int32 iFromPt = pLinesTable.Fields.FindField("FROMPOINTID"); Int32 iToPt = pLinesTable.Fields.FindField("TOPOINTID"); while (pRow != null) { if (iTokenCnt >= tokenLimit) { FabricUTILS.RedimPreserveString(ref sPointOIDList, 1); iTokenCnt = 0; iCnt++; } m_pFIDSetLines.Add(pRow.OID); Int32 i = (Int32)pRow.get_Value(iFromPt); if (i > -1) { bool bExists = false; m_pFIDSetPoints.Find(i, out bExists); if (!bExists) { m_pFIDSetPoints.Add(i); sPointOIDList[iCnt] = sPointOIDList[iCnt] + Convert.ToString(i) + ","; iTokenCnt++; } } i = (Int32)pRow.get_Value(iToPt); if (i > -1) { bool bExists = false; m_pFIDSetPoints.Find(i, out bExists); if (!bExists) { m_pFIDSetPoints.Add(i); sPointOIDList[iCnt] = sPointOIDList[iCnt] + Convert.ToString(i) + ","; iTokenCnt++; } } Marshal.ReleaseComObject(pRow); //garbage collection pRow = pLineCurs.NextRow(); } Marshal.ReleaseComObject(pLineCurs); //garbage collection //delete line records based on the selected parcels string sMessage = "Deleting lines..."; int iSetCnt = sOIDList.GetLength(0); if (iSetCnt > 1) { sMessage += "Step " + Convert.ToString(iStepCnt) + " of " + Convert.ToString(iSetCnt); } if (m_bShowProgressor) { m_pStepProgressor.Message = sMessage; } if (!bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsByFIDSet(pLinesTable, m_pFIDSetLines, m_pStepProgressor, m_pTrackCancel); } if (bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pLinesTable, m_pFIDSetLines, m_pStepProgressor, m_pTrackCancel); } if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } //delete the line points for the deleted parcels //build the list of the line points that need to be deleted. //IFeatureClass pFeatCLLinePoints = CFLinePointLayer.FeatureClass; string NewInClause = ""; //remove trailing comma if ((inClause.Substring(inClause.Length - 1, 1)) == ",") { NewInClause = inClause.Substring(0, inClause.Length - 1); } //m_pQF.WhereClause = (sPref + "parcelid" + sSuff).Trim() + " IN " + NewInClause + ")"; m_pQF.WhereClause = "PARCELID IN " + NewInClause + ")"; ICursor pLinePointCurs = pLinePtsTable.Search(m_pQF, false); IRow pLinePointFeat = pLinePointCurs.NextRow(); //Build an IDSet of linepoints for parcels to be deleted IFIDSet pFIDSetLinePoints = new FIDSetClass(); while (pLinePointFeat != null) { pFIDSetLinePoints.Add(pLinePointFeat.OID); Marshal.ReleaseComObject(pLinePointFeat); //garbage collection pLinePointFeat = pLinePointCurs.NextRow(); } //===========deletes linepoints associated with parcels iSetCnt = sOIDList.GetLength(0); sMessage = "Deleting line-points..."; if (iSetCnt > 1) { sMessage += "Step " + Convert.ToString(iStepCnt) + " of " + Convert.ToString(iSetCnt); } if (m_bShowProgressor) { m_pStepProgressor.Message = sMessage; } if (!bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsByFIDSet(pLinePtsTable, pFIDSetLinePoints, m_pStepProgressor, m_pTrackCancel); } if (bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pLinePtsTable, pFIDSetLinePoints, m_pStepProgressor, m_pTrackCancel); } if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } AbortEdits(bUseNonVersionedDelete, pEd, pWS); if (pLinePointCurs != null) { Marshal.ReleaseComObject(pLinePointCurs); //garbage } return; } ///////============================================== Marshal.ReleaseComObject(pLinePointCurs); //garbage iStepCnt++; } //now need to get points that should not be deleted, because they are used by lines that are not deleted. //first search for the remaining lines. Any that have from/to points that are in the point fidset are the points //that should stay IFIDSet pFIDSetNullGeomLinePtFrom = new FIDSetClass(); IFIDSet pFIDSetNullGeomLinePtTo = new FIDSetClass(); if (m_bShowProgressor) { m_pStepProgressor.Message = "Updating point delete list..."; } for (int z = 0; z <= iCnt; z++) { //remove trailing comma if ((sPointOIDList[z].Trim() == "")) { break; } if ((sPointOIDList[z].Substring(sPointOIDList[z].Length - 1, 1)) == ",") { sPointOIDList[z] = sPointOIDList[z].Substring(0, sPointOIDList[z].Length - 1); } } //string TheWhereClause = "(" + (sPref + "frompointid" + sSuff).Trim() + " IN ("; //UpdateDeletePointList(ref sPointOIDList, ref m_pFIDSetPoints, "frompointid", // TheWhereClause, pLinesTable, out pFIDSetNullGeomLinePtFrom); //TheWhereClause = "(" + (sPref + "topointid" + sSuff).Trim() + " IN ("; //UpdateDeletePointList(ref sPointOIDList, ref m_pFIDSetPoints, "topointid", // TheWhereClause, pLinesTable, out pFIDSetNullGeomLinePtTo); string TheWhereClause = "(FROMPOINTID IN ("; UpdateDeletePointList(ref sPointOIDList, ref m_pFIDSetPoints, "FROMPOINTID", TheWhereClause, pLinesTable, out pFIDSetNullGeomLinePtFrom); TheWhereClause = "(TOPOINTID IN ("; UpdateDeletePointList(ref sPointOIDList, ref m_pFIDSetPoints, "TOPOINTID", TheWhereClause, pLinesTable, out pFIDSetNullGeomLinePtTo); if (m_bShowProgressor) { m_pStepProgressor.Message = "Deleting points..."; } if (!bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsByFIDSet(pPointsTable, m_pFIDSetPoints, m_pStepProgressor, m_pTrackCancel); } if (bUseNonVersionedDelete) { bSuccess = FabricUTILS.DeleteRowsUnversioned(pWS, pPointsTable, m_pFIDSetPoints, m_pStepProgressor, m_pTrackCancel); } if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } //====Phase 2 of line-point delete. Remove the Line-points that no longer have underlying points. if (m_bShowProgressor) { m_pStepProgressor.Message = "Deleting line-points..."; } for (int z = 0; z <= iCnt; z++) { if ((sPointOIDList[z].Trim() == "")) { continue; } //remove line points where underlying points were deleted bSuccess = FabricUTILS.DeleteByQuery(pWS, pLinePtsTable, pLinePtsTable.Fields.get_Field(pLinePtsTable.FindField("LinePointID")), sPointOIDList, !bIsUnVersioned, m_pStepProgressor, m_pTrackCancel); if (!bSuccess) { if (!bIsUnVersioned) { pFabLocks.UndoLastAcquiredLocks(); } AbortEdits(bUseNonVersionedDelete, pEd, pWS); return; } } //===== //Empty geometry on points that are floating points on unjoined parcels m_pEmptyGeoms = new FIDSetClass(); FabricUTILS.IntersectFIDSetCommonIDs(pFIDSetNullGeomLinePtTo, pFIDSetNullGeomLinePtFrom, out m_pEmptyGeoms); ICadastralFabricSchemaEdit2 pSchemaEd = (ICadastralFabricSchemaEdit2)pCadFabric; pSchemaEd.ReleaseReadOnlyFields(pPointsTable, esriCadastralFabricTable.esriCFTPoints); //release safety-catch if (!bUseNonVersionedDelete) { FabricUTILS.EmptyGeometries((IFeatureClass)pPointsTable, m_pEmptyGeoms); } else { FabricUTILS.EmptyGeometriesUnversioned(pWS, CFPointLayer.FeatureClass, m_pEmptyGeoms); } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTPoints);//set safety back on if (m_bShowProgressor) { m_pStepProgressor.Message = "Resetting control point associations..."; } for (int z = 0; z <= iCnt; z++) { if ((sPointOIDList[z].Trim() == "")) { break; } //cleanup associated control points, and associations where underlying points were deleted //m_pQF.WhereClause = (sPref + "pointid" + sSuff).Trim() + " IN (" + sPointOIDList[z] + ")"; m_pQF.WhereClause = "POINTID IN (" + sPointOIDList[z] + ")"; pSchemaEd.ReleaseReadOnlyFields(pControlTable, esriCadastralFabricTable.esriCFTControl); //release safety-catch if (!FabricUTILS.ResetControlAssociations(pControlTable, m_pQF, bUseNonVersionedDelete)) { pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl);//set safety back on } } pSchemaEd.ResetReadOnlyFields(esriCadastralFabricTable.esriCFTControl);//set safety back on if (bUseNonVersionedDelete) { FabricUTILS.StopEditing(pWS); } if (pEd.EditState == esriEditState.esriStateEditing) { pEd.StopOperation("Delete parcels"); } //clear selection, to make sure the parcel explorer is updated and refreshed properly if (pFeatSel != null && bMoreThan995UnjoinedParcels) { pFeatSel.Clear(); } } catch (Exception ex) { if (bUseNonVersionedDelete) { FabricUTILS.AbortEditing(pWS); } if (pEd != null) { if (pEd.EditState == esriEditState.esriStateEditing) { pEd.AbortOperation(); } } MessageBox.Show(ex.Message); return; } finally { RefreshMap(pActiveView, CFParcelLayers, CFPointLayer, CFLineLayer, CFControlLayer, CFLinePointLayer); //update the TOC IMxDocument mxDocument = (ESRI.ArcGIS.ArcMapUI.IMxDocument)(ArcMap.Application.Document); for (int i = 0; i < mxDocument.ContentsViewCount; i++) { IContentsView pCV = (IContentsView)mxDocument.get_ContentsView(i); pCV.Refresh(null); } if (pMouseCursor != null) { pMouseCursor.SetCursor(0); } m_pStepProgressor = null; if (!(pProgressorDialog == null)) { pProgressorDialog.HideDialog(); } pProgressorDialog = null; if (bUseNonVersionedDelete) { pCadEd.CadastralFabricLayer = null; CFParcelLayers = null; CFPointLayer = null; CFLineLayer = null; CFControlLayer = null; CFLinePointLayer = null; } } }