using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.Commands; using KGIS.Framework.Maps; using KGIS.Framework.Platform.Helper; using KGIS.Framework.Utils; using KGIS.Framework.Utils.Dialog; using KGIS.Framework.Utils.Helper; using Kingo.PluginServiceInterface; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Kingo.Plugin.DataLoad.Commands { /// /// 导出BG数据到SHP文件 /// public class CmdExportBGDataToSHP : BaseMenuCommand { IEngineEditor m_pEditor; public override void OnClick() { try { IFeatureLayer featureClassBG = MapsManager.Instance.MapService.GetFeatureLayerByName("DLTBBG"); if (featureClassBG == null) return; IFeatureLayer pFeatureLayer = featureClassBG as IFeatureLayer; KGIS.Framework.Utils.Dialog.FolderBrowserDialog pBrowser = new KGIS.Framework.Utils.Dialog.FolderBrowserDialog { ShowNewFolderButton = true }; if (pBrowser.ShowDialog() == DialogResult.OK) { string savepath = pBrowser.SelectedPath; string fileName = pFeatureLayer.Name; IQueryFilter queryfilter = new QueryFilterClass(); fileName = pFeatureLayer.FeatureClass.AliasName; if (System.IO.File.Exists(System.IO.Path.Combine(savepath, fileName + ".shp")) || System.IO.File.Exists(System.IO.Path.Combine(savepath, fileName + ".SHP"))) { if (MessageHelper.ShowYesNoAndTips("同名文件已存在是否替换?") != DialogResult.Yes) { return; } DeleteShp(pFeatureLayer.FeatureClass.AliasName, savepath); } ExportFeaturesToShp(pFeatureLayer.FeatureClass, queryfilter, savepath, fileName); MessageHelper.ShowTips("导出成功!"); } } catch (Exception ex) { MessageHelper.ShowTips("数据导出失败!"); LogAPI.Debug("数据导出异常:" + ex); } } /// /// 导出SHP数据 /// /// /// /// /// public static void ExportFeaturesToShp(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 ("XZQTZLX,BGZT,JCZT,TZ,BGDL,BGFW,WBGLX,SJLY,SFJCTB,NYJY,NYYPDL,SFJZ,ONLYZLBG".Contains(field.Name)) continue; 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(); //关闭lock IWorkspaceFactoryLockControl ipWsFactoryLock = (IWorkspaceFactoryLockControl)workFactory; if (ipWsFactoryLock.SchemaLockingEnabled) { ipWsFactoryLock.DisableSchemaLocking(); } } catch (Exception ex) { ProgressHelper.CloseProcessBar(); MessageHelper.ShowError("导出SHAPE文件出错:" + ex.Message); LogAPI.Debug("导出SHAPE文件出错,可能的原因是:" + 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); } } } /// /// 删除同名SHP /// /// public static void DeleteShp(string fileName, string filePath) { IWorkspace pWorkspace = null; IWorkspaceFactory pWorkspaceFactory = null; IFeatureClass pFeatureClass = null; try { //打开shp工作空间 pWorkspaceFactory = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactory(); pWorkspace = pWorkspaceFactory.OpenFromFile(filePath, 0); IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace; pFeatureClass = pFeatureWorkspace.OpenFeatureClass(fileName); IDataset pFeaDataset = pFeatureClass as IDataset; pFeaDataset.Delete(); } catch (Exception ex) { LogAPI.Debug("删除shp失败,报错原因是:" + ex.Message); } finally { if (pWorkspaceFactory != null) { Marshal.ReleaseComObject(pWorkspaceFactory); } if (pWorkspace != null) { Marshal.ReleaseComObject(pWorkspace); } if (pFeatureClass != null) { Marshal.ReleaseComObject(pFeatureClass); } } } /// /// 获得匹配的字段索引集合 /// /// 源要素类 /// 目标要素类 /// 匹配字段集合-KEY为目标图层字段,VALUE为源图层字段 /// 是否获取必须字段 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 ("XZQTZLX,BGZT,JCZT,TZ,BGDL,BGFW,WBGLX,SJLY,SFJCTB,NYJY,NYYPDL,SFJZ,ONLYZLBG".Contains(pSourceField.Name)) continue; //目标图层的字段也必须为可编辑并且不是必须字段 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)); } } } public override void OnCreate(object Hook) { //throw new NotImplementedException(); m_pEditor = new EngineEditorClass(); } public override bool Enabled => JudgeIsHaveTargetPath(); private bool JudgeIsHaveTargetPath() { try { ProjectInfo prj = MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo; if (prj == null) { return false; } return !string.IsNullOrWhiteSpace(prj.BGDatabase) && m_pEditor.EditState == esriEngineEditState.esriEngineStateNotEditing; } catch (Exception ex) { LogAPI.Debug("判定 检测数据加载 按钮是否有效时失败,异常原因: " + ex + " ; "); return false; } } } }