AE实现批量修改SHP文件坐标系

因老板提到了一个需求,要求写一个小程序,能够批量修改shp文件的坐标系,自己思考了一下,可能关键的问题在于更改坐标系时对应shp文件中各个要素的坐标要跟着转换。关于使用AE里面哪些接口开始也是一头雾水,于是咨询了一下esri的小醉老师,感谢他提供的几种思路。自己研究了好几天,最后终于算是实现了,又学到了不少东西,拿出来分享一下。

先总结一下实现的方法思路:

1、使用IGeoDatasetSchemaEdit方法:只是更改prj文件,要素坐标并没有跟着转换过来,参见ESRI帮助文档解释:

Note that the AlterSpatialReference method does not project or otherwise modify the existing data in the dataset-this method merely rewrites the spatial reference associated with the dataset. The caller is responsible for ensuring the correctness and appropriateness of the supplied spatial reference. Its most common use is to supply spatial reference for dataset whose spatial reference is currently tagged as Unknown.

注:ArcCatalog也可更改已有shp文件的坐标系,但只是修改prj文件,要素坐标并没有跟着改变;

2、使用Project方法:Project只是获取数据,需要新创建shp文件,把几何数据写入,可行;

注:通过打开要素类编辑会话,然后依次pFeature.Shape.project(**)和pFeature.Store()的方法貌似不行,所以需要获取project后的坐标,写入新创建的FeatureClass中;
3、使用IFeatureDataConverter.ConvertFeatureClass方法:重新定义空间参考,可行;
4、使用GP工具:可行;

 

最后将使用ConvertFeatureClass和GP工具的代码分享一下:

