AE 线要素排序
对一个线状图层,相邻要素的OID并不连续。需要将这些要素按照空间关系重新排序,并体现在字段ORDER中,图层示意图如下
解决思路:先找出端点要素,端点要素即为位于图层开头或者末尾的要素,设为当前要素,再找出与当前端点要素相邻且没有处理过的要素。每找出一个要素,对要素的ORDER字段赋值为一个递增的序号。
难点:AE中我没有找到很好的遍历要素的方法,只能使用 IFeatureCursor 的方式来进行遍历,这增加了算法实现的复杂度。
具体流程:添加字段→找出图层端点要素→逐个找出与当前端点相邻的要素
①添加字段:
addTextField((IFeatureLayer)(map.get_Layer(line_index)),"M_ORDER","顺序");
public void addTextField(IFeatureLayer featureLayer, string name, string alias) { ISchemaLock pSchemaLock = featureLayer.FeatureClass as ISchemaLock; pSchemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); int nIndexOfGBTYPE = featureLayer.FeatureClass.Fields.FindField(name); if (nIndexOfGBTYPE == -1) { IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = name; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger; pFieldEdit.IsNullable_2 = true; pFieldEdit.AliasName_2 = alias; pFieldEdit.DefaultValue_2 = ""; pFieldEdit.Editable_2 = true; pFieldEdit.Length_2 = 100; featureLayer.FeatureClass.AddField(pField); } pSchemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); }
②获取字段序号以及要素数量等
int current_order = 1; int index_order = 999; int index_odevity = 999; IFeature pFeature_tml=pFeatureLayer_pipe.FeatureClass.GetFeature(1); List<int> occupiesID = new List<int>(); try { index_order = pFeatureLayer_pipe.FeatureClass.FindField("M_ORDER"); index_odevity = pFeatureLayer_pipe.FeatureClass.FindField("M_ODV"); } catch { } string where = ""; IQueryFilter filter = new QueryFilterClass(); filter.WhereClause = where; IFeatureClass pFeaterClass = pFeatureLayer_pipe.FeatureClass; int countFeature = pFeatureLayer_pipe.FeatureClass.FeatureCount(filter);
③找出端点要素,过程为两层循环:
//第一轮找出端点 IFeatureCursor pFeatcursor = pFeaterClass.Update(filter, false); IFeature pFeature = pFeatcursor.NextFeature(); while (pFeature != null) //遍历所有要素找出端点 { int id_out = pFeature.OID; int countNeighber = 0; IFeatureCursor pFeatcursor2 = pFeaterClass.Update(filter, false); IFeature pFeature2 = pFeatcursor2.NextFeature(); while (pFeature2 != null) //遍历所有要素 { int id_inner = pFeature2.OID; //判断是不是相邻 if (isNeighbour(pFeature2, pFeature)) { countNeighber++; } pFeature2 = pFeatcursor2.NextFeature(); } if (countNeighber == 1) { //是端点,存到字段里 pFeature_tml = pFeature; pFeature.set_Value(index_order, current_order++); int odv = (current_order-1) % 2; pFeature.set_Value(index_odevity, odv); pFeatcursor.UpdateFeature(pFeature);//将更新的内容保存 int id = pFeature.OID; occupiesID.Add(id); break; } pFeature = pFeatcursor.NextFeature(); }
private bool isNeighbour(IFeature feature1, IFeature feature2) { try { IPointCollection points1 = feature1.Shape as IPointCollection; IPoint pt1 = points1.get_Point(0); IPoint pt2 = points1.get_Point(points1.PointCount - 1); IPointCollection points2 = feature2.Shape as IPointCollection; IPoint pt3 = points2.get_Point(0); IPoint pt4 = points2.get_Point(points2.PointCount - 1); int count_zero = 0; double x1 = pt1.X; double y1 = pt1.Y; double x2 = pt2.X; double y2 = pt2.Y; double x3 = pt3.X; double y3 = pt3.Y; double x4 = pt4.X; double y4 = pt4.Y; double d1 = Math.Abs(getDistance(x1, y1, x3, y3)); double d2 = Math.Abs(getDistance(x1, y1, x4, y4)); double d3 = Math.Abs(getDistance(x2, y2, x3, y3)); double d4 = Math.Abs(getDistance(x2, y2, x4, y4)); if (d1 == 0) { count_zero++; } if (d2 == 0) { count_zero++; } if (d3 == 0) { count_zero++; } if (d4 == 0) { count_zero++; } if (count_zero == 1) { return true; } return false; } catch { throw; } }
④逐个找出所有相邻要素,并给字段赋值
//第二轮大循环 for (int i = 0; i < countFeature; i++) { IFeatureCursor pFeatcursor3 = pFeaterClass.Update(filter, false); IFeature pFeature3 = pFeatcursor3.NextFeature(); while (pFeature3 != null) //遍历所有要素 { int id = pFeature3.OID; //找出与当前要素相邻且没弄过的要素 if (isNeighbour(pFeature_tml, pFeature3) && !exist(occupiesID,id)) { pFeature3.set_Value(index_order, current_order++); int odv = (current_order - 1) % 2; pFeature3.set_Value(index_odevity, odv); pFeatcursor3.UpdateFeature(pFeature3);//将更新的内容保存 pFeature_tml = pFeature3; occupiesID.Add(id); break; } //当前要素的oid pFeature3 = pFeatcursor3.NextFeature(); } }
⑤程序结果
作者初出茅庐,如有疑问或者可以改进之处,还请多多指教!