ArcEngine 要素更新效率探讨

最近在做一个房籍图的管理系统,其中需要处理一下地图数据。要求是给图幅接合表的图层增加一个字段,然后在属性数据库中查询每个要素(格网)的图幅数,将结果写入新建字段里。


对于经常用程序做GIS数据处理的,这个实现起来并不难,使用ArcEngine简单写个处理程序即可。不过,不同于之前的应用类程序,这种数据处理程序是要考虑效率问题的。


我第一次写的函数

 private void FJT_Click(object sender, EventArgs e)
        {

  Stopwatch sp1 = new Stopwatch();          
            string sql="";
            IFeatureClass icladd = AEDataHelper.OpenMdbFeatureClass("D:\\数据\\最新汇总.mdb", "WBgrid");
            IFeatureCursor ifcu = icladd.Update(null, false);
            IFeature pfea = ifcu.NextFeature();
            sqlConnection.Open();
            while (pfea!=null)
            {
                int xh = pfea.Fields.FindField("testname");
                string va = pfea.get_Value(xh).ToString();
                sql = "SELECT count(*) as cou from tm_nameinfo where name=\'" + va+"\'";

               DataTable dt = Executmdbsql(sql,sqlConnection);
             //   DataTable dt = Executmdbsql2(sql);
               
                string guiddd = dt.Rows[0]["cou"].ToString();
                int fjt = pfea.Fields.FindField("FJTcount");
                pfea.set_Value(fjt, guiddd);
         
                pfea.Store();
                pfea = ifcu.NextFeature();

                
            }
           sqlConnection.Close();
           sqlConnection.Dispose();
           sp1.Stop();
           MessageBox.Show("处理完成!!!!!" + "耗时:" + sp1.ElapsedMilliseconds.ToString()+"毫秒");
           
         
        }

19272条要素,所需时间为107秒。速度怎么说呢,不好说,因为没有对比。如果想提速,可以从这几个方面考虑。


1 这函数里有循环,把能放在循环外的放外面

2 sql查询速度应该很快,可以忽略

3 虽然我是在更新空间要素,但是我更新的是它的属性字段,是否可以换个写法

4 ArcEngine 中有好多接口,不同接口的执行效率可能不同。

然后依据4我又换了一种写法

  private void FJT_Click(object sender, EventArgs e)
        {
            sp1.Start();
            string sql="";
            IFeatureClass icladd = AEDataHelper.OpenMdbFeatureClass("D:\\数据\\最新汇总.mdb", "WBgrid");
            IFeatureCursor ifcu = icladd.Update(null, false);
            IFeature pfea = ifcu.NextFeature();
            sqlConnection.Open();
            while (pfea!=null)
            {
                int xh = pfea.Fields.FindField("testname");
                string va = pfea.get_Value(xh).ToString();
                sql = "SELECT count(*) as cou from tm_nameinfo where name=\'" + va+"\'";

               DataTable dt = Executmdbsql(sql,sqlConnection);
             //   DataTable dt = Executmdbsql2(sql);
               
                string guiddd = dt.Rows[0]["cou"].ToString();
                int fjt = pfea.Fields.FindField("FJTcount");
                pfea.set_Value(fjt, guiddd);
                ifcu.UpdateFeature(pfea);
              //  pfea.Store();使用update效率会比store()好的多
                pfea = ifcu.NextFeature();

                
            }
           sqlConnection.Close();
           sqlConnection.Dispose();
           sp1.Stop();
           MessageBox.Show("处理完成!!!!!" + "耗时:" + sp1.ElapsedMilliseconds.ToString()+"毫秒");
           
         
        }


这次执行时间为52秒,只是改动一个地方,把pfea.Store()改为使用游标的ifcu.UpdateFeature(pfea)。从理论上看,前者相当于把要素的所有属性重新存了进来,而后者只是把更新的属性写入,自然后者效率高些。然而这并没完,根据3

我又换了一种写法

 private void FJTtest_Click(object sender, EventArgs e)
        {

  Stopwatch sp1 = new Stopwatch();  
            string sql = "";
            ITable it1 = AEDataHelper.OpenMdbTable("D:\\数据\\最新汇总.mdb", "WBgrid");
            ICursor ic1 = it1.Update(null, false);
            IRow prow = ic1.NextRow();
            sqlConnection.Open();
            while(prow!=null)
            {
                string xh = prow.get_Value(35).ToString();
                sql = "SELECT count(*) as cou from tm_nameinfo where name=\'" + xh + "\'";
                DataTable dt = Executmdbsql(sql, sqlConnection);
                 string guiddd = dt.Rows[0]["cou"].ToString();
                 prow.set_Value(34, guiddd);
                 ic1.UpdateRow(prow);
                 prow = ic1.NextRow();

            }
            sqlConnection.Close();
            sqlConnection.Dispose();
            sp1.Stop();
            MessageBox.Show("处理完成!!!!!" + "耗时:" + sp1.ElapsedMilliseconds.ToString() + "毫秒");
        }


这次执行完,速度是47秒!!!


细心的人可以发现,这次差别只是一个使用的是FeatureClass(即空间要素集),一次使用的是ITable(属性表)。难道这效率差是操作空间要素和属性要素造成的?理论上,我又没动空间数据,怎么可能又效率差?我又想了想,把第二种写法改了一下

private void FJT_Click(object sender, EventArgs e)
        {
            sp1.Start();
            string sql="";
            IFeatureClass icladd = AEDataHelper.OpenMdbFeatureClass("D:\\数据\\最新汇总.mdb", "WBgrid");
            IFeatureCursor ifcu = icladd.Update(null, false);
            IFeature pfea = ifcu.NextFeature();
            sqlConnection.Open();
            while (pfea!=null)
            {
            
                string va = pfea.get_Value(35).ToString();
                sql = "SELECT count(*) as cou from tm_nameinfo where name=\'" + va+"\'";

               DataTable dt = Executmdbsql(sql,sqlConnection);
         
               
                string guiddd = dt.Rows[0]["cou"].ToString();
            
                pfea.set_Value(34, guiddd);
                ifcu.UpdateFeature(pfea);
              //  pfea.Store();使用update效率会比store()好的多
                pfea = ifcu.NextFeature();

                
            }
           sqlConnection.Close();
           sqlConnection.Dispose();
           sp1.Stop();
           MessageBox.Show("处理完成!!!!!" + "耗时:" + sp1.ElapsedMilliseconds.ToString()+"毫秒");
           
         
        }

这次。。。46秒,和第三种写法差不多了。原来,执行效率和操作空间数据和属性数据没关系。。。

总结:ArcEngine 更新数据,使用游标更新要比使用要素直接更新快。。。。写了这么多,就得出个这么一句话尴尬

猜你喜欢

转载自blog.csdn.net/u010723516/article/details/78222501
今日推荐