现在的位置: 首页 > 综合 > 正文

参考ArcGIS10自定义实现要素附件管理(FeatureAttachmentManager)

2012年09月21日 ⁄ 综合 ⁄ 共 12795字 ⁄ 字号 评论关闭

 

一、ArcGIS10新特性

1、  在ArcGIS10中新增了要素附件功能。要素附件即:在FeatureClass中的每一个Feature都可以关联一个或多个任意格式附件文件(如,文档文件、图片和视频文件等)。另一方面,在数据库中,如果删除了featureClass则与之对应要素附件也会被删除。

2、  ArcGIS中的要素附件管理的原理。

(1)       创建要素附件。

在ArcGIS10中,只能为要素类(FeatureClass)创建附件(即:一个要素类对应一个附件表和一个关系类)。具体创建方法见下图1:

 

图1 为要素类(图中为DISTR)创建附件。

创建附件后,会在数据库中自动创建一个表(Table)和关系类(RelationshhipClass),如下图2所示:

 

图2要素类DISTR及其附件表(DISTR_ATTACH)和关系类(DISTR_ATTACHREL)

(2)       添加附件。

在ArcMap中,加载已经创建了附件的要素图层,开启编辑,即可为每一个要素添加附件。如下图3和图4所示:

 

图3添加附件

 

图4添加任意格式的附件

(3)       查询附件。

在ArcMap中进行要素属性查询时,如果要素存在附件,可以再要素属性查询窗口中看到,如下图5所示:

 

图5 要素属性查询

(4)       附件表和关系类

附件表结构和关系类如下图6、7所示:

 

图6附件表

 

图7关系类

3、  ArcGIS10中新增的接口:ITableAttachments

(1)       OMD图

 

(2)       ITableAttachments、IAttachmentManager、IEnumAttachment、IAttachment等接口相关属性和方法,可以参考开发帮助

二、自定义实现要素附件管理(适用于ArcGIS 9.3和ArcGIS10)

尽管ArcGIS10提供了附件管理功能,但是在使用的时候并不是很方便,主要原因是:

1、只能只对一个要素类进行管理,即:一个要素类对应一个附件表和关系类。如果要对所有的要素类进行附件管理,就需要为每一个要素创建一个附件表和关系类,不能进行统一管理。

2、受版本限制,目前只能在ArcGIS10及以上版本中使用这个功能,对于10之前的版本就无能为力了。

鉴于上面的原因,我们可以基于ArcGIS10的附件管理原理,自定义实现要素的附件管理功能,这样我们可以突破限制,对所有的要素类的附件进行统一管理同时不受版本的限制(目前已经测试在10和9.3中均适用)。实现的过程比较简单,具体的方法:

在数据库中创建一个附件表,所有要素类和所有的附件都存放在这个附件表中,在增、删、查的时候只要操作这个附件表就行了。具体的表结构设计:

附件表

下面不多说了,贴代码:

View Code

    public interface ISMFeatureAttachment
    {
        void SMAddAttachments();//添加附件表
        bool SMHasAttachments{get;}//判断是否存在附件表
        void SMDeleteAttachments();//删除附件表
        ISMAttachmentManager SMAttachmentManager { get; }//附件管理接口
    }
    public interface ISMAttachmentManager
    {
        bool SMAddAttachment(ISMAttachment attachment);//添加附件
        bool SMAddAttachment2(ISMAttachment attachment);//添加附件
        bool SMDeleteAttachment(int attachmentID);//删除指定附件ID的附件
        bool SMDeleteAttachmentForFeature(int featureID,string physicalLayerName);//删除指定要素的所有附件
        void SMUpdateAttachment(ISMAttachment attachment);//更新附件
        ISMEnumAttachment GetAttachmentByParentID(int featureID,bool IsOnlyInfo);//获取指定要素的所有附件
        //ISMAttachment GetAttachmentByAttachmentID(int attachmentID);//获取指定附件ID的附件
        IWorkspace Workspace { get; set; }//工作空间属性
        string AttachmentTableName { get; set; }//附件表名属性
    }

    public interface ISMAttachment
    {
        int AttachmentID { get; set; }
        int ParentID { get; set; }
        string ContentType { get; set; }
        IMemoryBlobStream Data { get; set; }
        uint DataSize { get; }
        string AttachmentName { get; set; }
        string PhysicalLayerName { get; set; }
    }
    public interface ISMEnumAttachment
    {
        ISMAttachment Next();
        void Reset();
        IWorkspace CurrentWorkspace{get;set;}
        ITable AttachmentTable{get;set;}
        List<ISMAttachment> AttachmentList { get;}
    }

 

