DayDreamInGIS ArcGIS-AddIn 之按属性分割图层工具

数据生产过程中,经常需要将图层中的数据根据某个字段分割成不同的图层,比如,一个全省的图斑数据,可能需要分割成每个市一个图层。本工具主要实现上述功能,工具界面如下:

由于功能比较简单,代码主要放在Form中实现。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.ArcMapUI;
using AddInAssiter;

namespace DayDreamInGISTool.ClassifyByAttributes
{
    public partial class frmSet : Form
    {
        public frmSet(IMap pMap)
        {
            this.pMap = pMap;
            InitializeComponent();
        }
        IMap pMap = null;
        IWorkspace pWs=null;
        IWorkspaceName pWsN = null;

        private IFeatureLayer pToBeSplitFtLyr = null;

        private void frmSet_Load(object sender, EventArgs e)
        {
            if (pMap.LayerCount == 0)
                return;

            //Combox中加载所有矢量图层
            GISCommonHelper.CartoLyrHelper.setFeatureLyrCombox(ref cmbLayer, pMap, 
                ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryAny);
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            string result = "";
            if (chkAll.Checked)
            {
                //处理所有的图层
                for (int i = 0; i < cmbLayer.Items.Count; i++)
                {
                    result += ExportData((IFeatureLayer)((GISCommonHelper.name_Layer)cmbLayer.Items[i]).layer);
                }
            }
            else
            {
                result += ExportData((IFeatureLayer)cmbLayer.SelectedValue);
            }

            MessageBox.Show("处理完成\r\n"+result);

            this.DialogResult = DialogResult.OK;
        }

        /// <summary>
        /// 对要素图层进行分割
        /// 该功能本质上是通过导出功能实现,大体实现流程
        /// (1)根据设置的分割字段,获取该图层该字段所有的唯一值
        /// (2)设置导出条件
        /// (3)导出到新的工作空间
        /// </summary>
        /// <param name="pFeatureLayer"></param>
        /// <returns></returns>
        private string ExportData(IFeatureLayer pFeatureLayer)
        {
            string strResult = "";
            string fengeFieldStr = cmbField.Items[cmbField.SelectedIndex].ToString();
            //分割字段类型只能是字符类型
            IField pField =pFeatureLayer.FeatureClass.Fields.get_Field(pFeatureLayer.FeatureClass.Fields.FindField(fengeFieldStr));
            
            //获取所有可能的值类型 调用AE的统计接口
            IDataStatistics pDS = new DataStatisticsClass();
            pDS.Field = fengeFieldStr;
            IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
            pDS.Cursor = pFeatureCursor as ICursor;

            System.Collections.IEnumerator enumerator;
            enumerator = pDS.UniqueValues;
            enumerator.Reset();
            int UVCount = pDS.UniqueValueCount;
            progressBar1.Maximum = UVCount;
            int tCount = 1;
            enumerator.MoveNext();
            object vl = enumerator.Current;
            while (vl != null)
            {
                //设置分割条件
                IQueryFilter pqf = new QueryFilterClass();
                pqf.WhereClause = string.Format("{0}=\'{1}\'",fengeFieldStr,vl);
                
                //将此属性值的数据输出至工作空间
                IDataset pInDataset = pFeatureLayer.FeatureClass as IDataset;
                IFeatureClassName pInFCName = pInDataset.FullName as IFeatureClassName;
                IWorkspace pInWorkspace = pInDataset.Workspace;
                //IDataset pOutDataset = pWs as IDataset;
                //IWorkspaceName pOutWorkspaceName = pOutDataset.FullName as IWorkspaceName;
                IWorkspaceName pOutWorkspaceName = pWsN;
                IFeatureClassName pOutFCName = new FeatureClassNameClass();
                IDatasetName pDatasetName = pOutFCName as IDatasetName;
                pDatasetName.WorkspaceName = pOutWorkspaceName;
                pDatasetName.Name = pInDataset.Name + "_" + vl;  //要素类名称
                //可能存在图层名重复或者非法的图层名
                IFieldChecker pFieldChecker = new FieldCheckerClass();
                pFieldChecker.InputWorkspace = pInWorkspace;
                pFieldChecker.ValidateWorkspace = pWs;
                IFields pFields = pFeatureLayer.FeatureClass.Fields;
                IFields pOutFields;
                IEnumFieldError pEnumFieldError;
                pFieldChecker.Validate(pFields, out pEnumFieldError, out pOutFields);
                IFeatureDataConverter pFeatureDataConverter = new FeatureDataConverterClass();
                pFeatureDataConverter.ConvertFeatureClass(pInFCName, pqf, null, pOutFCName, null, pOutFields, "", 100, 0);

                progressBar1.Value = tCount;

                enumerator.MoveNext();
                vl = enumerator.Current;
                tCount++;
            }
            strResult = string.Format("图层{0}分割完毕!\n", pFeatureLayer.Name);
            return strResult;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            //shapefile工作空间,FGDB工作空间,MDB工作空间
            pWsN = GISCommonHelper.GeoDatabaseHelper.BrowseWorkspace(this.Handle.ToInt32(), out pWs);
            if(pWsN!=null)
                this.txtPath.Text = pWsN.PathName;
        }

        private void cmbField_SelectedIndexChanged(object sender, EventArgs e)
        {
            //
        }

        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbField.Items.Clear();
            

            if (cmbLayer.SelectedIndex > -1)
            {
                pToBeSplitFtLyr = cmbLayer.SelectedValue as IFeatureLayer;
                //切换字段内容
                IFields pFields = pToBeSplitFtLyr.FeatureClass.Fields;
                for (int i = 0; i < pFields.FieldCount; i++)
                {
                    if (pFields.get_Field(i).Type == esriFieldType.esriFieldTypeString)
                    {
                        //分割只针对字符类型
                        cmbField.Items.Add(pFields.get_Field(i).Name);
                    }
                }
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

打开工作空间函数,其他内容请参考上一篇帖子 这里

public static IWorkspaceName BrowseWorkspace(int hwnd, out IWorkspace ws)
        {
            IGxObjectFilterCollection ipFilters = new GxDialogClass();
            //IGxObjectFilter ipFilter1 = new GxFilterFeatureDatasetsClass();  //要素数据集 ,导出时,IFeatureClassConverter对象无法写入Dataset中,此处隐藏掉
            //ipFilters.AddFilter(ipFilter1,false);
            IGxObjectFilter ifilt2 = new GxFilterWorkspacesClass();  //数据库工作空间,此类比较含糊,不知道具体指啥
            ipFilters.AddFilter(ifilt2, false);
            IGxObjectFilter ipFilter3 = new GxFilterFileFolderClass();  //文件工作空间
            ipFilters.AddFilter(ipFilter3, false);


            IGxDialog pGDialog = (IGxDialog)ipFilters;
            pGDialog.RememberLocation = true;
            pGDialog.Title = "请选择工作空间";
            pGDialog.AllowMultiSelect = false;

            IEnumGxObject pResultEnum = null;
            //IWorkspace ws = null;
            ws = null;
            IWorkspaceName wsn = null;
            if (pGDialog.DoModalOpen(hwnd, out pResultEnum) && pResultEnum != null)
            {
                IGxObject gxObj = pResultEnum.Next();
                if (gxObj is IGxDatabase)
                {
                    IGxDatabase gxDB = gxObj as IGxDatabase;
                    if (gxDB != null)
                    {
                        ws = gxDB.Workspace;
                        wsn = gxDB.WorkspaceName;
                    }
                }
                else if (gxObj is IGxFolder)
                {
                    //Todo: figure out how to decide which workspace to get for
                    // a particular folder (shapefile, raster etc.)                    
                    //IEnumName enumName = ((IGxFolder)gxObj).FileSystemWorkspaceNames;

                    // for now just assume we want a shapefile ...
                    IWorkspaceFactory wsf = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactoryClass();
                    ws = wsf.OpenFromFile(((IGxFile)gxObj).Path, hwnd);
                    IDataset pOutDataset = ws as IDataset;
                    wsn = pOutDataset.FullName as IWorkspaceName;
                }
                else if (gxObj is IGxDataset)
                {
                    //如果是数据集工作空间
                    IGxDataset gxDs = gxObj as IGxDataset;
                    if (gxDs != null)
                    {
                        ws = gxDs.Dataset.Workspace;
                        wsn = gxDs.DatasetName.WorkspaceName;
                    }

                }
                Marshal.FinalReleaseComObject(pResultEnum);
            }

            pGDialog.InternalCatalog.Close();
            Marshal.FinalReleaseComObject(pGDialog);

            return wsn;
        }

 

Button代码,Button代码主要实现弹出form窗体

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using System.Windows.Forms;

namespace DayDreamInGISTool.ClassifyByAttributes
{
    public class ButtonClassifyByAttributes : ESRI.ArcGIS.Desktop.AddIns.Button
    {
        public ButtonClassifyByAttributes()
        {
        }

        protected override void OnClick()
        {
            try
            {
                if (false)
                {
                    ArcMap.Application.CurrentTool = null;
                    return;
                }
                //
                //  TODO: Sample code showing how to access button host
                //
                ArcMap.Application.CurrentTool = null;

                IMap pMap = ArcMap.Document.FocusMap;
                //属性分割
                frmSet fs = new frmSet(pMap);
                fs.ShowDialog();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("发生未知错误:"+ex.Message);
            }
        }
        protected override void OnUpdate()
        {
            Enabled = ArcMap.Application != null;
        }
    }

}

 

某测试数据包含一个行政区字段,

分割之后的效果

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值