基于C#的ArcEngine二次开发36: 在地理数据库中创建要素类的接口及方法分析(下)

简介: 基于C#的ArcEngine二次开发36: 在地理数据库中创建要素类的接口及方法分析(下)

2.2.1 创建和存储的方法

CreateFeature方法被用来在地理数据库中创建单个要素,它的作用是分配一个系统ObjectID (OID),即OIDField字段的值

Store 方法将这个新特征存储到数据库中

创建要素的基本过程为:要么是在点线面要素类,要么是在参与几何网络或拓扑构建的要素类中,创建一个独立的要素

【The CreateFeature method is used to create individual features in the geodatabase. It has the effect of assigning a system-generated ObjectID (OID), which is the value of the OIDField. Use the IFeature.Store method to store this new feature in the database.This basic process to create a feature is used independently of whether the feature is created in a point, line, polygon feature class, or in a feature class participating in a geometric network or topology.】


Creating the feature:在一个要素类中调用CreateFeature 方法,其效果等同于在ITable 接口中调用CreateRow 方法,一旦方法被调用,其OID就是可用的;例外的情形是IFeatureClass 方法返回的是表示行对象的IFeature接口的引用【Calling the CreateFeature method on a feature class has the same effect as calling the CreateRow method on the ITable interface, except that the IFeatureClass method returns a reference to the IFeature interface representing the returned row object. The OID of the feature is available once the CreateFeature method is called.】

Create the geometry for the feature:一个行对象与要素的基本差异之一就是要素和几何图形的关系,创建集合图形有很多不同的方式【One of the fundamental differences between a feature and a row object is the association between a feature and a geometry. There are many different ways to create the geometry for the feature. For more information on creating geometries, see How to create a polyline and How to create a polygon.】

Store the geometry in the feature:使用IFeature.Shape 方法存储几何图形到要素中【Use the IFeature.Shape property to store the geometry with the feature.】

Set the subtype, initialize any default values, and set other field values:调用CreateFeature方法后,默认的子类型和字段值不会被自动初始化【After calling CreateFeature, the default subtype value is not automatically set nor are default values initialized. For features without a subtype that have defined default values, calling IRowSubtypes.InitDefaultValues initializes the default values. For features created within a feature class containing subtypes, use IRowSubtypes.SubtypeCode to set the subtype value for features before calling IRowSubtypes.InitDefaultValues to ensure the default values are set for the particular subtype. After initializing the default values, the remaining field values can be set through the IFeature.Value property. If the field values are not correct for the type of field, an error is raised. However, if the field is too small to accept the defined value, an error is raised after the call to the Store method.】

Store the feature:IFeature.Store 方法调用要素才会被存储到数据库中,一旦存储方法被调用,在统一编辑会话中的后续查询都将反映到要素中。【The feature is not written to the database until the IFeature.Store method has been called. Once Store has been called, all subsequent queries in the same edit session, using the geodatabase application programming interface (API), reflects the modified state of the feature.】

一旦IFeature.Store 方法调用,将会触发以下行为:


任何与特征相关的复杂行为都会发生。例如,网络要素创建相应的网络元素,拓扑在编辑的功能上创建dirty 区域,并且在覆盖IRowEvents接口的自定义功能上调用OnNew方法。【Any complex behavior inherent to the feature occurs. For example, network features create corresponding network elements, topologies create dirty areas over edited features, and the OnNew method is called on custom features that override the IRowEvents interface.】

如果要素属于实现IObjectClassEvents接口的拓展类,他的IObjectClassEvents.OnCreate也会被调用,这通常用于将对象的字段值设置为应用程序定义的变量【If the class the feature belongs to has a class extension that implements the IObjectClassEvents interface, its IObjectClassEvents.OnCreate method is called. This is often used to set an object's field values to application-defined variables.】

要素类的IObjectClassEvents接口公开事件。如果OnCreate事件有侦听器,则引发该事件,触发所有事件处理程序。【The IObjectClassEvents interface of a feature class exposes events. If the OnCreate event has listeners, the event is raised, triggering all event handlers.】

如果要素类参与具有通知的关系类,并且相关类具有实现IRelatedObjectClassEvents接口的类扩展,则会在扩展上触发RelatedObjectCreated方法。【If the feature's class participates in a relationship class with notification and the related class has a class extension that implements the IRelatedObjectClassEvents interface, the RelatedObjectCreated method is triggered on the extension.】

