`
devgis
  • 浏览: 134000 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

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

 
阅读更多

一、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;
                        try
                        {
                            schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
                            IDataset ds = pTable as IDataset;
                            ds.Delete();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("删除附件表失败.原因:\r\n"+ex.Message,"错误提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
                        }
                        finally
                        {
                            schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("删除附件表失败!\r\n原因:"+ex.Message);
                }
                
            }
        }
        #endregion
    }
复制代码

先贴部分代码吧,希望感兴趣的园友们可以一起讨论学习。水平有限,欢迎各位批评指正。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics