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

⑤程序结果

 

 作者初出茅庐,如有疑问或者可以改进之处,还请多多指教!

 

posted @ 2019-02-27 11:00  majiayou  阅读(325)  评论(0)    收藏  举报