/// <summary> /// 合并两个几何形状,并传出合并后的几何形状和错误信息。 /// 注意: /// 两个几何形状都必须是高级几何形状(如:point, multipoint, polyline and polygon), /// 低级几何形状(如:Line, Circular Arc, Elliptic Arc, Bézier Curve)需要转为高级几何形状 /// 可使用GeometryUtility.ConvertGeometryToHigh转为高级几何形状。 /// </summary> /// <param name="geometry1">待合并的几何形状1</param> /// <param name="geometry2">待合并的几何形状2</param> /// <param name="Unioned">合并后的几何形状</param> /// <param name="ErrMsg">错误信息</param> public static void Union(IGeometry geometry1, IGeometry geometry2, out IGeometry Unioned, out string ErrMsg) { ErrMsg = ""; Unioned = null; if (GeometryUtility.IsHighLevelGeometry(geometry1) && GeometryUtility.IsHighLevelGeometry(geometry2)) { ITopologicalOperator topoOp = (ITopologicalOperator)geometry1; IGeometry geometry = topoOp.Union(geometry2); if (GeometryUtility.IsValidGeometry(geometry)) { try { Simplify(geometry); Unioned = geometry; } catch (Exception ex) { ErrMsg = ex.Message; } } else { ErrMsg = "传入的几何形状合并失败。"; } } else { ErrMsg = "传入的几何形状不是高级几何形状,不能合并。"; } }
private IGeometry GetBasicGeo(string typevalue) //获取ParcelBasic图层中指定Type值的的Geometry! { IFeatureLayer pFeatureLayer = null; for (int i = 0; i < axMapControl1.Map.LayerCount; i++) { if (axMapControl1.Map.get_Layer(i).Name == "ParcelBasic") { pFeatureLayer = axMapControl1.Map.get_Layer(i) as IFeatureLayer; break; } } IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; IQueryFilter pQueryFilter = new QueryFilter(); pQueryFilter.WhereClause = "Type = '" + typevalue + "'"; IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, false); IFeature pFeature = pFeatureCursor.NextFeature(); IGeometry pTempGeo = pFeature.Shape; while (true) { pFeature = pFeatureCursor.NextFeature(); if (pFeature == null) { break; } ITopologicalOperator pTopo = pTempGeo as ITopologicalOperator; pTempGeo = pTopo.Union(pFeature.Shape); } return(pTempGeo); }
/// <summary> /// 获得总范围 /// </summary> /// <param name="dgView"></param> /// <returns></returns> private IGeometry GetUnionGeo(DevComponents.DotNetBar.Controls.DataGridViewX dgView) { IGeometry UnionGeo = null; for (int i = 0; i < dgView.RowCount; i++) { if (dgView.Rows[i].Cells[0].FormattedValue.ToString() == "") { continue; } bool b = Convert.ToBoolean(dgView.Rows[i].Cells[0].FormattedValue.ToString()); if (b) { IGeometry pGeo = dgView.Rows[i].Cells[1].Tag as IGeometry; if (pGeo == null) { continue; } if (UnionGeo == null) { UnionGeo = pGeo; } else { ITopologicalOperator pTop = UnionGeo as ITopologicalOperator; UnionGeo = pTop.Union(pGeo); pTop.Simplify(); } } } return(UnionGeo); }
/// <summary> /// 将矢量图层中所有要素的几何体进行合并操作得到一个新几何体。 /// </summary> /// <param name="featureLayer">输入矢量图层</param> /// <returns>合并后的新几何体</returns> public static IGeometry UnionFeatureToOneGeometry(IFeatureLayer featureLayer) { //定义IGeometry接口的对象,存储每一步拓扑操作后得到的几何体 IGeometry geometry = null; //使用null作为查询过滤器得到图层中所有要素的游标 IFeatureCursor featureCursor = featureLayer.Search(null, false); //获取IFeature接口的游标中的第一个元素 IFeature feature = featureCursor.NextFeature(); //当游标不为空时 while (feature != null) { //如果几何体不为空 if (geometry != null) { //进行接口转换,使用当前几何体的ITopologicalOperator接口进行拓扑操作 ITopologicalOperator topologicalOperator = geometry as ITopologicalOperator; //执行拓扑合并操作,将当前要素的几何体与已有几何体进行Union,返回新的合并后的几何体 if (topologicalOperator != null) { geometry = topologicalOperator.Union(feature.Shape); } } else { geometry = feature.Shape; } //移动游标到下一个要素 feature = featureCursor.NextFeature(); } return(geometry); }
public IGeometry getReceptionArea() { IFeatureWorkspace pFWorkspace = (IFeatureWorkspace)((IDataset)ServiceTerritoryFeature.Class).Workspace; IFeatureClass pTowerRangeFC = pFWorkspace.OpenFeatureClass("sde.TowerRange"); IFeatureCursor pRFCursor = pTowerRangeFC.Search(null, false); IGeometry pRecptionGeometry = null; IFeature pRangeFeature = pRFCursor.NextFeature(); while (pRangeFeature != null) { if (pRecptionGeometry == null) { pRecptionGeometry = pRangeFeature.Shape; } else { ITopologicalOperator pTopo = (ITopologicalOperator)pRecptionGeometry; pRecptionGeometry = pTopo.Union(pRangeFeature.Shape); } pRangeFeature = pRFCursor.NextFeature(); } return(pRecptionGeometry); }
private List <IGeometry> strokeIt(List <IGeometry> pGeo) { List <List <double> > indexes = new List <List <double> >(); List <List <int> > mummy = new List <List <int> >(); List <IGeometry> pGeoSave = new List <IGeometry>(); List <IGeometry> GeoList = new List <IGeometry>(); double angle = 2 * Math.PI / 3; for (int i = 0; i < pGeo.Count; i++) { mummy.Add(new List <int> { i }); pGeoSave.Add(pGeo[i]); GeoList.Add(pGeo[i]); for (int j = i + 1; j < pGeo.Count; j++) { if (CheckCrosses(pGeo[i], pGeo[j])) { double a = GetAngle(pGeo[i], pGeo[j]); if (a > angle) { List <double> index = new List <double>(); index.Add(i * 1.0); index.Add(j * 1.0); index.Add(a); indexes.Add(index); } } } } indexes.Sort((x, y) => y[2].CompareTo(x[2])); for (int k = 0; k < indexes.Count; k++) { List <double> index = indexes[k]; int i = Convert.ToInt32(index[0]); int j = Convert.ToInt32(index[1]); List <int> I = mummy.Find(x => x[0] == i); List <int> J = mummy.Find(x => x[0] == j); i = I[I.Count - 1]; j = J[J.Count - 1]; IGeometry r = GeoList[i]; IGeometry s = GeoList[j]; if (CheckCrosses(r, s) && GetAngle(r, s) > angle) { ITopologicalOperator wtf = r as ITopologicalOperator; IGeometry road = wtf.Union(s); pGeoSave.RemoveAt(pGeoSave.IndexOf(r)); pGeoSave.RemoveAt(pGeoSave.IndexOf(s)); pGeoSave.Add(road); GeoList.Add(road); List <List <int> > shabi = mummy.FindAll(x => (x[x.Count - 1] == i || x[x.Count - 1] == j)); shabi.ForEach(x => x.Add(GeoList.Count - 1)); } } return(pGeoSave); }
private void ChooseRoads(List <IGeometry> pGeo) { IGeometry r = new PolylineClass(); IGeometry s = new PolylineClass(); double angle = 2 * Math.PI / 3; int m = -1; for (int i = 0; i < pGeometryList.Count; i++) { for (int j = 0; j <= pGeometryList.Count; j++) { if (j == i) { j++; } if (j == pGeometryList.Count) { if (i == m) { break; } pGeoSave.Add(pGeometryList[i]); pGeometryList.RemoveAt(i); i--; break; } if (CheckCrosses(pGeometryList[i], pGeometryList[j])) { double a = GetAngle(pGeometryList[i], pGeometryList[j]); if (a > 2 * Math.PI / 3) { m = i; } if (a > angle) { angle = a; r = pGeometryList[i]; s = pGeometryList[j]; } } } } if (pGeometryList.Count == 0) { return; } ITopologicalOperator wtf = r as ITopologicalOperator; IGeometry road = wtf.Union(s); pGeometryList.Remove(r); pGeometryList.Remove(s); pGeometryList.Add(road); ChooseRoads(pGeometryList); }
/// <summary> /// 获取topo下的geometry union的数据 /// </summary> /// <param name="featureClass">源要素类</param> /// <param name="queryClause">查询条件</param> /// <param name="queryGeometry">指定范围下</param> /// <param name="spatialRelType">空间参考类型</param> /// <param name="topoUnionGeometry">输出topo union后的geometry</param> /// <param name="oidList">输出OID集合</param> /// <param name="geometryField">geometry字段名称,默认为Shape</param> public static void GetTopounionGeometryByQuery(IFeatureClass featureClass, String queryClause, IGeometry queryGeometry, esriSpatialRelEnum spatialRelType, out IGeometry topoUnionGeometry, out IList <string> oidList, string geometryField = "Shape") { List <IFeature> featureList = new List <IFeature>(); topoUnionGeometry = null; oidList = new List <string>(); try { ISpatialFilter spatialFilter = new SpatialFilter(); if (!string.IsNullOrEmpty(queryClause)) { spatialFilter.WhereClause = queryClause; } if (!string.IsNullOrEmpty(geometryField)) { spatialFilter.GeometryField = geometryField; } if (queryGeometry != null) { spatialFilter.Geometry = queryGeometry; spatialFilter.SpatialRel = spatialRelType; } ITopologicalOperator topologicalOperator = null; IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false); IFeature feature = featureCursor.NextFeature(); IGeometry geometryTemp; while (feature != null) { geometryTemp = feature.Shape; // feature.ShapeCopy; if (topologicalOperator == null) { topologicalOperator = geometryTemp as ITopologicalOperator; } else { topologicalOperator = topologicalOperator.Union(geometryTemp) as ITopologicalOperator; } oidList.Add(feature.OID.ToString()); featureList.Add(feature); feature = featureCursor.NextFeature(); } topoUnionGeometry = topologicalOperator as IGeometry; WorkspaceUtil.ReleaseComObject(featureCursor); } catch (Exception e) { LOG.Error(e, $"{nameof(GetTopounionGeometryByQuery)}抛异常"); } }
public static IGeometry GetShapeUnion(IFeatureLayer pFeaturelayer, double n_BufferSize) { IFeatureCursor ftCursor = pFeaturelayer.Search(null, false); IFeature curFeature = ftCursor.NextFeature(); IGeometry result = curFeature.Shape; curFeature = ftCursor.NextFeature(); while (curFeature != null) { ITopologicalOperator tpOp = result as ITopologicalOperator; result = tpOp.Union(curFeature.Shape); curFeature = ftCursor.NextFeature(); } ITopologicalOperator bufferOp = result as ITopologicalOperator; result = bufferOp.Buffer(n_BufferSize); return(result); }
private void button1_Click(object sender, EventArgs e) { bool f = true; if (this.ShapeType == "esriGeometryPolygon") { Console.WriteLine("开始"); IFeature pFeature = null; IFeatureCursor pFeatureCursor = null; IFeatureLayer pFeatureLayer = null; IGeometry UnionGeometry = null; for (int i = 0; i < this.count; i++) { // 获取ifeaturelayer接口 pFeatureLayer = (IFeatureLayer)arr[i]; // 空间查询返回所有的面 pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false); pFeature = pFeatureCursor.NextFeature(); // 获取每一个feature if (pFeature != null) { // 初始化存放合并图元的变量,初始形状为第一个图元 if (f) { UnionGeometry = pFeature.Shape; pFeature = pFeatureCursor.NextFeature(); // 指向下一个 f = false; } while (pFeature != null) { // 获取拓扑接口 ITopologicalOperator pTopologicalOperator = pFeature.Shape as ITopologicalOperator; // 调用拓扑接口的合并方法 UnionGeometry = pTopologicalOperator.Union(UnionGeometry); // 闪烁图元 // axMapControl1.FlashShape(UnionGeometry, 5, 300, null); pFeature = pFeatureCursor.NextFeature(); // 指向下一个 } } } axMapControl1.FlashShape(UnionGeometry, 5, 300, null); // 合并完之后再闪烁一下 } }
/// <summary> /// 合并两个几何形状 /// 注意: /// 两个几何形状都必须是高级几何形状(如:point, multipoint, polyline and polygon), /// 低级几何形状(如:Line, Circular Arc, Elliptic Arc, Bézier Curve)需要转为高级几何形状 /// 可使用GeometryUtility.ConvertGeometryToHigh转为高级几何形状。 /// </summary> /// <param name="beUnion">被合并ESRI的几何形状接口</param> /// <param name="unioned">合并的ESRI几何形状接口</param> public static void Union(IGeometry beUnion, ref IGeometry unioned) { if (unioned == null) { unioned = beUnion; } else { if ((GeometryUtility.IsValidGeometry(unioned)) && (unioned is ITopologicalOperator)) { ITopologicalOperator topoOp = (ITopologicalOperator)unioned; topoOp.Simplify(); IGeometry geometry = topoOp.Union(beUnion); if (geometry != null) { unioned = geometry; } } } }
/// <summary> /// 点集合转成范围 /// </summary> /// <param name="list"></params> /// <returns></returns> public static IGeometry GetGeoFromPoint(List <IPoint> list) { ITopologicalOperator ptopo = null; IGeometry objGeo = null; for (int i = 0; i < list.Count; i++) { IGeometry pGeo = (IGeometry)list[i]; if (ptopo == null) { ptopo = (ITopologicalOperator)pGeo; objGeo = pGeo; } else { objGeo = ptopo.Union(pGeo); ptopo = (ITopologicalOperator)objGeo; } } return(objGeo); }
public static IGeometry GetGeoFromFeature(List <IFeature> list) { ITopologicalOperator ptopo = null; IGeometry objGeo = null; for (int i = 0; i < list.Count; i++) { IGeometry pGeo = list[i].ShapeCopy; if (ptopo == null) { ptopo = (ITopologicalOperator)pGeo; objGeo = pGeo; } else { objGeo = ptopo.Union(pGeo); ptopo = (ITopologicalOperator)objGeo; } } return(objGeo); }
public static IGeometry GetGeometryByFeatureLayer(IFeatureLayer featureLayer) { IGeometry pGeometry = null; IFeatureCursor pFeatureCursor = featureLayer.FeatureClass.Search(null, false); IFeature pFeature = pFeatureCursor.NextFeature(); while (pFeature != null) { if (pGeometry == null) { pGeometry = pFeature.Shape; } else { ITopologicalOperator pTO = pGeometry as ITopologicalOperator; pGeometry = pTO.Union(pFeature.Shape); } pFeature = pFeatureCursor.NextFeature(); } return(pGeometry); }
/// <summary> /// 要素融合 陈亚飞添加 /// </summary> /// <param name="pFeatureClass">需要融合的图层</param> /// <param name="newOID">融合后保存的要素OID</param> /// <param name="oldOIDLst">需要融合的要素OID</param> public void MergeFeatures(IFeatureClass pFeatureClass, int newOID, List <int> oldOIDLst) { IGeometry tempGeo = null; for (int i = 0; i < oldOIDLst.Count; i++) { int oldOID = oldOIDLst[i]; IFeature pFeature = pFeatureClass.GetFeature(oldOID); if (tempGeo != null) { ITopologicalOperator pTop = tempGeo as ITopologicalOperator; tempGeo = pTop.Union(pFeature.Shape); //融合后将图形简单化 pTop = tempGeo as ITopologicalOperator; pTop.Simplify(); } else { tempGeo = pFeature.Shape; } } IFeature newFea = pFeatureClass.GetFeature(newOID); //将融合后的图形赋值给新的要素 newFea.Shape = tempGeo; //将新生成的要素存储 newFea.Store(); //融合后删除被融合的要素 for (int j = 0; j < oldOIDLst.Count; j++) { if (oldOIDLst[j] != newOID) { IFeature delFeature = pFeatureClass.GetFeature(oldOIDLst[j]); delFeature.Delete(); } } }
private IGeometry CombineFence(IGeometryArray geometryArray) { IGeometry firstGeometry = geometryArray.Element[0]; ITopologicalOperator topo = firstGeometry as ITopologicalOperator; if (!topo.IsKnownSimple) { topo.Simplify(); } for (int i = 1; i < geometryArray.Count; i++) { IGeometry newGeom = topo.Union(geometryArray.Element[i]); topo = newGeom as ITopologicalOperator; if (!topo.IsKnownSimple) { topo.Simplify(); } } topo.Simplify(); return(topo as IGeometry); }
//获得选择的图层的范围 public IGeometry GetFeaLayerGeometry(IFeatureSelection pFeatureSel, IFeatureLayer pMapLayer) { IEnumIDs pEnumIDs = pFeatureSel.SelectionSet.IDs; int id = pEnumIDs.Next(); IGeometry pGeo = null; while (id != -1) { IFeature pFeat = pMapLayer.FeatureClass.GetFeature(id); if (pGeo == null) { pGeo = pFeat.Shape; } else { ITopologicalOperator pTop = pGeo as ITopologicalOperator; pGeo = pTop.Union(pFeat.Shape); } id = pEnumIDs.Next(); } return(pGeo); }
/// <summary> /// Obtains the union of all feature geometires within a List of features /// </summary> /// <param name="featureList">list of features to union together</param> /// <returns>IGeometry of the unioned shapes contained in the parameter list</returns> public static IGeometry UnionGeometries(List <IFeature> featureList) { IGeometry unionGeometry = null; ITopologicalOperator topoOperator = null; foreach (IFeature feature in featureList) { if (!feature.Shape.IsEmpty) { if (unionGeometry != null) { topoOperator = (ITopologicalOperator)feature.Shape; unionGeometry = topoOperator.Union(unionGeometry); } else { unionGeometry = feature.Shape; } } } return(unionGeometry); }
/// <summary> /// Unions the cursor geometries. /// </summary> /// <param name="cursor">The cursor.</param> /// <returns>a single geometry</returns> public static IGeometry UnionCursorGeometries(IFeatureCursor cursor) { IFeature feature = null; IGeometry unionGeometry = null; ITopologicalOperator topoOperator = null; while ((feature = cursor.NextFeature()) != null) { if (!feature.Shape.IsEmpty) { if (unionGeometry != null) { topoOperator = (ITopologicalOperator)feature.Shape; unionGeometry = topoOperator.Union(unionGeometry); } else { unionGeometry = feature.Shape; } } } return(unionGeometry); }
public void GenerateDeadArea() { try { IGeometry pCoverageGeom = null; IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)_workspace; IWorkspaceEdit pWorspaceEdit = (IWorkspaceEdit)pFeatureWorkspace; ServiceTerritory pST = new ServiceTerritory(_workspace, "Main"); if (pST.ServiceTerritoryFeature != null) { if (pCoverageGeom == null) { pCoverageGeom = pST.ServiceTerritoryFeature.Shape; } else { ITopologicalOperator pTopoUnion = (ITopologicalOperator)pCoverageGeom; pCoverageGeom = pTopoUnion.Union(pST.ServiceTerritoryFeature.Shape); } } IFeatureClass pServiceFC = pFeatureWorkspace.OpenFeatureClass("ServiceTerritory"); IFeatureCursor pServiceCursor = pServiceFC.Search(null, false); IFeature pServiceFeature = pServiceCursor.NextFeature(); ITopologicalOperator pTopoClip = (ITopologicalOperator)pServiceFeature.Shape; IGeometry pDeadArea = pTopoClip.Difference(pCoverageGeom); IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit)_workspace; pWorkspaceEdit.StartEditing(true); pWorkspaceEdit.StartEditOperation(); IFeatureClass pDeadFC = pFeatureWorkspace.OpenFeatureClass("DeadArea"); IFeatureCursor pDeleteCursor = pDeadFC.Search(null, false); IFeature pExistingFeature = pDeleteCursor.NextFeature(); while (pExistingFeature != null) { pExistingFeature.Delete(); pExistingFeature = pDeleteCursor.NextFeature(); } IFeature pDeadFeature = pDeadFC.CreateFeature(); pDeadFeature.Shape = pDeadArea; //pDeadFeature.set_Value(pDeadFeature.Fields.FindField("COVERAGE_PCT"), dead_pct); pDeadFeature.Store(); pWorkspaceEdit.StopEditOperation(); pWorkspaceEdit.StopEditing(true); int dead_pct = (int)(100 * ((IArea)pDeadFeature.Shape).Area / ((IArea)pServiceFeature.Shape).Area); int reception_pct = 100 - dead_pct; //pST.UpdateCoveragePct(dead_pct, reception_pct); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
private void button2_Click(object sender, EventArgs e) { if (layer1 != null && layer2 != null) { bool f = true; IGeometry UnionGeometry = null; // 将叠加的图层合并到一起 List <string> resList = new List <string>(); // 存放分析的结果 // 通过图层的name属性来获得ilayer接口 IFeatureLayer pFeatureLayer = (IFeatureLayer)layer1; // 转换为ifeaturelayer接口 // 把每个面都取出来 IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false); IFeature pFeature = pFeatureCursor.NextFeature(); // 指向结果集的下一个要素 while (pFeature != null) // 如果不为空 { // 获取被叠加图层的ilayer接口 IFeatureLayer pByFeatureLayer = (IFeatureLayer)layer2; // 再获取ifeaturelayer接口 // new 一个空间查询过滤器 ISpatialFilter pSpatialFilter = new SpatialFilter(); if (pByFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint) { pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; // 包含 } else if (pByFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline) { pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; // 相交 } else if (pByFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon) { pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; // 相交 } pSpatialFilter.Geometry = pFeature.Shape; // 把每一个叠加图层赋值给空间过滤器 // 调用被叠加图层的search方法查询有多少图元 IFeatureCursor pByFeatureCursor = pByFeatureLayer.FeatureClass.Search(pSpatialFilter, false); IFeature pByFeature = pByFeatureCursor.NextFeature(); // 指向结果集的下一个要素 while (pByFeature != null) { if (f) { UnionGeometry = pByFeature.Shape; pFeature = pByFeatureCursor.NextFeature(); // 指向下一个 f = false; } else { // 获取拓扑接口 ITopologicalOperator pTopologicalOperator = pByFeature.Shape as ITopologicalOperator; // 调用拓扑接口的合并方法 UnionGeometry = pTopologicalOperator.Union(UnionGeometry); // 闪烁图元 // this.axMapControl1.FlashShape(UnionGeometry, 5, 300, null); pByFeature = pByFeatureCursor.NextFeature(); // 指向下一个 } } pFeature = pFeatureCursor.NextFeature(); // 指向结果集的下一个要素 } this.axMapControl1.FlashShape(UnionGeometry, 5, 300, null); } else { if (layer1 == null) { MessageBox.Show("请选择叠加的图层"); } if (layer2 == null) { MessageBox.Show("请选择被叠加的图层"); } } }
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 }
private void btnOK_Click(object sender, EventArgs e) { Exception eError = null; //界面控制判断和检查 if (txtSavePath.Text == "") { SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", "请选择保存路径!"); return; } //栅格数据文件名称 string pFileName = txtSavePath.Text.Trim(); pFileName = pFileName.Substring(pFileName.LastIndexOf('\\') + 1); //目标栅格数据存储类型 string pFormat = cmbDataFormat.Text.Trim().ToUpper(); #region 创建目标工作空间 IWorkspace pDesWS = null;//定义工作空间 //如果存在同名库体则删除 if (File.Exists(txtSavePath.Text.Trim())) { File.Delete(txtSavePath.Text.Trim()); } if (cmbDataFormat.Text.Trim().ToUpper() == "PDB") { pDesWS = CreateWorkspace(txtSavePath.Text.Trim(), "PDB", out eError); } else if (cmbDataFormat.Text.Trim().ToUpper() == "GDB") { pDesWS = CreateWorkspace(txtSavePath.Text.Trim(), "GDB", out eError); } else if (cmbDataFormat.Text.Trim().ToUpper() == "TIF") { pDesWS = CreateWorkspace(txtSavePath.Text.Trim(), "tif", out eError); } else if (cmbDataFormat.Text.Trim().ToUpper() == "IMG") { pDesWS = CreateWorkspace(txtSavePath.Text.Trim(), "img", out eError); } if (eError != null) { SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", "创建工作空间失败!"); return; } if (pDesWS == null) { return; } #endregion //IExtractionOp extraction = new RasterExtractionOpClass(); IGeometry clipExtent = null; //几何限制条件 #region 获得几何限制条件 IGeometry pGeo1 = null; IGeometry pGeo2 = null; IGeometry pGeo3 = null; pGeo1 = GetUnionGeo(dgMap); pGeo2 = GetUnionGeo(dgCounty); pGeo3 = GetUnionGeo(dgRange); ITopologicalOperator pTop = clipExtent as ITopologicalOperator; if (pGeo1 != null) { if (clipExtent == null) { clipExtent = pGeo1; } else { clipExtent = pTop.Union(pGeo1); } } pTop = clipExtent as ITopologicalOperator; if (pGeo2 != null) { if (clipExtent == null) { clipExtent = pGeo2; } else { clipExtent = pTop.Union(pGeo2); } } pTop = clipExtent as ITopologicalOperator; if (pGeo3 != null) { if (clipExtent == null) { clipExtent = pGeo3; } else { clipExtent = pTop.Union(pGeo3); } } if (clipExtent != null) { pTop = clipExtent as ITopologicalOperator; pTop.Simplify(); clipExtent = pTop as IGeometry; } #endregion try { #region 提取数据 IRaster pOrgRaster = null; //源栅格数据 if (m_dbType == "栅格数据集") { //源栅格数据图层 IRasterLayer mOrgRasterlyer = m_Layer as IRasterLayer; if (mOrgRasterlyer == null) { return; } //源栅格数据集 pOrgRaster = mOrgRasterlyer.Raster; if (pOrgRaster == null) { return; } //栅格数据集提取 StractData(pFileName, clipExtent, pDesWS, pFormat, pOrgRaster, checkBoxClip.Checked, out eError); if (eError != null) { SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", eError.Message); return; } } else { //源数据为栅格数据编目,步骤入下: //(1) 创建临时的工作空间; //(2) 将符合属性条件的栅格数据拼接成栅格数据集后,存储在临时的工作空间里面 //(3) 将临时的工作空间里面的栅格数据集案范围提取出来 //======================================================================================= #region 栅格编目数据提取 //(1)创建临时工作空间 IWorkspace tempWS = CreateWorkspace(ModData.temporaryDBPath, "GDB", out eError); if (eError != null) { SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", "创建临时的工作空间出错!"); return; } if (tempWS == null) { return; } //(2)遍历源栅格数据,将数据入库到临时工作空间里面 //源栅格数据图层 IFeatureLayer mOrgFeaLyer = m_Layer as IFeatureLayer; if (mOrgFeaLyer == null) { return; } IRasterDataset pResRDataset = null; //最后生成的栅格数据集 IFeatureClass pOrgFeaCls = mOrgFeaLyer.FeatureClass; IQueryFilter pFilter = new QueryFilterClass(); pFilter.WhereClause = txtWhereStr.Text.Trim(); IFeatureCursor pFeaCursor = pOrgFeaCls.Search(pFilter, false); if (pFeaCursor == null) { return; } IFeature pORgFea = pFeaCursor.NextFeature(); #region 遍历源栅格数据,进行源栅格数据入库(过滤和拼接) while (pORgFea != null) { IRasterCatalogItem pOrgRCItem = pORgFea as IRasterCatalogItem; IRasterDataset pOrgRasterDt = pOrgRCItem.RasterDataset; if (pResRDataset == null) { //第一个数据入库直接将源数据拷贝过去 if (pOrgRasterDt.CanCopy()) { pResRDataset = pOrgRasterDt.Copy(m_DesRasterCollName, tempWS) as IRasterDataset; pORgFea = pFeaCursor.NextFeature(); continue; } } //从第二个栅格数据开始,进行入库和拼接 IRaster pOrgRast = pOrgRasterDt.CreateDefaultRaster(); IRasterLoader pRasterLoad = new RasterLoaderClass(); if (pOrgRast != null) { pRasterLoad.Background = 0; //background value be ignored when loading pRasterLoad.PixelAlignmentTolerance = 0; //重采样的容差 pRasterLoad.MosaicColormapMode = rstMosaicColormapMode.MM_LAST; //拼接的颜色采用 last map color pRasterLoad.Load(pResRDataset, pOrgRast); } Marshal.ReleaseComObject(pRasterLoad); pORgFea = pFeaCursor.NextFeature(); } //释放cursor System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeaCursor); #endregion //(3) 将临时工作空间里面的栅格数据集提取出来 if (pResRDataset == null) { return; } pOrgRaster = pResRDataset.CreateDefaultRaster(); StractData(pFileName, clipExtent, pDesWS, pFormat, pOrgRaster, checkBoxClip.Checked, out eError); if (eError != null) { SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", eError.Message); return; } #endregion } #endregion SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", "操作完成!"); } catch (Exception er) { //******************************************************************* //guozheng added if (ModData.SysLog != null) { ModData.SysLog.Write(er, null, DateTime.Now); } else { ModData.SysLog = new SysCommon.Log.clsWriteSystemFunctionLog(); ModData.SysLog.Write(er, null, DateTime.Now); } //******************************************************************** SysCommon.Error.ErrorHandle.ShowFrmErrorHandle("提示", "提取栅格数据失败!\n" + er.Message); return; } this.Close(); }
private bool MergeFeatures(int nFeatureID) { IEngineEditor pEngineEdit = new EngineEditorClass(); IEngineEditLayers pEEditLayers = pEngineEdit as IEngineEditLayers; IFeatureLayer targetLayer = pEEditLayers.TargetLayer; IFeatureClass featureClass = targetLayer.FeatureClass; IFeatureSelection featureSelection = targetLayer as IFeatureSelection; ISelectionSet selectionSet = featureSelection.SelectionSet; if (selectionSet.Count < 2) { return(false); } pEngineEdit.StartOperation(); try { object miss = Type.Missing; if (targetLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint) { return(false); } IFeature featureTarget = featureClass.GetFeature(nFeatureID); if (featureTarget == null) { return(false); } ITopologicalOperator top = featureTarget.ShapeCopy as ITopologicalOperator; int nID = -1; IEnumIDs enumIDs = selectionSet.IDs; enumIDs.Reset(); while ((nID = enumIDs.Next()) >= 0) { if (nID == nFeatureID) { continue; } IFeature feature = featureClass.GetFeature(nID); top = top.Union(feature.Shape) as ITopologicalOperator; } featureTarget.Shape = top as IGeometry; featureTarget.Store(); //删除其余要素 enumIDs.Reset(); while ((nID = enumIDs.Next()) >= 0) { if (nID == nFeatureID) { continue; } IFeature feature = featureClass.GetFeature(nID); feature.Delete(); } pEngineEdit.StopOperation("Merge features"); return(true); } catch (System.Exception ex) { pEngineEdit.AbortOperation(); } return(false); }
public override void OnMouseDown(int Button, int Shift, int X, int Y) { //m_Cursor = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "AopenMap.cur")); if (Button == 1) { if (m_InUse == true) { m_pAV = m_HookHelper.ActiveView; m_pScrD = m_pAV.ScreenDisplay; IMap pMap = m_HookHelper.FocusMap; IPoint pPnt; pPnt = (IPoint)m_pScrD.DisplayTransformation.ToMapPoint(X, Y); if (m_pNewPolygonFeedback == null) { m_pNewPolygonFeedback = new NewPolygonFeedbackClass(); ISimpleLineSymbol pSLnSym; IRgbColor pRGB = new RgbColorClass(); pSLnSym = (ISimpleLineSymbol)m_pNewPolygonFeedback.Symbol; pRGB.Red = 140; pRGB.Green = 140; pRGB.Blue = 255; pSLnSym.Color = pRGB; pSLnSym.Style = esriSimpleLineStyle.esriSLSSolid; pSLnSym.Width = 2; m_pNewPolygonFeedback.Display = m_pScrD; m_pNewPolygonFeedback.Start(pPnt); } else { m_pNewPolygonFeedback.AddPoint(pPnt); } } } else if (Button == 2) { IPolygon pGeomLn; pGeomLn = m_pNewPolygonFeedback.Stop(); m_pNewPolygonFeedback = null; IMap pMap = m_HookHelper.FocusMap; ISpatialReference spatialReference = pMap.SpatialReference; //IBorder pBorder = new SymbolBorderClass(); //*****************************************88888888 if (pFirstGeom == null) { pFirstGeom = pGeomLn; } if (mGeomln != null) { pFirstGeom = mGeomln; } if (pFirstGeom != pGeomLn) { IPolygon mFirstGeom; mFirstGeom = pFirstGeom; IRelationalOperator pROperator = (IRelationalOperator)mFirstGeom; if (pROperator.Disjoint((IGeometry)pGeomLn) == false) { //先定义一个IGeometrycollection的多边形,将每个画出来的IgeometryCollection添加进去 //先添一个构成一个IPolygon,转化为ITopo_ ,再同样构成另一个,进行Union IGeometryCollection pcGeometry = new PolygonClass(); object o = System.Type.Missing; IPolygon cFirstGeom = new PolygonClass(); cFirstGeom = pFirstGeom; ITopologicalOperator tempTopo = (ITopologicalOperator)cFirstGeom; tempTopo.Simplify(); ITopologicalOperator pTopo = (ITopologicalOperator)pGeomLn; pTopo.Simplify(); IGeometry kGeom; kGeom = pTopo.Union((IGeometry)cFirstGeom); mGeomln = (IPolygon)kGeom; mGeomln.SpatialReference = spatialReference; m_pAV.FocusMap.ClipGeometry = mGeomln; //IBorder pBorder = new SymbolBorderClass(); //m_HookHelper.FocusMap.ClipBorder = pBorder; m_pAV.Extent = mGeomln.Envelope; m_pAV.Refresh(); m_Cursor = base.m_cursor; //layVisbleExceptMap(); } } else { //*************************************************8 //mGeomln = pGeomLn; pGeomLn.SpatialReference = spatialReference; LayerControl.LyrPolygon = pGeomLn; m_HookHelper.FocusMap.ClipGeometry = pGeomLn; IBorder pBorder = new SymbolBorderClass(); m_HookHelper.FocusMap.ClipBorder = pBorder; m_pAV.Extent = pGeomLn.Envelope; m_pAV.Refresh(); m_Cursor = base.m_cursor; pGeomLn = null; } } }
public override void OnClick() { try { IGeometry geometry = null; if (this._context.FocusMap.SelectionCount >= 1) { IEnumFeature enumFeature = this._context.FocusMap.FeatureSelection as IEnumFeature; enumFeature.Reset(); IFeature feature = enumFeature.Next(); ITopologicalOperator topologicalOperator = null; while (feature != null) { if (feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon) { if (topologicalOperator == null) { topologicalOperator = (feature.ShapeCopy as ITopologicalOperator); } else { topologicalOperator = (topologicalOperator.Union(feature.Shape) as ITopologicalOperator); topologicalOperator.Simplify(); } } feature = enumFeature.Next(); } geometry = (topologicalOperator as IGeometry); } else { ITopologicalOperator topologicalOperator = null; IGraphicsContainer graphicsContainer = this._context.FocusMap as IGraphicsContainer; graphicsContainer.Reset(); IElement element = graphicsContainer.Next(); if (element != null) { if (element is IPolygonElement) { if (topologicalOperator == null) { topologicalOperator = (element.Geometry as ITopologicalOperator); } else { topologicalOperator = (topologicalOperator.Union(element.Geometry) as ITopologicalOperator); topologicalOperator.Simplify(); } } element = graphicsContainer.Next(); } geometry = (topologicalOperator as IGeometry); } if (geometry == null && this._context.Hook is IApplication) { geometry = (this._context.Hook as IApplication).BufferGeometry; } if (geometry != null && !geometry.IsEmpty) { geometry.SpatialReference = this._context.FocusMap.SpatialReference; int num = this._subType; if (num != 0) { string str = System.IO.Path.GetTempPath() + "TempPersonGDB"; int num2 = 1; string path = str + ".mdb"; while (File.Exists(path)) { try { File.Delete(path); break; } catch { } num2++; path = str + " (" + num2.ToString() + ").mdb"; } IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory(); IWorkspaceName iworkspaceName_ = workspaceFactory.Create(System.IO.Path.GetDirectoryName(path), System.IO.Path.GetFileNameWithoutExtension(path), null, 0); IMap imap_ = new Map(); Clip.ClipMapByRegion(iworkspaceName_, this._context.FocusMap, geometry, imap_); new FormPrinterSetup(); CMapPrinter cMapPrinter; if (this._context.Hook is IApplication) { cMapPrinter = new CMapPrinter(imap_, ApplicationBase.StyleGallery); } else { cMapPrinter = new CMapPrinter(imap_); } cMapPrinter.showPrintUI("打印地图"); } else { new frmDir { FocusMap = this._context.FocusMap, ClipGeometry = geometry }.ShowDialog(); } } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } }