目录
1 需求说明与实现思路
1.1 需求说明
要素超出图廓错误是不允许的,作业过程需要将这些要素提示出来,供人工检查改正
注:本文设计方法思路,仅适用于矩形图廓的检查,对于不规则图廓,则不适用
1.2 需求实现思路
- 对于点要素,直接根据图廓坐标确定的矩形范围的角点坐标,判断其是否在图廓范围内
- 对于线要素,我们将线要素拆解为一组有序的点集,判断点集中的每一个点是否在图廓范围内
- 对于面要素,获取构成面的所有节点集合,判断点集中的每一个点是否在图廓范围内
基于上述分析,我们判断的关键就是点是否在图廓点确定的范围内的问题
2 源码实现
2.1 点是否在图廓范围内
图廓点集:
源码实现:
- 给定一个点pt,判断其是否在ranges围成的范围内
/// <summary>
/// 检查点是否在图廓点确定的数据范围内
/// </summary>
/// <param name="pt"></param>
/// <param name="ranges"></param>
/// <returns></returns>
public bool checkPointIsInner(PointF pt, List<PointF> ranges)
{
if (pt.X < ranges[0].X || pt.X > ranges[2].X)
{
return false;
}
if (pt.Y < ranges[0].Y || pt.Y > ranges[2].Y)
{
return false;
}
return true;
}
2.2 获取点面要素的集合
/// <summary>
/// 获取线面要素节点集
/// </summary>
/// <param name="fea">要素</param>
/// <returns>返回要素节点集合</returns>
public List<PointF> getFeatureVerticePts(IFeature fea)
{
IPointCollection feaPtsColl = fea.Shape as IPointCollection;
List<PointF> feaPts = new List<PointF>();
for (int i = 0; i < feaPtsColl.PointCount; i++)
{
feaPts.Add(new PointF((float)(feaPtsColl.Point[i].X), (float)(feaPtsColl.Point[i].Y)));
}
return feaPts;
}
2.3 获取要素 - IFeatureClass
/// <summary>
/// mdb数据库中提取指定名称的要素
/// </summary>
/// <param name="wsPath">mdb数据库</param>
/// <param name="layerName">要素层名称</param>
/// <returns>返回的要素</returns>
public IFeatureClass getIFeatureClass(string wsPath, string layerName)
{
IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0);
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
//2. 打开要素层
return featureWorkspace.OpenFeatureClass(layerName);
}
2.4 判断某个要素是否在节点范围内
此函数的思路是:判断给定IFeature对象是否在outline对象规定的范围内
/// <summary>
/// 检查线(面)要素是否超出图廓线范围
/// </summary>
/// <param name="outline">图廓线要素</param>
/// <param name="feaLine">线(面)要素</param>
/// <returns>false表示在图廓内部,true表示在图廓外边</returns>
public bool lineIsBeyondOutline(IFeature outline, IFeature feaLine)
{
List<PointF> outlinePts = getFeatureVerticePts(outline);
List<PointF> feaLinePts = getFeatureVerticePts(feaLine);
for (int i = 0; i < feaLinePts.Count; i++)
{
if (!checkPointIsInner(feaLinePts[i], outlinePts))
{
return true;
}
}
return false;
}
2.5 对图层进行检查
/// <summary>
/// 检查点图层
/// </summary>
/// <param name="wsPath">数据库名称</param>
/// <param name="layerName">图层名称</param>
public void checkPointsLayer(string wsPath, string layerName)
{
IFeatureClass pFeaterClass = getIFeatureClass(wsPath, layerName)
IFeature outline = getOutlineFromCPTL(wsPath);
//3. 获取投影信息
IGeoDataset geoDatabase = pFeaterClass as IGeoDataset;
//4. 查询所有要素
string where = "";
IQueryFilter filter = new QueryFilterClass();
filter.WhereClause = where;
//5.定义查询游标并循环迭代
IFeatureCursor pFeatcursor = pFeaterClass.Search(filter, false);
IFeature pFeature = pFeatcursor.NextFeature();
//6. 运算结果存储
List<IFeature> errLists = new List<IFeature>();
while (pFeature != null)
{
if (lineIsBeyondOutline(outline, pFeature))
{
errLists.Add(pFeature);
}
pFeature = pFeatcursor.NextFeature();
}
ExportPtsToShapefile(wsPath, errLists, layerName, esriGeometryType.esriGeometryPoint);
}
支持作者欢迎关注公众号