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;

}

}

 


 

转载自:https://blog.csdn.net/whz1571443359/article/details/79619752

You may also like...