ArcEngine 数据导出Shape的几种方式

Posted 杨千羽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArcEngine 数据导出Shape的几种方式相关的知识,希望对你有一定的参考价值。

ArcEngine 数据导出Shape的几种方式

 

这里志列出关键代码,该代码不是

方法一:创建一个shape要素类,结果与导出要素类一致,保存使用store速度最慢,忽略

 

方法二:使用IFeatureBuffer速度较快,缺点:数据量大,导出的时候容易报内存损坏错误使程序崩溃,把arcgis lisence服务重启几次后有时能导出成功不会崩溃,没找到原因,如有解决方案,请告知,谢谢

private static void ExportShapeLayer(string filePath, IFeatureLayer featureLayer)

string parentPath = filePath.Substring(0, filePath.LastIndexOf('\\\\'));

string fcName = filePath.Substring(filePath.LastIndexOf('\\\\') + 1, filePath.Length - filePath.LastIndexOf('\\\\') - 1);

 

string filedir = parentPath.Substring(parentPath.LastIndexOf('\\\\') + 1, parentPath.Length - parentPath.LastIndexOf('\\\\') - 1);

DirectoryInfo directoryInfoPath = Directory.GetParent(parentPath);

 

IWorkspaceFactory pWorkSpaceFac = new ShapefileWorkspaceFactoryClass();

IFeatureWorkspace pFeatureWorkSpace = pWorkSpaceFac.OpenFromFile(parentPath, 0) as IFeatureWorkspace;

 

//创建字段集2

IFeatureClassDescription fcDescription = new FeatureClassDescriptionClass();

IObjectClassDescription ocDescription = (IObjectClassDescription)fcDescription;//创建必要字段

IFields fields = ocDescription.RequiredFields;

 

int shapeFieldIndex = fields.FindField(fcDescription.ShapeFieldName);

IField field = fields.get_Field(shapeFieldIndex);

IGeometryDef geometryDef = field.GeometryDef;

IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;

 

if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon)

geometryDefEdit.GeometryType_2 = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon;

else if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline)

geometryDefEdit.GeometryType_2 = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline;

else if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)

geometryDefEdit.GeometryType_2 = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint;

 

ESRI.ArcGIS.Geometry.IProjectedCoordinateSystem tProjectedCoordinateSystem = ((featureLayer as IGeoDataset).SpatialReference) as ESRI.ArcGIS.Geometry.IProjectedCoordinateSystem;

geometryDefEdit.SpatialReference_2 = tProjectedCoordinateSystem;

 

IFieldChecker fieldChecker = new FieldCheckerClass();

IEnumFieldError enumFieldError = null;

IFields validatedFields = null; //将传入字段 转成 validatedFields

fieldChecker.ValidateWorkspace = (IWorkspace)pFeatureWorkSpace;

fieldChecker.Validate(fields, out enumFieldError, out validatedFields);

IFeatureClass shpFeatureClass = pFeatureWorkSpace.CreateFeatureClass(fcName, validatedFields, ocDescription.InstanceCLSID, ocDescription.ClassExtensionCLSID, esriFeatureType.esriFTSimple, fcDescription.ShapeFieldName, "");

 

for (int i = 0; i < featureLayer.FeatureClass.Fields.FieldCount; i++)

IField tfield = featureLayer.FeatureClass.Fields.get_Field(i);

if (tfield.Type == esriFieldType.esriFieldTypeBlob) continue;

if (filterArr.Contains(tfield.Name)) continue;

shpFeatureClass.AddField(tfield);

 

IFeatureLayer shpfeatureLayer = new FeatureLayerClass();

shpfeatureLayer.FeatureClass = shpFeatureClass;

 

 

ITable tb = featureLayer.FeatureClass as ITable;

IQueryFilter tQueryFilter = new QueryFilterClass();

tQueryFilter.WhereClause = "";

tQueryFilter.AddField(featureLayer.FeatureClass.OIDFieldName);

//计算要素总数

int totalCount = tb.RowCount(tQueryFilter);

 

ImportFeatureClassData_MarshalReleaseComObject(featureLayer, shpfeatureLayer, totalCount);

 

public static void ImportFeatureClassData_MarshalReleaseComObject(IFeatureLayer featureLayer, IFeatureLayer shpFeatureLayer, int totalCount)

try

int i = 0;

 

IFeatureClass shpFeatureClass = shpFeatureLayer.FeatureClass;

 

IFeatureBuffer pFeatureBuffer = shpFeatureClass.CreateFeatureBuffer();

IFeatureCursor pFeatureCursor = shpFeatureClass.Insert(true);

IFeatureCursor pFeatureCursorSource = featureLayer.FeatureClass.Search(null, false);

IFeature pFeatureSource = pFeatureCursorSource.NextFeature();

while (pFeatureSource != null)

i++;

ZzCom.CommonUtil.SimpleWaiterHelper.SetValue(i);

 

