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


相关文章
|
9月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
577 158
|
9月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(中)
使用MYSQL Report分析数据库性能
621 156
|
9月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(上)
最终建议:当前系统是完美的读密集型负载模型,优化重点应放在减少行读取量和提高数据定位效率。通过索引优化、分区策略和内存缓存,预期可降低30%的CPU负载,同时保持100%的缓冲池命中率。建议每百万次查询后刷新统计信息以持续优化
725 161
|
PHP 数据库
【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常
【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常
|
存储 数据挖掘 数据处理
2600 万表流计算分析如何做到? 时序数据库 TDengine 助力数百家超市智能化转型
在生鲜超市的高效运营中,实时数据分析至关重要。万象云鼎的“云鲜生”通过智能秤+网关+软件系统的组合,实现了销售数据的精准管理与优化。而在数据处理方面,TDengine 的流计算能力成为了这一方案的核心支撑。本文详细分享了“云鲜生”如何利用 TDengine 高效存储和分析海量销售数据,在优化超市运营、提升用户体验的同时,解决高基数分组、高并发查询等技术挑战。
401 1
|
存储 监控 数据挖掘
消防行业如何借助时序数据库 TDengine 打造高效的数据监控与分析系统
本篇文章来自“2024,我想和 TDengine 谈谈”征文活动的优秀投稿,深入探讨了如何在消防行业中运用 TDengine 进行业务建模。文章重点介绍了如何通过 TDengine 的超级表、标签设计和高效查询功能,有效管理消防监控系统中的时序数据。作者详细阐述了实时监控、报警系统以及历史数据分析在消防行业中的应用,展示了 TDengine 在数据压缩、保留策略和分布式架构下的强大优势。
433 0
|
关系型数据库 分布式数据库 数据库
瑶池数据库大讲堂|PolarDB HTAP:为在线业务插上实时分析的翅膀
瑶池数据库大讲堂介绍PolarDB HTAP,为在线业务提供实时分析能力。内容涵盖MySQL在线业务的分析需求与现有解决方案、PolarDB HTAP架构优化、针对分析型负载的优化(如向量化执行、多核并行处理)及近期性能改进和用户体验提升。通过这些优化,PolarDB HTAP实现了高效的数据处理和查询加速,帮助用户更好地应对复杂业务场景。
519 4
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
SQL 存储 BI
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句