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的几种方式的主要内容,如果未能解决你的问题,请参考以下文章