年度变更建库软件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.

557 lines
22 KiB

using System;
using System.Collections.Generic;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using System.Data;
using Kingo.Mobile.Shape2KOTool;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using KGIS.Framework.Utils;
using KGIS.Framework.AE.ExtensionMethod;
using OSGeo.OGR;
using OSGeo.GDAL;
using Kingo.Plugin.MakeTaskPackage.Model;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using KGIS.Framework.Maps;
namespace Kingo.Plugin.MakeTaskPackage.Common
{
public class ArcFeatureDataSource : Kingo.Mobile.Shape2KOTool.KoDataBase.ISpatialDataSource
{
private IQueryFilter pQueryFilter = new QueryFilterClass()
{
WhereClause = "1=1"
};
private IQueryFilter pSpatialFilter = new SpatialFilterClass()
{
WhereClause = "1=1"
};
private DataRow dr = null;
public ArcFeatureDataSource(IFeatureClass featureClass, ESRI.ArcGIS.Geometry.IGeometry queryGeometry, string geometryField, string whereClause, List<Kingo.Mobile.Shape2KOTool.XSDClass.Field> fields)
{
this.FeatureSource = featureClass;
if (!string.IsNullOrEmpty(whereClause))
this.pQueryFilter.WhereClause = whereClause;
IEnvelope envelope = (FeatureSource as IGeoDataset).Extent;
if (queryGeometry != null)
{
pSpatialFilter = new SpatialFilterClass() { Geometry = queryGeometry, GeometryField = geometryField, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects, WhereClause = this.pQueryFilter.WhereClause };
envelope = queryGeometry.Envelope;
}
//获取字段
this.Fields = new List<ShapeFieldInfo>();
for (int i = 0; i < FeatureSource.Fields.FieldCount; i++)
{
IField field = FeatureSource.Fields.get_Field(i);
//Kingo.Mobile.Shape2KOTool.XSDClass.Field fieldS = fields.Find(p => p.Name.ToLower() == field.Name.ToLower());
//if (fieldS == null) continue;
if (featureClass.ShapeFieldName == field.Name)
continue;
this.Fields.Add(ConvertArcFieldToShapeFieldInfo(FeatureSource.Fields.get_Field(i), null));
}
//获取空间参考
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(pQueryFilter);
// 获取图形类型 点 线 面
this.GeometryType = (Mobile.Shape2KOTool.XSDClass.esriGeometryType)FeatureSource.ShapeType;
//计算最大范围
if (envelope.IsEmpty)
{
//当图层数据为空时,extent为空
this.Extent = new Mobile.Shape2KOTool.XSDClass.EnvelopeN();
}
else
{
this.Extent = new Kingo.Mobile.Shape2KOTool.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();
}
public ArcFeatureDataSource( IFeatureLayer featureLayer, ESRI.ArcGIS.Geometry.IGeometry queryGeometry, string where="")
{
try
{
//// 注册所有的驱动
//Ogr.RegisterAll();
//Gdal.AllRegister();
////消除中文路径无法识别的问题
//OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
////解决shape文件字段中文内容读取问题
//OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
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 = where;
}
//获取字段
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));
}
//增加SHAPE_AREA 字段
//int areaIndex= layerFields.FindField("SHAPE_AREA");
//if (areaIndex < 0)
//{
// this.Fields.Add(new ShapeFieldInfo() {
// FieldName="SHAPE_AREA",
// FieldAlias = "SHAPE_AREA",
// FieldType= eFieldType.shpDouble
// });
//}
//获取空间参考
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(pQueryFilter);
// 获取图形类型 点 线 面
this.GeometryType = (Mobile.Shape2KOTool.XSDClass.esriGeometryType)FeatureSource.ShapeType;
//计算最大范围
if (envelope.IsEmpty)
{
//当图层数据为空时,extent为空
this.Extent = new Mobile.Shape2KOTool.XSDClass.EnvelopeN();
}
else
{
this.Extent = new Kingo.Mobile.Shape2KOTool.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);
}
}
private DataTable Table = null;
private IFeatureCursor pFeatureCursor = null;
public void Close()
{
if (pFeatureCursor != null)
{
Marshal.ReleaseComObject(pFeatureCursor);
pFeatureCursor = null;
}
this.EOF = true;
}
public IFeatureClass FeatureSource { get; private set; }
public string DataSourcePath { get; set; }
public Dictionary<string, int> Distinct(string fieldName)
{
Dictionary<string, int> values = new Dictionary<string, int>();
//ICursor cursor = (ICursor)FeatureSource.Search(null, false);
//IDataStatistics dataStatistics = new DataStatisticsClass();
//dataStatistics.Field = "Layer";
//dataStatistics.Cursor = cursor;
//System.Collections.IEnumerator enumerator = dataStatistics.UniqueValues;
//enumerator.Reset();
//while (enumerator.MoveNext())
//{
// object myObject = enumerator.Current;
// values.Add(myObject.ToString(), 0);
//}
////cursor = (ICursor)featureClass.Search(null, false);
//dataStatistics.Cursor = cursor;
//ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
//Console.WriteLine("mean value - {0}", statisticsResults.Mean);
IDataset pDataset = FeatureSource as IDataset;
IQueryDef pQueryDef = (pDataset.Workspace.WorkspaceFactory as IFeatureWorkspace).CreateQueryDef();
pQueryDef.SubFields = "count(*)," + fieldName;
pQueryDef.Tables = pDataset.Name + " group by " + fieldName;
ICursor pCur = pQueryDef.Evaluate();
try
{
IRow row = pCur.NextRow();
while (row != null)
{
values.Add(row.get_Value(1).ToString(), Convert.ToInt32(row.get_Value(0)));
}
}
finally
{
Marshal.ReleaseComObject(pCur);
pCur = null;
Marshal.ReleaseComObject(pQueryDef);
pQueryDef = null;
}
return values;
}
public bool EOF { get; private set; }
public Mobile.Shape2KOTool.XSDClass.EnvelopeN Extent { get; private set; }
public List<Mobile.Shape2KOTool.ShapeFieldInfo> Fields { get; set; }
public Mobile.Shape2KOTool.XSDClass.esriGeometryType GeometryType { get; private set; }
public System.Data.DataTable GetAllRecord()
{
throw new NotImplementedException();
}
private IFeature pFeature = null;
public System.Data.DataRow GetNextRecord()
{
if (EOF == true)
{
throw new Exception("读取已经结束");
}
if (pFeatureCursor == null)
{
throw new Exception("没有打开数据");
}
//DateTime dt1 = DateTime.Now;
//Console.WriteLine(DateTime.Now.ToString());
DataRow row = ConvertFeature2DataRow(pFeature);
//DateTime dt2 = DateTime.Now;
//Console.WriteLine(dt2.Subtract(dt1).TotalMilliseconds.ToString());
//释放资源
Marshal.ReleaseComObject(pFeature);
pFeature = null;
pFeature = pFeatureCursor.NextFeature();
if (pFeature == null)
{
EOF = true;
}
//DateTime dt3 = DateTime.Now;
//Console.WriteLine(dt3.Subtract(dt2).TotalMilliseconds.ToString());
//GC.Collect();
//row.Delete();
//row = null;
return row;
}
private System.Data.DataRow ConvertFeature2DataRow(IFeature feature)
{
//DateTime dt1 = DateTime.Now;
//Console.WriteLine(DateTime.Now.ToString());
//DataRow dr = Table.NewRow();
foreach (DataColumn item in Table.Columns)
{
int index = feature.Fields.FindField(item.ColumnName);
if (index > -1)
{
dr[item] = feature.get_Value(index);
}
}
//DateTime dt2 = DateTime.Now;
//Console.WriteLine(dt2.Subtract(dt1).TotalMilliseconds.ToString());
//if (feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
//{
// IArea area = feature.Shape as IArea;
// if (area != null)
// dr["SHAPE_AREA"] = area.Area;
//}
//else
// dr["SHAPE_AREA"] = 0;
dr["SHAPE"] = GetShapeString(feature.ShapeCopy);
//DateTime dt3 = DateTime.Now;
//Console.WriteLine(dt3.Subtract(dt2).TotalMilliseconds.ToString());
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;
if (geometry.GeometryType == esriGeometryType.esriGeometryPolygon)
{
IPolygon polygon = geometry as IPolygon;
if (polygon == null || polygon.IsEmpty)
return "MULTIPOLYGON EMPTY";
//"MULTIPOLYGON ((( 39496841.71395018 3996653.16102896, 39496672.94504374 3996656.38199206, 39496669.92898465 3996498.40799711, 39496838.69799109 3996495.18603399, 39496841.71395018 3996653.16102896)))"
IGeometryCollection pGeometryCollection = polygon as IGeometryCollection;
if (pGeometryCollection == null || pGeometryCollection.GeometryCount < 1)
return "MULTIPOLYGON EMPTY";
StringBuilder sb = new StringBuilder("MULTIPOLYGON ((");
for (int i = 0; i < pGeometryCollection.GeometryCount; i++)
{
if (pGeometryCollection.get_Geometry(i) is IRing)
{
sb.Append("(");
IPointCollection pPoints = pGeometryCollection.get_Geometry(i) as IPointCollection;
for (int j = 0; j < pPoints.PointCount; j++)
{
IPoint pt = pPoints.get_Point(j);
sb.AppendFormat("{0} {1},", pt.X, pt.Y);
}
sb.Remove(sb.Length - 1, 1);
sb.Append("),");
}
}
sb.Remove(sb.Length - 1, 1);
sb.Append("))");
return sb.ToString();
}
else if (geometry.GeometryType == esriGeometryType.esriGeometryPoint)
{
IPoint point = geometry as IPoint;
if (point == null) return "POINT EMPTY";
return string.Format("POINT ( {0} {1})", point.X, point.Y);
}
else if (geometry.GeometryType == esriGeometryType.esriGeometryPolyline)
{
IPolyline polygon = geometry as IPolyline;
if (polygon == null || polygon.IsEmpty)
return "MULTILINESTRING EMPTY";
//"MULTIPOLYGON ((( 39496841.71395018 3996653.16102896, 39496672.94504374 3996656.38199206, 39496669.92898465 3996498.40799711, 39496838.69799109 3996495.18603399, 39496841.71395018 3996653.16102896)))"
IGeometryCollection pGeometryCollection = polygon as IGeometryCollection;
if (pGeometryCollection == null || pGeometryCollection.GeometryCount < 1)
return "MULTILINESTRING EMPTY";
StringBuilder sb = new StringBuilder("MULTILINESTRING (");
for (int i = 0; i < pGeometryCollection.GeometryCount; i++)
{
if (pGeometryCollection.get_Geometry(i) is IPointCollection)
{
sb.Append("(");
IPointCollection pPoints = pGeometryCollection.get_Geometry(i) as IPointCollection;
for (int j = 0; j < pPoints.PointCount; j++)
{
IPoint pt = pPoints.get_Point(j);
sb.AppendFormat("{0} {1},", pt.X, pt.Y);
}
sb.Remove(sb.Length - 1, 1);
sb.Append("),");
}
}
sb.Remove(sb.Length - 1, 1);
sb.Append(")");
return sb.ToString(); ;
}
else
return "EMPTY";
}
public byte[] ConvertGeometryToWKB(IGeometry geometry)
{
IWkb wkb = geometry as IWkb;
//byte[] b = new byte[wkb.WkbSize];
//int byte_count = wkb.WkbSize;
//try
//{
// wkb.ExportToWkb(ref byte_count, out b[0]);
//}
//catch (Exception ex)
//{
// Kingo.Mobile.Common.LogAPI.Debug(ex);
//}
//return b;
ITopologicalOperator oper = geometry as ITopologicalOperator;
oper.Simplify();
IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[];
return b;
}
//public string ConvertGeometryToWKT(IGeometry geometry)
//{
// byte[] b = ConvertGeometryToWKB(geometry);
// WKBReader reader = new WKBReader();
// GeoAPI.Geometries.IGeometry g = reader.Read(b);
// WKTWriter writer = new WKTWriter();
// return writer.Write(g);
//}
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;
}
public int RecordCount { get; private set; }
public void Reset()
{
if (pFeatureCursor != null)
{
Marshal.ReleaseComObject(pFeatureCursor);
pFeatureCursor = null;
}
if (pFeature != null)
{
Marshal.ReleaseComObject(pFeature);
pFeature = null;
}
pFeatureCursor = FeatureSource.Search(pQueryFilter, false);
pFeature = pFeatureCursor.NextFeature();
//防止没有记录
if (pFeature == null)
{
EOF = true;
}
else
{
EOF = false;
}
}
public Mobile.Shape2KOTool.SpatialRefrenceStruct SpatialReference { get; private set; }
}
}