if (pFeatureSource.ShapeCopy == null)

pFeatureSource = pFeatureCursorSource.NextFeature();

continue;

 

IFeature pFeatureTarget = pFeatureBuffer as IFeature;

ArcengineUtil.SetZValue(pFeatureTarget, pFeatureSource.ShapeCopy);

 

//修复几何,否则质检容易报自相交错误

IGeometry geometry = GeometryOperateHelper.SimplifyGeometry(pFeatureSource.ShapeCopy);

ArcengineUtil.SetZValue(pFeatureTarget, geometry);

 

pFeatureTarget.Shape = geometry;

 

IFields fields = FeatureOperatorUtil.CopyFields(pFeatureSource.Fields);

IFields tagerfields = FeatureOperatorUtil.CopyFields(pFeatureTarget.Fields);

Dictionary<int, int> tempdic = FeatureOperatorUtil.GetFieldMap(fields, tagerfields);

FeatureOperatorUtil.CopyFeatureAttribute(pFeatureSource, pFeatureTarget, tempdic);

 

//这里容易报内存损坏,继续执行会重复插入该记录造成记录有重复(原因:可能是频繁的读写)

pFeatureCursor.InsertFeature(pFeatureBuffer);

 

if (i % 500 == 0)

pFeatureCursor.Flush();

 

Marshal.FinalReleaseComObject(pFeatureTarget);

Marshal.FinalReleaseComObject(pFeatureSource);

Marshal.FinalReleaseComObject(pFeatureBuffer);

Marshal.FinalReleaseComObject(pFeatureCursor);

 

pFeatureTarget = null;

pFeatureSource = null;

pFeatureBuffer = null;

pFeatureCursor = null;

 

GC.Collect(); // 强制对所有代进行垃圾回收。

GC.WaitForPendingFinalizers(); //挂起当前线程,直到处理终结器队列的线程清空该队列为止。

 

pFeatureBuffer = shpFeatureClass.CreateFeatureBuffer();

pFeatureCursor = shpFeatureClass.Insert(true);

pFeatureTarget = pFeatureBuffer as IFeature;

 

pFeatureSource = pFeatureCursorSource.NextFeature();

 

pFeatureCursor.Flush();

 

if (pFeatureCursor != null)

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(pFeatureCursor);

pFeatureCursor = null;

 

if (pFeatureBuffer != null)

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(pFeatureBuffer);

pFeatureBuffer = null;

 

if (pFeatureSource != null)

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(pFeatureSource);

pFeatureSource = null;

 

if (pFeatureCursorSource != null)

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(pFeatureCursorSource);

pFeatureCursorSource = null;

 

//释放

GC.Collect();

GC.WaitForPendingFinalizers();

 

ZzCom.CommonUtil.SimpleWaiterHelper.SetValue(totalCount);

Application.DoEvents();

catch (Exception e)

ZzLog4net.ZzLogUtil.Logger.LogInfo(string.Format("异常信息:0 异常位置:1 时间:'2'", e.Message, e.ToString(),

System.DateTime.Now));

throw e;

finally

ZzCom.CommonUtil.SimpleWaiterHelper.SetValue(totalCount);

Application.DoEvents();

 

方法三使用IFeatureDataConverter2或者IFeatureDataConverter,速度最快,缺点无法知道导出的要素总数和当前要素,无法做进度条,不知道arcgis使用的那种方法(求告知),速度快还有进度条,这个地方要注意把大字段处理了,处理方案可以把输出字段集拷贝一份,把大字段改成string类型,或者使用IFeatureDataConverter2像以下处理。

public static void ExportFeatureClassToShp(IFeatureLayer featureLayer, string ExportShapeFileName, string ExportFilePath,string exportShapeType)

try

 

IFeatureClass apFeatureClass = featureLayer.FeatureClass;

if (apFeatureClass == null)

MessageBox.Show("请选择", "系统提示");

return;

if (ExportShapeFileName == "")

return;

 

//设置导出要素类的参数

IFeatureClassName pOutFeatureClassName = new FeatureClassNameClass();

IDataset pOutDataset = (IDataset)apFeatureClass;

 

pOutFeatureClassName = (IFeatureClassName)pOutDataset.FullName;

 

//IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();

//IWorkspaceName pInWorkspaceName = new WorkspaceNameClass();

//pInWorkspaceName = pShpWorkspaceFactory.Create(ExportFilePath, ExportShapeFileName, null, 0);

 

 

IWorkspaceFactory pWorkSpaceFac = new ShapefileWorkspaceFactoryClass();

IWorkspace workspace = pWorkSpaceFac.OpenFromFile(ExportFilePath, 0);

 

IFeatureDatasetName pInFeatureDatasetName = null;

 

IDataset outDataSet = workspace as IDataset;

IWorkspaceName outWorkspaceName = outDataSet.FullName as IWorkspaceName;

 

IFeatureClassName pInFeatureClassName = new FeatureClassNameClass();

