ITopologicalOperator接口
//拓扑接口cut方法(因为会出现两个不连接的图斑算一个要素的情况,所以复杂多边形或者多部分多边形要谨慎使用)
public List<IGeometry> Cut(List<IFeature> Polygon, List<IPolyline> pFishNetList) { List<IGeometry> NewPolygon = new List<IGeometry>(); //每一条线依次切割所有多边形 IGeometry leftGeom; IGeometry rightGeom; //把IFeature全部转成IGeometry for (int i = 0; i < Polygon.Count;i++ ) { IGeometry pGeo = Polygon[i].Shape as IGeometry; NewPolygon.Add(pGeo); } for (int i = 0; i < pFishNetList.Count;i++ ) { List<int> index = new List<int>();//存储被替换掉的原多边形 for (int j = 0; j < NewPolygon.Count; j++) { IGeometry pGeometry = NewPolygon[j]; ITopologicalOperator pTopoOpe = (ITopologicalOperator)pGeometry; pTopoOpe.Simplify(); //pGeometry本身的SpatialReference是unknow,必须要设置成跟pFishNetList[i]一致,否则下面Crosses判断会报错 pGeometry.SpatialReference = pFishNetList[i].SpatialReference; IRelationalOperator pRelOperator = pGeometry as IRelationalOperator; IArea pArea = pGeometry as IArea;//判断面积是否是平均值的两倍 double area = pArea.Area; if (pRelOperator.Crosses(pFishNetList[i] as IGeometry) && (area >= MeanArea)) { pTopoOpe.Cut(pFishNetList[i], out leftGeom, out rightGeom); index.Add(j);//记录要被替换的多边形的序号 NewPolygon.Add(leftGeom); NewPolygon.Add(rightGeom); } } for (int k = index.Count-1; k > -1; k--) { NewPolygon.RemoveAt(index[k]);//删除掉那些多边形 } index.Clear();//清空,下次再用 } return NewPolygon; }
注:(上图中的overlap判断可能会有问题,有时候有重叠却也返回false,
所以下面Intersect方法的时候判断改成了多边形外环是否大于0,等于0即没有外环,是空的)
//为了避免Cut方法的缺陷,用ITopologicalOperator的Intersect方法(面切割面)
/////////////////////////////////////////////////////////////////////////////
public List<IGeometry> Intersect(List<IFeature> Polygon, List<IPolygon> pEnvelopeList) { List<IGeometry> pIntersectList = new List<IGeometry>(); List<IGeometry> NewPolygonList = new List<IGeometry>();//存面积大于平均值的多边形(因为类型要转成IGeometry) List<IGeometry> OriPolygonList = new List<IGeometry>();//存面积xiaoyu平均值的多边形 //把IFeature(Polygon)全部转成IGeometry for (int i = 0; i < Polygon.Count; i++) { IArea pArea = Polygon[i].Shape as IArea;//判断面积是否是平均值的两倍 double area = pArea.Area; IGeometry pGeo = Polygon[i].Shape as IGeometry; if (area >= MeanArea) { NewPolygonList.Add(pGeo); } else { OriPolygonList.Add(pGeo); } } for (int i = 0; i < pEnvelopeList.Count; i++) { for (int j = 0; j < NewPolygonList.Count; j++) {
//拓扑切割方法intersect ITopologicalOperator pTopoOpe = (ITopologicalOperator)NewPolygonList[j]; pTopoOpe.Simplify(); //pGeometry本身的SpatialReference是unknow,必须要设置成跟pFishNetList[i]一致,否则下面Crosses判断会报错 NewPolygonList[j].SpatialReference = pEnvelopeList[i].SpatialReference; IRelationalOperator pRelOperator = NewPolygonList[j] as IRelationalOperator; IPolygon resultPolygon = new PolygonClass(); resultPolygon = pTopoOpe.Intersect(pEnvelopeList[i].Envelope as IGeometry, esriGeometryDimension.esriGeometry2Dimension) as IPolygon; //判断面积是否大于平均值的一半,不到一半的不存 IArea pArea = resultPolygon as IArea; double area = pArea.Area; if (resultPolygon.ExteriorRingCount != 0 && (area>(MeanArea/2)))//这句前面一个判断是防止它把空的图形也存进来 { pIntersectList.Add(resultPolygon as IGeometry); } } } foreach(IGeometry geo in OriPolygonList) { pIntersectList.Add(geo);//把不用切割的小图形也存进来,不管大小,都作为一个图形存起来 } return pIntersectList; }
//合并两个要素为一个用拓扑接口Union方法
public IGeometry Union(List<IPolyline> FishNetList) { IGeometry pUnion = null; IGeometry pGeometry = FishNetList[0] as IGeometry; for (int i = 1; i < FishNetList.Count;i++ ) { ITopologicalOperator pTopoOpe = (ITopologicalOperator)pGeometry; pTopoOpe.Simplify(); (FishNetList[i] as ITopologicalOperator).Simplify(); pUnion = pTopoOpe.Union(FishNetList[i] as IGeometry); pGeometry = pUnion; } return pUnion; }
to be continue······