View Code

    /// <summary>
/// 摘要:附件管理器
/// </summary>
public class SMAttachmentManagerClass:ISMAttachmentManager
{
private int m_FeatureID;
private IWorkspace m_Workspace;
private string m_AttachmentTableName;
/// <summary>
/// 构造函数
/// </summary>
public SMAttachmentManagerClass()
{
}

#region ISMAttachmentManager 成员

/// <summary>
/// 添加附件
/// </summary>
/// <param name="featureID">要素ID</param>
/// <param name="attachment">附件对象</param>
public bool SMAddAttachment(ISMAttachment attachment)
{
try
{
//打开附件表
ITable pTable = (this.Workspace as IFeatureWorkspace).OpenTable(this.m_AttachmentTableName);
IRow pRow
= pTable.CreateRow();
IFields fields
= pRow.Fields;
for (int i = 0; i < fields.FieldCount; i++)
{
IField field
= pTable.Fields.get_Field(i);
if (field.Name.ToUpper() == "OBJECTID") continue;
switch (field.Name.ToUpper())
{
case "PARENTID":
pRow.set_Value(i, attachment.ParentID);
break;
case "ATTACHMENTNAME":
pRow.set_Value(i, attachment.AttachmentName);
break;
case "CONTENTTYPE":
pRow.set_Value(i, attachment.ContentType.ToString());
break;
case "DATA":
pRow.set_Value(i,(
object)attachment.Data);
break;
case "DATASIZE":
pRow.set_Value(i,attachment.DataSize);
break;
case "PHYSICALLAYERNAME":
pRow.set_Value(i,attachment.PhysicalLayerName);
break;
default:
break;
}
}
pRow.Store();
return true;
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// 添加附件
/// </summary>
/// <param name="attachment">附件</param>
/// <returns></returns>
public bool SMAddAttachment2(ISMAttachment attachment)
{
IRowBuffer rowBuffer
= null;
ICursor insertCursor
= null;
try
{
IWorkspaceEdit pWSEdit
= this.Workspace as IWorkspaceEdit;
//打开附件表
ITable pTable = (this.Workspace as IFeatureWorkspace).OpenTable(this.m_AttachmentTableName);
IFields fields
= pTable.Fields;
pWSEdit.StartEditing(
true);
pWSEdit.StartEditOperation();

rowBuffer = pTable.CreateRowBuffer();
insertCursor
= pTable.Insert(true);

for (int i = 0; i < fields.FieldCount; i++)
{
IField field
= rowBuffer.Fields.get_Field(i);
if (field.Name.ToUpper() == "OBJECTID") continue;
switch (field.Name.ToUpper())
{
case "PARENTID":
rowBuffer.set_Value(i, attachment.ParentID);
break;
case "ATTACHMENTNAME":
rowBuffer.set_Value(i, attachment.AttachmentName);
break;
case "CONTENTTYPE":
rowBuffer.set_Value(i, attachment.ContentType.ToString());
break;
case "DATA":
rowBuffer.set_Value(i, attachment.Data);
break;
case "DATASIZE":
rowBuffer.set_Value(i, attachment.DataSize);
break;
case "PHYSICALLAYERNAME":
rowBuffer.set_Value(i, attachment.PhysicalLayerName);
break;
default:
break;
}
}
insertCursor.InsertRow(rowBuffer);
insertCursor.Flush();
pWSEdit.StopEditOperation();
pWSEdit.StopEditing(
true);
return true;
}
catch (Exception)
{
return false;
}
finally
{
if (rowBuffer != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(rowBuffer); }
if (insertCursor != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(insertCursor); }
}
}

/// <summary>
/// 删除指定附件
/// </summary>
/// <param name="attachmentID"></param>
public bool SMDeleteAttachment(int attachmentID)
{
string whereClause = string.Format("objectID={0}", attachmentID);
DeletRows(whereClause);
return true;
}

/// <summary>
/// 删除要素的所有附件
/// </summary>
/// <param name="featureID"></param>
public bool SMDeleteAttachmentForFeature(int featureID,string physicalLayerName)
{
string whereClause = string.Format("ParentID={0} and PhysicalLayerName='{1}'",featureID,physicalLayerName);
DeletRows(whereClause);
return true;
}

/// <summary>
/// 更新附件
/// </summary>
/// <param name="attachment"></param>
public void SMUpdateAttachment(ISMAttachment attachment)
{
//删除原始附件记录
string WhereClause = string.Format("OBJECTID={0}",attachment.AttachmentID);
DeletRows(WhereClause);
//添加附件
SMAddAttachment(attachment);
}

/// <summary>
/// 获取指定要素的所有附件
/// </summary>
/// <param name="featureID">要素ID</param>
/// <returns></returns>
public ISMEnumAttachment GetAttachmentByParentID(int featureID, bool IsOnlyInfo)
{
ITable pTable
= (this.Workspace as IFeatureWorkspace).OpenTable(this.m_AttachmentTableName);
ISMEnumAttachment enumAttachment
= new SMEnumAttachmentClass(featureID,IsOnlyInfo,this.Workspace,pTable);
return enumAttachment;
}

/// <summary>
/// 工作空间
/// </summary>
public IWorkspace Workspace
{
get
{
return this.m_Workspace;
}
set
{
this.m_Workspace = value;
}
}

/// <summary>
/// 附件表名
/// </summary>
public string AttachmentTableName
{
get
{
return this.m_AttachmentTableName;
}
set
{
this.m_AttachmentTableName = value;
}
}
#endregion

/// <summary>
/// 快速删除表中的行对象
/// </summary>
/// <param name="whereClause"></param>
private void DeletRows(string whereClause)
{
try
{
ITable pTable
= (this.Workspace as IFeatureWorkspace).OpenTable(this.m_AttachmentTableName);
IQueryFilter pQueryFilter
= new QueryFilterClass();
pQueryFilter.WhereClause
= whereClause;

pTable.DeleteSearchedRows(pQueryFilter);//快速删除
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(
"异常来自:SMDeleteAttachment:\r\n" + ex.Message);
}
}
}

public class SMAttachmentClass:ISMAttachment
{
private IFeature m_Feature;//要素
private int m_AttachmentID;//附件ID
private int m_ParentID;//要素ID
private string m_ContentType;//附件内容类型
private IMemoryBlobStream m_Data;//附件
private uint m_DataSize;//附件大小
private string m_AttachmentName;//附件名称
private string m_PhysicalLayerName;//物理图层名
public SMAttachmentClass()
{}
#region ISMAttachment 成员
/// <summary>
/// 附件ID
/// </summary>
public int AttachmentID
{
get { return this.m_AttachmentID; }
set { this.m_AttachmentID = value;}
}
/// <summary>
/// 要素ID
/// </summary>
public int ParentID
{
get
{
return this.m_ParentID;
}
set
{
this.m_ParentID=value;
}
}
/// <summary>
/// 附件类型
/// </summary>
public string ContentType
{
get
{
return this.m_ContentType;
}
set
{
this.m_ContentType = value;
}
}
/// <summary>
/// 附件数据
/// </summary>
public ESRI.ArcGIS.esriSystem.IMemoryBlobStream Data
{
get
{
return this.m_Data;
}
set
{
this.m_Data=value;
}
}
/// <summary>
/// 附件大小
/// </summary>
public uint DataSize
{
get { return this.m_Data.Size; }
}
/// <summary>
/// 附件名称
/// </summary>
public string AttachmentName
{
get
{
return this.m_AttachmentName;
}
set
{
this.m_AttachmentName=value;
}
}
/// <summary>
/// 物理图层名
/// </summary>
public string PhysicalLayerName
{
get
{
return this.m_PhysicalLayerName;
}
set
{
this.m_PhysicalLayerName = value;
}
}
#endregion
}

public class SMFeatureAttachmentClass:ISMFeatureAttachment
{
private IWorkspace m_Workspace;
private string m_TableName;
private ISMAttachmentManager m_AttachmentManager;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="ws"></param>
/// <param name="tablename"></param>
public SMFeatureAttachmentClass(IWorkspace ws,string tablename)
{
this.m_Workspace=ws;
this.m_TableName = tablename;//附件表名
}

#region ISMFeatureAttachment 成员
/// <summary>
/// 添加要素附件表
/// </summary>
public void SMAddAttachments()
{
try
{
if (this.SMHasAttachments)
{
MessageBox.Show(
string.Format("要素附件表【{0}】已经存在。", this.m_TableName), "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
IFields fields
= this.CreateFiledCollectionForTable();//字段集合
if (fields != null)
{
if (this.CreateAttachmentTable(this.m_Workspace, this.m_TableName, fields))
{
MessageBox.Show(
string.Format("要素附件表【{0}】创建成功.", this.m_TableName), "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show(
string.Format("要素附件表【{0}】创建失败.", this.m_TableName), "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show(
"初始化字段集合失败!");
}
}
}
catch (Exception ex)
{
MessageBox.Show(
string.Format("要素附件表【{0}】创建失败。原因:\r\n"+ex.Message, this.m_TableName), "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 检查附件表是否存在
/// </summary>
public bool SMHasAttachments
{
get
{
IWorkspace2 ws2
= this.m_Workspace as IWorkspace2;
if (ws2.get_NameExists(esriDatasetType.esriDTTable, this.m_TableName))
{
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// 删除附件表
/// </summary>
public void SMDeleteAttachments()
{
DeleteAttachmentTable(
this.m_TableName);//删除附件表
}
/// <summary>
/// 附件管理器
/// </summary>
public ISMAttachmentManager SMAttachmentManager
{
get
{
if (this.m_AttachmentManager == null)
{
this.m_AttachmentManager = new SMAttachmentManagerClass();
m_AttachmentManager.Workspace
= this.m_Workspace;
m_AttachmentManager.AttachmentTableName
= this.m_TableName;
}
return this.m_AttachmentManager;
}
}
#endregion

#region 辅助函数
/// <summary>
/// 创建附件表
/// </summary>
/// <param name="tablename">表名</param>
private bool CreateAttachmentTable(IWorkspace workspace,string tablename,IFields fields)
{
try
{
IFeatureWorkspace featureWorkspace
= (IFeatureWorkspace)workspace;
IObjectClassDescription ocDescription
= new ObjectClassDescriptionClass();

IFieldChecker fieldChecker = new FieldCheckerClass();
IEnumFieldError enumFieldError
= null;
IFields validatedFields
= null;
fieldChecker.ValidateWorkspace
= workspace;
fieldChecker.Validate(fields,
out enumFieldError, out validatedFields);

ITable table = featureWorkspace.CreateTable(tablename, validatedFields,
ocDescription.InstanceCLSID,
null, "");
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 创建字段集合
/// </summary>
private IFields CreateFiledCollectionForTable()
{
IFields pFields
= new FieldsClass();
IFieldsEdit pFieldsEdit
= pFields as IFieldsEdit;
IField pField
= null;

//AttachmentID
pField = new FieldClass();
IFieldEdit pFieldEdit
= pField as IFieldEdit;
pFieldEdit.Name_2
= "AttachmentID";
pFieldEdit.AliasName_2
= "附件ID";
pFieldEdit.Type_2
= esriFieldType.esriFieldTypeOID;
pFieldsEdit.AddField(pField);
//ParentID
pField = new FieldClass();
IFieldEdit parentField
= pField as IFieldEdit;
parentField.Type_2
= esriFieldType.esriFieldTypeInteger;
parentField.Name_2
= "ParentID";
parentField.AliasName_2
= "要素ID";
parentField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);
//AttachmentName
pField = new FieldClass();
IFieldEdit nameField
= pField as IFieldEdit;
nameField.Type_2
= esriFieldType.esriFieldTypeString;
nameField.Name_2
= "AttachmentName";
nameField.AliasName_2
= "附件名称";
nameField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);
//ContentType
pField = new FieldClass();
IFieldEdit contentField
= pField as IFieldEdit;
contentField.Type_2
= esriFieldType.esriFieldTypeString;
contentField.Name_2
= "ContentType";
contentField.AliasName_2
= "附件类型";
contentField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);
//Data
pField = new FieldClass();
IFieldEdit dataField
= pField as IFieldEdit;
dataField.Type_2
= esriFieldType.esriFieldTypeBlob;
dataField.Name_2
= "Data";
dataField.AliasName_2
= "附件数据";
dataField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);
//DataSize
pField = new FieldClass();
IFieldEdit datasizeField
= pField as IFieldEdit;
datasizeField.Type_2
= esriFieldType.esriFieldTypeInteger;
datasizeField.Name_2
= "DataSize";
datasizeField.AliasName_2
= "附件大小";
datasizeField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);
//PhysicalLayerName
pField = new FieldClass();
IFieldEdit layerField
= pField as IFieldEdit;
layerField.Type_2
= esriFieldType.esriFieldTypeString;
layerField.Name_2
= "PhysicalLayerName";
layerField.AliasName_2
= "物理图层名";
layerField.IsNullable_2
= false;
pFieldsEdit.AddField(pField);

return pFields;
}
/// <summary>
/// 删除附件表
/// </summary>
/// <param name="tablename">表名</param>
private void DeleteAttachmentTable(string tablename)
{
if (this.SMHasAttachments)
{
try
{
if (MessageBox.Show(string.Format("确定要删除附件表【{0}】吗?", this.m_TableName), "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
ITable pTable
= (this.m_Workspace as IFeatureWorkspace).OpenTable(this.m_TableName);
ISchemaLock schemaLock
= pTable as ISchemaLock;

抱歉!评论已关闭.