public static void CreateFeature(IFeatureClass featureClass, IPolyline polyline)
{
    // Build the feature.
    IFeature feature = featureClass.CreateFeature();
    feature.Shape = polyline;
    // Apply the appropriate subtype to the feature.
    ISubtypes subtypes = (ISubtypes)featureClass;
    IRowSubtypes rowSubtypes = (IRowSubtypes)feature;
    if (subtypes.HasSubtype)
    {
        // In this example, the value of 3 represents the polymer vinyl chloride (PVC) subtype.
        rowSubtypes.SubtypeCode = 3;
    }
    // Initialize any default values the feature has.
    rowSubtypes.InitDefaultValues();
    // Update the value on a string field that indicates who installed the feature.
    int contractorFieldIndex = featureClass.FindField("CONTRACTOR");
    feature.set_Value(contractorFieldIndex, "K Johnston");
    // Commit the new feature to the geodatabase.
    feature.Store();
}

2.2.2 使用插入光标创建

插入光标用于将行插入表中,并支持InsertRow方法。插入游标用于大容量行插入。与在表上多次调用CreateRow,然后在新行上调用Store方法相比,使用insert游标在将数据加载到简单表和要素类中时提供了更快的性能。


在通过参与拓扑、几何网络、自定义特性实现自定义行为的表上插入游标,一些类扩展将在内部使用CreateRow和Store方法来实现多态性(在这些情况下性能没有差异)。


InsertRow方法将行缓冲区作为参数。应用程序在插入行的表对象上使用CreateRowBuffer方法获取行缓冲区。每次调用光标上的InsertRow都会在数据库中创建一行,该行的初始值设置为输入行缓冲区中的值。一个单行缓冲区可用于多个InsertRow调用。所创建行的ObjectID由InsertRow方法返回。


请记住,如果要插入的几何图形位于与要插入的要素类不同的空间参照中,则必须投影这些几何图形,这可能会导致性能下降。为了避免这种情况,请确保要插入的几何图形与要插入的要素类使用相同的空间参照。


将真值传递给ITable.Insert方法的UseBuffering参数时,返回一个Insert游标,该游标缓冲客户端的行,并将它们成批发送到服务器以提高性能。始终启用缓冲,除非在编辑会话外部插入行(缓冲只能在编辑会话期间使用)。


应用程序负责在插入所有行之后调用insert游标上的Flush方法。如果未调用Flush方法,则游标在销毁时(当应用程序释放游标上的所有引用时)刷新其缓冲区。但是,依赖析构函数刷新插入游标并不能使应用程序有机会检测调用flush方法时可能出现的错误,例如,如果基础数据库中表的存储空间已满。下一个代码示例提供了一个基本模板来检查刷新是否成功。


如果使用空间缓存,则应在使用插入光标大容量加载要素之前禁用空间缓存。有关更多信息,请参阅ispatialchemanager。


下面的代码示例使用要素缓冲区将一组新要素插入到道路要素类中。特征的数量由geometryList参数的大小决定,特征从列表中按顺序获取其形状属性。所有功能的“TYPE”值都设置为“Primary Highway”。这些插入文件存储在缓冲区中,只有在调用Flush时才会刷新。


代码同2.1.3

2.2.3 使用仅加载模式插入行

IFeatureClassLoad接口是ArcSDE中的要素类以及文件Geodatabase中的要素类和表支持的可选接口。它可以用于启用“仅加载模式”,这可以提高数据加载的性能。仅在插入新行或要素时使用“仅加载”模式。编辑现有要素时不要使用“仅加载”模式。


使用ArcSDE,将要素类置于仅加载模式将禁用插入要素时更新空间索引。在文件geodatabase中,将要素类或表置于“仅加载”模式将禁用在插入行或要素时更新空间索引和属性索引。将要素类或表从仅加载模式中取出可重建索引。


当要素类或表处于仅加载模式时,其他应用程序无法处理数据。只有在通过ISchemaLock接口获取要素类上的独占架构锁之后,才能将要素类或表置于仅加载模式。


当启用或禁用仅加载模式时,应用程序负责确保类上没有未完成的游标。在启用仅加载模式之前实例化的任何游标都应在启用仅加载模式之前使用Marshal.releasecommobject或管理comleaser刷新(如果需要)并销毁,在禁用仅加载模式之前,应使用Marshal.ReleaseComObject或管理ComReleaser刷新和销毁以仅加载模式实例化的所有游标。否则可能导致意外错误。


下面的代码示例是前一个插入光标示例的修改版本,在插入发生之前启用了仅加载模式

