首页 > 技术文章 > Arcengine创建内存工作空间帮助类

King2019Blog 2019-08-08 10:06 原文

/// <summary>
/// 创建内存要素类
/// </summary>
public class MyMemoryWorkspace : IDisposable
{
    /// <summary>
    /// 内存工作空间
    /// </summary>
    public static IWorkspace MyWorkspace { get; private set; }

    /// <summary>
    /// 要素类集合
    /// </summary>
    private readonly Dictionary<string, IFeatureClass> _featureClasses;

    public MyMemoryWorkspace()
    {
        _featureClasses = new Dictionary<string, IFeatureClass>();
    }

    /// <summary>
    /// 创建内存工作空间
    /// </summary>
    /// <param name="memoryWorkspaceName">内存工作空间名称</param>
    /// <returns></returns>
    public MyMemoryWorkspace CreateMemoryWorkspace(string memoryWorkspaceName = "memoryWorkspace")
    {
        // Create an in-memory workspace factory.
        Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.InMemoryWorkspaceFactory");
        IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)
            Activator.CreateInstance(factoryType);

        // Create an in-memory workspace.
        IWorkspaceName workspaceName = workspaceFactory.Create("", memoryWorkspaceName,
                                                               null, 0);
        // Cast for IName and open a reference to the in-memory workspace through the name object.
        IName name = (IName)workspaceName;
        MyWorkspace = (IWorkspace)name.Open();
        return this;
    }

    /// <summary>
    /// 创建内存图层
    /// </summary>
    /// <param name="dataSetName">要素名称</param>
    /// <param name="aliasName">要素别名</param>
    /// <param name="spatialRef">空间参考</param>
    /// <param name="geometryType">要素图形类型</param>
    /// <param name="propertyFields">字段集合</param>
    /// <returns></returns>
    public MyMemoryWorkspace CreateMemoryFeatureClass(string dataSetName,
                                                      string aliasName,
                                                      ISpatialReference spatialRef,
                                                      esriGeometryType geometryType,
                                                      IFields propertyFields)
    {


        IField oField = new FieldClass();
        IFields oFields = new FieldsClass();
        IFieldsEdit oFieldsEdit = null;
        IFieldEdit oFieldEdit = null;
        IFeatureClass oFeatureClass;
        try
        {
            oFieldsEdit = (IFieldsEdit)oFields;
            oFieldEdit = (IFieldEdit)oField;

            if (propertyFields != null)
                for (int i = 0; i < propertyFields.FieldCount; i++)
                    oFieldsEdit.AddField(propertyFields.Field[i]);

            IGeometryDef geometryDef = new GeometryDefClass();
            IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
            geometryDefEdit.AvgNumPoints_2 = 5;
            geometryDefEdit.GeometryType_2 = geometryType;
            geometryDefEdit.GridCount_2 = 1;
            geometryDefEdit.HasM_2 = false;
            geometryDefEdit.HasZ_2 = false;
            geometryDefEdit.SpatialReference_2 = spatialRef;

            oFieldEdit.Name_2 = "SHAPE";
            oFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
            oFieldEdit.GeometryDef_2 = geometryDef;
            oFieldEdit.IsNullable_2 = true;
            oFieldEdit.Required_2 = true;
            oFieldsEdit.AddField(oField);

            oFeatureClass = ((IFeatureWorkspace)MyWorkspace).CreateFeatureClass(dataSetName, oFields, null, null,
                                                                                esriFeatureType.esriFTSimple, "SHAPE", "");
            ((IDataset)oFeatureClass).BrowseName = dataSetName;
        }
        finally
        {
            try
            {
                Marshal.ReleaseComObject(oField);
                Marshal.ReleaseComObject(oFields);
                if (oFieldsEdit != null)
                    Marshal.ReleaseComObject(oFieldsEdit);
                if (oFieldEdit != null)
                    Marshal.ReleaseComObject(oFieldEdit);
            }
            catch
            {
                //
            }

            GC.Collect();
        }
        _featureClasses.Add(aliasName, oFeatureClass);
        return this;
    }

    /// <summary>
    /// 创建默认内存图层
    /// </summary>
    /// <param name="dataSetName">要素名称</param>
    /// <param name="aliasName">要素别名</param>
    /// <param name="spatialRef">空间参考</param>
    /// <param name="geometryType">要素图形类型</param>
    /// <param name="propertyFields">字段集合</param>
    /// <returns></returns>
    public MyMemoryWorkspace CreateDefaultMemoryFeatureClass(string dataSetName,
                                                             string aliasName,
                                                             ISpatialReference spatialRef,
                                                             esriGeometryType geometryType,
                                                             IFields propertyFields)
    {


        IField oField = new FieldClass();
        IFields oFields = new FieldsClass();
        IFieldsEdit oFieldsEdit = null;
        IFieldEdit oFieldEdit = null;
        IFeatureClass oFeatureClass;

        try
        {
            oFieldsEdit = (IFieldsEdit)oFields;
            oFieldEdit = (IFieldEdit)oField;

            IField field = new FieldClass();
            IFieldEdit fieldEdit = (IFieldEdit)field;
            fieldEdit.Name_2 = "OBJECTID";
            fieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
            fieldEdit.IsNullable_2 = false;
            fieldEdit.Required_2 = false;
            oFieldsEdit.AddField(field);

            if (propertyFields != null)
                for (int i = 0; i < propertyFields.FieldCount; i++)
                    oFieldsEdit.AddField(propertyFields.Field[i]);

            IGeometryDef geometryDef = new GeometryDefClass();
            IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
            geometryDefEdit.AvgNumPoints_2 = 5;
            geometryDefEdit.GeometryType_2 = geometryType;
            geometryDefEdit.GridCount_2 = 1;
            geometryDefEdit.HasM_2 = false;
            geometryDefEdit.HasZ_2 = false;
            geometryDefEdit.SpatialReference_2 = spatialRef;

            oFieldEdit.Name_2 = "SHAPE";
            oFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
            oFieldEdit.GeometryDef_2 = geometryDef;
            oFieldEdit.IsNullable_2 = true;
            oFieldEdit.Required_2 = true;
            oFieldsEdit.AddField(oField);

            oFeatureClass = ((IFeatureWorkspace)MyWorkspace).CreateFeatureClass(dataSetName, oFields, null, null,
                                                                                esriFeatureType.esriFTSimple, "SHAPE", "");
            ((IDataset)oFeatureClass).BrowseName = dataSetName;
        }
        finally
        {
            try
            {
                Marshal.ReleaseComObject(oField);
                Marshal.ReleaseComObject(oFields);
                if (oFieldsEdit != null)
                    Marshal.ReleaseComObject(oFieldsEdit);
                if (oFieldEdit != null)
                    Marshal.ReleaseComObject(oFieldEdit);
            }
            catch
            {
                //
            }

            GC.Collect();
        }
        _featureClasses.Add(aliasName, oFeatureClass);
        return this;
    }


    /// <summary>
    /// 插入要素
    /// </summary>
    /// <param name="featureClassName"></param>
    /// <param name="myFeature"></param>
    public MyMemoryWorkspace InsertFeature(string featureClassName, MyFeature myFeature)
    {
        if (featureClassName == null) throw new ArgumentNullException(nameof(featureClassName));
        if (myFeature == null) throw new ArgumentNullException(nameof(myFeature));

        IFeatureClass featureClass;
        _featureClasses.TryGetValue(featureClassName, out featureClass);
        if (featureClass == null) return this;

        try
        {
            using (ComReleaser comReleaser = new ComReleaser())
            {
                // Create an insert cursor.
                IFeatureCursor insertCursor = featureClass.Insert(true);
                comReleaser.ManageLifetime(insertCursor);

                // Create the feature buffer.
                IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
                comReleaser.ManageLifetime(featureBuffer);
                featureBuffer.Shape = myFeature.Geometry;
                foreach (KeyValuePair<string, object> row in myFeature.RowData)
                {
                    int fieldIndex = featureBuffer.Fields.FindField(row.Key);
                    featureBuffer.set_Value(fieldIndex, row.Value);
                }

                insertCursor.InsertFeature(featureBuffer);
                insertCursor.Flush();
            }
        }
        catch (Exception)
        {
        }
        return this;
    }

    /// <summary>
    /// 插入要素
    /// </summary>
    /// <param name="featureClassName"></param>
    /// <param name="myFeature"></param>
    public MyMemoryWorkspace InsertFeature(string featureClassName, IEnumerable<MyFeature> myFeature)
    {
        if (featureClassName == null) throw new ArgumentNullException(nameof(featureClassName));
        if (myFeature == null) throw new ArgumentNullException(nameof(myFeature));

        IFeatureClass featureClass;
        _featureClasses.TryGetValue(featureClassName, out featureClass);
        if (featureClass == null) return this;
        try
        {
            using (ComReleaser comReleaser = new ComReleaser())
            {
                // Create an insert cursor.
                IFeatureCursor insertCursor = featureClass.Insert(true);
                comReleaser.ManageLifetime(insertCursor);
                Dictionary<string, int> fieldIndexDic = new Dictionary<string, int>();
                if (myFeature.FirstOrDefault().RowData.Count > 0)
                {
                    IFields fields = insertCursor.Fields;
                    foreach (string fieldName in myFeature.FirstOrDefault() != null ? myFeature.FirstOrDefault().RowData.Keys : null)
                    {
                        if ("OBJECTID".Equals(fieldName.ToUpper())
                            || "FID".Equals(fieldName.ToUpper())
                            || "SHAPE.AREA".Equals(fieldName.ToUpper())
                            || "SHAPE.LEN".Equals(fieldName.ToUpper()))
                            continue;
                        int fieldIndex = fields.FindField(fieldName);
                        if (fieldIndex < 0) continue;
                        fieldIndexDic.Add(fieldName, fieldIndex);
                    }
                    ComReleaser.ReleaseCOMObject(fields);
                }

                foreach (MyFeature feature in myFeature)
                {
                    // Create the feature buffer.
                    IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
                    comReleaser.ManageLifetime(featureBuffer);
                    featureBuffer.Shape = feature.Geometry;
                    foreach (KeyValuePair<string, object> row in feature.RowData)
                    {
                        int index;
                        bool isTrue = fieldIndexDic.TryGetValue(row.Key, out index);
                        if (isTrue)
                            featureBuffer.set_Value(index, row.Value);
                    }
                    insertCursor.InsertFeature(featureBuffer);
                }
                insertCursor.Flush();
            }
        }
        catch (Exception)
        {
            // Handle the failure in a way appropriate to the application.
        }
        return this;
    }

    /// <summary>
    /// 获取一个要素类
    /// </summary>
    /// <returns></returns>
    public IFeatureClass BuildFeatureClass()
    {
        return _featureClasses.Count > 0 ? _featureClasses.Values.First() : null;
    }

    /// <summary>
    /// 获取要素类集合
    /// </summary>
    /// <returns></returns>
    public Dictionary<string, IFeatureClass> BuildFeatureClasses()
    {
        return _featureClasses;
    }


    #region IDisposable

        private void ReleaseUnmanagedResources()
    {
        if (MyWorkspace != null)
            ComReleaser.ReleaseCOMObject(MyWorkspace);
        if (_featureClasses.Count > 0)
            foreach (IFeatureClass value in _featureClasses.Values)
                ComReleaser.ReleaseCOMObject(value);
        _featureClasses.Clear();
    }

    protected virtual void Dispose(bool disposing)
    {
        ReleaseUnmanagedResources();
        if (disposing)
        {
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion
}

/// <summary>
/// 要素对象
/// </summary>
public class MyFeature
{
    public MyFeature()
    {
        RowData = new Dictionary<string, object>();
    }
    public IGeometry Geometry { get; set; }
    public Dictionary<string, object> RowData { get; set; }
}

推荐阅读