ArcEngine转换要素类的投影坐标系(20190722)

1、需求

上一篇博客对不同坐标系统之间的转换做了简要的介绍,在此基础之上今天用ArcEngine来实现要素类投影坐标系转换的功能。

2、设计思路

(1)遍历IFeatureWorkspace中的所有shp,将其加到IFeatureClass的列表中,每一个IFeatureClass的Name添加到下拉列表框的Items中;
(2)从下拉框中选择了IFeatureClass实例后,得到实例的SpatialReference属性,将其值作为输入要素类坐标系文本框的Text属性;
(3)通过ESRI.ArcGIS.CatalogUI的ISpatialReferenceDialog2对话框接口选择转入的坐标系;
(4)在DataGridView中输入七参数;
(5)调用转换坐标系的类;
(6)转换坐标系有三个步骤:1、根据输入的路径和文件名,和输入的转入坐标系建立空的shp文件;2、实例化IGeoTransformation接口,通过该接口的PutParameters()和PutSpatialReferences()方法输入七参数和起始和转入的坐标系;(3)通过IGeometry2接口中的ProjectEx()方法转换要素类的坐标系,这里一定要注意Value Z应该为false还是true。

3、界面设计

有了这些分析步骤,设计了如下的界面:
界面设计

4、代码实现

这里主要说一下转换坐标的实现代码,我这里主要是用了四个方法,其中一个集成方法,前端可直接调用,三个工具方法,在集成方法中调用,以及一个基本操作方法——建立空shp文件的方法(DataManager.cs中的静态方法),这里将前两类方法的代码copy在下面:
///
/// 空间参考转换类,转换现要素的空间参考,生成新的shp文件
///
class SpatialRefConversion
{
#region 定义变量
private string TransName;
private ISpatialReference spatialRefFrom;
private ISpatialReference spatialRefTo;
//坐标转换七参数
private double Tx,Ty,Tz,Rx,Ry,Rz,SD;
private IFeatureClass inFeatureClass, outFeatureClass;
//坐标变换接口
IGeoTransformation geoTransformation;
#endregion

    #region 构造函数
    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="pFeatureClass">待转换的要素类</param>
    /// <param name="poutFeatureClass">导出的要素类</param>
    /// <param name="pSpatialRefTo"></param>
    /// <param name="pTx">坐标转换七参数Tx</param>
    /// <param name="pTy">坐标转换七参数Ty</param>
    /// <param name="pTz">坐标转换七参数Tz</param>
    /// <param name="pRx">坐标转换七参数Rx</param>
    /// <param name="pRy">坐标转换七参数Ry</param>
    /// <param name="pRz">坐标转换七参数Rz</param>
    /// <param name="pSD">坐标转换七参数SD</param>
    public SpatialRefConversion(IFeatureClass pFeatureClass,ISpatialReference pSpatialRefTo,
        double pTx,double pTy,double pTz ,double pRx,double pRy,double pRz,double pSD)
    {
        inFeatureClass = pFeatureClass;
        //outFeatureClass = poutFeatureClass;
        TransName = "TransferName";
        IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset;
        spatialRefFrom = pGeoDataset.SpatialReference;
        spatialRefTo = pSpatialRefTo;
        Tx = pTx;
        Ty = pTy;
        Tz = pTz;
        Rx = pRx;
        Ry = pRy;
        Rz = pRz;
        SD = pSD; 
    }
    #endregion


    #region 集成方法,在前端直接调用
    /// <summary>
    /// 转换要素类的坐标系
    /// </summary>
    /// <param name="fileName">目标要素类的名字</param>
    /// <param name="savePath">存储目标要素类的路径</param>
    public void SpatialRefTrans(string fileName,string savePath)
    {
                                                                                                //三个步骤完成坐标系的转换
        outFeatureClass = CreateNewShpFile(inFeatureClass, fileName, savePath, spatialRefTo);   //step.1 建立空的shpfile,以提供复制要素的空间
        geoTransformation = CreateSpatialRefTrans();                                            //step.2 创建坐标转换接口,为IGeometry2接口的ProjectEx()方法提供转换参数
        featureClassTransSpatialRef(inFeatureClass, outFeatureClass);                           //step.3 遍历待复制的要素类,复制图形和属性并改变图形的坐标系
    }
    #endregion