//仅插入模式加载
public static void LoadOnlyModeInsert(IFeatureClass featureClass, List < IGeometry >
    geometryList)
{
    // 将FeatureClass转化为IFeatureClassLoad接口
    IFeatureClassLoad featureClassLoad = (IFeatureClassLoad)featureClass;
    //要素解锁,独占此数据库
    ISchemaLock schemaLock = (ISchemaLock)featureClass;
    try
    {
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
        // 设置要素类为仅加载模式
        featureClassLoad.LoadOnlyMode = true;
        using(ComReleaser comReleaser = new ComReleaser())
        {
            //创建要素缓冲
            IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
            comReleaser.ManageLifetime(featureBuffer);
            // 创建插入光标
            IFeatureCursor insertCursor = featureClass.Insert(true);
            comReleaser.ManageLifetime(insertCursor);
            // 获取TYPE字段索引,并将其赋值为Primary Highway
            int typeFieldIndex = featureClass.FindField("TYPE");
            featureBuffer.set_Value(typeFieldIndex, "Primary Highway");
            //遍历几何要素列表
            foreach (IGeometry geometry in geometryList)
            {
                //设置几何图形,并将要素缓冲插入
                featureBuffer.Shape = geometry;
                insertCursor.InsertFeature(featureBuffer);
            }
            //缓冲区刷新
            insertCursor.Flush();
        }
    }
    catch (Exception)
    {
        // 异常处理失败的情形
    }
    finally
    {
        // 解除要素类的仅加载模式
        featureClassLoad.LoadOnlyMode = false;
        //解除独占锁,设置为共享锁
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
    }
}

2.2.4 使用缓冲和刷新


当对插入光标使用缓冲时,对insert row的调用不会向数据库管理系统(DBMS)写入新行,而是向客户端缓冲区写入新行。当调用ICursor.Flush或当缓冲区达到其最大大小时,缓冲区中包含的行作为批处理操作写入DBMS。由于DBMS写入可以发生在Flush调用或InsertRow调用上(如果缓冲区已达到其最大大小),这两个调用都应该具有适当的错误处理。


缓冲只能在编辑会话期间使用。


还有其他一些事件可以触发刷新,比如游标的销毁(如前所述)。在编辑会话中,停止编辑操作将刷新已版本化的数据,而停止编辑会话将刷新未版本化的数据。此外,在编辑操作中创建搜索或更新光标将刷新已缓存的所有行。


下图显示了缓冲在企业地理数据库中的工作方式


20200426181640456.png

X 重要参考

与本文相关的帮助文档中的示例:

Updating existing features

Updating attributes of existing features

Updating geometry of existing features

Adjusting feature locations with spatial adjustment

Editing with the geodatabase API

Creating features

Updating features

Obtaining changes made in the current edit session

Validating features

Listening to object class events

How to listen to workspace edit events


相关文章
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
1914 1
|
数据库
【YashanDB知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置
【YashanDB知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置
【YashanDB知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置
|
存储 关系型数据库 MySQL
MySQL数据库中进行日期比较的多种方法介绍。
以上方法提供了灵活多样地处理和对比MySQL数据库中存储地不同格式地日子信息方式。根据实际需求选择适当方式能够有效执行所需操作并保证性能优化。
1213 10
|
SQL Oracle 关系型数据库
比较MySQL和Oracle数据库系统,特别是在进行分页查询的方法上的不同
两者的性能差异将取决于数据量大小、索引优化、查询设计以及具体版本的数据库服务器。考虑硬件资源、数据库设计和具体需求对于实现优化的分页查询至关重要。开发者和数据库管理员需要根据自身使用的具体数据库系统版本和环境,选择最合适的分页机制,并进行必要的性能调优来满足应用需求。
698 11
|
Oracle 安全 关系型数据库
【Oracle】使用Navicat Premium连接Oracle数据库两种方法
以上就是两种使用Navicat Premium连接Oracle数据库的方法介绍,希望对你有所帮助!
2887 28
|
存储 算法 Java
实现不同数据库的表间的 JOIN 运算的极简方法
跨库计算是数据分析中的常见难题,尤其涉及多数据库系统时,表间 JOIN 操作复杂度显著提升。esProc 提供了一种高效解决方案,能够简化跨库 JOIN 的实现。例如,在车辆管理、交管和公民信息系统中,通过 esProc 可轻松完成如下任务:按城市统计有车公民事件数量、找出近一年获表彰的车主信息,以及按年份和品牌统计车辆违章次数。esProc 支持不同关联场景(如维表关联与主子表关联)的优化算法,如内存索引、游标处理和有序归并,从而大幅提升编码和运算效率。无论是同构还是异构数据源,esProc 均能灵活应对,为复杂数据分析提供强大支持。
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
632 16
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
2870 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
数据库
【YashanDB 知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置
**数据库主备切换简介** 在数据库正常或异常情况下,实现主备切换至关重要。若配置不当,主节点故障将影响业务使用,尤其在23.2版本中。原因包括资源紧张或主节点异常。解决方法涵盖手动和自动切换: 1. **一主一备部署**: - **手动切换**:支持Switchover(同步正常时)和Failover(主库损坏时)。 - **自动切换**:启用yasom仲裁选主开关。 2. **一主两备部署**: - 默认最大保护模式,自动切换开启。 需检查并配置自动切换以确保高可用性。经验总结:一主一备默认关闭自动切换,需手动开启;一主两备默认开启。