基于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


相关文章
|
18天前
|
存储 监控 安全
数据库多实例的部署与配置方法
【10月更文挑战第23天】数据库多实例的部署和配置需要综合考虑多个因素,包括硬件资源、软件设置、性能优化、安全保障等。通过合理的部署和配置,可以充分发挥多实例的优势,提高数据库系统的运行效率和可靠性。在实际操作中,要不断总结经验,根据实际情况进行调整和优化,以适应不断变化的业务需求。
|
6天前
|
SQL Java 数据库连接
数据库常用接口
ODBC(Open Database Connectivity):开放数据库互连技术为访问不同的SQL数据库提供了一个共同的接口。ODBC使用SQL作为访问数据的标准。这一接口提供了最大限度的互操作性,一个应用程序可以通过共同的一组代码访问不同的SQL数据库管理系统(DBMS)。 一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是Access,MySQL还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。
|
6天前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
|
8天前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
27 3
|
17天前
|
SQL Oracle 关系型数据库
Oracle数据库优化方法
【10月更文挑战第25天】Oracle数据库优化方法
25 7
|
25天前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
1月前
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
1月前
|
SQL 存储 监控
串口调试助手连接SQL数据库的技巧与方法
串口调试助手是电子工程师和软件开发人员常用的工具,它能够帮助用户进行串口通信的调试和数据分析
|
8天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
23 4
|
6天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
20 1