    #region 工具方法,在集成方法中调用
    //step.1 建立空的shpfile,以提供复制要素的空间
    /// <summary>
    /// 建立空的shpfile,以提供复制要素的空间
    /// </summary>
    /// <param name="FromfeatureClass">待转换的要素类</param>
    /// <param name="name">待建立空shp文件名</param>
    /// <param name="savePath">存储空shp文件的路径</param>
    /// <param name="spatialReference">新建shp文件的空间参考(目标坐标系)</param>
    /// <returns>返回建立空shp的要素类</returns>
    private IFeatureClass CreateNewShpFile(IFeatureClass FromfeatureClass, string name, string savePath, ISpatialReference spatialReference)
    {
        IFeatureClass pFeatureClass;
        ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
        string s = FromfeatureClass.ShapeType.ToString();

        //定义属性字段
        DataManager DM = new DataManager();
        IFields pFields = new FieldsClass();
        IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
        IField pField = new FieldClass();
        IFieldEdit pFieldEdit = (IFieldEdit)pField;

        //设置地理属性字段,点线面,空间参考等
        pFieldEdit.Name_2 = "shape";
        pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
        IGeometryDef pGeoDef = new GeometryDefClass();
        IGeometryDefEdit pGeoDefEdit = pGeoDef as IGeometryDefEdit;
        pGeoDefEdit.GeometryType_2 = FromfeatureClass.ShapeType;
        pGeoDefEdit.SpatialReference_2 = spatialReference;
        pGeoDefEdit.HasM_2 = true;
        pGeoDefEdit.HasZ_2 = true;
        pFieldEdit.GeometryDef_2 = pGeoDef;
        pFieldsEdit.AddField(pField);

        //遍历各字段设置其他属性字段
        for (int i = 2; i < FromfeatureClass.Fields.FieldCount; i++)
        {
            pField = new FieldClass();
            pFieldEdit = (IFieldEdit)pField;
            pFieldEdit.Name_2 = FromfeatureClass.Fields.Field[i].Name;
            pFieldEdit.AliasName_2 = FromfeatureClass.Fields.Field[i].AliasName;
            pFieldEdit.Type_2 = FromfeatureClass.Fields.Field[i].Type;
            pFieldsEdit.AddField(pField);
        }
        //建立空的shapefile
        pFeatureClass = DM.CreateVoidShp(savePath, name, pFields, spatialReference);
        return pFeatureClass;
    }

    //step.2 创建坐标转换接口,为IGeometry2接口的ProjectEx()方法提供转换参数
    /// <summary>
    /// 创建坐标转换接口,为IGeometry2接口的ProjectEx()方法提供转换参数
    /// </summary>
    /// <returns>返回根据坐标转换参数创建的坐标转换接口</returns>
    private IGeoTransformation CreateSpatialRefTrans()
    {
        //转换和待转换的坐标系
        IGeographicCoordinateSystem pGeoCoordSysFrom = (spatialRefFrom as IProjectedCoordinateSystem).GeographicCoordinateSystem;
        IGeographicCoordinateSystem pGeoCoordSysTo = (spatialRefTo as IProjectedCoordinateSystem).GeographicCoordinateSystem;
        //定义转换参数
        ICoordinateFrameTransformation pCoordinateFrameTrans = new CoordinateFrameTransformationClass();
        pCoordinateFrameTrans.PutParameters(Tx,Ty,Tz,Rx,Ry,Rz,SD);
        pCoordinateFrameTrans.PutSpatialReferences(pGeoCoordSysFrom, pGeoCoordSysTo);
        pCoordinateFrameTrans.Name = TransName;
        //geoTransformationOperationSet.Set(esriTransformDirection.esriTransformForward, pCoordinateFrameTrans);
        geoTransformation = pCoordinateFrameTrans as IGeoTransformation;
        return geoTransformation;
    }

