在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