方法一
創建一個shape要素類,結果與導出要素類一致,保存使用store速度最慢,忽略
方法二
使用IFeatureBuffer速度較快,缺點:數據量大,導出的時候容易報內存損壞錯誤使程序崩潰
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.Field[shapeFieldIndex];
IGeometryDef geometryDef = field.GeometryDef;
IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
if (featureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon)
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
else if (featureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
else if (featureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
IProjectedCoordinateSystem tProjectedCoordinateSystem = (featureLayer as IGeoDataset).SpatialReference as 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);
GC.Collect(); // 強制對所有代進行垃圾回收。
GC.WaitForPendingFinalizers(); //掛起當前線程,直到處理終結器隊列的線程清空該隊列為止。
pFeatureBuffer = shpFeatureClass.CreateFeatureBuffer();
pFeatureCursor = shpFeatureClass.Insert(true);
pFeatureTarget = pFeatureBuffer as IFeature;
}
pFeatureSource = pFeatureCursorSource.NextFeature();
}
pFeatureCursor.Flush();
Marshal.FinalReleaseComObject(pFeatureCursor);
if (pFeatureBuffer != null)
Marshal.FinalReleaseComObject(pFeatureBuffer);
Marshal.FinalReleaseComObject(pFeatureCursorSource);
//釋放
GC.Collect();
GC.WaitForPendingFinalizers();
ZzCom.CommonUtil.SimpleWaiterHelper.SetValue(totalCount);
MediaTypeNames.Application.DoEvents();
}
catch (Exception e)
{
ZzLog4net.ZzLogUtil.Logger.LogInfo(string.Format("異常信息:{0} 異常位置:{1} 時間:'{2}'", e.Message, e,
DateTime.Now));
throw e;
}
finally
{
}
}
方法三
使用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) 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.Field[(int) iCounter].Type != esriFieldType.esriFieldTypeGeometry)
continue;
pGeoField = pOutFields.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 {WhereClause = ""};
else if (exportShapeType.Equals("所選要素"))
{
inputQueryFilter = new QueryFilterClass
{
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;
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = geometry;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
inputQueryFilter = spatialFilter;
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;
}
}
private int ExportToShapefile(IFeatureClass pFeatureClass, IWorkspace outWorkspace)
{
try
{
//輸入的要素類空間
IDataset inDataSet = pFeatureClass as IDataset;
if (inDataSet != null)
{
IFeatureClassName inFcName = inDataSet.FullName as IFeatureClassName;
IWorkspace inWorkspace = inDataSet.Workspace;
//輸出的shapfile文件的工作空間
IDataset outDataSet = outWorkspace as IDataset;
IWorkspaceName outWorkspaceName = outDataSet.FullName as IWorkspaceName;
IFeatureClassName outFCName = new FeatureClassNameClass();
IDatasetName dataSetName = (IDatasetName) outFCName;
dataSetName.WorkspaceName = outWorkspaceName;
dataSetName.Name = pFeatureClass.AliasName;
//檢查字段的有效性
IFieldChecker fieldChecker = new FieldCheckerClass();
fieldChecker.InputWorkspace = inWorkspace;
fieldChecker.ValidateWorkspace = outWorkspace;
IFields fields = pFeatureClass.Fields;
IFields outFields;
IEnumFieldError enumFieldError = null;
fieldChecker.Validate(fields, out enumFieldError, out outFields);
//調用IFeatureDataConverter接口進行數據轉換
IFeatureDataConverter featureDataConverter = new FeatureDataConverterClass();
featureDataConverter.ConvertFeatureClass(inFcName, null, null, outFCName, null, outFields, "", 100, 0);
}
}
catch
{
return 0;
}
return 1;
}
方法四
使用GP服務調用ESRI.ArcGIS.ConversionTools.FeatureClassToShapefile工具
private void btnSdeToShp_Click(object sender, EventArgs e)
{
string sDBName = "TEST";
string SdeConnFilePath = @"E:\temp\DBConnettion\ConnectionTo" + sDBName + ".sde";
string destiShpPath = @"E:\temp\SHP";
IWorkspace psdeWorkspace = db.OpenSdeWorkspace(sDBName, SdeConnFilePath);
IFeatureWorkspace pFeaWs = psdeWorkspace as IFeatureWorkspace;
IFeatureClass pFeatureClass = pFeaWs.OpenFeatureClass("TEST.dbo.ZD");
Geoprocessor gp = new Geoprocessor();
gp.OverwriteOutput = true;
ESRI.ArcGIS.ConversionTools.FeatureClassToShapefile covertToshp =
new ESRI.ArcGIS.ConversionTools.FeatureClassToShapefile();
covertToshp.Input_Features = pFeatureClass;
covertToshp.Output_Folder = destiShpPath;
try
{
gp.Execute(covertToshp, null);
}
catch (Exception ex)
{
string str = "";
for (int i = 0; i < gp.MessageCount; i++)
{
str += gp.GetMessage(i);
str += "\n";
}
MessageBox.Show(str);
}
}
