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
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; |
|
} |
|
|
|
|
|
} |
|
}
|
|
|