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; }
}
}