(1)使用ConvertFeatureClass方法(红色部分是关键):

 public void ConvertFeatureClass(IWorkspaceFactory _pSWorkspaceFactory, String _pSWs, string _pSName, IWorkspaceFactory _pTWorkspaceFactory, String _pTWs, string _pTName)
        {
            try
            {
                // 打开工作空间
                IWorkspace pSWorkspace _pSWorkspaceFactory.OpenFromFile(_pSWs, 0);
                IWorkspace pTWorkspace _pTWorkspaceFactory.OpenFromFile(_pTWs, 0);

                IFeatureWorkspace pFtWs pSWorkspace as IFeatureWorkspace;
                IFeatureClass pSourceFeatureClass pFtWs.OpenFeatureClass(_pSName);
                IDataset pSDataset pSourceFeatureClass as IDataset;

                IFeatureClassName pSourceFeatureClassName pSDataset.FullName as IFeatureClassName;
                IDataset pTDataset (IDataset)pTWorkspace;
                IName pTDatasetName pTDataset.FullName;
                IWorkspaceName pTargetWorkspaceName (IWorkspaceName)pTDatasetName;
                IFeatureClassName pTargetFeatureClassName new FeatureClassNameClass();

                IDatasetName pTargetDatasetName (IDatasetName)pTargetFeatureClassName;
                pTargetDatasetName.Name _pTName;
                pTargetDatasetName.WorkspaceName pTargetWorkspaceName;


                // 创建字段检查对象
                IFieldChecker pFieldChecker new FieldCheckerClass();
                IFields sourceFields pSourceFeatureClass.Fields;
                IFields pTargetFields null;
                IEnumFieldError pEnumFieldError null;


                pFieldChecker.InputWorkspace pSWorkspace;
                pFieldChecker.ValidateWorkspace pTWorkspace;

                // 验证字段
                pFieldChecker.Validate(sourceFields, out pEnumFieldError, out pTargetFields);
                if (pEnumFieldError != null)
                {
                    Console.WriteLine("Errors were encountered during field validation.");
                }


                // 获取源要素类的空间参考,可以通过获取源要素类中Shape字段的GeometryDef字段获得
                // 这里应该也可以自定义GeometryDef,实现源要素类的投影变换?
                String pShapeFieldName pSourceFeatureClass.ShapeFieldName;
                int pFieldIndex pSourceFeatureClass.FindField(pShapeFieldName);
                IField pShapeField sourceFields.get_Field(pFieldIndex);


                IGeometryDef geometryDef new GeometryDefClass();
                IGeometryDefEdit geometryDefEdit (IGeometryDefEdit)geometryDef;
                geometryDefEdit.GeometryType_2 ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint;

                // 定义新的空间参考
                ISpatialReferenceFactory pSpatialReferFac new SpatialReferenceEnvironmentClass();
                ISpatialReference pSpatialRefer pSpatialReferFac.CreateGeographicCoordinateSystem((int)4214);
                if (pSpatialRefer != null)
                {
                    geometryDefEdit.SpatialReference_2 pSpatialRefer;
                }
                //IGeometryDef pTargetGeometryDef pShapeField.GeometryDef;
                IGeometryDef pTargetGeometryDef geometryDef;


                // 创建要素转换对象
                IFeatureDataConverter pFDConverter new FeatureDataConverterClass();

                IEnumInvalidObject pEnumInvalidObject pFDConverter.ConvertFeatureClass

                    (pSourceFeatureClassName, null, null, pTargetFeatureClassName,
                    pTargetGeometryDef, pTargetFields, "", 1000, 0);

                IInvalidObjectInfo pInvalidInfo null;
                pEnumInvalidObject.Reset();
                while ((pInvalidInfo pEnumInvalidObject.Next()) != null)
                {
                    Console.WriteLine("Errors occurred for the following feature: {0}",
                        pInvalidInfo.InvalidObjectID);
                }
                
                // 执行成功
                MessageBox.Show("转换成功!");
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

 

(2)使用GP工具:

       Geoprocessor gp new Geoprocessor();
            // 定义新的空间参考
            ISpatialReferenceFactory pSpaRefFactory new SpatialReferenceEnvironmentClass();
            ISpatialReference SpatialRefNingbo pSpaRefFactory.CreateESRISpatialReferenceFromPRJFile(Application.StartupPath "");
            ISpatialReference SpatialRef54 pSpaRefFactory.CreateESRISpatialReferenceFromPRJFile(Application.StartupPath "1954.prj");
            Project prj new Project();
            //prj.in_coor_system SpatialRefNingbo;
            //prj.out_coor_system SpatialRef54;
            prj.out_coor_system SpatialRefNingbo;
            prj.in_coor_system SpatialRef54;
            prj.in_dataset @"E:\测试\CopyShpFields\testPt_Project.shp";
            prj.out_dataset @"E:\测试\CopyShpFields\testPt_Project_Project.shp";
            IGeoProcessorResult result gp.Execute(prj, null) as IGeoProcessorResult;
            //判断叠置分析是否成功
            if (result.Status != esriJobStatus.esriJobSucceeded)
                MessageBox.Show("执行失败!");
            else
                MessageBox.Show("执行成功!");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用说明 本程序可以一次性对多个SHP文件增加相 同字段.增加多个字段请输入字段名和类 型,长度等不同参数即可实现. 要注意的 是, 存放SHP文件夹一定不能中文命名 1. 请把本程序复制到 SHP文件夹中运行 例如复制到D:\123,将对D盘下123目录中 的所有SHP文件进行运算(包括子文件夹) 2. 因为 ARCMAP 的命令不支持中文文件名 所以存放SHP 的文文件夹请不要以中文 命名或特殊符号命名 3. ARCMAP的命令行不支持以数字开头.但可 在字段后面加数字,如CODE1,CODE2.所以 字段名不要用到数字开头,确实要用到数 字的请把SHP文转成TAB在MAPINFO里修改 但奇怪的是,直接在属性列表中却可以添 加以数字开头的字段 4. 在运行程序后,请把弹出的记事本内容复 制到ARCMAP的命令行里粘帖后回车即可 5. 在XPSP2和2003SERVER系统中可以执行 不能在98中运行,2000的系统没测试 6.(还请哪位精通批处理的大侠指点一下) 目前尚有一个问题没有解决,就是同一类型 的字段如果要加二个,不能连着加.得关了程 序再开才能进行.否则弹的记事本内容中,前 面的内容还是上次的字段路径. 但可以连着加不同的字段类型. 比如加完TEXT类型的字段.不能接着加TEXT 类型的字段,但可以加DATE/FLOAT等其他类型 ___________________________________ 如果不能运行或出现其他错误,请到我的 百度空间留言说明你的情况及建议: http://hi.baidu.com/lgx8280998 -----为解决问题而学习 BY 千浪 2009-03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值