ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FeatureClass投影转换方法总结

2020-05-08 09:56:03  阅读:312  来源: 互联网

标签:name FeatureClass 投影 转换方法 featureClass var null featureDataset out


方法1:使用IGeoDatasetSchemaEdit.AlterSpatialReference

/// <summary>
/// 用于未知空间参考坐标系的数据集赋予空间参考坐标系,且会覆盖已存在的空间参考系
/// </summary>
/// <param name="geoDataset"></param>
/// <param name="spatialReference"></param>
/// <param name="isSucceed"></param>
public void DefineProjection(IGeoDataset geoDataset,ISpatialReference spatialReference, out bool isSucceed)
{
    isSucceed = false;
    IGeoDatasetSchemaEdit geoDatasetSchemaEidt = geoDataset as IGeoDatasetSchemaEdit;
    if (geoDatasetSchemaEidt.CanAlterSpatialReference == true)
    {
        geoDatasetSchemaEidt.AlterSpatialReference(spatialReference);
        isSucceed = true;
    }
}

上面方法相当于实现了 ArcMap Toolbox中的Define Projection, 只做了投影定义,没有起点投影转换作用

参考ArcEngine帮助:


方法2:IFeatureDataConverter.ConvertFeatureClass

/// <summary>
/// 要素类从现有投影转换为新的投影
/// </summary>
/// <param name="featureClass">要素类</param>
/// <param name="newSpatialReference">新的坐标参考系</param>
/// <param name="out_path">输出路径</param>
/// <param name="out_name">输出要素类名</param>
/// <param name="out_featureDataset_name">输出路径为Geodatabae时, 要素数据集名</param>
public void Project( IFeatureClass featureClass, IQueryFilter queryFilter,
    ISpatialReference newSpatialReference, string out_path, string out_name,
    string out_featureDataset_name = null)
{
    var geoDataset = (IGeoDataset)featureClass;
    var spatialReference = geoDataset.SpatialReference;
    IClone comparison = spatialReference as IClone;
    if (comparison.IsEqual((IClone)newSpatialReference))
        return;
    Type factoryType = null;
    string extension = System.IO.Path.GetExtension(out_path);
    if (extension == ".gdb")
    {
        factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
    }
    else if (extension == "")
    {
        factoryType = Type.GetTypeFromProgID("esriDataSourcesFile.ShapefileWorkspaceFactory");
        out_featureDataset_name = null;
    }
    else
        return;
    var out_workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
    var out_workspace = out_workspaceFactory.OpenFromFile(out_path, 0);
    // 删除已存在同名要素类
    IWorkspace2 out_workspace2 = (IWorkspace2)out_workspace;
    IFeatureWorkspace out_featureWorkspace = (IFeatureWorkspace)out_workspace2;
    if (out_workspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, out_name))
    {
        var tmp_dataset = (IDataset)out_featureWorkspace.OpenFeatureClass(out_name);
        tmp_dataset.Delete();
    }
    // 输出要素数据集名
    IFeatureDataset out_featureDataset = null;
    IFeatureDatasetName out_featureDatasetName = null;
    if (!String.IsNullOrWhiteSpace(out_featureDataset_name))
    {
        if (out_workspace2.get_NameExists(esriDatasetType.esriDTFeatureDataset, out_featureDataset_name))
            out_featureDataset = out_featureWorkspace.OpenFeatureDataset(out_featureDataset_name);
        else
            out_featureDataset = out_featureWorkspace.CreateFeatureDataset(out_featureDataset_name,                                                     spatialReference);
        // 判断要素数据集的空间参考系与新参考系是否相同
        var tmp_geoDataset = (IGeoDataset)out_featureDataset;
        var tmp_comparison = tmp_geoDataset.SpatialReference as IClone;
        if (!tmp_comparison.IsEqual((IClone)newSpatialReference))
            return;
        out_featureDatasetName = (IFeatureDatasetName)out_featureDataset.FullName;
    }
    // 输出工作空间名
    IDataset out_dataset = (IDataset)out_workspace;
    IWorkspaceName out_workspaceName = (IWorkspaceName)out_dataset.FullName;
    // 输出FeatureClass名
    IFeatureClassName out_featureClassName = new FeatureClassNameClass();
    IDatasetName out_datasetName = out_featureClassName as IDatasetName;
    out_datasetName.WorkspaceName = out_workspaceName;
    out_datasetName.Name = out_name;
    // 输入的工作空间
    IDataset in_dataset = featureClass as IDataset;
    IFeatureClassName in_featureClassName = in_dataset.FullName as IFeatureClassName;
    IWorkspace in_workspace = in_dataset.Workspace;
    //检查字段的有效性
    IFieldChecker fieldChecker = new FieldCheckerClass();
    fieldChecker.InputWorkspace = in_workspace;
    fieldChecker.ValidateWorkspace = out_workspace;
    IFields in_fields = featureClass.Fields;
    IEnumFieldError enumFieldError;
    IFields out_fields;
    fieldChecker.Validate(in_fields, out enumFieldError, out out_fields);
    // 获取源要素类的空间参考,可以通过获取源要素类中Shape字段的GeometryDef字段获得
    // 这里应该也可以自定义GeometryDef,实现源要素类的投影变换?
    IGeometryDef geometryDef = new GeometryDefClass();
    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
    geometryDefEdit.GeometryType_2 = featureClass.ShapeType;
    geometryDefEdit.SpatialReference_2 = newSpatialReference;
    // 调用IFeatureDataConverter接口进行数据转换
    IFeatureDataConverter featureDataConverter = new FeatureDataConverterClass();
    featureDataConverter.ConvertFeatureClass(
        in_featureClassName,
        queryFilter,
        out_featureDatasetName,
        out_featureClassName,
        geometryDef,
        out_fields,
        "",
        1000,
        0);
}

