using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.Helper;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Kingo.Plugin.DataLoad.Helper
{
    /// 
    /// DataLoad_AECommonHelper
    /// 
    public static class DLAECommonHelper
    {
        /// 
        /// 删除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)
            {
                PluginServiceInterface.CommonHelper.RecordsErrLog("删除shp失败,报错原因:", ex);
            }
            finally
            {
                if (pWorkspaceFactory != null)
                {
                    Marshal.ReleaseComObject(pWorkspaceFactory);
                }
                if (pWorkspace != null)
                {
                    Marshal.ReleaseComObject(pWorkspace);
                }
                if (pFeatureClass != null)
                {
                    Marshal.ReleaseComObject(pFeatureClass);
                }
            }
        }
        /// 
        /// 导出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;
            try
            {
                if (pSourceFeatureClass == null)
                {
                    MessageHelper.ShowTips("未获取到要素类!");
                    return;
                }
                if (!System.IO.Directory.Exists(forlder))
                    System.IO.Directory.CreateDirectory(forlder);
                int count = pSourceFeatureClass.FeatureCount(pQueryFilter);
                pFeatureCursor = pSourceFeatureClass.Search(pQueryFilter, true);
                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);
                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);
                }
                pInsertFeatureCursor.Flush();
                //关闭lock
                IWorkspaceFactoryLockControl ipWsFactoryLock = (IWorkspaceFactoryLockControl)workFactory;
                if (ipWsFactoryLock.SchemaLockingEnabled)
                {
                    ipWsFactoryLock.DisableSchemaLocking();
                }
            }
            catch (Exception ex)
            {
                MessageHelper.ShowError("导出SHAPE文件出错:" + ex.Message);
                PluginServiceInterface.CommonHelper.RecordsErrLog("导出SHAPE文件出错,可能的原因是:", ex);
            }
            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数据_获得匹配的字段索引集合
        /// 
        /// 源要素类
        /// 目标要素类
        /// 匹配字段集合-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));
                }
            }
        }
        /// 
        /// 创建要素集(GDB、MDB)
        /// 
        /// 
        /// 
        /// 
        public static IFeatureDataset CreateFeatureDataset(WorkspaceAPI workspaceAPI, string DataSetName = "")
        {
            try
            {
                IFeatureWorkspace targetWorkspac = workspaceAPI.CurrentWorkspace as IFeatureWorkspace;
                //object tst = workspaceAPI.CurrentWorkspace;
                ISpatialReference SpatialReference = new UnknownCoordinateSystemClass();
                IControlPrecision2 pCP = SpatialReference as IControlPrecision2;
                //要素分辨率
                ISpatialReferenceResolution spatialReferenceResolution = SpatialReference as ISpatialReferenceResolution;
                spatialReferenceResolution.set_XYResolution(false, 0.000005);
                spatialReferenceResolution.set_ZResolution(false, 0.000005);
                //要素数据集容差
                ISpatialReferenceTolerance spatialReferenceTolerance = SpatialReference as ISpatialReferenceTolerance;
                double tolerance = 0;
                if (double.TryParse(SysConfigsOprator.GetAppsetingValueByKey("Tolerance"), out tolerance))
                {
                    spatialReferenceTolerance.XYTolerance = tolerance;
                    spatialReferenceTolerance.ZTolerance = tolerance;
                    spatialReferenceTolerance.MTolerance = tolerance;
                }
                else
                {
                    spatialReferenceTolerance.XYTolerance = 0.0001;
                    spatialReferenceTolerance.ZTolerance = 0.0001;
                    spatialReferenceTolerance.MTolerance = 0.0001;
                }
                SpatialReference.SetDomain(0, 45035996273.705, 0, 45035996273.705);
                return targetWorkspac.CreateFeatureDataset(DataSetName == "" ? "TDDC" : DataSetName, SpatialReference);
            }
            catch (Exception ex)
            {
                PluginServiceInterface.CommonHelper.RecordsErrLog("创建要素集异常:", ex);
                throw ex;
            }
        }
    }
}