目录
在数据检查过程中,我们需要点要素是否落在实体上进行检查处理,本文针对这个需求介绍两种实现思路
背景依托:我们需要检查AGNP层的AK和BB点与RESA/RESP/RESL是否实体对应关系
思路:首先将需要进行实体要素检查的要素聚合呈multipart要素,然后与AGNP层进行逻辑运算,最终选出不再实体上的AK或BB
1 基于选择集的要素实体检查
该思路为先基于AGNP层所有要素点建立选择集,然后用multipart要素与该选择集求交运算,减去相交的部分,再从最终结果中筛选出CLASS为AK/BB的要素。
1.1 基于AGNP层建立选择集
如果在AO开发,需现将IFeatureClass转化为IFeatureLayer进行运算:
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = agnpFeatureClass;
IFeatureSelection pSelection = pFeatureLayer as IFeatureSelection;
如果在Addins下,直接读取IFeatureLayer
/// <summary>
/// 根据图层名找到图层
/// </summary>
/// <param name="pMap">地图名称</param>
/// <param name="layerName">图层名称</param>
/// <returns>未找到图层返回null,找到图层返回目标图层</returns>
public static IFeatureLayer GetLayerByName(IMap pMap, string layerName)
{
for(int i = 0; i < pMap.LayerCount; i++)
{
if(pMap.getLayer(i).Name == layerName)
{
return pMap.getLayer(i) as IFeatureLayer;
}
}
return null;
}
更多信息参见:基于C#的ArcEngine二次开发32:属性sql查询语句与IMap,ILayer,IFeatureLayer,IFeatureClass关系
1.2 基于要素类创建multipart要素
/// <summary>
/// 获取空间参考
/// </summary>
/// <returns></returns>
private ISpatialReference GetSpatialReference(IFeatureClass in_FeatureClass)
{
IGeoDataset pGeoDataset = in_FeatureClass as IGeoDataset;
ISpatialReference pSpatialReference = pGeoDataset.SpatialReference;
return pSpatialReference;
}
/// <summary>
/// 合并几何体
/// </summary>
/// <returns></returns>
private IGeometry GetMergeGeometry(IFeatureClass in_FeatureClass)
{
IGeometryBag pGeometryBag = new GeometryBag() as IGeometryBag;
pGeometryBag.SpatialReference = GetSpatialReference(in_FeatureClass);
IGeometryCollection pGeometryCollection = pGeometryBag as IGeometryCollection;
// 属性过滤
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = "GB = 310200 or GB = 310500";
// 要素游标
IFeatureCursor pFeatureCursor = in_FeatureClass.Search(pQueryFilter, true);
IFeature pFeature = pFeatureCursor.NextFeature();
if (pFeature == null)
{
return null;
}
// 遍历游标
object missing = Type.Missing;
while (pFeature != null)
{
pGeometryCollection.AddGeometry(pFeature.ShapeCopy, ref missing, ref missing);
pFeature = pFeatureCursor.NextFeature();
}
Marshal.ReleaseComObject(pFeatureCursor);
// 合并要素
ITopologicalOperator pTopologicalOperator = null;
if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
{
pTopologicalOperator = new Multipoint() as ITopologicalOperator;
pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
}
else if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
{
pTopologicalOperator = new Polyline() as ITopologicalOperator;
pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
}
else
{
pTopologicalOperator = new Polygon() as ITopologicalOperator;
pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry);
}
return pTopologicalOperator as IGeometry;
}
关于multipart更多信息,参见:
- 基于C#的ArcEngine二次开发23:复合要素的识别与导出
- 基于C#的ArcEngine二次开发34:使用ConstructUnion方法进行多要素合并
- 基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature
1.3 选择集建立与剔除
public ISelectionSet selectSubtract(IFeatureClass agnpFeatureClass, string[] pFeatureClassNames)
{
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = agnpFeatureClass;
IFeatureSelection pSelection = pFeatureLayer as IFeatureSelection;
pSelection.SelectFeatures(null, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResultNew, false);
//设置查询条件,如果表达式错误会报异常信息
ISpatialFilter queryFilter = new QueryFilterClass();
//读取RESA/RESL/RESP层
for(int i = 0; i < pFeatureClassNames.Length; i++)
{
IFeatureClass pFeatureClass = (srcWorkspace as IFeatureWorkspace).OpenFeatureClass(pFeatureClassNames[i]);
IGeometry pGeometry = GetMergeGeometry(pFeatureClass);
//设置空间查询条件
queryFilter.Geometry = pGeometry;
queryFilter.GeometryField = "SHAPE";
queryFilter.SpatialRel= esriSpatialRelEnum.esriSpatialRelIntersects;
//选择集过滤
pSelection.SelectFeatures(queryFilter, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResaultSubtract, false);
}
ISelectionSet pSelectionSet = pSelection.SelectionSet;
//导出代码
}
2 基于空间相离原理的实体检查
2.1 空间相离判断
//判断AGNP层要素与构造的复合要素是否相离
private bool spatialdDisjiont(IFeature pFeature, IGeometry multipartGeometry)
{
IReleationalOperation pRelOpr = pFeature.ShapeCopy;
return pRelOpr.Disjoint(multipartGeometry);
}
2.2 逐图层判断
private void check(IWorkspace srcWorkspace, IGeometry multipartA, IGeometry multipartS, IGeometry multipartP)
{
IFeatureWorkspace pFeatureWorkspace = srcWorkspace as IFeatureWorkspace;
IFeatureClass pRefFeatureClass = pFeatureWorkspace .OpenFeatureClass(refFeatureClassName);
IFeatureCursor pCursor = pRefFeatureClass.Search(null, false);
IFeature pFeature = pCursor.NextFeature();
while(pFeature != null)
{
if(spatialRel(pFeature, multipartA) && spatialRel(pFeature, multipartL) && spatialRel(pFeature, multipartP))
{
exportSingleAKorBB(pFeature);
}
pFeature = pCursor.NextFeature();
}
}
3 导出选择集
3.1 创建导出要素类
private void CreateFeatureClass(string strShapeFolder, string refFeatureClassName,string ouFeatureClassName)
{
IWorkspaceFactory pWSF = new FileGDBWorkspaceFactoryClass();
IWorkspace srcWorkspace = pWSF.OpenFromFile(strShapeFolder,0);
IFeatureWorkspace pFeatureWorkspace = srcWorkspace as IFeatureWorkspace;
IFeatureClass pRefFeatureClass = pFeatureWorkspace .OpenFeatureClass(refFeatureClassName);
IGeoDataset refGeodataset = pRefFeatureClass as IGeoDataset;
IFields pFields = refGeodataset.Fields;
IFeatureDataset pWorkDataset = pFeatureWorkspace.OpenFeatureDataset("MainDataFrame");
IWorkspace2 pWorkspace2 = pWorkDataset.Workspace as IWorkspace2;
if(pWorkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, ouFeatureClassName))
{
IFeatureClass pDelFeatureClass = pFeatureWorkspace .OpenFeatureClass(ouFeatureClassName);
IDataset pDS = pDelFeatureClass as IDataset;
pDS.Delete();
}
pWorkDataset.CreateFeatureClass(ouFeatureClassName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
}
3.2 根据选择集导出要素
exportSelectionSetAKorBB(IFeatureClass ouFeatureClass, ISelectionSet pSelectinset, string type)
{
ICursor pCursor;
pSelectinset.Search(null, false, out pCursor);
IFeatureCursor pFeatureCursor = pCursor as IFeatureCursor;
IFeature pFeature = pFeatureCursor.NextFeature;
while(pFeature != null)
{
if(pFeature.get_Value(pFeature.Fields.FindField("STACOD")).ToString() != "删除" && pFeature.get_Value(pFeature.Fields.FindField("CLASS")).ToString() != type)
{
IFeature ouFeature = ouFeatureClass.CreateFeture();
for(int ii = 0; ii < ouFeatureClass.Fields.FieldCount; ii++)
{
string fiedldName = pFeature.Fields.get_Field(ii).Name;
switch(ouFeature.Fields.get_Field(ii).Name)
{
case "OBJECTID": break;
case "CREATED_USER": break;
case "CREATED_DATE": break;
case "CREATED_EDITED_USER": break;
case "CREATED_EDITED_DATE": break;
default :
ouFeature.set_Value(ii, pFeature.get_Value(ii));
break;
}
}
ouFeature.Shape = pFeature.ShapeCopy;
ouFeature.Store();
}
pFeature = pFeatureCursor.NextFeature;
}
}
3.3 导出单个要素
exportSingleAKorBB(IFeatureClass ouFeatureClass, IFeature pFeature, string type)
{
if(pFeature.get_Value(pFeature.Fields.FindField("STACOD")).ToString() != "删除" && pFeature.get_Value(pFeature.Fields.FindField("CLASS")).ToString() != type)
{
IFeature ouFeature = ouFeatureClass.CreateFeture();
for(int ii = 0; ii < ouFeatureClass.Fields.FieldCount; ii++)
{
string fiedldName = pFeature.Fields.get_Field(ii).Name;
switch(ouFeature.Fields.get_Field(ii).Name)
{
case "OBJECTID": break;
case "CREATED_USER": break;
case "CREATED_DATE": break;
case "CREATED_EDITED_USER": break;
case "CREATED_EDITED_DATE": break;
default :
ouFeature.set_Value(ii, pFeature.get_Value(ii));
break;
}
}
ouFeature.Shape = pFeature.ShapeCopy;
ouFeature.Store();
}
}