ArcEngine 數據導出Shape的幾種方式


方法一

​ 創建一個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);

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM