using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; namespace Kingo.RuleCheck.AEHelper { public static class FeatureAPI { #region 面转线 /// /// 面转线 /// /// 多边形面要素 public static List FeatureToLine(IFeature pFeature) { List result = new List(); try { if (pFeature != null && pFeature.Shape != null) { IGeometry pGeometry = pFeature.ShapeCopy; result = PolygonToLine(pGeometry); } return result; } catch (Exception ex) { throw ex; } } /// /// 面转线 /// /// 多边形面 public static List PolygonToLine(IGeometry pGeometry) { List result = new List(); try { if (pGeometry != null && pGeometry.GeometryType == esriGeometryType.esriGeometryPolygon) { ITopologicalOperator topologicalOperator = pGeometry as ITopologicalOperator; if (topologicalOperator == null) return result; topologicalOperator.Simplify(); //外环图形 GeometryBag ExterGeometryBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag; if (ExterGeometryBag == null) return result; IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection; IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection; //List geometry = new List(); for (int g = 0; g < ExterRingGeometryCollection.GeometryCount; g++) { IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(g); result.Add(PolygonToPolyline(ExterGeometry)); //内环图形 IGeometryBag InteriorBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).get_InteriorRingBag(ExterGeometry as IRing); if (InteriorBag == null) continue; IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection; if (InteriorRingGeometryCollection == null) continue; for (int IG = 0; IG < InteriorRingGeometryCollection.GeometryCount; IG++) { IGeometry interiorGeo = InteriorRingGeometryCollection.get_Geometry(IG); result.Add(PolygonToPolyline(interiorGeo)); } } } return result; } catch (Exception ex) { throw ex; } } private static IGeometry PolygonToPolyline(IGeometry pGeo) { try { if (pGeo == null) return null; Ring ring = pGeo as Ring; if (ring == null) return null; IPointCollection pc = ring as IPointCollection; IGeometryCollection pPolyline = new PolylineClass(); for (int j = 1; j < pc.PointCount; j++) { ILine pLine = new LineClass(); pLine.SpatialReference = pGeo.SpatialReference; pLine.PutCoords(pc.get_Point(j - 1), pc.get_Point(j)); ISegment pSegment = pLine as ISegment; // 创建一个Path对象 ISegmentCollection pPath = new PathClass(); object o = Type.Missing; // 通过Isegmentcoletcion接口为Path对象添加Segment对象 pPath.AddSegment(pSegment, ref o, ref o); // 创建一个Polyline对象 pPolyline.AddGeometry(pPath as IGeometry, ref o, ref o); } return pPolyline as IGeometry; } catch (Exception ex) { throw ex; } } #endregion /// /// 求两个图形相交部分 /// /// 图形1 /// 图形2 /// public static IGeometry InterSect(IGeometry pGeo1, IGeometry pGeo2) { try { IGeometry result = null; if (pGeo1 == null || pGeo2 == null) return null; ITopologicalOperator topo = pGeo1 as ITopologicalOperator; if (topo != null) { topo.Simplify(); pGeo2.SpatialReference = pGeo1.SpatialReference; ITopologicalOperator topo2 = pGeo2 as ITopologicalOperator; topo2.Simplify(); if (pGeo1.GeometryType == esriGeometryType.esriGeometryPoint || pGeo2.GeometryType == esriGeometryType.esriGeometryPoint) { result = topo.Intersect(pGeo2, esriGeometryDimension.esriGeometry0Dimension); } else if (pGeo1.GeometryType == esriGeometryType.esriGeometryPolyline || pGeo2.GeometryType == esriGeometryType.esriGeometryPolyline) { result = topo.Intersect(pGeo2, esriGeometryDimension.esriGeometry1Dimension); } else { result = topo.Intersect(pGeo2, pGeo2.Dimension); } if (result != null) { ITopologicalOperator resultTopo = result as ITopologicalOperator; resultTopo.Simplify(); } return result; } return null; } catch (Exception ex) { throw ex; } } /// /// 求目标图形与指定图形不相交部分 /// /// 目标多边形 /// 指定的图形 /// public static IGeometry Difference(IGeometry pGeo1, IGeometry pGeo2) { try { IGeometry result = null; if (pGeo1 == null || pGeo2 == null) return null; ITopologicalOperator topo = pGeo1 as ITopologicalOperator; if (topo != null) { topo.Simplify(); result = topo.Difference(pGeo2); ITopologicalOperator resTopo = result as ITopologicalOperator; resTopo.Simplify(); return result; } return null; } catch (Exception ex) { throw ex; } } /// /// 使用指定的线裁切目标多边形 /// /// 目标多边形 /// 指定的图形 /// public static List CutGeometry(IGeometry pGeo1, IPolyline pGeo2) { List result = new List(); try { if (pGeo1 == null || pGeo2 == null) return result; ITopologicalOperator topo = pGeo1 as ITopologicalOperator; if (topo != null) { topo.Simplify(); IGeometry leftGeo = null; IGeometry rightGeo = null; topo.Cut(pGeo2, out leftGeo, out rightGeo); if (leftGeo != null && !leftGeo.IsEmpty) result.Add(leftGeo); if (rightGeo != null && !rightGeo.IsEmpty) result.Add(rightGeo); } return result; } catch (Exception ex) { throw ex; } } /// /// 判断两个图形是否是叠加关系(相邻的也算相交) /// /// /// /// public static bool IsOverlaps(IGeometry pGeo1, IGeometry pGeo2) { if (pGeo1.SpatialReference.FactoryCode != pGeo2.SpatialReference.FactoryCode) { pGeo2.Project(pGeo1.SpatialReference); } ITopologicalOperator topological = pGeo1 as ITopologicalOperator; if (topological != null && !topological.IsKnownSimple) { topological.Simplify(); } ITopologicalOperator topological2 = pGeo2 as ITopologicalOperator; if (topological2 != null && !topological2.IsKnownSimple) { topological2.Simplify(); } IRelationalOperator relational = pGeo1 as IRelationalOperator; if (relational != null) { bool b = relational.Overlaps(pGeo2); if (!b) { relational = pGeo1 as IRelationalOperator; b = relational.Touches(pGeo2); } return b; } return false; } /// /// 判断两个图形是否相交(不包含相邻的) /// /// /// /// public static bool IsInterSect(IGeometry pGeo1, IGeometry pGeo2) { IGeometry geo = InterSect(pGeo1, pGeo2); if (geo == null || geo.IsEmpty) return false; if (geo.Dimension == esriGeometryDimension.esriGeometry2Dimension) { IArea area = geo as IArea; if (area == null) return false; } return true; } /// /// 判断两个图形是否相邻 /// /// /// /// public static bool IsAdjacent(IGeometry pGeo1, IGeometry pGeo2) { bool result = false; //IPolyline polyline; IRelationalOperator topoOper = pGeo1 as IRelationalOperator; result = topoOper.Touches(pGeo2); if (result) { ITopologicalOperator topo = pGeo1 as ITopologicalOperator; if (topo != null) { topo.Simplify(); ITopologicalOperator topo2 = pGeo2 as ITopologicalOperator; topo2.Simplify(); IGeometry geo = topo.Intersect(pGeo2, esriGeometryDimension.esriGeometry1Dimension); if (geo == null) { result = false; } else if (geo.IsEmpty) { result = false; } } } return result; //IPolyline polyline; //ITopologicalOperator topoOper = pGeo1 as ITopologicalOperator; //polyline = topoOper.Intersect(pGeo2, esriGeometryDimension.esriGeometry1Dimension) as IPolyline; //if (polyline != null && !polyline.IsEmpty) //{ // return true; //} //return false; } /// /// 判断点pPoint是否与图形pGeo边界上的点重叠,如果重叠返回图形上重叠点的索引 /// /// /// /// public static int IsInterSect(IPoint pPoint, IGeometry pGeo) { int result = -1; if (pPoint.IsEmpty || pGeo.IsEmpty) return result; IGeometryCollection geoCollection = pGeo as IGeometryCollection; if (geoCollection != null) { for (int i = 0; i < geoCollection.GeometryCount; i++) { IPointCollection points = geoCollection.Geometry[i] as IPointCollection; for (int j = 0; j < points.PointCount; j++) { IPoint p = points.Point[j]; ITopologicalOperator topo = p as ITopologicalOperator; if (topo != null) { IGeometry geo = topo.Intersect(pPoint, pPoint.Dimension); if (geo == null || geo.IsEmpty) continue; result = j; break; } } if (result != -1) break; } } return result; } public static double GetInterArea(IGeometry pGeo1, IGeometry pGeo2) { IGeometry geo = InterSect(pGeo1, pGeo2); if (geo == null || geo.IsEmpty) return 0; IArea area = geo as IArea; if (area == null || area.Area < 1) return 0; return area.Area; } /// /// 判断图形1是否包含图形2 /// /// 图形1 /// 图形2 /// public static bool IsContains(IGeometry pGeo1, IGeometry pGeo2) { try { ITopologicalOperator topological = pGeo1 as ITopologicalOperator; if (topological != null && !topological.IsKnownSimple) { topological.Simplify(); } ITopologicalOperator topological2 = pGeo2 as ITopologicalOperator; pGeo2.SpatialReference = pGeo1.SpatialReference; if (topological2 != null && !topological2.IsKnownSimple) { topological2.Simplify(); } IRelationalOperator relational = pGeo1 as IRelationalOperator; if (relational != null) { return relational.Contains(pGeo2); } return false; } catch (Exception ex) { throw ex; } } /// /// 获取图形共边边长 /// /// /// /// public static double LengthOfSide(IGeometry iPolygon1, IGeometry iPolygon2) { IPolyline polyline; ITopologicalOperator topoOper = iPolygon1 as ITopologicalOperator; polyline = topoOper.Intersect(iPolygon2, esriGeometryDimension.esriGeometry1Dimension) as IPolyline; return polyline.Length; } /// /// 拷贝要素 /// /// /// /// public static IFeature FeatureCopy(IFeature source, List ignoreFields = null) { try { IFeatureClass targetFeatureClass = (IFeatureClass)source.Class; IFeatureBuffer target = targetFeatureClass.CreateFeatureBuffer(); FeatureCopy(source, target, ignoreFields); return target as IFeature; } catch (Exception ex) { throw ex; } } private static void FeatureCopy(IFeature source, IFeatureBuffer target, List ignoreFields = null) { for (int i = 0; i < target.Fields.FieldCount; i++) { IField ft = target.Fields.get_Field(i); if (!ft.Editable || (ignoreFields != null && ignoreFields.Contains(ft.Name))) continue; int index = source.Fields.FindField(ft.Name); if (index > -1) { try { target.set_Value(i, source.get_Value(index)); } catch { } } } } /// /// 合并矢量图形,以第一条为基准,调用此方法之前需开启编辑,并控制会回滚,执行完成后会删除所有记录 /// /// /// public static IFeature MergeFeature(List features) { try { if (features == null || features.Count == 0) return null; if (features.Count == 1) return features[0]; IFeature baseFeature = features[0]; IFeature target = FeatureCopy(baseFeature); ITopologicalOperator2 topo = baseFeature.Shape as ITopologicalOperator2; foreach (IFeature f in features) { if (f != baseFeature) { ITopologicalOperator topo2 = f.Shape as ITopologicalOperator; topo2.Simplify(); topo.Simplify(); topo = topo.Union(f.Shape) as ITopologicalOperator2; } } if (!topo.IsSimple) { topo.Simplify(); } target.Shape = topo as IGeometry; return target; } catch (Exception ex) { throw ex; } } /// /// 合并矢量图形,以第一条为基准,调用此方法之前需开启编辑,并控制会回滚,执行完成后会删除所有记录 /// /// /// public static IGeometry MergeGeometry(List pGeometry) { try { if (pGeometry == null || pGeometry.Count == 0) return null; if (pGeometry.Count == 1) return pGeometry[0]; IGeometry baseGeo = pGeometry[0]; //IGeometry target = FeatureCopy(baseFeature); ITopologicalOperator2 topo = baseGeo as ITopologicalOperator2; foreach (IGeometry f in pGeometry) { if (f != baseGeo) { ITopologicalOperator2 topolog = f as ITopologicalOperator2; topolog.Simplify(); topo.Simplify(); topo = topo.Union(f) as ITopologicalOperator2; } } if (!topo.IsSimple) { topo.Simplify(); } //target.Shape = topo as IGeometry; return topo as IGeometry; } catch (Exception ex) { throw ex; } } /// /// 分割 /// /// /// /// public static List SplitFeature(IFeature features, IPolyline splitLine) { if (features.Shape.GeometryType != esriGeometryType.esriGeometryPolygon && features.Shape.GeometryType != esriGeometryType.esriGeometryPolyline) { throw new Exception("无法分割除面和线之外的图形"); } List result = new List(); ITopologicalOperator4 topo = features.Shape.Envelope as ITopologicalOperator4; //IGeometryCollection geos = null; try { IGeometry leftGeo; IGeometry rightGeo; topo.Cut(splitLine, out leftGeo, out rightGeo); if (!leftGeo.IsEmpty) { IFeature feature = FeatureCopy(features); feature.Shape = leftGeo; result.Add(feature); } if (!rightGeo.IsEmpty) { IFeature feature = FeatureCopy(features); feature.Shape = rightGeo; result.Add(feature); } } catch { result.Add(features); return result; } //for (int i = 0; i < geos.GeometryCount; i++) //{ // IPolygon polygon = geos.get_Geometry(i) as IPolygon; // if (polygon != null) // { // IFeature feature = FeatureCopy(features); // feature.Shape = polygon; // result.Add(feature); // } //} return result; } /// /// 分割 /// /// /// /// public static List SplitFeature(List features, IPolyline splitLine, out List splitedList) { List result = new List(); splitedList = new List(); foreach (IFeature f in features) { List subResults = SplitFeature(f, splitLine); result.AddRange(subResults); if (subResults.Count > 1) { splitedList.Add(f); } } return result; } /// /// 根据点打断线 /// /// /// /// public static List SplitLineAtPoint(IPoint pPoint, IPolyline pLine) { List result = new List(); //对那条线在点击点处,进行打断 IPolycurve pPolycurve = (IPolycurve)pLine; bool HasSplitHappened; int newPartIndex; int newSegmentIndex; //打断 pPolycurve.SplitAtPoint(pPoint, false, true, out HasSplitHappened, out newPartIndex, out newSegmentIndex); if (HasSplitHappened) { IGeometryCollection pGeometryCollection = (IGeometryCollection)pPolycurve; for (int i = 0; i < pGeometryCollection.GeometryCount; i++) { IGeometryCollection line = new PolylineClass(); IGeometry pGeo = pGeometryCollection.get_Geometry(i); line.AddGeometries(1, ref pGeo); result.Add(line as IPolyline); } } else { result.Add(pLine); } return result; } /// /// 根据点捕捉要素 /// /// /// /// public static List Snapping(IPoint pPoint, List pLayers, int buffer = 5) { List result = new List(); try { if (pPoint != null && pLayers != null) { foreach (IFeatureLayer item in pLayers) { IIdentify identify = item as IIdentify; if (identify == null) continue; ITopologicalOperator pTopo = pPoint as ITopologicalOperator; IGeometry pGeometry = pTopo.Buffer(buffer).Envelope as IGeometry; ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeometry); if (array == null) continue; for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) continue; IFeature f = row.Row as IFeature; result.Add(f); } } } } catch (Exception ex) { throw ex; } return result; } /// /// 根据线捕捉要素 /// /// /// /// public static List Snapping(IGeometry pGeo, List pLayers, double buffer = 0.0001) { List result = new List(); try { if (pGeo == null || pGeo.IsEmpty || pLayers == null) { return result; } foreach (IFeatureLayer item in pLayers) { IIdentify identify = item as IIdentify; if (identify == null) continue; ITopologicalOperator pTopo = pGeo as ITopologicalOperator; if (pTopo == null) { continue; } pTopo.Simplify(); //修改人:李进营 修改时间:2018-09-18 注释缓冲代码,解决Gis10.2绘制慢的问题 //IGeometry bufferGeometry = pTopo.Buffer(buffer); IGeometry bufferGeometry = pGeo; if (bufferGeometry == null || bufferGeometry.IsEmpty) { continue; } IGeometry pGeometry = bufferGeometry.Envelope as IGeometry; if (pGeometry == null || pGeometry.IsEmpty) { continue; } pTopo = pGeometry as ITopologicalOperator; if (pTopo != null) { pTopo.Simplify(); } ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeometry); if (array == null || array.Count <= 0) continue; for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) continue; IFeature f = row.Row as IFeature; result.Add(f); } } } catch (Exception ex) { throw ex; } return result; } /// /// 识别要素 /// /// /// /// public static List Identify(IGeometry pGeo, ILayer pLayer, double buffer = 0.0001) { List result = new List(); try { if (pGeo == null || pGeo.IsEmpty || pLayer == null) { return result; } IIdentify identify = pLayer as IIdentify; if (identify == null) { return result; } //ITopologicalOperator pTopo = pGeo as ITopologicalOperator; //IGeometry pGeometry = pTopo.Buffer(buffer).Envelope as IGeometry; ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeo); if (array == null) { return result; } for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) continue; IFeature f = row.Row as IFeature; result.Add(f); } } catch (Exception ex) { throw ex; } return result; } /// /// 识别要素 /// /// 指定图形 /// 目标图层 /// 返回目标图层中与指定图形有交集的要素集合(不包含相邻要素) public static List Identify2(IGeometry pGeo, ILayer pLayer) { List result = new List(); try { if (pGeo != null && !pGeo.IsEmpty && pLayer != null) { IIdentify identify = pLayer as IIdentify; if (identify == null) return result; ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeo); if (array == null) return result; for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) continue; IFeature f = row.Row as IFeature; IGeometry geo = InterSect(f.ShapeCopy, pGeo); if (geo != null && !geo.IsEmpty) result.Add(f); } } } catch (Exception ex) { throw ex; } return result; } /// /// 识别要素 /// /// 指定图形 /// 目标图层 /// 返回目标图层中与指定图形有交集的要素集合(不包含相邻要素) public static Dictionary IdentifyReturnIntersect(IGeometry pGeo, ILayer pLayer) { Dictionary result = new Dictionary(); try { if (pGeo != null && !pGeo.IsEmpty && pLayer != null) { IIdentify identify = pLayer as IIdentify; if (identify == null) return result; ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeo); if (array == null) return result; for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) { continue; } IFeature f = row.Row as IFeature; //pGeo.Project(((pLayer as IFeatureLayer).FeatureClass as IGeoDataset).SpatialReference); IGeometry geometry = f.ShapeCopy; if (!geometry.SpatialReference.Name.Equals(pGeo.SpatialReference.Name)) { geometry.Project(pGeo.SpatialReference); } IGeometry geo = InterSect(geometry, pGeo); if (geo != null && !geo.IsEmpty) { result.Add(geo, f); } } } } catch (Exception ex) { throw ex; } return result; } /// /// 属性自动赋值(对指定要素通过压盖指定图层方式进行属性继承,如果压盖多个则以面积大的要素属性为准) /// /// 指定要素 /// 指定图层 public static void AutoSetAttribute(IFeature pFeature, IFeatureLayer pLayer) { try { if (pFeature == null || pLayer == null) { return; } IIdentify identify = pLayer as IIdentify; if (identify == null) return; ESRI.ArcGIS.esriSystem.IArray iarray = identify.Identify(pFeature.ShapeCopy as IGeometry); if (iarray == null) { return; } //与之相交部分面积 double area = -1; IFeature s_Feature = null; for (int i = 0; i < iarray.Count; i++) { IFeatureIdentifyObj pFeatIdObj = iarray.get_Element(i) as IFeatureIdentifyObj; IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject; IFeature newFeature = pRowObj.Row as IFeature; if (newFeature.Shape.SpatialReference != pFeature.Shape.SpatialReference) { newFeature.Shape.SpatialReference = pFeature.Shape.SpatialReference; } IGeometry geo = FeatureAPI.InterSect(pFeature.ShapeCopy, newFeature.ShapeCopy); if (geo != null && !geo.IsEmpty) { if (area < (geo as IArea).Area) { area = (geo as IArea).Area; s_Feature = newFeature; } } } if (s_Feature != null) { #region 属性继承 for (int i = 0; i < pFeature.Fields.FieldCount; i++) { IField field = pFeature.Fields.get_Field(i); if (!field.Editable || field.Name.ToUpper() == "SHAPE" || field.Name.ToUpper() == "BSM") continue; int index = s_Feature.Fields.FindField(field.Name); if (index == -1) index = s_Feature.Fields.FindFieldByAliasName(field.Name); if (index == -1) continue; if (s_Feature.Fields.get_Field(index).Type == field.Type) { if (!(s_Feature.get_Value(index) is DBNull)) { pFeature.set_Value(i, s_Feature.get_Value(index)); } } } } #endregion } catch (Exception ex) { throw ex; } } /// /// 裁切要素(以指定的要素通过压盖指定图层的要素,将压盖到的要素进行裁切) /// /// 指定要素 /// 指定图层 public static List CutInterSectFeature(IFeature pFeature, IFeatureLayer pLayer) { List result = new List(); try { IIdentify identify = pLayer as IIdentify; ESRI.ArcGIS.esriSystem.IArray iarray = identify.Identify(pFeature.ShapeCopy as IGeometry); if (iarray != null) { for (int i = 0; i < iarray.Count; i++) { IFeatureIdentifyObj pFeatIdObj = iarray.get_Element(i) as IFeatureIdentifyObj; IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject; IFeature newFeature = pRowObj.Row as IFeature; if (newFeature.Shape.SpatialReference != pFeature.Shape.SpatialReference) { newFeature.Shape.SpatialReference = pFeature.Shape.SpatialReference; } ITopologicalOperator topOper = newFeature.ShapeCopy as ITopologicalOperator; IGeometry geometryNew = topOper.Difference(pFeature.ShapeCopy as IGeometry); IGeometryCollection geoCollection = geometryNew as IGeometryCollection; //外环图形 IGeometryCollection ExterGeometryBag = (geometryNew as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as IGeometryCollection; if (geoCollection != null && geoCollection.GeometryCount > 1) { if (geoCollection.GeometryCount == ExterGeometryBag.GeometryCount) { IGeometryCollection geos = new PolygonClass(); geos.AddGeometry(geoCollection.get_Geometry(0)); newFeature.Shape = geos as IGeometry; for (int j = 1; j < geoCollection.GeometryCount; j++) { IFeature f = pLayer.FeatureClass.CreateFeature(); geos = new PolygonClass(); geos.AddGeometry(geoCollection.get_Geometry(j)); f.Shape = geos as IGeometry; f.Store(); result.Add(f); } } else { newFeature.Shape = geometryNew; } } else { newFeature.Shape = geometryNew; } result.Add(newFeature); newFeature.Store(); } } } catch (Exception ex) { throw ex; } return result; } /// /// 将多环图形打散(不包含内环图形) /// /// 多环多边形 /// public static List DissolveGeometryByRing(IGeometry pGeometry) { try { ISpatialReference sr = pGeometry.SpatialReference; List result = null; if (pGeometry == null) return null; if (pGeometry.IsEmpty) return null; ITopologicalOperator topologicalOperator = pGeometry as ITopologicalOperator; if (topologicalOperator == null) return null; topologicalOperator.Simplify(); //外环图形 GeometryBag ExterGeometryBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag; if (ExterGeometryBag == null) return null; IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection; for (int g = 0; g < ExterRingGeometryCollection.GeometryCount; g++) { IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection; IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(g); if (ExterGeometry == null) continue; geometry.AddGeometry(ExterGeometry); //内环图形 IGeometryBag InteriorBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).get_InteriorRingBag(ExterGeometry as IRing); if (InteriorBag == null) continue; IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection; if (InteriorRingGeometryCollection == null) continue; for (int IG = 0; IG < InteriorRingGeometryCollection.GeometryCount; IG++) { IGeometry interiorGeo = InteriorRingGeometryCollection.get_Geometry(IG); if (interiorGeo == null) continue; geometry.AddGeometry(interiorGeo); } if (result == null) { result = new List(); } (geometry as IGeometry).SpatialReference = sr; result.Add(geometry as IGeometry); } return result; } catch (Exception ex) { throw ex; } } #region 生成新的图斑(处理同属性要素分割/合并问题) /// /// 生成新的图斑(处理同权属、同坐落要素分割/合并问题) /// /// /// /// public static List GenerateNewFeature(IGeometry pGeo, IFeatureClass pFc) { List result = new List(); try { #region IFeatureLayer layer = new FeatureLayerClass(); layer.FeatureClass = pFc; if (layer == null) return result; IIdentify indentify = layer as IIdentify; if (indentify == null) return result; IArray pIDs = indentify.Identify(pGeo); if (pIDs == null || pIDs.Count <= 0) { return result; } int count = pIDs.Count; List featureInfo = new List(); for (int index = 0; index < pIDs.Count; index++) { IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj; IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject; IFeature dltbFeature = pRowObj.Row as IFeature; IGeometry newGeo = dltbFeature.ShapeCopy; newGeo.SpatialReference = pGeo.SpatialReference; if (!FeatureAPI.IsInterSect(pGeo, newGeo)) continue; int fieldIndex = dltbFeature.Fields.FindField("ZLDWDM"); if (fieldIndex == -1) { throw new Exception("地类图斑要素类中未找到【ZLDWDM】字段!"); } object ZLDWDM = dltbFeature.get_Value(fieldIndex); if (ZLDWDM == null) throw new Exception("坐落单位代码为空!"); fieldIndex = dltbFeature.Fields.FindField("QSDWDM"); if (fieldIndex == -1) { throw new Exception("地类图斑要素类中未找到【QSDWDM】字段!"); } object QSDWDM = dltbFeature.get_Value(fieldIndex); if (QSDWDM == null) throw new Exception("权属单位代码为空!"); if (featureInfo.Count == 0) { FeatureInfo f = new FeatureInfo(); f.GeometryList = new List(); f.ZLDWDM = ZLDWDM.ToString(); f.QSDWDM = QSDWDM.ToString(); f.GeometryList.Add(newGeo); featureInfo.Add(f); } else { FeatureInfo f = featureInfo.FirstOrDefault(e => e.ZLDWDM == ZLDWDM.ToString() && e.QSDWDM == QSDWDM.ToString()); if (f != null) { f.GeometryList.Add(newGeo); } else { f = new FeatureInfo(); f.GeometryList = new List(); f.ZLDWDM = ZLDWDM.ToString(); f.QSDWDM = QSDWDM.ToString(); f.GeometryList.Add(newGeo); featureInfo.Add(f); } } } foreach (FeatureInfo item in featureInfo) { List newFeatureList = new List(); double area = 0; if (item.GeometryList == null) continue; foreach (IGeometry geo in item.GeometryList) { //获取相交部分图形 IGeometry geo2 = FeatureAPI.InterSect(geo, pGeo); ITopologicalOperator2 topo2 = geo2 as ITopologicalOperator2; if (topo2 != null) { topo2.Simplify(); } //feature.Shape = geo2; //将面积最大的插入到集合索引开始位置,方便后面继承属性取值 if ((geo2 as IArea) != null && (geo2 as IArea).Area > area) { area = (geo2 as IArea).Area; newFeatureList.Insert(0, geo2); } else { newFeatureList.Add(geo2); } } if (newFeatureList.Count == 0) { continue; } //同坐落及权属的图斑合并 IGeometry MergeFeatuer = FeatureAPI.MergeGeometry(newFeatureList); if (MergeFeatuer != null && !MergeFeatuer.IsEmpty) { result.Add(MergeFeatuer); } } #endregion } catch (Exception ex) { throw ex; } return result; } #endregion /// /// 线转面 /// /// 线对象 /// IGeometry 面对象 public static IGeometry ConstructPolygonFromPolyline(IPolyline pPolyline) { IGeometry newGeometry = null; try { IGeometryCollection pPolygonGeoCol = new PolygonClass(); if (pPolyline == null || pPolyline.IsEmpty) { return pPolygonGeoCol as IGeometry; } IGeometryCollection pPolylineGeoCol = pPolyline as IGeometryCollection; ISegmentCollection pSegCol = new RingClass(); ISegment pSegment = null; object missing = Type.Missing; for (int i = 0; i < pPolylineGeoCol.GeometryCount; i++) { ISegmentCollection pPolylineSegCol = pPolylineGeoCol.get_Geometry(i) as ISegmentCollection; for (int j = 0; j < pPolylineSegCol.SegmentCount; j++) { pSegment = pPolylineSegCol.get_Segment(j); pSegCol.AddSegment(pSegment, ref missing, ref missing); } pPolygonGeoCol.AddGeometry(pSegCol as IGeometry, ref missing, ref missing); } newGeometry = pPolygonGeoCol as IGeometry; if (newGeometry != null && !newGeometry.IsEmpty) { ITopologicalOperator topologicalOperator = newGeometry as ITopologicalOperator; if (!topologicalOperator.IsKnownSimple) { topologicalOperator.Simplify(); } } } catch (Exception ex) { throw ex; } return newGeometry; } /// /// 拆分多部件要素 /// /// 选中要素集合 public static void SplitMultipartFeature(List SelectedFeature) { try { foreach (IFeature item in SelectedFeature) { IGeometry geo = item.ShapeCopy; ITopologicalOperator topologicalOperator = geo as ITopologicalOperator; if (topologicalOperator == null) continue; topologicalOperator.Simplify(); if (item.ShapeCopy.GeometryType == esriGeometryType.esriGeometryPolygon) { #region //外环图形 GeometryBag ExterGeometryBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag; if (ExterGeometryBag == null) continue; //IGeometry firstGeo = null; IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection; for (int i = 0; i < ExterRingGeometryCollection.GeometryCount; i++) { IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection; IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(i); if (ExterGeometry != null && !ExterGeometry.IsEmpty) { geometry.AddGeometry(ExterGeometry); } else { continue; } //内环图形 IGeometryBag InteriorBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).get_InteriorRingBag(ExterGeometry as IRing); if (InteriorBag != null) { IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection; if (InteriorRingGeometryCollection == null) continue; for (int IG = 0; IG < InteriorRingGeometryCollection.GeometryCount; IG++) { IGeometry interiorGeo = InteriorRingGeometryCollection.get_Geometry(IG); if (interiorGeo != null && !interiorGeo.IsEmpty) { geometry.AddGeometry(interiorGeo); } } } if ((geometry as IGeometry) == null || (geometry as IGeometry).IsEmpty) { continue; } if (i == 0) { //firstGeo = geometry as IGeometry; item.Shape = geometry as IGeometry; item.Store(); } else { IFeature newFeaturte = (item.Class as IFeatureClass).CreateFeature(); IFeatureEdit pFeatureEdit = item as IFeatureEdit; pFeatureEdit.SplitAttributes(newFeaturte); (geometry as IGeometry).SpatialReference = item.ShapeCopy.SpatialReference; newFeaturte.Shape = geometry as IGeometry; newFeaturte.Store(); } } //if (firstGeo != null) //{ // firstGeo.SpatialReference = item.ShapeCopy.SpatialReference; // item.Shape = firstGeo; // item.Store(); //} #endregion } else if (item.ShapeCopy.GeometryType == esriGeometryType.esriGeometryPolyline) { #region IGeometryCollection pGeocoll = geo as IGeometryCollection; int geomcount = pGeocoll.GeometryCount; if (geomcount > 1) { for (int k = 1; k < geomcount; k++) { IFeature newFeaturte = (item.Class as IFeatureClass).CreateFeature(); IFeatureEdit pFeatureEdit = item as IFeatureEdit; pFeatureEdit.SplitAttributes(newFeaturte); IGeometry newGeom = pGeocoll.get_Geometry(k); IPointCollection points = newGeom as IPointCollection; IPointCollection line = new PolylineClass(); for (int i = 0; i < points.PointCount; i++) { line.AddPoint(points.get_Point(i)); } newGeom = line as IGeometry; newGeom.SpatialReference = item.ShapeCopy.SpatialReference; newFeaturte.Shape = newGeom; newFeaturte.Store(); } IGeometry newGeom2 = pGeocoll.get_Geometry(0); IPointCollection points2 = newGeom2 as IPointCollection; IPointCollection line2 = new PolylineClass(); for (int i = 0; i < points2.PointCount; i++) { line2.AddPoint(points2.get_Point(i)); } newGeom2 = line2 as IGeometry; newGeom2.SpatialReference = item.ShapeCopy.SpatialReference; if (newGeom2 != null && !newGeom2.IsEmpty) item.Shape = newGeom2; item.Store(); } #endregion } } } catch (Exception ex) { throw ex; } } /// /// 弧形(弧线和弧面)形折线化:按70米对弧线增加内差点(等分点) /// /// 需要折线化的图形 /// 返回当前图形是否包含弧线:true:表示包含弧线 false:表示不包含弧线 public static bool ArcToPolyline(ref IGeometry newGeometry) { bool ContainsArcs = false; try { if (newGeometry == null || newGeometry.IsEmpty) { return false; } ESRI.ArcGIS.Geometry.ISegmentCollection segmentCollection = newGeometry as ESRI.ArcGIS.Geometry.ISegmentCollection; if (segmentCollection == null || segmentCollection.SegmentCount <= 0) { return false; } for (int i = 0; i < segmentCollection.SegmentCount; i++) { ISegment segment = segmentCollection.Segment[i]; //圆弧,椭圆弧,贝塞尔弧 if (segment.GeometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryCircularArc || segment.GeometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryEllipticArc || segment.GeometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryBezier3Curve) { ContainsArcs = true; if (segmentCollection.Segment[i].Length > 70) { int cutCount = (int)(Math.Ceiling(segment.Length / 70)); ICurve curve = segment as ICurve; IPointCollection polyline = new Polyline() as IPointCollection; IConstructMultipoint constructMultipoint = new Multipoint() as IConstructMultipoint; constructMultipoint.ConstructDivideEqual(curve, cutCount); polyline.SetPointCollection((constructMultipoint as IPointCollection)); segmentCollection.ReplaceSegmentCollection(i, 1, (polyline as ISegmentCollection)); //SegmentCollection.RemoveSegments(i, 1, false); //SegmentCollection.InsertSegmentCollection(1, (polyline as ISegmentCollection)); //pFeature.Shape = SegmentCollection as IGeometry; } else { IPolyline polyline = new PolylineClass() { FromPoint = segment.FromPoint, ToPoint = segment.ToPoint, SpatialReference = newGeometry.SpatialReference }; segmentCollection.ReplaceSegmentCollection(i, 1, (polyline as ISegmentCollection)); //segmentCollection.RemoveSegments(i, 1, false); //segmentCollection.in(1, (polyline as ISegmentCollection)); } } else { continue; } } if (ContainsArcs) { newGeometry = (segmentCollection as IGeometry); ITopologicalOperator topological = newGeometry as ITopologicalOperator; if (!topological.IsKnownSimple) { topological.Simplify(); } } } catch (Exception ex) { throw ex; } return ContainsArcs; } /// /// 给弧形(弧线和弧面)附近相交的图形折线化加点 /// /// 当前弧形要素 /// 弧形所在的图层:此方法是针对的面图层 public static void AddFeaturePoint(IFeature feature, IFeatureLayer featureLayer) { try { if (featureLayer == null || featureLayer.FeatureClass == null) { throw new Exception("图层不能为空!"); } if (featureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon || feature.Shape.GeometryType != esriGeometryType.esriGeometryPolygon) { throw new Exception("图层或图形不是面图层!"); } bool isSplit; int splitIndex, segIndex; IIdentify identify = featureLayer as IIdentify; IArray iarray = identify.Identify(feature.ShapeCopy); IGeometry currentGeometry = feature.ShapeCopy; for (int i = 0; i < iarray.Count; i++) { IFeatureIdentifyObj pFeatIdObj = iarray.get_Element(i) as IFeatureIdentifyObj; IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject; IFeature newFeature = pRowObj.Row as IFeature; if (newFeature.OID == feature.OID || newFeature == null || newFeature.Shape.IsEmpty) { continue; } newFeature.Shape.SpatialReference = currentGeometry.SpatialReference; ITopologicalOperator topological = newFeature.ShapeCopy as ITopologicalOperator; IPolyline pPolyline = topological.Boundary as IPolyline; //判断图形是否相交 if (!FeatureAPI.IsInterSect(currentGeometry, newFeature.ShapeCopy)) { IRelationalOperator relationalOperator = currentGeometry as IRelationalOperator; //判断图形是否有共边 if (!relationalOperator.Touches(newFeature.ShapeCopy)) { continue; } } //newGeometry = KGIS.Framework.AE.FeatureAPI.Difference(newGeometry, newFeature.ShapeCopy); IPointCollection pointCollection = currentGeometry as IPointCollection; for (int j = 0; j < pointCollection.PointCount; j++) { IGeometry geo = InterSect(newFeature.ShapeCopy as IGeometry, pointCollection.get_Point(j) as IGeometry); if (geo != null && !geo.IsEmpty) { pPolyline.SplitAtPoint(pointCollection.get_Point(j), false, false, out isSplit, out splitIndex, out segIndex); } //else //{ // IRelationalOperator relationalOperator = pointCollection.get_Point(j) as IRelationalOperator; // string relationDescription = "RELATE(G1, G2, 'T********')"; // bool isIntersects = relationalOperator.Relation(pPolyline, relationDescription); // if (!isIntersects) // { // continue; // } // //判断图形是否有共边 // //if (!relationalOperator.Overlaps(pointCollection.get_Point(j))&& !relationalOperator.Contains(pointCollection.get_Point(j))) // //{ // // continue; // //} // pPolyline.SplitAtPoint(pointCollection.get_Point(j), false, false, out isSplit, out splitIndex, out segIndex); //} } IGeometry geometry = pPolyline; FeatureAPI.ArcToPolyline(ref geometry); newFeature.Shape = ConstructPolygonFromPolyline(geometry as IPolyline); newFeature.Store(); } } catch (Exception) { throw; } } /// /// 判断两个图形是否一样 /// /// /// /// public static bool GetEqual(IGeometry pGeo1, IGeometry pGeo2) { ITopologicalOperator topological = pGeo1 as ITopologicalOperator; if (topological != null && !topological.IsKnownSimple) { topological.Simplify(); } ITopologicalOperator topological2 = pGeo2 as ITopologicalOperator; if (topological2 != null && !topological2.IsKnownSimple) { topological2.Simplify(); } IRelationalOperator relational = pGeo1 as IRelationalOperator; if (relational != null) { return relational.Contains(pGeo2); } return false; } /// /// 求目标图形与指定图形不相交部分 /// /// 目标多边形 /// 指定的图形 /// public static IGeometry Union(IGeometry pGeo1, IGeometry pGeo2) { try { IGeometry result = null; if (pGeo1 == null || pGeo2 == null) return null; ITopologicalOperator topo = pGeo1 as ITopologicalOperator; if (topo != null) { topo.Simplify(); result = topo.Union(pGeo2); ITopologicalOperator resTopo = result as ITopologicalOperator; resTopo.Simplify(); return result; } return null; } catch (Exception ex) { throw ex; } } } partial class FeatureInfo { /// /// 坐落单位代码 /// public string ZLDWDM { get; set; } /// /// 权属单位代码 /// public string QSDWDM { get; set; } /// /// 要素集合 /// public List FeatureList { get; set; } /// /// 图形集合 /// public List GeometryList { get; set; } } }