using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.Platform.Helper; using KGIS.Framework.Utils; using KGIS.Framework.Utils.Helper; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace kingo.Plugin.BGResultManager.Utility { public class FeatureOperator { public static void ExportFeaturesToShp2(IFeatureClass pSourceFeatureClass, IQueryFilter pQueryFilter, string forlder, string fileName) { IWorkspaceFactory workFactory = null; IFeatureWorkspace pFeatureWorkspace = null; IFeatureCursor pFeatureCursor = null; IFeatureClass pFeatureClass = null; IFeatureCursor pInsertFeatureCursor = null; int count = 0; try { if (pSourceFeatureClass == null) { MessageHelper.ShowTips("未获取到要素集!"); return; } if (!System.IO.Directory.Exists(forlder)) { System.IO.Directory.CreateDirectory(forlder); } count = pSourceFeatureClass.FeatureCount(pQueryFilter); pFeatureCursor = pSourceFeatureClass.Search(pQueryFilter, true); ProgressHelper.ShowProcessBar("正在导出,请稍候..."); workFactory = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactoryClass(); pFeatureWorkspace = workFactory.OpenFromFile(forlder, 0) as IFeatureWorkspace; //创建字段信息 IFields pFields = new FieldsClass(); IFieldsEdit pFieldsEdit = pFields as IFieldsEdit; List fieldNames = new List(); for (int i = 0; i < pSourceFeatureClass.Fields.FieldCount; i++) { IField field = pSourceFeatureClass.Fields.get_Field(i); if ((field.Type == esriFieldType.esriFieldTypeBlob || field.Type == esriFieldType.esriFieldTypeRaster) && field.Type != esriFieldType.esriFieldTypeGeometry) continue; if (field.Type == esriFieldType.esriFieldTypeGeometry) { IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "Shape"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry; IGeometryDef pGeometryDef = new GeometryDef(); IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit; pGeometryDefEdit.GeometryType_2 = pSourceFeatureClass.ShapeType;//pFeature.Shape.GeometryType; if ((pSourceFeatureClass as IGeoDataset) != null) { pGeometryDefEdit.SpatialReference_2 = (pSourceFeatureClass as IGeoDataset).SpatialReference;//pFeature.Shape.SpatialReference; } pFieldEdit.GeometryDef_2 = pGeometryDef; pFieldsEdit.AddField(pField); } else { IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Length_2 = field.Length; if (field.AliasName == "种植属性名称") { pFieldEdit.Length_2 = field.Length + 10; } if (field.Name.Length > 10) { string fname = field.Name.Substring(0, 10); int n = 1; while (fieldNames.Contains(fname)) { string end = n.ToString(); fname = fname.Remove(10 - end.Length) + end; n++; } pFieldEdit.Name_2 = fname; } else { pFieldEdit.Name_2 = field.Name; } fieldNames.Add(pFieldEdit.Name); pFieldEdit.AliasName_2 = field.AliasName; pFieldEdit.Type_2 = field.Type; pFieldsEdit.AddField(pField); } } pFeatureClass = pFeatureWorkspace.CreateFeatureClass(fileName, pFields, null, null, pSourceFeatureClass.FeatureType, "SHAPE", ""); pInsertFeatureCursor = pFeatureClass.Insert(true); int num = 0; ProgressHelper.CountProgress = count; Dictionary dicMatchFields = new Dictionary(); GetMatchFieldsDirectory(pSourceFeatureClass, pFeatureClass, ref dicMatchFields, true); IFeatureBuffer featureAdd = pFeatureClass.CreateFeatureBuffer(); IFeature pFeature = null; while ((pFeature = pFeatureCursor.NextFeature()) != null) { featureAdd.Shape = pFeature.Shape; foreach (KeyValuePair kvpMatchField in dicMatchFields) { if (pFeature.Value[kvpMatchField.Value] != DBNull.Value) { featureAdd.set_Value(kvpMatchField.Key, pFeature.get_Value(kvpMatchField.Value)); } else { featureAdd.set_Value(kvpMatchField.Key, null); } } pInsertFeatureCursor.InsertFeature(featureAdd); num++; if (num % 100 == 0 || num == count) { ProgressHelper.CurrentProgress = num; } } pInsertFeatureCursor.Flush(); ProgressHelper.CloseProcessBar(); } catch (Exception ex) { ProgressHelper.CloseProcessBar(); MessageHelper.ShowError("导出SHAP文件出错:" + ex.Message); LogAPI.Debug("导出SHAP文件出错,可能的原因是:" + ex.Message); } finally { if (pFeatureCursor != null) { Marshal.ReleaseComObject(pFeatureCursor); } if (pFeatureClass != null) { Marshal.ReleaseComObject(pFeatureClass); } if (pInsertFeatureCursor != null) { Marshal.ReleaseComObject(pInsertFeatureCursor); } if (pFeatureWorkspace != null) { Marshal.ReleaseComObject(pFeatureWorkspace); } if (workFactory != null) { Marshal.ReleaseComObject(workFactory); } } } public static void GetMatchFieldsDirectory(IClass pSourceClass, IClass pTargetClass, ref Dictionary dicMatchFields, bool isGetRequired = false) { for (int i = 0; i < pTargetClass.Fields.FieldCount; i++) { IField pTargetField = pTargetClass.Fields.get_Field(i); //目标图层的字段必须为可编辑并且不是必须字段 if (pTargetField.Required == false && pTargetField.Editable == true) { int iSourceFeatureClassIndex = pSourceClass.Fields.FindField(pTargetField.Name); if (pTargetField.Name == "SHAPE_Leng") { iSourceFeatureClassIndex = pSourceClass.Fields.FindField("SHAPE_Length"); } //源要素类中该字段存在 if (iSourceFeatureClassIndex > -1) { IField pSourceField = pSourceClass.Fields.get_Field(iSourceFeatureClassIndex); //目标图层的字段也必须为可编辑并且不是必须字段 if (pSourceField.Required == false && pSourceField.Editable == true) { //添加到字段匹配集合中 dicMatchFields.Add(i, iSourceFeatureClassIndex); } else if (isGetRequired) { dicMatchFields.Add(i, iSourceFeatureClassIndex); } } } //此处为了保留原有要素ObjectID字段值 if (pTargetField.Name.Equals("OIDCOPY", StringComparison.CurrentCultureIgnoreCase)) { dicMatchFields.Add(i, pSourceClass.FindField(pSourceClass.OIDFieldName)); } } } } }