上面的方法相当于实现了ArcMap的Toolbox中的Project,但是不具备选择地理基准面的转换方式



方法3:通过创建新的FeatureClass,将原有FeatureClass的要素复制到新的FeatureClass的过程中,使用IGeometry5.Project与IGeometry5.ProjectEx对要素进行投影转换

/// <summary>
/// 要素类从现有投影转换为新的投影
/// </summary>
/// <param name="featureClass">要素类</param>
/// <param name="newSpatialReference">新的坐标参考系</param>
/// <param name="out_path">输出路径</param>
/// <param name="out_name">输出要素类名</param>
/// <param name="out_featureDataset_name">输出路径为Geodatabae时, 要素数据集名</param>
/// <param name="esriSRGeoTransformationTypeObject">地理基准面转换方式</param>
/// <returns></returns>
public IFeatureClass Project(
    IFeatureClass featureClass,
    ISpatialReference newSpatialReference,
    string out_path,
    string out_name,
    string out_featureDataset_name = null,
    object esriSRGeoTransformationTypeObject = null)
{
    var geoDataset = (IGeoDataset)featureClass;
    var spatialReference = geoDataset.SpatialReference;
    IClone comparison = spatialReference as IClone;
    if (comparison.IsEqual((IClone)newSpatialReference))
        return null;
    // 检查地理基准面转换
    int gTransformationType = int.MinValue;
    if (esriSRGeoTransformationTypeObject is esriSRGeoTransformationType)
        gTransformationType = (int)esriSRGeoTransformationTypeObject;
    else if (esriSRGeoTransformationTypeObject is esriSRGeoTransformation2Type)
        gTransformationType = (int)esriSRGeoTransformationTypeObject;
    else if (esriSRGeoTransformationTypeObject is esriSRGeoTransformation3Type)
        gTransformationType = (int)esriSRGeoTransformationTypeObject;
    IGeoTransformation geoTransformation = null;
    if (gTransformationType != int.MinValue)
    {
        ISpatialReferenceFactory2 spatialReferenceFactory2 = new SpatialReferenceEnvironmentClass();
        geoTransformation = (IGeoTransformation)spatialReferenceFactory2.CreateGeoTransformation(gTransformationType);
    }
    // 打开输出路径的工作空间
    Type factoryType = null;
    string extension = System.IO.Path.GetExtension(out_path);
    if (extension == ".gdb")
    {
        factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
    }
    else if (extension == "")
    {
        factoryType = Type.GetTypeFromProgID("esriDataSourcesFile.ShapefileWorkspaceFactory");
        out_featureDataset_name = null;
    }
    else
        return null;
    var out_workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
    var out_workspace = out_workspaceFactory.OpenFromFile(out_path, 0);
    var featureWorkspace = (IFeatureWorkspace)out_workspace;
    // 删掉存在的同名要素类
    IFeatureClass out_featureClass = null;
    var workspace2 = (IWorkspace2)out_workspace;
    if (workspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, out_name))
    {
        out_featureClass = featureWorkspace.OpenFeatureClass(out_name);
        ((IDataset)out_featureClass).Delete();
    }
    // 复制属性字段,添加修改的SHAPE字段
    int shapeFieldIndex = featureClass.FindField(featureClass.ShapeFieldName); // 获得Shape字段索引
    IFields out_fields = new FieldsClass();
    IFieldsEdit fieldsEdit = (IFieldsEdit)out_fields;
    for (int i = 0; i < featureClass.Fields.FieldCount; i++)
    {
        if (i == shapeFieldIndex)
        {
            IGeometryDef geometryDef = new GeometryDefClass();
            IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
            geometryDefEdit.GeometryType_2 = featureClass.ShapeType;
            geometryDefEdit.SpatialReference_2 = newSpatialReference;
            IField shpField = new FieldClass();
            IFieldEdit pFieldEdit = (IFieldEdit)shpField;
            pFieldEdit.Name_2 = "SHAPE";
            pFieldEdit.AliasName_2 = "SHAPE";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
            pFieldEdit.GeometryDef_2 = geometryDef;
            fieldsEdit.AddField(shpField); 
        }
        else
        {
            fieldsEdit.AddField(featureClass.Fields.Field[i]);
        }
    }
    // 创建要素类
    if (String.IsNullOrWhiteSpace(out_featureDataset_name))
    {   // 在Geodatabase/Shapefile工作空间建立要素类
        out_featureClass = featureWorkspace.CreateFeatureClass(
            out_name,
            out_fields,
            featureClass.CLSID,
            featureClass.EXTCLSID,
            esriFeatureType.esriFTSimple,
            "Shape",
            "");
    }
    else
    {   // 在Geodatabase的FeatureDataset建立要素类
        IFeatureDataset featureDataset = null;
        if (workspace2.get_NameExists(esriDatasetType.esriDTFeatureDataset, out_featureDataset_name))
            featureDataset = featureWorkspace.OpenFeatureDataset(out_featureDataset_name);
        else
            featureDataset = featureWorkspace.CreateFeatureDataset(out_featureDataset_name, spatialReference);
        out_featureClass = featureDataset.CreateFeatureClass(
            out_name,
            out_fields,
            featureClass.CLSID,
            featureClass.EXTCLSID,
            esriFeatureType.esriFTSimple,
            "Shape",
            "");
        Marshal.ReleaseComObject(featureDataset);
    }
    // 生成两个要素类字段的对应表
    Dictionary<int, int> fieldsDictionary = new Dictionary<int, int>();
    for (int i = 0; i < featureClass.Fields.FieldCount; i++)
    {
        if (featureClass.Fields.Field[i].Editable == false)
            continue; // 跳过系统自动生成的不可编辑的字段
        string field_name = featureClass.Fields.Field[i].Name.ToUpper();
        for (int j = 0; j < out_featureClass.Fields.FieldCount; j++)
        {
            string field_name2 = out_featureClass.Fields.Field[j].Name.ToUpper();
            if (field_name == field_name2)
                fieldsDictionary.Add(i, j);
        }
    }
    // 向输出要素类中添加要素
    var searchFeatureCursor = featureClass.Search(null, false);
    var insertFeatureCursor = out_featureClass.Insert(true);
    IFeatureBuffer insertFeatureBuffer = out_featureClass.CreateFeatureBuffer();
    IFeature feature = searchFeatureCursor.NextFeature();
    int index = 0;
    while (feature != null)
    {
        // 复制要素的属性值
        foreach (KeyValuePair<int, int> keyValue in fieldsDictionary)
        {
            if (keyValue.Key == shapeFieldIndex) // 投影转换
            {
                IGeometry5 geometry = feature.ShapeCopy as IGeometry5;
                if (geoTransformation == null)
                    geometry.Project(newSpatialReference);
                else geometry.ProjectEx(newSpatialReference,esriTransformDirection.esriTransformForward,geoTransformation, false, 0, 0);
                insertFeatureBuffer.Shape = geometry;
            }
            else
            {
                insertFeatureBuffer.set_Value(keyValue.Value, feature.get_Value(keyValue.Key));
            }
        }
        insertFeatureCursor.InsertFeature(insertFeatureBuffer);
        feature = searchFeatureCursor.NextFeature();
        if (index++ % 1000 == 0) insertFeatureCursor.Flush();
    }
    insertFeatureCursor.Flush();
    Marshal.ReleaseComObject(spatialReference);
    Marshal.ReleaseComObject(out_workspace);
    Marshal.ReleaseComObject(searchFeatureCursor);
    Marshal.ReleaseComObject(insertFeatureCursor);
    Marshal.ReleaseComObject(insertFeatureBuffer);
    return out_featureClass;
}

上面的方法相当于实现了ArcMap的ToolBox中的Project,具备可选地理基准面的转换方式

标签:name,FeatureClass,投影,转换方法,featureClass,var,null,featureDataset,out
来源: https://www.cnblogs.com/King2019Blog/p/12848669.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有