AE对象的深度克隆和不同数据集的值域拷贝

     在AE二次开发过程中很多时候需要克隆对象,如IMap ,ILayer,IDomain,IElement等等,如果简单的用等于是行不通的,如果每一个细节的赋值,又容易遗漏很多东西。所以就提供了深度克隆的方法:

以IDomain深度克隆为例:

                     IObjectCopy pObjectCopy = new ObjectCopyClass();
                     object preDomain = pObjectCopy.Copy(perDomain);//对象的深度复制
                     IDomain acessDomain = preDomain as IDomain;

这样就会把值域的名称、描述及代码等细节都会一个不落的克隆过去。

  #region 导出数据到本地数据库
        /// <summary>
        /// 导出数据到本地数据库
        /// </summary>
        /// <param name="exportDataName"></param>
        /// <param name="fatherDatasetName"></param>
        /// <param name="saveName"></param>
        /// <returns></returns>
        public bool ExportDataToLocalMDb(string exportDataName, string fatherDatasetName, string saveMdbFileName)
        {
            IDataset outDataset = GetDataset(exportDataName, fatherDatasetName);
            if (outDataset == null)
            {
                string msg = string.Format("{0} 中不包含 {1} 的相关数据!", fatherDatasetName, exportDataName);
                MessageBox.Show(msg, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return true;
            }
            IFeatureClass infeatCls = outDataset as IFeatureClass;

            IWorkspaceFactory pWSF = new ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass();
            string mdbDirectoryStr = System.IO.Path.GetDirectoryName(saveMdbFileName);
            string mdbFileNameStr = System.IO.Path.GetFileNameWithoutExtension(saveMdbFileName);
            if (File.Exists(saveMdbFileName))
            {
                MessageBox.Show("文件\"" + saveMdbFileName + "\"已存在,请重新选择数据库文件", "文件已存在",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }
            pWSF.Create(mdbDirectoryStr, mdbFileNameStr, null, 0);
            
            IWorkspace pWorkspace = pWSF.OpenFromFile(saveMdbFileName, 0);
       
            string outFeatClsName = outDataset.Name.Substring(outDataset.Name.IndexOf('.') + 1);
            SaveFeatureClassToAccessMdb(infeatCls, null, pWorkspace, outFeatClsName);
            
            IFeatureClass operaFeatCls = pWorkspace.OpenFeatureClass(outFeatClsName);
            //值域复制
            if (pWorkspace != null)
            {
                CopyIDomainSDEToMDB(currentWorkspace, pWorkspace);
            }
            //有值域字段复制
            if (operaFeatCls != null)
            {
                CopyDomainWithField(infeatCls, operaFeatCls);
            }
            return true;
        }
        
        /// <summary>
        /// 把值域从远程数据库复制到本地数据库中
        /// </summary>
        /// <param name="sdeWSP">远程SDE数据库</param>
        /// <param name="accessWSP">本地MDB数据库</param>
        private void CopyIDomainSDEToMDB(IWorkspace sdeWSP, IWorkspace accessWSP)
        {
            IWorkspaceDomains sdeWSPDoms = (IWorkspaceDomains)sdeWSP ;
            IWorkspaceDomains accessWSPDoms = (IWorkspaceDomains)accessWSP;
            IEnumDomain sdeEnumDomain = sdeWSPDoms.Domains;
            //复制过程
            if (sdeEnumDomain != null)
            {
                 IDomain perDomain = null;

                 while ((perDomain = sdeEnumDomain.Next()) != null)
                 {
                     //深度克隆
                     IObjectCopy pObjectCopy = new ObjectCopyClass();
                     object preDomain = pObjectCopy.Copy(perDomain);//对象的深度复制
                     IDomain acessDomain = preDomain as IDomain;

                     if (CheckDomainExist(acessDomain.Name, accessWSPDoms) > -1)
                     {
                         accessWSPDoms.DeleteDomain(acessDomain.Name);
                     }
                     accessWSPDoms.AddDomain(acessDomain);
                 }

            }
        }
        /// <summary>
        /// 检查域名是否存在
        /// </summary>
        /// <param name="checkDomainName">值域名称</param>
        /// <param name="pWorkspaceDomains">域名</param>
        /// <returns></returns>若存在返回其域索引位置,不存在则返回-1
        private int CheckDomainExist(string checkDomainName, IWorkspaceDomains pWorkspaceDomains)
        {
            IDomain domain = null;
            IEnumDomain enumDomain = pWorkspaceDomains.Domains;
            if (enumDomain != null)
            {
                while ((domain = enumDomain.Next()) != null)
                {
                    if (domain.Name == checkDomainName)
                        return domain.DomainID;
                }
            }
            return -1;
        }
        /// <summary>
        /// 输出过程中输出值域代码
        /// </summary>
        /// <param name="sdeFClass">SDE数据库数据集</param>
        /// <param name="accessFClass">本地数据库数据集</param>
        private void CopyDomainWithField(IFeatureClass sdeFClass,IFeatureClass accessFClass)
        {
            int fieldCount = sdeFClass.Fields.FieldCount;
            //两个数据集的值域复制
            IDataset pDset = accessFClass as IDataset;
            IWorkspaceDomains workapceDom = pDset.Workspace as IWorkspaceDomains;
            ISchemaLock schemaLock = (ISchemaLock)accessFClass;
            IClassSchemaEdit classSchemaEdit = (IClassSchemaEdit)accessFClass;
            for (int i=0;i<fieldCount;i++)
            {
                IField field = sdeFClass.Fields.get_Field(i);
                IFieldEdit pFieldEdit=field as IFieldEdit;
                if(pFieldEdit.Domain==null)
                    continue;
                //深度克隆
                IDomain acessDomain = workapceDom.get_DomainByName(pFieldEdit.Domain.Name);
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
                classSchemaEdit.AlterDomain(field.Name, acessDomain);
            }
        }
        #endregion
原文地址:https://www.cnblogs.com/wylaok/p/2578445.html