年度变更建库软件5.0版本
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

308 lines
10 KiB

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<ShapeFieldInfo> 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<ShapeFieldInfo>();
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;
}
}
}