IDatasetName pInDatasetClassName;

pInDatasetClassName = (IDatasetName)pInFeatureClassName;

pInDatasetClassName.Name = ExportShapeFileName;//作为输出参数

pInDatasetClassName.WorkspaceName = outWorkspaceName;

 

long iCounter;

IFields pOutFields, pInFields;

IFieldChecker pFieldChecker;

IField pGeoField;

IEnumFieldError pEnumFieldError = null;

pInFields = apFeatureClass.Fields;

pFieldChecker = new FieldChecker();

pFieldChecker.InputWorkspace = apFeatureClass.FeatureDataset.Workspace;

pFieldChecker.ValidateWorkspace = workspace;

pFieldChecker.Validate(pInFields, out pEnumFieldError, out pOutFields);

 

pGeoField = null;

for (iCounter = 0; iCounter < pOutFields.FieldCount; iCounter++)

if (pOutFields.get_Field((int)iCounter).Type == esriFieldType.esriFieldTypeGeometry)

pGeoField = pOutFields.get_Field((int)iCounter);

break;

 

List<int> FieldErrorList = new List<int>();

IFieldError fieldError = pEnumFieldError.Next();

while (fieldError != null)

FieldErrorList.Add(fieldError.FieldIndex);

fieldError = pEnumFieldError.Next();

 

IQueryFilter InputQueryFilter = null;

ISelectionSet pSelectionSet = null;

 

if (exportShapeType.Equals("所有要素"))

InputQueryFilter = new QueryFilterClass();

InputQueryFilter.WhereClause = "";

else if (exportShapeType.Equals("所选要素"))

InputQueryFilter = new QueryFilterClass();

InputQueryFilter.WhereClause = "";

IFeatureSelection pFeatureSelection = featureLayer as IFeatureSelection;

//pFeatureSelection.SelectFeatures(InputQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);

pSelectionSet = pFeatureSelection.SelectionSet;

else if (exportShapeType.Equals("视图范围内所有要素"))

IEnvelope env = EsriCtrlUtil.MapCtrl.Extent;

IGeometry geometry = env as IGeometry;

ISpatialFilter spatialFilter = new SpatialFilterClass();

spatialFilter.Geometry = geometry;

spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

InputQueryFilter = spatialFilter as IQueryFilter;

InputQueryFilter.WhereClause = "";

 

StringBuilder strBuilderSubFields = new StringBuilder();

 

string subFields = "";

IFields pFields = new FieldsClass();

IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;

for (int i = 0; i < pOutFields.FieldCount; i++)

IField pField = pOutFields.get_Field(i);

if (pField.Type == esriFieldType.esriFieldTypeBlob ||

pField.Type == esriFieldType.esriFieldTypeRaster ||

pField.Type == esriFieldType.esriFieldTypeGUID) continue;

if (FieldErrorList.Contains(i))

continue;

pFieldsEdit.AddField(pField);

if (InputQueryFilter != null)

InputQueryFilter.AddField(pField.Name);

strBuilderSubFields.Append(pField.Name + ",");

 

string SubFields = strBuilderSubFields.ToString().Substring(0, strBuilderSubFields.Length - 1);

if (InputQueryFilter != null)

InputQueryFilter.SubFields = SubFields;

 

IGeometryDef pOutGeometryDef;

IGeometryDefEdit pOutGeometryDefEdit;

pOutGeometryDef = pGeoField.GeometryDef;

pOutGeometryDefEdit = (IGeometryDefEdit)pOutGeometryDef;

pOutGeometryDefEdit.GridCount_2 = 1;

pOutGeometryDefEdit.set_GridSize(0, 1500000);

 

 

int strSubIndex = pOutDataset.Name.IndexOf('.');

string fcName = pOutDataset.Name.Substring(strSubIndex + 1, pOutDataset.Name.Length - (strSubIndex + 1));

IFeatureClassName sourceFeatureClassName = new FeatureClassNameClass();

sourceFeatureClassName = (IFeatureClassName)pOutDataset.FullName;

IDatasetName sourceDatasetName = (IDatasetName)sourceFeatureClassName;

 

 

IFeatureDataConverter2 pShpToClsConverter2 = new FeatureDataConverterClass();

pShpToClsConverter2.ConvertFeatureClass(sourceDatasetName, InputQueryFilter, pSelectionSet, null, pInFeatureClassName, pOutGeometryDef, pOutFields, "", 1000, 0);

catch (Exception ex)

throw ex;

 

 

以上是关于ArcEngine 数据导出Shape的几种方式的主要内容,如果未能解决你的问题,请参考以下文章

Hive数据导出的几种方式

Mysql导出数据的几种方式

oracle导入导出数据的几种方式

pandas中查看数据类型的几种方式

PHPWordPHPWord导出PDF格式文件的几种方式以及最优解并附代码

PHPWordPHPWord导出PDF格式文件的几种方式以及最优解并附代码