• 参考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
        }

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

  • 相关阅读:
    2011年3月21日星期一
    AutoCAD VBA尺寸标注
    2011年3月22日星期二
    The method isEmpty() is undefined for the type String/String类型的isEmpty报错
    安全沙箱冲突..Error #2044: 未处理的 securityError:。 text=Error #2048: 安全沙箱冲
    Flash Builder4.6 无法启动,并且报 Failed to create the Java Virtual Machine (2—可能更好些)
    Flash Builder4.6 入门Demo_trace
    去掉JW Player水印及右键官方菜单
    JS如何判断单个radio是否被选中
    用JSON报错 java.lang.ClassNotFoundException: org.apache.commons.lang.exception.NestableRuntimeExcept .
  • 原文地址:https://www.cnblogs.com/397926301/p/2736885.html
Copyright © 2020-2023  润新知