using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using Kingo.Plugin.ShapeToKOApp.Class; using Kingo.Plugin.ShapeToKOApp.Enum; using Kingo.Plugin.ShapeToKOApp; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Kingo.Plugin.ShapeToKOApp.KoDataBase { public class ArcFeatureDataSource:ISpatialDataSource { private DataRow dr = null; private DataTable Table = null; private IFeatureCursor pFeatureCursor = null; public IFeatureClass FeatureSource { get; private set; } public string DataSourcePath { get; set; } public bool EOF { get; private set; } public XSDClass.EnvelopeN Extent { get; private set; } public List Fields { get; set; } public XSDClass.esriGeometryType GeometryType { get; private set; } private IFeature pFeature = null; public int RecordCount { get; private set; } public SpatialRefrenceStruct SpatialReference { get; private set; } private IQueryFilter pQueryFilter = new QueryFilterClass() { WhereClause = "1=1" }; private IQueryFilter pSpatialFilter = new SpatialFilterClass() { WhereClause = "1=1" }; public ArcFeatureDataSource(IFeatureLayer featureLayer, ESRI.ArcGIS.Geometry.IGeometry queryGeometry, string where = "") { try { this.FeatureSource = featureLayer.FeatureClass; if (!string.IsNullOrWhiteSpace(where)) { this.pQueryFilter.WhereClause = where; } else { this.pQueryFilter.WhereClause = (featureLayer as IFeatureLayerDefinition).DefinitionExpression; } IEnvelope envelope = (FeatureSource as IGeoDataset).Extent; if (queryGeometry != null) { pSpatialFilter = new SpatialFilterClass() { Geometry = queryGeometry, GeometryField = featureLayer.FeatureClass.ShapeFieldName, SpatialRel = esriSpatialRelEnum.esriSpatialRelContains, WhereClause = this.pQueryFilter.WhereClause }; envelope = queryGeometry.Envelope; } else { pSpatialFilter.WhereClause = this.pQueryFilter.WhereClause; } //获取字段 this.Fields = new List(); ILayerFields layerFields = featureLayer as ILayerFields; for (int i = 0; i < FeatureSource.Fields.FieldCount; i++) { IField field = FeatureSource.Fields.get_Field(i); int index = layerFields.FindField(field.Name); IFieldInfo fieldInfo = layerFields.get_FieldInfo(index); if (!fieldInfo.Visible) continue; if (FeatureSource.ShapeFieldName == field.Name) continue; this.Fields.Add(ConvertArcFieldToShapeFieldInfo(FeatureSource.Fields.get_Field(i), fieldInfo.Alias)); } //获取空间参考 ISpatialReference spatialReference = (FeatureSource as IGeoDataset).SpatialReference; int wkid = spatialReference.FactoryCode; SpatialRefrenceStruct srs = SpatialRefrenceStruct.GetAllData().Find(p => p.WKID == wkid); if (srs != null) { this.SpatialReference = srs; } this.RecordCount = FeatureSource.FeatureCount(pSpatialFilter); // 获取图形类型 点 线 面 this.GeometryType = (XSDClass.esriGeometryType)FeatureSource.ShapeType; //计算最大范围 if (envelope.IsEmpty) { //当图层数据为空时,extent为空 this.Extent = new XSDClass.EnvelopeN(); } else { this.Extent = new XSDClass.EnvelopeN() { XMax = envelope.XMax, XMin = envelope.XMin, YMax = envelope.YMax, YMin = envelope.YMin }; } //创建DataTable Table = new DataTable(); foreach (var item in this.Fields) { Table.Columns.Add(item.FieldName, typeof(object)); } //this.Table.Columns.Add("OBJECTID", typeof(int)); this.Table.Columns.Add("SHAPE", typeof(string)); dr = Table.NewRow(); } catch (Exception ex) { //LogAPI.Debug("获取图层信息失败:" + ex); } } public void Close() { if (pFeatureCursor != null) { Marshal.ReleaseComObject(pFeatureCursor); pFeatureCursor = null; } this.EOF = true; } public System.Data.DataRow GetNextRecord() { if (EOF == true) { throw new Exception("读取已经结束"); } if (pFeatureCursor == null) { throw new Exception("没有打开数据"); } DataRow row = ConvertFeature2DataRow(pFeature); //释放资源 Marshal.ReleaseComObject(pFeature); pFeature = null; pFeature = pFeatureCursor.NextFeature(); if (pFeature == null) { EOF = true; } return row; } private System.Data.DataRow ConvertFeature2DataRow(IFeature feature) { foreach (DataColumn item in Table.Columns) { int index = feature.Fields.FindField(item.ColumnName); if (index > -1) { dr[item] = feature.get_Value(index); } } dr["SHAPE"] = GetShapeString(feature.ShapeCopy); return dr; } private string GetShapeString(IGeometry geometry) { byte[] wkb = ConvertGeometryToWKB(geometry); OSGeo.OGR.Geometry rstGeometry = null; try { rstGeometry = OSGeo.OGR.Geometry.CreateFromWkb(wkb); } catch (Exception ex) { // LogAPI.Debug("rstGeometry:" + ex.Message); } string wkt = ""; try { rstGeometry.ExportToWkt(out wkt); } catch (Exception ex) { // LogAPI.Debug("rstGeometry.ExportToWkt:" + ex.Message); } return wkt; } public byte[] ConvertGeometryToWKB(IGeometry geometry) { IWkb wkb = geometry as IWkb; ITopologicalOperator oper = geometry as ITopologicalOperator; oper.Simplify(); IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3; byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[]; return b; } public void Open() { try { if (FeatureSource == null) { throw new Exception("矢量数据为空!"); } if (pFeatureCursor != null) { Marshal.ReleaseComObject(pFeatureCursor); pFeatureCursor = null; } if (pFeature != null) { Marshal.ReleaseComObject(pFeature); pFeature = null; } pFeatureCursor = FeatureSource.Search(pSpatialFilter, false); pFeature = pFeatureCursor.NextFeature(); //防止没有记录 if (pFeature == null) { EOF = true; } else { EOF = false; } } catch (Exception ex) { // LogAPI.Debug("打开数据源失败:" + ex); } } private ShapeFieldInfo ConvertArcFieldToShapeFieldInfo(IField field, string aliasName) { ShapeFieldInfo pShapeFieldInfo = new ShapeFieldInfo(); pShapeFieldInfo.FieldName = field.Name; pShapeFieldInfo.FieldAlias = aliasName; pShapeFieldInfo.FieldSize = (short)field.Length; pShapeFieldInfo.FieldDecimal = (short)field.Scale; switch (field.Type) { case esriFieldType.esriFieldTypeInteger: case esriFieldType.esriFieldTypeSmallInteger: pShapeFieldInfo.FieldType = eFieldType.shpInteger; break; case esriFieldType.esriFieldTypeDouble: case esriFieldType.esriFieldTypeSingle: pShapeFieldInfo.FieldType = eFieldType.shpDouble; break; case esriFieldType.esriFieldTypeString: case esriFieldType.esriFieldTypeGlobalID: case esriFieldType.esriFieldTypeGUID: case esriFieldType.esriFieldTypeOID: case esriFieldType.esriFieldTypeXML: case esriFieldType.esriFieldTypeDate: pShapeFieldInfo.FieldType = eFieldType.shpText; break; //pShapeFieldInfo.FieldType = eFieldType.shpDate; break; default: pShapeFieldInfo.FieldType = eFieldType.shpText; break; } return pShapeFieldInfo; } } }