    //step.3 遍历待复制的要素类,复制图形和属性并改变图形的坐标系
    /// <summary>
    /// 遍历待复制的要素类,复制图形和属性并改变图形的坐标系
    /// </summary>
    /// <param name="fromFeatureClass">待复制的要素类</param>
    /// <param name="toFeatureClass">目标要素类</param>
    private void featureClassTransSpatialRef(IFeatureClass fromFeatureClass,IFeatureClass toFeatureClass)
    {
        IFeature pFeature;
        IGeometry2 pGeometry;
        IFeatureCursor toCursor = toFeatureClass.Insert(true);
        int FeatureCount = fromFeatureClass.FeatureCount(null);
        for (int i = 0; i < FeatureCount; i++)
        {
            pFeature = fromFeatureClass.GetFeature(i);
            pGeometry = pFeature.Shape as IGeometry2;
            IZAware pZAware = pGeometry as IZAware;
            pZAware.ZAware = true;
            pGeometry.ProjectEx(spatialRefTo, esriTransformDirection.esriTransformForward, geoTransformation, false, 0, 0);
            IFeatureBuffer pFeaBuffer = toFeatureClass.CreateFeatureBuffer();
            pFeaBuffer.Shape = pGeometry;
            for (int j = 2; j < fromFeatureClass.Fields.FieldCount; j++)
            {
                try
                {
                    pFeaBuffer.set_Value(j, pFeature.Value[fromFeatureClass.FindField(toFeatureClass.Fields.Field[j].Name)]);
                }
                catch
                {
                    continue;
                }
            }
            toCursor.InsertFeature(pFeaBuffer);
            toCursor.Flush();
        }
    }
    #endregion
}

5、代码分享

源代码可以从github上下载,也欢迎各路大神多多指点:https://github.com/ranhongwu/190722ProjectShp

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C# ArcEngine中更改GDB中要素数据集的坐标系,可以按照以下步骤操作: 1. 打开要素数据集所在的GDB文件: ``` IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactory(); IWorkspace workspace = workspaceFactory.OpenFromFile(@"C:\data\myGDB.gdb", 0); ``` 2. 获取要素数据集: ``` IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace; IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset("myFeatureDataset"); ``` 3. 获取要素数据集的描述对象: ``` IDataset dataset = featureDataset as IDataset; IObjectClassDescription objectClassDescription = new FeatureClassDescriptionClass(); IFields fields = null; IUID uid = objectClassDescription.CLSID; IEnumDataset enumDataset = featureDataset.Subsets; enumDataset.Reset(); IDataset subsetDataset = enumDataset.Next(); while (subsetDataset != null) { if (subsetDataset is IFeatureClass) { IFeatureClass featureClass = subsetDataset as IFeatureClass; if (featureClass.AliasName == "myFeatureClass") { fields = featureClass.Fields; uid = featureClass.ClassID; break; } } subsetDataset = enumDataset.Next(); } ``` 4. 创建新的要素,并设置其坐标系: ``` IFeatureClassDescription newFeatureClassDescription = new FeatureClassDescriptionClass(); IObjectClassDescription newObjectClassDescription = newFeatureClassDescription as IObjectClassDescription; IFieldsEdit newFieldsEdit = new FieldsClass(); IFields newFields = fields; newFieldsEdit.Clone(ref newFields); IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit; bool hasParent = dataset.Category == "Feature Dataset"; IObjectClass newObjectClass = featureDataset.CreateFeatureClass("newFeatureClass", newFieldsEdit, uid, null, esriFeatureType.esriFTSimple, "SHAPE", ""); IDataset newDataset = newObjectClass as IDataset; IGeoDataset geoDataset = newDataset as IGeoDataset; ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass(); ISpatialReference newSpatialReference = spatialReferenceFactory.CreateProjectedCoordinateSystem(3857); //设置新的坐标系 geoDataset.SpatialReference = newSpatialReference; ``` 需要注意的是,更改坐标系可能会影响到数据的准确性和精度,建议在更改前备份数据并谨慎操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值